Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68e0858177 | ||
|
|
9a44550e2e | ||
|
|
916389ca55 | ||
|
|
c71ed9a982 | ||
|
|
c7ad45ebbb | ||
|
|
56ccc04f2a | ||
|
|
be030c2ae9 | ||
|
|
b8f1b81c0f | ||
|
|
31fcf4ea83 | ||
|
|
5a48735f36 | ||
|
|
97fb9014f3 | ||
|
|
6580f1d261 |
@@ -0,0 +1,46 @@
|
||||
# Wallitor
|
||||
|
||||
A dynamic wallpaper software build with tauri.
|
||||
|
||||
## Setup
|
||||
|
||||
This project has two parts, core and GUI.
|
||||
|
||||
### Core
|
||||
|
||||
Build solution with *MSVC*, you'll get a dynamic library.
|
||||
|
||||
### GUI
|
||||
|
||||
GUI is build with *tauri* and *vite+vue*, using *pnpm* as package manager.
|
||||
|
||||
1. Install node packages.
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
2. Build project
|
||||
|
||||
```bash
|
||||
pnpm tauri build --no-bundle
|
||||
```
|
||||
|
||||
### Combination
|
||||
|
||||
Copy libracy and place in the same directory with executable file.
|
||||
|
||||
## Releases
|
||||
|
||||
See [Release](https://github.com/RogerChen2005/wallitor/releases)
|
||||
|
||||
## Contributions
|
||||
|
||||
Welcome Issues and PRs!
|
||||
|
||||
## Acknowledgement
|
||||
|
||||
Wallitor was based on these projects:
|
||||
|
||||
* [tauri-apps/tauri](https://github.com/tauri-apps/tauri): Build smaller, faster, and more secure desktop applications with a web frontend.
|
||||
* [vitejs/vite](https://github.com/vitejs/vite): Next generation frontend tooling. It's fast!
|
||||
* [vuejs/vue](https://github.com/vuejs/vue): Vue is a **progressive framework** for building user interfaces.
|
||||
@@ -1,22 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "conFig.h"
|
||||
|
||||
conFig::conFig(const char* ffpath,const char* videoPath, BOOL mute) {
|
||||
std::string tmp =ffpath;
|
||||
this->ffpath = std::wstring(tmp.begin(), tmp.end());
|
||||
tmp = videoPath;
|
||||
this->videoPath = std::wstring(tmp.begin(), tmp.end());
|
||||
this->mute = mute;
|
||||
}
|
||||
|
||||
conFig::conFig(const conFig& config) {
|
||||
this->ffpath = config.ffpath;
|
||||
this->mute = config.mute;
|
||||
this->videoPath = config.videoPath;
|
||||
}
|
||||
|
||||
conFig::conFig() {
|
||||
this->ffpath = L"";
|
||||
this->mute = TRUE;
|
||||
this->videoPath = L"";
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
class conFig
|
||||
{
|
||||
public:
|
||||
std::wstring ffpath;
|
||||
std::wstring videoPath;
|
||||
BOOL mute;
|
||||
conFig(const char* ffpath, const char* videoPath,BOOL mute);
|
||||
conFig(const conFig& config);
|
||||
conFig();
|
||||
};
|
||||
|
||||
@@ -18,18 +18,10 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
playerInstance* player_instance = NULL;
|
||||
|
||||
extern "C" __declspec(dllexport) void init(const char* ffpath,const char* videoPath, BOOL mute) {
|
||||
player_instance = new playerInstance(conFig(ffpath, videoPath, mute));
|
||||
player_instance->generate();
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void destroy() {
|
||||
player_instance->exit();
|
||||
delete player_instance;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) BOOL set_wallpaper(const char* window_title) {
|
||||
return set_as_wallpaper(window_title);
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) BOOL any_maximized() {
|
||||
return !detectWindowMaximized();
|
||||
}
|
||||
@@ -1,89 +1,64 @@
|
||||
#include "pch.h"
|
||||
#include "playerInstance.h"
|
||||
|
||||
playerInstance::playerInstance(const conFig& config) {
|
||||
this->config = config;
|
||||
this->hFfplay = NULL;
|
||||
}
|
||||
HWND hWorkerw = NULL;
|
||||
|
||||
static BOOL CALLBACK EnumWindowsProc(_In_ HWND hwnd, _In_ LPARAM Lparam) {
|
||||
HWND hDefView = FindWindowEx(hwnd, 0, L"SHELLDLL_DefView", 0);
|
||||
if (hDefView != 0) {
|
||||
HWND hWorkerw = FindWindowEx(0, hwnd, L"WorkerW", 0);
|
||||
ShowWindow(hWorkerw, SW_HIDE);
|
||||
hWorkerw = FindWindowEx(0, hwnd, L"WorkerW", 0);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL playerInstance::showWindow(LPCWSTR lpParameter) {
|
||||
if (this->hFfplay != NULL) {
|
||||
DWORD dwPID = 0;
|
||||
GetWindowThreadProcessId(hFfplay, &dwPID);
|
||||
char strCmd[MAX_PATH] = { 0 };
|
||||
sprintf_s(strCmd, "taskkill /pid %d -f", dwPID);
|
||||
system(strCmd);
|
||||
}
|
||||
STARTUPINFO si{ 0 };
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
PROCESS_INFORMATION pi{ 0 };
|
||||
if (CreateProcess(this->config.ffpath.c_str(), (LPWSTR)lpParameter, 0, 0, 0, CREATE_NO_WINDOW, 0, 0, &si, &pi)) {
|
||||
Sleep(600);//等待视频播放器启动完成
|
||||
HWND hProgman = FindWindow(L"Progman", 0);// 找到PI窗口
|
||||
SendMessageTimeout(hProgman, 0x052c, 0, 0, 0, 100, 0);// 给它发特殊消息
|
||||
this->hFfplay = FindWindowW(L"SDL_app", 0);// 找到视频窗口
|
||||
SetParent(hFfplay, hProgman);// 将视频窗口设苦为PM的子窗口
|
||||
int systemWidth = GetSystemMetrics(0);
|
||||
int systemHeight = GetSystemMetrics(1);
|
||||
RECT cRct;
|
||||
GetWindowRect(hFfplay, &cRct);
|
||||
//if (horw) {
|
||||
int width = cRct.right - cRct.left;
|
||||
int x = (systemWidth - width) / 2;
|
||||
MoveWindow(hFfplay, 0, 0, systemWidth, systemHeight, 1);
|
||||
/* }
|
||||
else {
|
||||
int height = cRct.bottom - cRct.top;
|
||||
int x = (sheight - height) / 2;
|
||||
MoveWindow(hFfplay, 0, x, cRct.right - cRct.left, cRct.bottom - cRct.top, 0);
|
||||
}*/
|
||||
EnumWindows(EnumWindowsProc, 0);// 找到第二个workerw窗口并隐藏它
|
||||
BOOL try_find_worker(HWND hProgman,HWND hPlayer) {
|
||||
HWND hWorkerW = FindWindowEx(hProgman, 0, L"WorkerW", 0);
|
||||
if (hWorkerW != NULL) {
|
||||
SetParent(hPlayer, hWorkerW);
|
||||
return TRUE;
|
||||
}
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return FALSE;
|
||||
else return FALSE;
|
||||
}
|
||||
|
||||
void playerInstance::generate() {
|
||||
std::wstring fcmd = L" \"";
|
||||
fcmd += this->config.videoPath + L"\"";
|
||||
fcmd += L" -noborder -loop 0";
|
||||
if (this->config.mute) {
|
||||
fcmd += L" -an";
|
||||
}
|
||||
fcmd += L" -fs";
|
||||
this->showWindow(fcmd.c_str());
|
||||
}
|
||||
|
||||
void playerInstance::exit() {
|
||||
if (this->hFfplay != NULL) {
|
||||
DWORD dwPID = 0;
|
||||
GetWindowThreadProcessId(this->hFfplay, &dwPID);
|
||||
char strCmd[MAX_PATH] = { 0 };
|
||||
sprintf_s(strCmd, "taskkill /pid %d -f", dwPID);
|
||||
system(strCmd);
|
||||
}
|
||||
HWND shell_in_progman(HWND hProgman) {
|
||||
HWND hShell = FindWindowEx(hProgman, 0, L"SHELLDLL_DefView", 0);
|
||||
return hShell;
|
||||
}
|
||||
|
||||
BOOL set_as_wallpaper(const char* window_title) {
|
||||
HWND hProgman = FindWindow(L"Progman", 0);// 找到PI窗口
|
||||
SendMessageTimeout(hProgman, 0x052c, 0, 0, 0, 100, 0);// 给它发特殊消息
|
||||
SendMessageTimeout(hProgman, 0x052c, 0, 0, SMTO_NORMAL, 0x3e8, 0);// 给它发特殊消息
|
||||
std::string tmp = window_title;
|
||||
HWND player = FindWindowW(0, std::wstring(tmp.begin(), tmp.end()).c_str());// 找到视频窗口
|
||||
if (player == NULL) return FALSE;
|
||||
SetParent(player, hProgman);// 将视频窗口设苦为PM的子窗口
|
||||
EnumWindows(EnumWindowsProc, 0);// 找到第二个workerw窗口并隐藏它
|
||||
HWND hPlayer = FindWindowW(0, std::wstring(tmp.begin(), tmp.end()).c_str());// 找到视频窗口
|
||||
if (hPlayer == NULL) return FALSE;
|
||||
HWND hDefView = shell_in_progman(hProgman);
|
||||
if (hDefView!=NULL) {
|
||||
if (try_find_worker(hProgman, hPlayer)) {
|
||||
ShowWindow(hDefView, SW_HIDE);
|
||||
Sleep(0);
|
||||
ShowWindow(hDefView, SW_SHOWNORMAL);
|
||||
return TRUE;
|
||||
}
|
||||
else return FALSE;
|
||||
}
|
||||
else {
|
||||
SetParent(hPlayer, hProgman);// 将视频窗口设苦为PM的子窗口
|
||||
EnumWindows(EnumWindowsProc, 0);// 找到第二个workerw窗口并隐藏它
|
||||
if (hWorkerw) {
|
||||
ShowWindow(hWorkerw, SW_HIDE);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL CALLBACK CheckMaximized(_In_ HWND hwnd, _In_ LPARAM Lparam) {
|
||||
BOOL isMaximized = IsZoomed(hwnd);
|
||||
if (isMaximized) return FALSE;
|
||||
else return TRUE;
|
||||
}
|
||||
|
||||
BOOL detectWindowMaximized() {
|
||||
return EnumWindows(CheckMaximized, 0);
|
||||
}
|
||||
@@ -1,16 +1,5 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "conFig.h"
|
||||
class playerInstance
|
||||
{
|
||||
private:
|
||||
HWND hFfplay;
|
||||
conFig config;
|
||||
public:
|
||||
playerInstance(const conFig& config);
|
||||
BOOL showWindow(LPCWSTR lpParameter);
|
||||
void generate();
|
||||
void exit();
|
||||
};
|
||||
|
||||
BOOL set_as_wallpaper(const char* window_title);
|
||||
BOOL detectWindowMaximized();
|
||||
@@ -142,13 +142,11 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="conFig.h" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="playerInstance.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="conFig.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
<ClInclude Include="playerInstance.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="conFig.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
@@ -38,8 +35,5 @@
|
||||
<ClCompile Include="playerInstance.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="conFig.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,39 +0,0 @@
|
||||
# wallitor-gui
|
||||
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
||||
|
||||
## Type Support for `.vue` Imports in TS
|
||||
|
||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
pnpm install
|
||||
```
|
||||
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
### Type-Check, Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
pnpm build
|
||||
```
|
||||
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
|
||||
```sh
|
||||
pnpm lint
|
||||
```
|
||||
@@ -14,6 +14,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.0.0-rc.0",
|
||||
"@tauri-apps/plugin-autostart": "^2.0.0",
|
||||
"@tauri-apps/plugin-dialog": "^2.0.0",
|
||||
"@tauri-apps/plugin-fs": "2.0.0-rc.2",
|
||||
"element-plus": "^2.8.5",
|
||||
|
||||
@@ -11,6 +11,9 @@ importers:
|
||||
'@tauri-apps/api':
|
||||
specifier: 2.0.0-rc.0
|
||||
version: 2.0.0-rc.0
|
||||
'@tauri-apps/plugin-autostart':
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
'@tauri-apps/plugin-dialog':
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
@@ -645,6 +648,9 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
hasBin: true
|
||||
|
||||
'@tauri-apps/plugin-autostart@2.0.0':
|
||||
resolution: {integrity: sha512-NEwOQWVasZ8RczXkMLNJokRDujneuMH/UFA5t84DLkbNZUmiD3G7HZWhgSd1YQ0BFU9h9w+h2B/py3y6bzWg4Q==}
|
||||
|
||||
'@tauri-apps/plugin-dialog@2.0.0':
|
||||
resolution: {integrity: sha512-ApNkejXP2jpPBSifznPPcHTXxu9/YaRW+eJ+8+nYwqp0lLUtebFHG4QhxitM43wwReHE81WAV1DQ/b+2VBftOA==}
|
||||
|
||||
@@ -3092,6 +3098,10 @@ snapshots:
|
||||
'@tauri-apps/cli-win32-ia32-msvc': 2.0.0-rc.16
|
||||
'@tauri-apps/cli-win32-x64-msvc': 2.0.0-rc.16
|
||||
|
||||
'@tauri-apps/plugin-autostart@2.0.0':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.0.2
|
||||
|
||||
'@tauri-apps/plugin-dialog@2.0.0':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.0.2
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
/gen/schemas
|
||||
resource/
|
||||
wallitor-core.dll
|
||||
settings.json
|
||||
@@ -103,6 +103,30 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-executor"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
|
||||
dependencies = [
|
||||
"async-task",
|
||||
"concurrent-queue",
|
||||
"fastrand",
|
||||
"futures-lite",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-fs"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"blocking",
|
||||
"futures-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "2.3.4"
|
||||
@@ -227,6 +251,17 @@ version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||
|
||||
[[package]]
|
||||
name = "auto-launch"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f012b8cc0c850f34117ec8252a44418f2e34a2cf501de89e29b241ae5f79471"
|
||||
dependencies = [
|
||||
"dirs 4.0.0",
|
||||
"thiserror",
|
||||
"winreg 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
@@ -744,13 +779,33 @@ dependencies = [
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||
dependencies = [
|
||||
"dirs-sys 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
"dirs-sys 0.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -841,7 +896,7 @@ dependencies = [
|
||||
"rustc_version",
|
||||
"toml 0.8.2",
|
||||
"vswhom",
|
||||
"winreg",
|
||||
"winreg 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2052,7 +2107,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
|
||||
dependencies = [
|
||||
"malloc_buf",
|
||||
"objc_exception",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2071,6 +2125,9 @@ name = "objc-sys"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2"
|
||||
@@ -2098,6 +2155,30 @@ dependencies = [
|
||||
"objc2-quartz-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-cloud-kit"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-core-location",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-contacts"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889"
|
||||
dependencies = [
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-data"
|
||||
version = "0.2.2"
|
||||
@@ -2122,6 +2203,18 @@ dependencies = [
|
||||
"objc2-metal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-location"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781"
|
||||
dependencies = [
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-contacts",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-encode"
|
||||
version = "4.0.3"
|
||||
@@ -2140,6 +2233,18 @@ dependencies = [
|
||||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-link-presentation"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398"
|
||||
dependencies = [
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-metal"
|
||||
version = "0.2.2"
|
||||
@@ -2166,12 +2271,71 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc_exception"
|
||||
version = "0.1.2"
|
||||
name = "objc2-symbols"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4"
|
||||
checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-ui-kit"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-cloud-kit",
|
||||
"objc2-core-data",
|
||||
"objc2-core-image",
|
||||
"objc2-core-location",
|
||||
"objc2-foundation",
|
||||
"objc2-link-presentation",
|
||||
"objc2-quartz-core",
|
||||
"objc2-symbols",
|
||||
"objc2-uniform-type-identifiers",
|
||||
"objc2-user-notifications",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-uniform-type-identifiers"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe"
|
||||
dependencies = [
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-user-notifications"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-core-location",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-web-kit"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68bc69301064cebefc6c4c90ce9cba69225239e4b8ff99d445a2b5563797da65"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3342,13 +3506,13 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "tauri"
|
||||
version = "2.0.0-rc.16"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "246bd333561c5601241b7a09f19957d5f659667f3c1191c869a066fb309e1841"
|
||||
checksum = "44438500b50708bfc1e6083844e135d1b516325aae58710dcd8fb67e050ae87c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
"dirs",
|
||||
"dirs 5.0.1",
|
||||
"dunce",
|
||||
"embed_plist",
|
||||
"futures-util",
|
||||
@@ -3392,13 +3556,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-build"
|
||||
version = "2.0.0-rc.13"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5bc30f14b3c1548d75dfdf3e40bffe20a53bc4e3381e9bacc21dc765d701d0a"
|
||||
checksum = "935f9b3c49b22b3e2e485a57f46d61cd1ae07b1cbb2ba87387a387caf2d8c4e7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cargo_toml",
|
||||
"dirs",
|
||||
"dirs 5.0.1",
|
||||
"glob",
|
||||
"heck 0.5.0",
|
||||
"json-patch",
|
||||
@@ -3414,9 +3578,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-codegen"
|
||||
version = "2.0.0-rc.13"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1cfb6089cfc626b81bb8aa4692ede527732011dfd22486d8ac5bf299189841f"
|
||||
checksum = "95d7443dd4f0b597704b6a14b964ee2ed16e99928d8e6292ae9825f09fbcd30e"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"brotli",
|
||||
@@ -3441,9 +3605,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-macros"
|
||||
version = "2.0.0-rc.12"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f04ed6fadd294ef8061137463fe31abccbb5fa61ff9946aab2896acd140cff1"
|
||||
checksum = "4d2c0963ccfc3f5194415f2cce7acc975942a8797fbabfb0aa1ed6f59326ae7f"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
@@ -3455,9 +3619,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin"
|
||||
version = "2.0.0-rc.13"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6de7ffe64afa61c4cc13d450d64643b8db6cbb177a802beb88bf595594505ddf"
|
||||
checksum = "b2e6660a409963e4d57b9bfab4addd141eeff41bd3a7fb14e13004a832cf7ef6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"glob",
|
||||
@@ -3470,6 +3634,21 @@ dependencies = [
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-autostart"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bba6bb936e0fd0a58ed958b49e2e423dd40949c9d9425cc991be996959e3838e"
|
||||
dependencies = [
|
||||
"auto-launch",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-dialog"
|
||||
version = "2.0.0-rc.7"
|
||||
@@ -3531,10 +3710,25 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime"
|
||||
version = "2.0.0-rc.13"
|
||||
name = "tauri-plugin-single-instance"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d9465366fd7f9e9c77385fa8b7cb583b060544e8800bd0309deb100008c312d"
|
||||
checksum = "a25ac834491d089699a2bc9266a662faf373c9f779f05a2235bc6e4d9e61769a"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"thiserror",
|
||||
"windows-sys 0.59.0",
|
||||
"zbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8f437293d6f5e5dce829250f4dbdce4e0b52905e297a6689cc2963eb53ac728"
|
||||
dependencies = [
|
||||
"dpi",
|
||||
"gtk",
|
||||
@@ -3551,9 +3745,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-runtime-wry"
|
||||
version = "2.0.0-rc.14"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a03a49d6bcc0e65d64ea4420e2097270a25a9e1ff0fb2ece75e54fbbd54e45f7"
|
||||
checksum = "1431602bcc71f2f840ad623915c9842ecc32999b867c4a787d975a17a9625cc6"
|
||||
dependencies = [
|
||||
"gtk",
|
||||
"http",
|
||||
@@ -3577,9 +3771,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-utils"
|
||||
version = "2.0.0-rc.13"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a271545e4c25b36b922d98cf7e0c1755f64e92355705f656893e352aef0331e3"
|
||||
checksum = "c38b0230d6880cf6dd07b6d7dd7789a0869f98ac12146e0d18d1c1049215a045"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"cargo_metadata",
|
||||
@@ -3851,7 +4045,7 @@ checksum = "533fc2d4105e0e3d96ce1c71f2d308c9fbbe2ef9c587cab63dd627ab5bde218f"
|
||||
dependencies = [
|
||||
"core-graphics",
|
||||
"crossbeam-channel",
|
||||
"dirs",
|
||||
"dirs 5.0.1",
|
||||
"libappindicator",
|
||||
"muda",
|
||||
"objc2",
|
||||
@@ -4048,14 +4242,17 @@ name = "wallitor-gui"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"lazy_static",
|
||||
"libloading 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-autostart",
|
||||
"tauri-plugin-dialog",
|
||||
"tauri-plugin-fs",
|
||||
"tauri-plugin-shell",
|
||||
"tauri-plugin-single-instance",
|
||||
"window-vibrancy",
|
||||
]
|
||||
|
||||
@@ -4611,6 +4808,15 @@ dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.52.0"
|
||||
@@ -4623,14 +4829,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.44.1"
|
||||
version = "0.46.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "440600584cfbd8b0d28eace95c1f2c253db05dae43780b79380aa1e868f04c73"
|
||||
checksum = "6fa1c8c760041c64ce6be99f83d6cb55fe3fcd85a1ad46d32895f6e65cee87ba"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"block",
|
||||
"cocoa",
|
||||
"core-graphics",
|
||||
"block2",
|
||||
"crossbeam-channel",
|
||||
"dpi",
|
||||
"dunce",
|
||||
@@ -4643,8 +4847,11 @@ dependencies = [
|
||||
"kuchikiki",
|
||||
"libc",
|
||||
"ndk",
|
||||
"objc",
|
||||
"objc_id",
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation",
|
||||
"objc2-ui-kit",
|
||||
"objc2-web-kit",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"raw-window-handle",
|
||||
@@ -4699,9 +4906,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-executor",
|
||||
"async-fs",
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"async-process",
|
||||
"async-recursion",
|
||||
"async-task",
|
||||
"async-trait",
|
||||
"blocking",
|
||||
"derivative",
|
||||
"enumflags2",
|
||||
"event-listener",
|
||||
|
||||
@@ -25,4 +25,10 @@ tauri-plugin-fs = "2.0.0-rc"
|
||||
tauri-plugin-dialog = "2.0.0-rc"
|
||||
chrono = "0.4.38"
|
||||
libloading = "0.8.5"
|
||||
lazy_static = "1.5.0"
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||
tauri-plugin-autostart = "2.0.0-rc"
|
||||
tauri-plugin-single-instance = "2.0.0-rc"
|
||||
|
||||
|
||||
|
||||
@@ -3,5 +3,15 @@
|
||||
"identifier": "default",
|
||||
"description": "Capability for the main window",
|
||||
"windows": ["main"],
|
||||
"permissions": ["core:default", "shell:allow-open", "dialog:allow-open", "dialog:default","core:webview:allow-create-webview-window","core:window:allow-destroy"]
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"shell:allow-open",
|
||||
"dialog:allow-open",
|
||||
"dialog:default",
|
||||
"core:webview:allow-create-webview-window",
|
||||
"core:window:allow-destroy",
|
||||
"autostart:allow-enable",
|
||||
"autostart:allow-disable",
|
||||
"autostart:allow-is-enabled"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"default":{"identifier":"default","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["core:default","shell:allow-open","dialog:allow-open","dialog:default","core:webview:allow-create-webview-window","core:window:allow-destroy"]},"migrated":{"identifier":"migrated","description":"permissions that were migrated from v1","local":true,"windows":["main"],"permissions":["core:default","core:window:allow-maximize","core:window:allow-unmaximize","core:window:allow-toggle-maximize","core:window:allow-minimize","core:window:allow-unminimize","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-start-dragging"]},"video":{"identifier":"video","description":"Capability for the main window","local":true,"windows":["wallitor_video_playback"],"permissions":["core:default","shell:allow-open","core:window:allow-destroy"]}}
|
||||
{"default":{"identifier":"default","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["core:default","shell:allow-open","dialog:allow-open","dialog:default","core:webview:allow-create-webview-window","core:window:allow-destroy","autostart:allow-enable","autostart:allow-disable","autostart:allow-is-enabled"]},"migrated":{"identifier":"migrated","description":"permissions that were migrated from v1","local":true,"windows":["main"],"permissions":["core:default","core:window:allow-maximize","core:window:allow-unmaximize","core:window:allow-toggle-maximize","core:window:allow-minimize","core:window:allow-unminimize","core:window:allow-show","core:window:allow-hide","core:window:allow-close","core:window:allow-start-dragging"]},"video":{"identifier":"video","description":"Capability for the main window","local":true,"windows":["wallitor_video_playback"],"permissions":["core:default","shell:allow-open","core:window:allow-destroy"]}}
|
||||
@@ -1827,6 +1827,41 @@
|
||||
"Identifier": {
|
||||
"description": "Permission identifier",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n",
|
||||
"type": "string",
|
||||
"const": "autostart:default"
|
||||
},
|
||||
{
|
||||
"description": "Enables the disable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:allow-disable"
|
||||
},
|
||||
{
|
||||
"description": "Enables the enable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:allow-enable"
|
||||
},
|
||||
{
|
||||
"description": "Enables the is_enabled command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:allow-is-enabled"
|
||||
},
|
||||
{
|
||||
"description": "Denies the disable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:deny-disable"
|
||||
},
|
||||
{
|
||||
"description": "Denies the enable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:deny-enable"
|
||||
},
|
||||
{
|
||||
"description": "Denies the is_enabled command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:deny-is-enabled"
|
||||
},
|
||||
{
|
||||
"description": "Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n",
|
||||
"type": "string",
|
||||
|
||||
@@ -1827,6 +1827,41 @@
|
||||
"Identifier": {
|
||||
"description": "Permission identifier",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "This permission set configures if your\napplication can enable or disable auto\nstarting the application on boot.\n\n#### Granted Permissions\n\nIt allows all to check, enable and\ndisable the automatic start on boot.\n\n",
|
||||
"type": "string",
|
||||
"const": "autostart:default"
|
||||
},
|
||||
{
|
||||
"description": "Enables the disable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:allow-disable"
|
||||
},
|
||||
{
|
||||
"description": "Enables the enable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:allow-enable"
|
||||
},
|
||||
{
|
||||
"description": "Enables the is_enabled command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:allow-is-enabled"
|
||||
},
|
||||
{
|
||||
"description": "Denies the disable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:deny-disable"
|
||||
},
|
||||
{
|
||||
"description": "Denies the enable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:deny-enable"
|
||||
},
|
||||
{
|
||||
"description": "Denies the is_enabled command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "autostart:deny-is-enabled"
|
||||
},
|
||||
{
|
||||
"description": "Default core plugins set which includes:\n- 'core:path:default'\n- 'core:event:default'\n- 'core:window:default'\n- 'core:webview:default'\n- 'core:app:default'\n- 'core:image:default'\n- 'core:resources:default'\n- 'core:menu:default'\n- 'core:tray:default'\n",
|
||||
"type": "string",
|
||||
|
||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 974 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 903 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,64 @@
|
||||
use crate::handler::get_absolute_path;
|
||||
use lazy_static::lazy_static;
|
||||
use libloading::{self, Library};
|
||||
use std::{ffi::CString, ops::Deref, sync::Arc};
|
||||
|
||||
struct CoreModule {
|
||||
_module: Arc<Library>,
|
||||
pub set_wallpaper: libloading::os::windows::Symbol<unsafe extern "C" fn(*const i8) -> i8>,
|
||||
pub any_maximized: libloading::os::windows::Symbol<unsafe extern "C" fn() -> i8>,
|
||||
}
|
||||
|
||||
impl CoreModule {
|
||||
fn new(library_path: &str) -> CoreModule {
|
||||
let library_dir = get_absolute_path(&String::from(library_path));
|
||||
// 首先加载动态库
|
||||
let _module = Arc::new(unsafe { Library::new(library_dir).unwrap() });
|
||||
// 然后获取符号
|
||||
let set_wallpaper: libloading::os::windows::Symbol<unsafe extern "C" fn(*const i8) -> i8> = unsafe {
|
||||
_module
|
||||
.get::<unsafe extern "C" fn(*const i8) -> i8>(b"set_wallpaper\0")
|
||||
.unwrap()
|
||||
.into_raw()
|
||||
};
|
||||
let any_maximized: libloading::os::windows::Symbol<unsafe extern "C" fn() -> i8> = unsafe {
|
||||
_module
|
||||
.get::<unsafe extern "C" fn() -> i8>(b"any_maximized\0")
|
||||
.unwrap()
|
||||
.into_raw()
|
||||
};
|
||||
// 返回初始化的结构体
|
||||
CoreModule {
|
||||
_module,
|
||||
set_wallpaper,
|
||||
any_maximized,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref core_module: CoreModule = CoreModule::new("wallitor-core.dll");
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn set_wallpaper(title: String) -> bool {
|
||||
let title = CString::new(title.to_string()).unwrap();
|
||||
unsafe {
|
||||
let res = core_module.set_wallpaper.deref()(title.as_ptr());
|
||||
if res == 0 {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn any_zoomed() -> bool {
|
||||
unsafe {
|
||||
let res = core_module.any_maximized.deref()();
|
||||
if res == 0 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
use crate::handler::get_absolute_path;
|
||||
use crate::{reader, VERSION};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use tauri::ipc::Response;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_file(path: String) -> Response {
|
||||
let p = get_absolute_path(&path);
|
||||
if let Ok(true) = fs::exists(&p) {
|
||||
let data: Vec<u8> = fs::read(&p).unwrap();
|
||||
return tauri::ipc::Response::new(data);
|
||||
}
|
||||
tauri::ipc::Response::new(String::from(""))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn read_resource_dir() -> String {
|
||||
let mut file_map = reader::FileMap::new();
|
||||
let path = get_absolute_path(&String::from(".\\resource"));
|
||||
if let Ok(false) = fs::exists(&path) {
|
||||
fs::create_dir(&path).expect("Can't create dir");
|
||||
}
|
||||
file_map
|
||||
.read_resourse_directory(&path)
|
||||
.expect("Can't read dir");
|
||||
serde_json::to_string(&file_map).unwrap()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn del_folder(path: String) -> bool {
|
||||
let p = Path::new(&path);
|
||||
if p.starts_with(".\\") {
|
||||
let folder_path = get_absolute_path(&path);
|
||||
if folder_path.is_dir() {
|
||||
if let Ok(true) = fs::exists(&folder_path) {
|
||||
if fs::remove_dir_all(&folder_path).is_ok() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Settings {
|
||||
title_bar: String,
|
||||
auto_start: bool,
|
||||
auto_pause: bool,
|
||||
version: String,
|
||||
}
|
||||
|
||||
impl Settings {
|
||||
fn new() -> Settings {
|
||||
Settings {
|
||||
title_bar: String::from("win"),
|
||||
auto_start: false,
|
||||
auto_pause: true,
|
||||
version: String::from(VERSION),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SETTING_PATH: &str = "./settings.json";
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_settings() -> String {
|
||||
let setting_path = get_absolute_path(&String::from(SETTING_PATH));
|
||||
if let Ok(file) = fs::read(setting_path) {
|
||||
let mut settings: Settings = serde_json::from_slice(&file).unwrap();
|
||||
settings.version = String::from(VERSION);
|
||||
return json!(settings).to_string();
|
||||
} else {
|
||||
set_settings(Settings::new()).await;
|
||||
return json!(Settings::new()).to_string();
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn set_settings(settings: Settings) -> bool {
|
||||
let setting_path = get_absolute_path(&String::from(SETTING_PATH));
|
||||
if fs::write(setting_path, json!(settings).to_string()).is_ok() {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
pub mod apply;
|
||||
pub mod file;
|
||||
pub mod wallpaper;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
pub fn get_absolute_path(path: &String) -> PathBuf {
|
||||
let binding = std::env::current_exe().unwrap();
|
||||
let base_dir = binding.parent().unwrap();
|
||||
return base_dir.join(Path::new(path));
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
use crate::handler::get_absolute_path;
|
||||
use chrono::Local;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{self, json};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct AddInfo {
|
||||
name: String,
|
||||
preview: String,
|
||||
media: String,
|
||||
description: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Info {
|
||||
media_type: String,
|
||||
description: String,
|
||||
created: i64,
|
||||
entry_point: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct Opt {
|
||||
mute: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Config {
|
||||
name: String,
|
||||
info: Info,
|
||||
option: Opt,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn new_wallpaper(info: AddInfo) -> String {
|
||||
let base_path = get_absolute_path(&String::from("./resource"));
|
||||
let base_url = base_path.to_str().unwrap();
|
||||
let current_time: i64 = Local::now().timestamp();
|
||||
let folder = format!("{}/{}", base_url, current_time);
|
||||
if fs::create_dir_all(Path::new(&folder)).is_err() {
|
||||
return String::from("Error creating folder.");
|
||||
}
|
||||
if !info.preview.is_empty() {
|
||||
if let Ok(false) = fs::exists(Path::new(&info.preview)) {
|
||||
return String::from("Source Image doesn't exist.");
|
||||
}
|
||||
let preview = Path::new(&info.preview);
|
||||
if let Some(ext) = preview.extension().and_then(|f| f.to_str()) {
|
||||
if fs::copy(
|
||||
Path::new(&info.preview),
|
||||
Path::new(&format!("{}/preview.{}", folder, ext)),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return String::from("Error copy image.");
|
||||
}
|
||||
} else {
|
||||
return String::from("Invalid Image Path.");
|
||||
}
|
||||
}
|
||||
if fs::create_dir(Path::new(&format!("{}/res", folder))).is_err() {
|
||||
return String::from("Error creating res folder.");
|
||||
}
|
||||
let media = Path::new(&info.media);
|
||||
if let Some(filename) = media.file_name().and_then(|f| f.to_str()) {
|
||||
if fs::copy(
|
||||
Path::new(&info.media),
|
||||
Path::new(&format!("{}/res/{}", folder, filename)),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return String::from("Error copy media.");
|
||||
}
|
||||
let config = json!(Config {
|
||||
name: info.name,
|
||||
info: Info {
|
||||
media_type: String::from("video"),
|
||||
description: info.description,
|
||||
created: current_time,
|
||||
entry_point: String::from(filename)
|
||||
},
|
||||
option: Opt { mute: true }
|
||||
});
|
||||
if fs::write(
|
||||
Path::new(&format!("{}/config.json", folder)),
|
||||
config.to_string(),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return String::from("Error write config.");
|
||||
}
|
||||
} else {
|
||||
return String::from("Invalid media path.");
|
||||
}
|
||||
String::from("Success")
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct EditInfo {
|
||||
path: String,
|
||||
name: String,
|
||||
preview: String,
|
||||
description: String,
|
||||
mute: bool,
|
||||
}
|
||||
|
||||
fn delete_preview(target_dir: &String) -> bool {
|
||||
if let Ok(entries) = fs::read_dir(target_dir) {
|
||||
for entry in entries {
|
||||
if let Ok(entry) = entry {
|
||||
let path = entry.path();
|
||||
if let Some(file_name) = path.file_stem().and_then(|s| s.to_str()) {
|
||||
if file_name == "preview" {
|
||||
if fs::remove_file(path).is_err() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn copy_preview(source_file: &String, target_dir: &String) -> bool {
|
||||
let preview_path = Path::new(source_file);
|
||||
if let Ok(true) = fs::exists(preview_path) {
|
||||
if delete_preview(target_dir) {
|
||||
if let Some(ext) = preview_path.extension().and_then(|f| f.to_str()) {
|
||||
if fs::copy(
|
||||
preview_path,
|
||||
Path::new(&format!("{}/preview.{}", target_dir, ext)),
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn edit_wallpaper(info: EditInfo) -> bool {
|
||||
let folder_path = &get_absolute_path(&info.path);
|
||||
if let Ok(true) = fs::exists(folder_path) {
|
||||
let config_path_str = format!("{}/config.json", info.path);
|
||||
let config_path = &get_absolute_path(&config_path_str);
|
||||
if let Ok(file) = fs::read(config_path) {
|
||||
let mut config: Config = serde_json::from_slice(&file).unwrap();
|
||||
config.info.description = info.description;
|
||||
config.name = info.name;
|
||||
config.option.mute = info.mute;
|
||||
if let Ok(()) = fs::write(config_path, json!(config).to_string()) {
|
||||
if !info.preview.is_empty() {
|
||||
return copy_preview(&info.preview, &info.path);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
@@ -1,173 +1,43 @@
|
||||
mod handler;
|
||||
mod reader;
|
||||
mod setup;
|
||||
extern crate lazy_static;
|
||||
use tauri::Manager;
|
||||
use tauri_plugin_autostart::MacosLauncher;
|
||||
|
||||
use chrono::Local;
|
||||
use libloading::{Library, Symbol};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{self, json};
|
||||
use std::ffi::CString;
|
||||
use std::path::Path;
|
||||
use std::{fs};
|
||||
use tauri::ipc::Response;
|
||||
static VERSION: &str = "1.0.0";
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.setup(setup::init)
|
||||
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
|
||||
let window = app.get_webview_window("main").expect("no main window");
|
||||
if let Ok(true) = window.is_minimized() {
|
||||
let _ = window.unminimize();
|
||||
}
|
||||
if let Ok(false) = window.is_visible() {
|
||||
let _ = window.show();
|
||||
}
|
||||
let _ = window.set_focus();
|
||||
}))
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_autostart::init(
|
||||
MacosLauncher::LaunchAgent,
|
||||
None,
|
||||
))
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
read_resource_dir,
|
||||
get_file,
|
||||
new_wallpaper,
|
||||
set_wallpaper,
|
||||
del_folder
|
||||
handler::file::get_file,
|
||||
handler::file::read_resource_dir,
|
||||
handler::file::del_folder,
|
||||
handler::wallpaper::new_wallpaper,
|
||||
handler::apply::set_wallpaper,
|
||||
handler::wallpaper::edit_wallpaper,
|
||||
handler::apply::any_zoomed,
|
||||
handler::file::get_settings,
|
||||
handler::file::set_settings,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn read_resource_dir() -> String {
|
||||
let mut file_map = reader::FileMap::new();
|
||||
let path = Path::new(".\\resource");
|
||||
if let Ok(false) = fs::exists(path) {
|
||||
fs::create_dir(path).expect("Can't create dir");
|
||||
}
|
||||
file_map
|
||||
.read_resourse_directory(path)
|
||||
.expect("Can't read dir");
|
||||
serde_json::to_string(&file_map).unwrap()
|
||||
}
|
||||
|
||||
// remember to call `.manage(MyState::default())`
|
||||
#[tauri::command]
|
||||
async fn get_file(path: String) -> Response {
|
||||
let p = Path::new(&path);
|
||||
if let Ok(true) = fs::exists(p) {
|
||||
let data: Vec<u8> = fs::read(p).unwrap();
|
||||
return tauri::ipc::Response::new(data);
|
||||
}
|
||||
tauri::ipc::Response::new(String::from(""))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn del_folder(path: String) -> bool {
|
||||
let p = Path::new(&path);
|
||||
if p.starts_with(".\\") {
|
||||
if p.is_dir() {
|
||||
if let Ok(true) = fs::exists(p) {
|
||||
if fs::remove_dir_all(p).is_ok() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct AddInfo {
|
||||
name: String,
|
||||
preview: String,
|
||||
media: String,
|
||||
description: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Info {
|
||||
media_type: String,
|
||||
description: String,
|
||||
created: i64,
|
||||
entry_point: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Opt {
|
||||
mute: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Config {
|
||||
name: String,
|
||||
info: Info,
|
||||
option: Opt,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn new_wallpaper(info: AddInfo) -> String {
|
||||
let base_url = String::from("./resource");
|
||||
let current_time: i64 = Local::now().timestamp();
|
||||
let folder = format!("{}/{}", base_url, current_time);
|
||||
if fs::create_dir_all(Path::new(&folder)).is_err() {
|
||||
return String::from("Error creating folder.");
|
||||
}
|
||||
if !info.preview.is_empty() {
|
||||
if let Ok(false) = fs::exists(Path::new(&info.preview)) {
|
||||
return String::from("Source Image doesn't exist.");
|
||||
}
|
||||
let preview = Path::new(&info.preview);
|
||||
if let Some(ext) = preview.extension().and_then(|f| f.to_str()) {
|
||||
if fs::copy(
|
||||
Path::new(&info.preview),
|
||||
Path::new(&format!("{}/preview.{}", folder, ext)),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return String::from("Error copy image.");
|
||||
}
|
||||
} else {
|
||||
return String::from("Invalid Image Path.");
|
||||
}
|
||||
}
|
||||
if fs::create_dir(Path::new(&format!("{}/res", folder))).is_err() {
|
||||
return String::from("Error creating res folder.");
|
||||
}
|
||||
let media = Path::new(&info.media);
|
||||
if let Some(filename) = media.file_name().and_then(|f| f.to_str()) {
|
||||
if fs::copy(
|
||||
Path::new(&info.media),
|
||||
Path::new(&format!("{}/res/{}", folder, filename)),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return String::from("Error copy media.");
|
||||
}
|
||||
let config = json!(Config {
|
||||
name: info.name,
|
||||
info: Info {
|
||||
media_type: String::from("video"),
|
||||
description: info.description,
|
||||
created: current_time,
|
||||
entry_point: String::from(filename)
|
||||
},
|
||||
option: Opt { mute: true }
|
||||
});
|
||||
if fs::write(
|
||||
Path::new(&format!("{}/config.json", folder)),
|
||||
config.to_string(),
|
||||
)
|
||||
.is_err()
|
||||
{
|
||||
return String::from("Error write config.");
|
||||
}
|
||||
} else {
|
||||
return String::from("Invalid media path.");
|
||||
}
|
||||
String::from("Success")
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn set_wallpaper(title: String) -> bool {
|
||||
let lib = unsafe { Library::new("wallitor-core.dll").unwrap() };
|
||||
type SetFn = unsafe extern "C" fn(*const i8) -> i8;
|
||||
let set: Symbol<SetFn> = unsafe { lib.get(b"set_wallpaper\0").unwrap() };
|
||||
let title = CString::new(title.to_string()).unwrap();
|
||||
unsafe {
|
||||
let res = set(title.as_ptr());
|
||||
if res == 0 {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use serde::{Serialize, Serializer};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
enum FileType {
|
||||
File(String),
|
||||
Directory(HashMap<String,FileType>)
|
||||
Directory(HashMap<String, FileType>),
|
||||
}
|
||||
|
||||
impl Serialize for FileType {
|
||||
@@ -28,7 +28,7 @@ pub struct FileMap {
|
||||
impl FileMap {
|
||||
pub fn new() -> FileMap {
|
||||
FileMap {
|
||||
files:HashMap::new()
|
||||
files: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,10 @@ impl FileMap {
|
||||
let dir = entry?;
|
||||
let path = dir.path();
|
||||
if path.is_file() {
|
||||
files.insert(path.file_name().unwrap().to_string_lossy().to_string(), FileType::File(path.to_string_lossy().to_string()));
|
||||
files.insert(
|
||||
path.file_name().unwrap().to_string_lossy().to_string(),
|
||||
FileType::File(path.to_string_lossy().to_string()),
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(files)
|
||||
@@ -50,7 +53,10 @@ impl FileMap {
|
||||
let path = dir.path();
|
||||
if path.is_dir() {
|
||||
let resource = self.read_resource(path.as_path())?;
|
||||
self.files.insert(path.to_string_lossy().to_string(), FileType::Directory(resource)) ;
|
||||
self.files.insert(
|
||||
path.to_string_lossy().to_string(),
|
||||
FileType::Directory(resource),
|
||||
);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -40,6 +40,7 @@ pub fn init(app: &mut App) -> std::result::Result<(), Box<dyn std::error::Error>
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.show();
|
||||
let _ = window.set_focus();
|
||||
let _ = window.unminimize();
|
||||
}
|
||||
}
|
||||
TrayIconEvent::Click {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { onBeforeMount } from 'vue';
|
||||
import TitleBar from './components/TitleBar.vue';
|
||||
import { RouterView } from 'vue-router'
|
||||
import { useStore } from 'vuex';
|
||||
|
||||
const isDarkTheme = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
const html_node = document.getElementsByTagName("html")[0]
|
||||
@@ -13,9 +15,13 @@ isDarkTheme.addEventListener('change', (event) => {
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeMount(() => {
|
||||
useStore().dispatch("get_settings");
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<title-bar mode="win"></title-bar>
|
||||
<title-bar></title-bar>
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1729046702329" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3377" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M874.666667 480H224L514.133333 170.666667c12.8-12.8 10.666667-34.133333-2.133333-44.8s-32-10.666667-44.8 2.133333l-341.333333 362.666667c-2.133333 2.133333-4.266667 6.4-6.4 8.533333-2.133333 4.266667-2.133333 6.4-2.133334 10.666667s0 8.533333 2.133334 10.666666c2.133333 4.266667 4.266667 6.4 6.4 8.533334l341.333333 362.666666c6.4 6.4 14.933333 10.666667 23.466667 10.666667 8.533333 0 14.933333-2.133333 21.333333-8.533333 12.8-12.8 12.8-32 2.133333-44.8L224 544H874.666667c17.066667 0 32-14.933333 32-32s-14.933333-32-32-32z" fill="currentColor" p-id="3378"></path></svg>
|
||||
|
After Width: | Height: | Size: 907 B |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1729046722817" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3526" data-darkreader-inline-fill="" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M853.333333 501.333333c-17.066667 0-32 14.933333-32 32v320c0 6.4-4.266667 10.666667-10.666666 10.666667H170.666667c-6.4 0-10.666667-4.266667-10.666667-10.666667V213.333333c0-6.4 4.266667-10.666667 10.666667-10.666666h320c17.066667 0 32-14.933333 32-32s-14.933333-32-32-32H170.666667c-40.533333 0-74.666667 34.133333-74.666667 74.666666v640c0 40.533333 34.133333 74.666667 74.666667 74.666667h640c40.533333 0 74.666667-34.133333 74.666666-74.666667V533.333333c0-17.066667-14.933333-32-32-32z" fill="#666666" p-id="3527" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #4d5356;"></path><path d="M405.333333 484.266667l-32 125.866666c-2.133333 10.666667 0 23.466667 8.533334 29.866667 6.4 6.4 14.933333 8.533333 23.466666 8.533333h8.533334l125.866666-32c6.4-2.133333 10.666667-4.266667 14.933334-8.533333l300.8-300.8c38.4-38.4 38.4-102.4 0-140.8-38.4-38.4-102.4-38.4-140.8 0L413.866667 469.333333c-4.266667 4.266667-6.4 8.533333-8.533334 14.933334z m59.733334 23.466666L761.6 213.333333c12.8-12.8 36.266667-12.8 49.066667 0 12.8 12.8 12.8 36.266667 0 49.066667L516.266667 558.933333l-66.133334 17.066667 14.933334-68.266667z" fill="#666666" p-id="3528" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #4d5356;"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1728972948301" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3377" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M904.533333 422.4l-85.333333-14.933333-17.066667-38.4 49.066667-70.4c14.933333-21.333333 12.8-49.066667-6.4-68.266667l-53.333333-53.333333c-19.2-19.2-46.933333-21.333333-68.266667-6.4l-70.4 49.066666-38.4-17.066666-14.933333-85.333334c-2.133333-23.466667-23.466667-42.666667-49.066667-42.666666h-74.666667c-25.6 0-46.933333 19.2-53.333333 44.8l-14.933333 85.333333-38.4 17.066667L296.533333 170.666667c-21.333333-14.933333-49.066667-12.8-68.266666 6.4l-53.333334 53.333333c-19.2 19.2-21.333333 46.933333-6.4 68.266667l49.066667 70.4-17.066667 38.4-85.333333 14.933333c-21.333333 4.266667-40.533333 25.6-40.533333 51.2v74.666667c0 25.6 19.2 46.933333 44.8 53.333333l85.333333 14.933333 17.066667 38.4L170.666667 727.466667c-14.933333 21.333333-12.8 49.066667 6.4 68.266666l53.333333 53.333334c19.2 19.2 46.933333 21.333333 68.266667 6.4l70.4-49.066667 38.4 17.066667 14.933333 85.333333c4.266667 25.6 25.6 44.8 53.333333 44.8h74.666667c25.6 0 46.933333-19.2 53.333333-44.8l14.933334-85.333333 38.4-17.066667 70.4 49.066667c21.333333 14.933333 49.066667 12.8 68.266666-6.4l53.333334-53.333334c19.2-19.2 21.333333-46.933333 6.4-68.266666l-49.066667-70.4 17.066667-38.4 85.333333-14.933334c25.6-4.266667 44.8-25.6 44.8-53.333333v-74.666667c-4.266667-27.733333-23.466667-49.066667-49.066667-53.333333z m-19.2 117.333333l-93.866666 17.066667c-10.666667 2.133333-19.2 8.533333-23.466667 19.2l-29.866667 70.4c-4.266667 10.666667-2.133333 21.333333 4.266667 29.866667l53.333333 76.8-40.533333 40.533333-76.8-53.333333c-8.533333-6.4-21.333333-8.533333-29.866667-4.266667L576 768c-10.666667 4.266667-17.066667 12.8-19.2 23.466667l-17.066667 93.866666h-57.6l-17.066666-93.866666c-2.133333-10.666667-8.533333-19.2-19.2-23.466667l-70.4-29.866667c-10.666667-4.266667-21.333333-2.133333-29.866667 4.266667l-76.8 53.333333-40.533333-40.533333 53.333333-76.8c6.4-8.533333 8.533333-21.333333 4.266667-29.866667L256 576c-4.266667-10.666667-12.8-17.066667-23.466667-19.2l-93.866666-17.066667v-57.6l93.866666-17.066666c10.666667-2.133333 19.2-8.533333 23.466667-19.2l29.866667-70.4c4.266667-10.666667 2.133333-21.333333-4.266667-29.866667l-53.333333-76.8 40.533333-40.533333 76.8 53.333333c8.533333 6.4 21.333333 8.533333 29.866667 4.266667L448 256c10.666667-4.266667 17.066667-12.8 19.2-23.466667l17.066667-93.866666h57.6l17.066666 93.866666c2.133333 10.666667 8.533333 19.2 19.2 23.466667l70.4 29.866667c10.666667 4.266667 21.333333 2.133333 29.866667-4.266667l76.8-53.333333 40.533333 40.533333-53.333333 76.8c-6.4 8.533333-8.533333 21.333333-4.266667 29.866667L768 448c4.266667 10.666667 12.8 17.066667 23.466667 19.2l93.866666 17.066667v55.466666z" fill="currentColor" p-id="3378"></path><path d="M512 394.666667c-64 0-117.333333 53.333333-117.333333 117.333333s53.333333 117.333333 117.333333 117.333333 117.333333-53.333333 117.333333-117.333333-53.333333-117.333333-117.333333-117.333333z m0 170.666666c-29.866667 0-53.333333-23.466667-53.333333-53.333333s23.466667-53.333333 53.333333-53.333333 53.333333 23.466667 53.333333 53.333333-23.466667 53.333333-53.333333 53.333333z" fill="currentColor" p-id="3379"></path></svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -64,16 +64,12 @@ import { open } from '@tauri-apps/plugin-dialog';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { useStore } from 'vuex';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import type { AddInfo } from '@/ts/types';
|
||||
|
||||
const store = useStore();
|
||||
const visible = defineModel<boolean>();
|
||||
const bg = ref<HTMLDivElement | null>(null);
|
||||
interface AddInfo {
|
||||
name: string,
|
||||
preview: string,
|
||||
media: string,
|
||||
description: string
|
||||
}
|
||||
|
||||
const addInfo = ref<AddInfo>({
|
||||
name: "",
|
||||
preview: "",
|
||||
@@ -189,6 +185,16 @@ function handleAdd() {
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes add-item-entry {
|
||||
0% {
|
||||
top: 100%;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: calc(100% - 60px);
|
||||
}
|
||||
}
|
||||
|
||||
.item-add-bg {
|
||||
border: solid var(--bd-color) 1px;
|
||||
backdrop-filter: blur(30px) saturate(180%);
|
||||
@@ -202,6 +208,7 @@ function handleAdd() {
|
||||
width: 85%;
|
||||
height: calc(100% - 55px);
|
||||
transition: .8s cubic-bezier(0.9, 0, 0, 1.1);
|
||||
animation: add-item-entry .3s ease-in-out;
|
||||
}
|
||||
|
||||
.item-add-show {
|
||||
|
||||
@@ -52,9 +52,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineProps, defineExpose, defineEmits, defineModel, watch, ref, type PropType } from 'vue';
|
||||
import { defineProps, defineExpose, defineEmits, defineModel, watch, ref, type PropType, computed } from 'vue';
|
||||
type Position = "left" | "right";
|
||||
import type { Cell } from '@/ts/types'
|
||||
import type { Cell, Settings } from '@/ts/types'
|
||||
import { useStore } from 'vuex';
|
||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
|
||||
const appWindow = getCurrentWebviewWindow();
|
||||
@@ -66,8 +66,9 @@ const props = defineProps({
|
||||
|
||||
})
|
||||
const store = useStore();
|
||||
const settings = computed<Settings>(() => store.state.settings)
|
||||
const visible = defineModel<boolean>();
|
||||
const emit = defineEmits(["submit"]);
|
||||
defineEmits(["submit"]);
|
||||
const visible_ = ref(false);
|
||||
const cell = ref<Cell>({
|
||||
img: "",
|
||||
@@ -87,7 +88,7 @@ const cell = ref<Cell>({
|
||||
})
|
||||
const bg = ref<HTMLDivElement | null>(null);
|
||||
defineExpose({ open })
|
||||
watch(() => visible.value, (val, _) => {
|
||||
watch(() => visible.value, (val) => {
|
||||
if (val) {
|
||||
visible_.value = true;
|
||||
}
|
||||
@@ -107,11 +108,15 @@ function open(conFig: Cell) {
|
||||
}
|
||||
|
||||
function apply() {
|
||||
store.commit("apply_wallpaper",{
|
||||
url:`/video/?url=${cell.value.path}\\res\\${cell.value.config.info.entry_point}&mute=${cell.value.config.option.mute}`,
|
||||
let params: { [key: string]: string } = {
|
||||
url: `${cell.value.path}\\res\\${cell.value.config.info.entry_point}`,
|
||||
mute: `${cell.value.config.option.mute}`,
|
||||
auto_pause: `${settings.value.auto_pause}`
|
||||
}
|
||||
store.dispatch("apply_wallpaper", {
|
||||
url: `/video/?${(new URLSearchParams(params)).toString()}`,
|
||||
title: "wallitor_video_playback"
|
||||
})
|
||||
appWindow.minimize();
|
||||
}).then(() => appWindow.minimize())
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
<div id="close" @click="handleClose">
|
||||
<el-icon :size="25">
|
||||
<Close />
|
||||
</el-icon>
|
||||
<SvgIcon name="window-close" size="25px"></SvgIcon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -15,7 +13,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, nextTick } from 'vue'
|
||||
import "@/style/cui.scss"
|
||||
import "@/style/cui.css"
|
||||
|
||||
export default defineComponent({
|
||||
name: "CDiaLog",
|
||||
@@ -63,7 +61,7 @@ export default defineComponent({
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
#mask {
|
||||
z-index: 200;
|
||||
position: absolute;
|
||||
@@ -71,8 +69,6 @@ export default defineComponent({
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
backdrop-filter: blur(10px);
|
||||
animation: cui-dialog-blur .6s;
|
||||
}
|
||||
|
||||
#bg {
|
||||
@@ -87,6 +83,7 @@ export default defineComponent({
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
animation: cui-dialog-appear .6s cubic-bezier(0, 0.6, 0.2, 1.0);
|
||||
box-shadow: var(--shadow-edge-glow), var(--shadow);
|
||||
}
|
||||
|
||||
#content {
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<div class="item-edit-content">
|
||||
<main class="item-edit-main">
|
||||
<table class="item-edit-form">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="item-edit-form-title">标题</td>
|
||||
<td><input type="text" v-model="data.name" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="item-edit-form-title">文件</td>
|
||||
<td>
|
||||
<template v-if="image_src">
|
||||
<img :src="image_src" class="item-edit-image" @click="selectPreview">
|
||||
</template>
|
||||
<template v-else-if="data.preview">
|
||||
<img :src="data.preview" class="item-edit-image" @click="selectPreview">
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="item-edit-preview" @click="selectPreview">
|
||||
<div class="item-edit-preview-text">
|
||||
<SvgIcon name="add" size="20px"></SvgIcon>点击添加封面
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="item-edit-form-title">描述</td>
|
||||
<td><textarea class="item-edit-description" v-model="data.description"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="item-edit-form-title">静音</td>
|
||||
<td>
|
||||
<div><input type="checkbox" v-model="data.mute" /></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><button class="apply-button" @click="handleEdit" ref="applyButton">添加</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { open } from '@tauri-apps/plugin-dialog';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { useStore } from 'vuex';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import type { EditInfo } from '@/ts/types';
|
||||
|
||||
const store = useStore();
|
||||
const data = defineModel<EditInfo>("data", {
|
||||
required: true
|
||||
})
|
||||
const emit = defineEmits(["submit"]);
|
||||
const image_src = ref("");
|
||||
const image_path = ref("");
|
||||
const support_img_ext = ['.jpg', '.png', '.gif', '.webp'];
|
||||
const support_img_ext_map: { [key in (typeof support_img_ext)[number]]: string } = {
|
||||
'.jpg': 'image/jpeg',
|
||||
'.png': 'image/png',
|
||||
'.gif': 'image/gif',
|
||||
'.webp': 'image/webp'
|
||||
}
|
||||
const applyButton = ref<HTMLButtonElement | null>(null);
|
||||
|
||||
async function handleFileOpen() {
|
||||
const file = await open({
|
||||
multiple: false,
|
||||
directory: false,
|
||||
});
|
||||
return file;
|
||||
}
|
||||
|
||||
function selectPreview() {
|
||||
handleFileOpen().then((file) => {
|
||||
if (file) {
|
||||
let ext = file.substring(file.lastIndexOf("."));
|
||||
if (support_img_ext.includes(ext)) {
|
||||
image_path.value = file;
|
||||
invoke("get_file", {
|
||||
path: file
|
||||
}).then((res) => {
|
||||
let binary_data_arr = new Uint8Array(res as number[]);
|
||||
const blob = new Blob([binary_data_arr], { type: support_img_ext_map[ext] });
|
||||
const imageUrl = URL.createObjectURL(blob);
|
||||
image_src.value = imageUrl;
|
||||
})
|
||||
} else ElMessage({
|
||||
type: "error",
|
||||
message: "文件格式不受支持"
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function checkInfo(info: EditInfo) {
|
||||
if (!info.name) return false
|
||||
else return true;
|
||||
}
|
||||
|
||||
function handleEdit() {
|
||||
if (checkInfo(data.value)) {
|
||||
if (applyButton.value) {
|
||||
ElMessage({
|
||||
type: "info",
|
||||
message: "正在修改项目, 请勿重新点击或关闭程序"
|
||||
})
|
||||
const info = Object.assign({}, data.value);
|
||||
info.preview = image_path.value;
|
||||
applyButton.value.disabled = true;
|
||||
invoke("edit_wallpaper", {
|
||||
info: info
|
||||
}).then((res) => {
|
||||
console.log(info);
|
||||
if (applyButton.value) applyButton.value.disabled = false;
|
||||
if (res as boolean) {
|
||||
store.commit("getWpList");
|
||||
emit("submit");
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "修改成功"
|
||||
})
|
||||
}
|
||||
else ElMessage({
|
||||
type: "error",
|
||||
message: `修改失败 ${res}`
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
else ElMessage({
|
||||
type: "error",
|
||||
message: "请填写名称并选择媒体文件"
|
||||
})
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.item-edit-show {
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
.item-edit-content {
|
||||
padding: 10px;
|
||||
height: calc(100% - 20px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.item-edit-main {
|
||||
margin: 10px;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.item-edit-main::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.item-edit-header-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 5px;
|
||||
background-color: #3b93ff;
|
||||
transition: .3s;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.item-edit-header-icon:hover {
|
||||
background-color: #1e5daa;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item-edit-header-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.item-edit-header-title {
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.item-edit-main {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.item-edit-preview {
|
||||
background: linear-gradient(135deg, #0000000A 0%, #FFFFFF0A 100%);
|
||||
border-radius: 5px;
|
||||
width: 400px;
|
||||
height: 200px;
|
||||
margin-bottom: 10px;
|
||||
box-shadow: var(--shadow-edge-glow);
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
transition: .5s;
|
||||
}
|
||||
|
||||
.item-edit-preview:hover {
|
||||
background: var(--bg-hover-fill);
|
||||
}
|
||||
|
||||
.item-edit-preview:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.item-edit-image {
|
||||
background: linear-gradient(135deg, #0000001A 0%, #FFFFFF1A 100%);
|
||||
border-radius: 5px;
|
||||
width: 400px;
|
||||
margin-bottom: 10px;
|
||||
box-shadow: var(--shadow-edge-glow);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item-edit-image:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.item-edit-form {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.item-edit-form td {
|
||||
vertical-align: top;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.item-edit-description {
|
||||
width: 300px;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
.item-edit-form-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.item-edit-preview-text {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
</style>
|
||||
@@ -25,6 +25,10 @@ const props = defineProps({
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@keyframes item-card-entry{
|
||||
0%{opacity: 0;transform: translateY(10px);}
|
||||
100%{opacity: 1;transform: translateY(0px);}
|
||||
}
|
||||
:root {
|
||||
--item-card-size: 200px;
|
||||
--item-card-margin: 20px;
|
||||
@@ -43,6 +47,7 @@ const props = defineProps({
|
||||
box-shadow: 0 0 1px 6px transparent;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
animation: item-card-entry 0.3s ease-out;
|
||||
}
|
||||
|
||||
.item-card-main {
|
||||
@@ -52,7 +57,6 @@ const props = defineProps({
|
||||
}
|
||||
|
||||
.item-card:hover {
|
||||
box-shadow: var(--shadow-edge-glow), var(--shadow);
|
||||
cursor: pointer;
|
||||
transform: scale(1.03);
|
||||
box-shadow: 0 0 2px 5px rgba(177, 177, 177, 0.151);
|
||||
@@ -67,7 +71,7 @@ const props = defineProps({
|
||||
}
|
||||
|
||||
.item-card:hover .item-card-title {
|
||||
bottom: 0;
|
||||
bottom: 5px;
|
||||
}
|
||||
|
||||
.item-card-main img {
|
||||
@@ -78,10 +82,11 @@ const props = defineProps({
|
||||
.item-card-title {
|
||||
position: absolute;
|
||||
bottom: -40px;
|
||||
right: 5px;
|
||||
right: 10px;
|
||||
transition: .3s;
|
||||
font-size: 30px;
|
||||
font-weight: 400;
|
||||
color: var(--text-color);
|
||||
text-shadow: 1px 1px 2px var(--bg-color);
|
||||
}
|
||||
</style>
|
||||
@@ -1,37 +1,38 @@
|
||||
<template>
|
||||
<div data-tauri-drag-region class="titlebar colbox">
|
||||
<template v-if="mode == 'mac'">
|
||||
<div class="titlebar-button-wrapper colbox">
|
||||
<div class="titlebar-button" id="titlebar-minimize" @click="minimize">
|
||||
<svg-icon name="window-minimize" color="red"></svg-icon>
|
||||
</div>
|
||||
<div class="titlebar-button" id="titlebar-maximize" @click="toggleMaximize">
|
||||
<template v-if="maximized">
|
||||
<svg-icon name="window-maximized"></svg-icon>
|
||||
</template>
|
||||
<template v-else>
|
||||
<svg-icon name="window-maximize" width="13px"></svg-icon>
|
||||
</template>
|
||||
</div>
|
||||
<div class="titlebar-button" id="titlebar-close" @click="close">
|
||||
<svg-icon name="window-close"></svg-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="titlebar-icon-wrapper colbox">
|
||||
<template v-if="mode == 'mac'">
|
||||
<div class="titlebar-button titlebar-close button-style-mac" @click="close">
|
||||
<svg-icon name="window-close" :size="button_size_mac"></svg-icon>
|
||||
</div>
|
||||
<div class="titlebar-button titlebar-minimize button-style-mac" @click="minimize">
|
||||
<svg-icon name="window-minimize" :size="button_size_mac"></svg-icon>
|
||||
</div>
|
||||
<div class="titlebar-button titlebar-maximize button-style-mac" @click="toggleMaximize">
|
||||
<svg-icon name="window-maximize" :size="button_size_mac"></svg-icon>
|
||||
</div>
|
||||
</template>
|
||||
<img src="@/assets/vw.png" class="titlebar-icon">
|
||||
<div class="titlebar-icon-title">
|
||||
Wallitor
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="mode == 'win'">
|
||||
|
||||
<div class="titlebar-button-wrapper colbox">
|
||||
<div class="titlebar-button" id="titlebar-minimize" @click="minimize">
|
||||
<div class="titlebar-button" id="titlebar-settings" :class="{
|
||||
'button-style-win': mode == 'win'
|
||||
}" @click="openSettings">
|
||||
<div class="titlebar-button-rect">
|
||||
<svg-icon name="setting" :size="button_size_default"></svg-icon>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="mode == 'win'">
|
||||
<div class="titlebar-button titlebar-minimize button-style-win" @click="minimize">
|
||||
<div class="titlebar-button-rect">
|
||||
<svg-icon name="window-minimize" :size="button_size_default"></svg-icon>
|
||||
</div>
|
||||
</div>
|
||||
<div class="titlebar-button" id="titlebar-maximize" @click="toggleMaximize">
|
||||
<div class="titlebar-button titlebar-maximize button-style-win" @click="toggleMaximize">
|
||||
<template v-if="maximized">
|
||||
<div class="titlebar-button-rect">
|
||||
<svg-icon name="window-maximized" :size="button_size_alter"></svg-icon>
|
||||
@@ -43,33 +44,38 @@
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="titlebar-button" id="titlebar-close" @click="close">
|
||||
<div class="titlebar-button titlebar-close button-style-win" @click="close">
|
||||
<div class="titlebar-button-rect">
|
||||
<svg-icon name="window-close" :size="button_size_default"></svg-icon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SvgIcon from '@/components/SvgIcon.vue';
|
||||
import { ref, defineProps } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import { onMounted, ref, computed } from 'vue'
|
||||
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useStore } from 'vuex';
|
||||
import type { Settings } from '@/ts/types';
|
||||
const appWindow = getCurrentWebviewWindow();
|
||||
const router = useRouter();
|
||||
|
||||
type Mode = "win" | "mac";
|
||||
|
||||
const maximized = ref(false);
|
||||
const button_size_default = ref("18px");
|
||||
const button_size_alter = ref("15px")
|
||||
const props = defineProps({
|
||||
mode: {
|
||||
type: String as PropType<Mode>,
|
||||
default: "win"
|
||||
}
|
||||
const button_size_mac = ref("11px")
|
||||
const store = useStore();
|
||||
const settings = computed<Settings>(() => store.state.settings);
|
||||
const mode = computed<Mode>(() => settings.value.title_bar);
|
||||
|
||||
onMounted(() => {
|
||||
console.log(mode);
|
||||
})
|
||||
|
||||
function minimize() {
|
||||
@@ -84,6 +90,10 @@ function toggleMaximize() {
|
||||
function close() {
|
||||
appWindow.hide();
|
||||
}
|
||||
|
||||
function openSettings() {
|
||||
router.push("settings");
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@@ -129,7 +139,7 @@ function close() {
|
||||
z-index: 300;
|
||||
}
|
||||
|
||||
.titlebar-button {
|
||||
.button-style-win.titlebar-button {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
padding-top: 3px;
|
||||
@@ -146,20 +156,67 @@ function close() {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#titlebar-minimize {
|
||||
#titlebar-settings {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button-style-win#titlebar-settings {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
#titlebar-close {
|
||||
.button-style-win.titlebar-close {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
#titlebar-minimize .titlebar-button-rect:hover,
|
||||
#titlebar-maximize .titlebar-button-rect:hover {
|
||||
#titlebar-settings .titlebar-button-rect:hover,
|
||||
.button-style-win.titlebar-minimize .titlebar-button-rect:hover,
|
||||
.button-style-win.titlebar-maximize .titlebar-button-rect:hover {
|
||||
background-color: var(--bg-hover-fill);
|
||||
}
|
||||
|
||||
#titlebar-close .titlebar-button-rect:hover {
|
||||
.button-style-win.titlebar-close .titlebar-button-rect:hover {
|
||||
background-color: var(--bg-hover-fill-close);
|
||||
}
|
||||
|
||||
|
||||
.button-style-mac.titlebar-button {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
border-radius: 100%;
|
||||
margin-left: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #000000b4
|
||||
}
|
||||
|
||||
.button-style-mac.titlebar-minimize {
|
||||
background: #FFBB39;
|
||||
border: 1px solid #CFA64E;
|
||||
}
|
||||
|
||||
.button-style-mac.titlebar-maximize {
|
||||
background: #606060;
|
||||
border: 1px solid #656565;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.button-style-mac:hover.titlebar-maximize {
|
||||
background: #00CD4E;
|
||||
border: 1px solid #0EA642;
|
||||
}
|
||||
|
||||
.button-style-mac.titlebar-close {
|
||||
background: #FF5D5B;
|
||||
border: 1px solid #CF544D;
|
||||
}
|
||||
|
||||
.button-style-mac svg {
|
||||
opacity: 0;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.button-style-mac:hover svg {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
@@ -10,12 +10,9 @@ const router = createRouter({
|
||||
component: HomeView
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/AboutView.vue')
|
||||
path: '/settings',
|
||||
name: 'settings',
|
||||
component: () => import('../views/SettingsView.vue')
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
@@ -1,13 +1,37 @@
|
||||
import { createStore } from 'vuex'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import type { ResourceDir, wpConfig, Cell } from '@/ts/types'
|
||||
import { WebviewWindow, } from '@tauri-apps/api/webviewWindow'
|
||||
import type { ResourceDir, wpConfig, Cell, Settings } from '@/ts/types'
|
||||
import { WebviewWindow } from '@tauri-apps/api/webviewWindow'
|
||||
import { emit } from '@tauri-apps/api/event'
|
||||
import { enable, isEnabled, disable } from '@tauri-apps/plugin-autostart'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
function arrayBufferToString(buffer: ArrayBuffer): string {
|
||||
const decoder = new TextDecoder('utf-8')
|
||||
return decoder.decode(buffer)
|
||||
}
|
||||
|
||||
function check_auto_start(settings: Settings) {
|
||||
const status = settings.auto_start
|
||||
isEnabled().then((current) => {
|
||||
if (current == true && status == false) {
|
||||
disable().then(() =>
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '已经禁用开机自启'
|
||||
})
|
||||
)
|
||||
} else if (current == false && status == true) {
|
||||
enable().then(() =>
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: '已经启用开机自启'
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const support_ext = ['.jpg', '.png', '.gif', '.webp']
|
||||
const support_ext_map: { [key in (typeof support_ext)[number]]: string } = {
|
||||
'.jpg': 'image/jpeg',
|
||||
@@ -21,7 +45,13 @@ export const store = createStore({
|
||||
state() {
|
||||
return {
|
||||
wpList: [] as Cell[],
|
||||
videoWindow: null as VideoWindow
|
||||
videoWindow: null as VideoWindow,
|
||||
settings: {
|
||||
title_bar: 'win',
|
||||
auto_pause: true,
|
||||
auto_start: false,
|
||||
version: '1.0.0'
|
||||
} as Settings
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
@@ -73,10 +103,13 @@ export const store = createStore({
|
||||
}
|
||||
})
|
||||
},
|
||||
apply_wallpaper(state, payload:{
|
||||
title:string,
|
||||
new_wallpaper_window(
|
||||
state,
|
||||
payload: {
|
||||
title: string
|
||||
url: string
|
||||
}) {
|
||||
}
|
||||
) {
|
||||
const window_options = {
|
||||
title: payload.title,
|
||||
url: payload.url,
|
||||
@@ -85,9 +118,45 @@ export const store = createStore({
|
||||
decorations: false,
|
||||
transparent: true
|
||||
}
|
||||
if (state.videoWindow)
|
||||
state.videoWindow.destroy().then((_) => {state.videoWindow = new WebviewWindow(payload.title, window_options)})
|
||||
else state.videoWindow = new WebviewWindow(payload.title,window_options)
|
||||
state.videoWindow = new WebviewWindow(payload.title, window_options)
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async apply_wallpaper(
|
||||
{ state, commit },
|
||||
payload: {
|
||||
title: string
|
||||
url: string
|
||||
}
|
||||
) {
|
||||
return new Promise<boolean>((resolve) => {
|
||||
if (state.videoWindow) {
|
||||
state.videoWindow.destroy().then(() => {
|
||||
commit('new_wallpaper_window', payload)
|
||||
resolve(true)
|
||||
})
|
||||
} else {
|
||||
commit('new_wallpaper_window', payload)
|
||||
resolve(true)
|
||||
}
|
||||
})
|
||||
},
|
||||
async get_settings({ state }) {
|
||||
const settings = await invoke('get_settings')
|
||||
state.settings = JSON.parse(settings as string) as Settings
|
||||
check_auto_start(state.settings)
|
||||
return
|
||||
},
|
||||
async set_settings({ state }, payload: Settings) {
|
||||
state.settings = payload
|
||||
const settings: boolean = await invoke('set_settings', {
|
||||
settings: state.settings
|
||||
})
|
||||
if (state.settings.auto_pause) {
|
||||
await emit('start_auto_pause')
|
||||
} else await emit('stop_auto_pause')
|
||||
check_auto_start(state.settings)
|
||||
return settings
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
@keyframes cui-dialog-appear {
|
||||
0% {
|
||||
/* opacity: 0%; */
|
||||
transform: translate(-50%, -50%) scale(0.7);
|
||||
}
|
||||
|
||||
100% {
|
||||
/* opacity: 100%; */
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cui-dialog-disappear {
|
||||
0% {
|
||||
opacity: 100%;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0%;
|
||||
transform: translate(-50%, -50%) scale(0.5);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cui-dialog-blur {
|
||||
0% {
|
||||
opacity: 0%;
|
||||
/* backdrop-filter: blur(0px); */
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 100%;
|
||||
/* backdrop-filter: blur(10px); */
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ type WallpaperType = 'Video'
|
||||
export interface Info {
|
||||
media_type: WallpaperType
|
||||
description: string
|
||||
created: number,
|
||||
created: number
|
||||
entry_point: string
|
||||
}
|
||||
export interface Option {
|
||||
@@ -20,7 +20,7 @@ export interface Cell {
|
||||
}
|
||||
|
||||
export interface Resource {
|
||||
"config.json": string,
|
||||
'config.json': string
|
||||
[filename: string]: string
|
||||
}
|
||||
|
||||
@@ -29,3 +29,25 @@ export interface ResourceDir {
|
||||
[resId: string]: Resource
|
||||
}
|
||||
}
|
||||
|
||||
interface AddInfo {
|
||||
name: string
|
||||
preview: string
|
||||
media: string
|
||||
description: string
|
||||
}
|
||||
|
||||
interface EditInfo {
|
||||
path: string
|
||||
name: string
|
||||
preview: string
|
||||
description: string
|
||||
mute: boolean
|
||||
}
|
||||
|
||||
export interface Settings {
|
||||
title_bar: 'win' | 'mac'
|
||||
auto_start: boolean
|
||||
auto_pause: boolean
|
||||
version: string
|
||||
}
|
||||
|
||||
@@ -6,10 +6,12 @@ import { ref, onMounted, computed, nextTick } from 'vue';
|
||||
import CRMenu from '@/components/CRMenu.vue';
|
||||
import CRMenuCell from '@/components/CRMenuCell.vue';
|
||||
import SvgIcon from '@/components/SvgIcon.vue';
|
||||
import type { Cell } from '@/ts/types'
|
||||
import type { Cell, EditInfo } from '@/ts/types'
|
||||
import { useStore } from 'vuex';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import CDialog from '@/components/CDialog.vue';
|
||||
import EditItem from '@/components/EditItem.vue';
|
||||
|
||||
const store = useStore();
|
||||
const items = computed<Cell[]>(() => store.state.wpList);
|
||||
@@ -38,7 +40,19 @@ const options = ref<{ name: string, icon: string, handler: (data: Cell) => void
|
||||
name: "删除",
|
||||
icon: "delete",
|
||||
handler: del_wallpaper
|
||||
}, {
|
||||
name: "修改",
|
||||
icon: "edit",
|
||||
handler: edit_wallpaper
|
||||
}])
|
||||
const edit_visible = ref(false);
|
||||
const edit_data = ref<EditInfo>({
|
||||
path: "",
|
||||
name: "",
|
||||
preview: "",
|
||||
description: "",
|
||||
mute: true
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
store.commit("getWpList");
|
||||
@@ -73,6 +87,21 @@ function del_wallpaper(data: Cell) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function edit_wallpaper(data: Cell) {
|
||||
edit_visible.value = true;
|
||||
edit_data.value = {
|
||||
path: data.path,
|
||||
name: data.config.name,
|
||||
preview: data.img,
|
||||
description: data.config.info.description,
|
||||
mute: data.config.option.mute
|
||||
}
|
||||
}
|
||||
|
||||
function handle_edit_close() {
|
||||
edit_visible.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -92,6 +121,11 @@ function del_wallpaper(data: Cell) {
|
||||
</CRMenuCell>
|
||||
</template>
|
||||
</CRMenu>
|
||||
<CDialog v-model:visible="edit_visible" height="80%" width="80%">
|
||||
<template #content>
|
||||
<EditItem v-model:data="edit_data" @submit="handle_edit_close"></EditItem>
|
||||
</template>
|
||||
</CDialog>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<div class="settings-wrapper">
|
||||
<div class="settings-back colbox" @click="back_home">
|
||||
<SvgIcon name="direction-left"></SvgIcon>
|
||||
<div class="settings-back-text">返回</div>
|
||||
</div>
|
||||
<table class="settings-table">
|
||||
<tbody class="setting-table-body">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="settings-label">
|
||||
<div class="settings-label-title">标题栏样式</div>
|
||||
<div class="settings-label-subtitle">选择选题栏关闭按钮样式</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<el-select @change="save" v-model="settings.title_bar">
|
||||
<el-option label="Windows" value="win"></el-option>
|
||||
<el-option label="OSX" value="mac"></el-option>
|
||||
</el-select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="settings-label">
|
||||
<div class="settings-label-title">开机自启</div>
|
||||
<div class="settings-label-subtitle">开机自启</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><el-switch @change="save" v-model="settings.auto_start"></el-switch></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="settings-label">
|
||||
<div class="settings-label-title">最大化自动暂停</div>
|
||||
<div class="settings-label-subtitle">最大化自动暂停</div>
|
||||
</div>
|
||||
</td>
|
||||
<td><el-switch @change="save" v-model="settings.auto_pause"></el-switch></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ElSelect, ElSwitch, ElOption, ElMessage } from 'element-plus';
|
||||
import { entry } from '@/ts/entry';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useStore } from 'vuex';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import SvgIcon from '@/components/SvgIcon.vue';
|
||||
import type { Settings } from '@/ts/types';
|
||||
const router = useRouter();
|
||||
const store = useStore();
|
||||
const settings = ref<Settings>(store.state.settings);
|
||||
|
||||
onMounted(() => {
|
||||
const table_body = document.querySelector(".setting-table-body") as HTMLElement;
|
||||
entry("left", table_body, 50);
|
||||
})
|
||||
|
||||
function back_home() {
|
||||
router.push("/")
|
||||
}
|
||||
|
||||
function save() {
|
||||
store.dispatch("set_settings", settings.value).then((status) => {
|
||||
if (status as boolean) {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "设置已更改"
|
||||
})
|
||||
}
|
||||
else ElMessage({
|
||||
type: "error",
|
||||
message: "设置更改失败"
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.settings-wrapper {
|
||||
padding-left: 30px;
|
||||
padding-right: 30px;
|
||||
width: calc(100% - 60px);
|
||||
}
|
||||
|
||||
.settings-back {
|
||||
color: var(--text-color);
|
||||
padding: 8px;
|
||||
margin: 5px;
|
||||
width: fit-content;
|
||||
border-radius: 10px;
|
||||
transition: .3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.settings-back:hover {
|
||||
background-color: var(--bg-color-alter);
|
||||
}
|
||||
|
||||
.settings-back:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.settings-table {
|
||||
width: calc(100% - 80px);
|
||||
margin-left: 40px;
|
||||
margin-right: 40px;
|
||||
}
|
||||
|
||||
.settings-table td,
|
||||
th {
|
||||
padding: 5px;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.settings-label-title {
|
||||
margin-bottom: 3px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.settings-label-subtitle {
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.settings-back-text {
|
||||
transform: translateY(-3px);
|
||||
margin-left: 4px;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
@@ -1,8 +1,10 @@
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window'
|
||||
interface Params {
|
||||
url?: string,
|
||||
url?: string
|
||||
mute?: string
|
||||
auto_pause?: string
|
||||
}
|
||||
function getSearchParamsAsObject() {
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
@@ -13,15 +15,81 @@ function getSearchParamsAsObject() {
|
||||
return paramsObject
|
||||
}
|
||||
|
||||
listen('video_pause', () => {
|
||||
const player = document.getElementById('player') as HTMLVideoElement
|
||||
if (player) player.pause()
|
||||
})
|
||||
|
||||
class player {
|
||||
playing: boolean
|
||||
params: Params
|
||||
interval: number
|
||||
constructor(params: Params) {
|
||||
this.params = params
|
||||
this.playing = false
|
||||
this.interval = 0
|
||||
}
|
||||
init_player(videoUrl: string) {
|
||||
const player = document.getElementById('player') as HTMLVideoElement
|
||||
if (player) {
|
||||
player.src = videoUrl
|
||||
player.play()
|
||||
this.playing = true
|
||||
if (this.params.mute) {
|
||||
player.muted = JSON.parse(this.params.mute)
|
||||
}
|
||||
player.loop = true
|
||||
setTimeout(() => {
|
||||
player.style.opacity = '1'
|
||||
}, 0)
|
||||
}
|
||||
if (this.params.auto_pause && this.params.auto_pause === 'true') {
|
||||
this.detect_zoom()
|
||||
}
|
||||
}
|
||||
detect_zoom() {
|
||||
this.clear_detection()
|
||||
this.interval = window.setInterval(() => {
|
||||
invoke('any_zoomed').then((res) => {
|
||||
if (res as boolean) {
|
||||
if (this.playing) {
|
||||
const player = document.getElementById('player') as HTMLVideoElement
|
||||
if (player) {
|
||||
player.pause()
|
||||
this.playing = false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!this.playing) {
|
||||
const player = document.getElementById('player') as HTMLVideoElement
|
||||
if (player) {
|
||||
player.play()
|
||||
this.playing = true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
clear_detection() {
|
||||
if (this.interval) {
|
||||
clearInterval(this.interval)
|
||||
this.interval = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let player_instance: player | null = null
|
||||
|
||||
window.onload = () => {
|
||||
invoke('set_wallpaper', {
|
||||
title: 'wallitor_video_playback'
|
||||
}).then((res) => {
|
||||
if (!res) {
|
||||
console.error("Unable to set wallpaper.");
|
||||
const win = getCurrentWindow();
|
||||
win.destroy();
|
||||
return;
|
||||
console.error('Unable to set wallpaper.')
|
||||
const win = getCurrentWindow()
|
||||
win.destroy()
|
||||
return
|
||||
}
|
||||
const params: Params = getSearchParamsAsObject()
|
||||
if (params.url) {
|
||||
@@ -31,17 +99,17 @@ window.onload = () => {
|
||||
const binary_data_arr = new Uint8Array(res as number[])
|
||||
const blob = new Blob([binary_data_arr], { type: 'video/mp4' })
|
||||
const videoUrl = URL.createObjectURL(blob)
|
||||
const player = document.getElementById('player') as HTMLVideoElement
|
||||
if (player) {
|
||||
player.src = videoUrl
|
||||
player.play()
|
||||
if(params.mute) {
|
||||
player.muted = JSON.parse(params.mute);
|
||||
}
|
||||
player.loop = true
|
||||
setTimeout(()=>{player.style.opacity = '1'},0);
|
||||
}
|
||||
player_instance = new player(params)
|
||||
player_instance.init_player(videoUrl)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
listen('stop_auto_pause', () => {
|
||||
if (player_instance) player_instance.clear_detection()
|
||||
})
|
||||
|
||||
listen('start_auto_pause', () => {
|
||||
if (player_instance) player_instance.detect_zoom()
|
||||
})
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
// vite.config.ts
|
||||
import { fileURLToPath, URL } from "node:url";
|
||||
import { defineConfig } from "file:///D:/code/wallitor/wallitor-gui/node_modules/.pnpm/vite@5.4.7_@types+node@20.16.7/node_modules/vite/dist/node/index.js";
|
||||
import vue from "file:///D:/code/wallitor/wallitor-gui/node_modules/.pnpm/@vitejs+plugin-vue@5.1.4_vite@5.4.7_@types+node@20.16.7__vue@3.5.8_typescript@5.4.5_/node_modules/@vitejs/plugin-vue/dist/index.mjs";
|
||||
import vueDevTools from "file:///D:/code/wallitor/wallitor-gui/node_modules/.pnpm/vite-plugin-vue-devtools@7.4.6_rollup@4.22.4_vite@5.4.7_@types+node@20.16.7__vue@3.5.8_typescript@5.4.5_/node_modules/vite-plugin-vue-devtools/dist/vite.mjs";
|
||||
import ElementPlus from "file:///D:/code/wallitor/wallitor-gui/node_modules/.pnpm/unplugin-element-plus@0.8.0_rollup@4.22.4/node_modules/unplugin-element-plus/dist/vite.mjs";
|
||||
import path from "path";
|
||||
import { createSvgIconsPlugin } from "file:///D:/code/wallitor/wallitor-gui/node_modules/.pnpm/vite-plugin-svg-icons@2.0.1_vite@5.4.7_@types+node@20.16.7_/node_modules/vite-plugin-svg-icons/dist/index.mjs";
|
||||
var __vite_injected_original_dirname = "D:\\code\\wallitor\\wallitor-gui";
|
||||
var __vite_injected_original_import_meta_url = "file:///D:/code/wallitor/wallitor-gui/vite.config.ts";
|
||||
var vite_config_default = defineConfig({
|
||||
clearScreen: false,
|
||||
// Tauri expects a fixed port, fail if that port is not available
|
||||
server: {
|
||||
strictPort: true
|
||||
},
|
||||
envPrefix: ["VITE_", "TAURI_PLATFORM", "TAURI_ARCH", "TAURI_FAMILY", "TAURI_PLATFORM_VERSION", "TAURI_PLATFORM_TYPE", "TAURI_DEBUG"],
|
||||
plugins: [
|
||||
vue(),
|
||||
vueDevTools(),
|
||||
createSvgIconsPlugin({
|
||||
iconDirs: [
|
||||
path.resolve(__vite_injected_original_dirname, "src/assets/svgs")
|
||||
],
|
||||
symbolId: "icon-[name]"
|
||||
}),
|
||||
ElementPlus({
|
||||
// options
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": fileURLToPath(new URL("./src", __vite_injected_original_import_meta_url))
|
||||
}
|
||||
},
|
||||
build: {
|
||||
// Tauri uses Chromium on Windows and WebKit on macOS and Linux
|
||||
target: process.env.TAURI_PLATFORM == "windows" ? "chrome105" : "safari13",
|
||||
// don't minify for debug builds
|
||||
minify: !process.env.TAURI_DEBUG ? "esbuild" : false,
|
||||
// 为调试构建生成源代码映射 (sourcemap)
|
||||
sourcemap: !!process.env.TAURI_DEBUG,
|
||||
rollupOptions: {
|
||||
input: {
|
||||
main: path.resolve(__vite_injected_original_dirname, "index.html"),
|
||||
video: path.resolve(__vite_injected_original_dirname, "video/index.html")
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
export {
|
||||
vite_config_default as default
|
||||
};
|
||||
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxjb2RlXFxcXHdhbGxpdG9yXFxcXHdhbGxpdG9yLWd1aVwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiRDpcXFxcY29kZVxcXFx3YWxsaXRvclxcXFx3YWxsaXRvci1ndWlcXFxcdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL0Q6L2NvZGUvd2FsbGl0b3Ivd2FsbGl0b3ItZ3VpL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZmlsZVVSTFRvUGF0aCwgVVJMIH0gZnJvbSAnbm9kZTp1cmwnXHJcblxyXG5pbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd2aXRlJ1xyXG5pbXBvcnQgdnVlIGZyb20gJ0B2aXRlanMvcGx1Z2luLXZ1ZSdcclxuaW1wb3J0IHZ1ZURldlRvb2xzIGZyb20gJ3ZpdGUtcGx1Z2luLXZ1ZS1kZXZ0b29scydcclxuaW1wb3J0IEVsZW1lbnRQbHVzIGZyb20gJ3VucGx1Z2luLWVsZW1lbnQtcGx1cy92aXRlJ1xyXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xyXG5pbXBvcnQgeyBjcmVhdGVTdmdJY29uc1BsdWdpbiB9IGZyb20gXCJ2aXRlLXBsdWdpbi1zdmctaWNvbnNcIjtcclxuXHJcbi8vIGh0dHBzOi8vdml0ZWpzLmRldi9jb25maWcvXHJcbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZyh7XHJcbiAgY2xlYXJTY3JlZW46IGZhbHNlLFxyXG4gIC8vIFRhdXJpIGV4cGVjdHMgYSBmaXhlZCBwb3J0LCBmYWlsIGlmIHRoYXQgcG9ydCBpcyBub3QgYXZhaWxhYmxlXHJcbiAgc2VydmVyOiB7XHJcbiAgICBzdHJpY3RQb3J0OiB0cnVlLFxyXG4gIH0sXHJcbiAgZW52UHJlZml4OiBbJ1ZJVEVfJywgJ1RBVVJJX1BMQVRGT1JNJywgJ1RBVVJJX0FSQ0gnLCAnVEFVUklfRkFNSUxZJywgJ1RBVVJJX1BMQVRGT1JNX1ZFUlNJT04nLCAnVEFVUklfUExBVEZPUk1fVFlQRScsICdUQVVSSV9ERUJVRyddLFxyXG4gIHBsdWdpbnM6IFtcclxuICAgIHZ1ZSgpLFxyXG4gICAgdnVlRGV2VG9vbHMoKSxcclxuICAgIGNyZWF0ZVN2Z0ljb25zUGx1Z2luKHtcclxuICAgICAgaWNvbkRpcnM6IFtcclxuICAgICAgICBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCBcInNyYy9hc3NldHMvc3Znc1wiKSxcclxuICAgICAgXSxcclxuICAgICAgc3ltYm9sSWQ6IFwiaWNvbi1bbmFtZV1cIlxyXG4gICAgfSksXHJcbiAgICBFbGVtZW50UGx1cyh7XHJcbiAgICAgIC8vIG9wdGlvbnNcclxuICAgIH0pLFxyXG4gIF0sXHJcbiAgcmVzb2x2ZToge1xyXG4gICAgYWxpYXM6IHtcclxuICAgICAgJ0AnOiBmaWxlVVJMVG9QYXRoKG5ldyBVUkwoJy4vc3JjJywgaW1wb3J0Lm1ldGEudXJsKSlcclxuICAgIH1cclxuICB9LFxyXG4gIGJ1aWxkOiB7XHJcbiAgICAvLyBUYXVyaSB1c2VzIENocm9taXVtIG9uIFdpbmRvd3MgYW5kIFdlYktpdCBvbiBtYWNPUyBhbmQgTGludXhcclxuICAgIHRhcmdldDogcHJvY2Vzcy5lbnYuVEFVUklfUExBVEZPUk0gPT0gJ3dpbmRvd3MnID8gJ2Nocm9tZTEwNScgOiAnc2FmYXJpMTMnLFxyXG4gICAgLy8gZG9uJ3QgbWluaWZ5IGZvciBkZWJ1ZyBidWlsZHNcclxuICAgIG1pbmlmeTogIXByb2Nlc3MuZW52LlRBVVJJX0RFQlVHID8gJ2VzYnVpbGQnIDogZmFsc2UsXHJcbiAgICAvLyBcdTRFM0FcdThDMDNcdThCRDVcdTY3ODRcdTVFRkFcdTc1MUZcdTYyMTBcdTZFOTBcdTRFRTNcdTc4MDFcdTY2MjBcdTVDMDQgKHNvdXJjZW1hcClcclxuICAgIHNvdXJjZW1hcDogISFwcm9jZXNzLmVudi5UQVVSSV9ERUJVRyxcclxuICAgIHJvbGx1cE9wdGlvbnM6IHtcclxuICAgICAgaW5wdXQ6IHtcclxuICAgICAgICBtYWluOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnaW5kZXguaHRtbCcpLFxyXG4gICAgICAgIHZpZGVvOiBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAndmlkZW8vaW5kZXguaHRtbCcpLFxyXG4gICAgICB9LFxyXG4gICAgfSxcclxuICB9LFxyXG59KVxyXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQWlSLFNBQVMsZUFBZSxXQUFXO0FBRXBULFNBQVMsb0JBQW9CO0FBQzdCLE9BQU8sU0FBUztBQUNoQixPQUFPLGlCQUFpQjtBQUN4QixPQUFPLGlCQUFpQjtBQUN4QixPQUFPLFVBQVU7QUFDakIsU0FBUyw0QkFBNEI7QUFQckMsSUFBTSxtQ0FBbUM7QUFBZ0ksSUFBTSwyQ0FBMkM7QUFVMU4sSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDMUIsYUFBYTtBQUFBO0FBQUEsRUFFYixRQUFRO0FBQUEsSUFDTixZQUFZO0FBQUEsRUFDZDtBQUFBLEVBQ0EsV0FBVyxDQUFDLFNBQVMsa0JBQWtCLGNBQWMsZ0JBQWdCLDBCQUEwQix1QkFBdUIsYUFBYTtBQUFBLEVBQ25JLFNBQVM7QUFBQSxJQUNQLElBQUk7QUFBQSxJQUNKLFlBQVk7QUFBQSxJQUNaLHFCQUFxQjtBQUFBLE1BQ25CLFVBQVU7QUFBQSxRQUNSLEtBQUssUUFBUSxrQ0FBVyxpQkFBaUI7QUFBQSxNQUMzQztBQUFBLE1BQ0EsVUFBVTtBQUFBLElBQ1osQ0FBQztBQUFBLElBQ0QsWUFBWTtBQUFBO0FBQUEsSUFFWixDQUFDO0FBQUEsRUFDSDtBQUFBLEVBQ0EsU0FBUztBQUFBLElBQ1AsT0FBTztBQUFBLE1BQ0wsS0FBSyxjQUFjLElBQUksSUFBSSxTQUFTLHdDQUFlLENBQUM7QUFBQSxJQUN0RDtBQUFBLEVBQ0Y7QUFBQSxFQUNBLE9BQU87QUFBQTtBQUFBLElBRUwsUUFBUSxRQUFRLElBQUksa0JBQWtCLFlBQVksY0FBYztBQUFBO0FBQUEsSUFFaEUsUUFBUSxDQUFDLFFBQVEsSUFBSSxjQUFjLFlBQVk7QUFBQTtBQUFBLElBRS9DLFdBQVcsQ0FBQyxDQUFDLFFBQVEsSUFBSTtBQUFBLElBQ3pCLGVBQWU7QUFBQSxNQUNiLE9BQU87QUFBQSxRQUNMLE1BQU0sS0FBSyxRQUFRLGtDQUFXLFlBQVk7QUFBQSxRQUMxQyxPQUFPLEtBQUssUUFBUSxrQ0FBVyxrQkFBa0I7QUFBQSxNQUNuRDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQ0YsQ0FBQzsiLAogICJuYW1lcyI6IFtdCn0K
|
||||