chore: remove unused deps and refactor tauri api

This commit is contained in:
Kuingsmile
2025-07-03 14:45:25 +08:00
parent 96aa24a5fe
commit 3f6d754b50
19 changed files with 392 additions and 829 deletions

View File

@@ -19,7 +19,8 @@
"homepage": "https://github.com/OpenListTeam/openlist-desktop", "homepage": "https://github.com/OpenListTeam/openlist-desktop",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"web:build": "tsc --noEmit && vite build", "tsc:check": "vue-tsc --noEmit",
"web:build": "vue-tsc --noEmit && vite build",
"web:preview": "vite preview", "web:preview": "vite preview",
"build": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build", "build": "cross-env NODE_OPTIONS='--max-old-space-size=4096' tauri build",
"tauri:dev": "cross-env RUST_BACKTRACE=1 tauri dev", "tauri:dev": "cross-env RUST_BACKTRACE=1 tauri dev",
@@ -63,24 +64,22 @@
"@tauri-apps/plugin-process": "^2.3.0", "@tauri-apps/plugin-process": "^2.3.0",
"@tauri-apps/plugin-shell": "^2.3.0", "@tauri-apps/plugin-shell": "^2.3.0",
"@tauri-apps/plugin-store": "^2.3.0", "@tauri-apps/plugin-store": "^2.3.0",
"@vueuse/core": "^13.4.0",
"chrono-node": "^2.8.3", "chrono-node": "^2.8.3",
"dexie": "^4.0.11", "lucide-vue-next": "^0.525.0",
"lucide-vue-next": "^0.523.0",
"pinia": "^3.0.3", "pinia": "^3.0.3",
"vue": "^3.5.17", "vue": "^3.5.17",
"vue-i18n": "11.1.7", "vue-i18n": "11.1.8",
"vue-router": "^4.5.1" "vue-router": "^4.5.1"
}, },
"devDependencies": { "devDependencies": {
"@tauri-apps/cli": "^2.6.0", "@tauri-apps/cli": "^2.6.2",
"@types/node": "^22.9.3", "@types/node": "^22.9.3",
"@typescript-eslint/eslint-plugin": "^8.35.0", "@typescript-eslint/eslint-plugin": "^8.35.1",
"@typescript-eslint/parser": "^8.35.0", "@typescript-eslint/parser": "^8.35.1",
"@vitejs/plugin-vue": "^6.0.0", "@vitejs/plugin-vue": "^6.0.0",
"adm-zip": "^0.5.16", "adm-zip": "^0.5.16",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"eslint": "^9.29.0", "eslint": "^9.30.1",
"eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-unicorn": "^59.0.1", "eslint-plugin-unicorn": "^59.0.1",
"fs-extra": "^11.3.0", "fs-extra": "^11.3.0",
@@ -91,8 +90,8 @@
"node-fetch": "^3.3.2", "node-fetch": "^3.3.2",
"tar": "^7.4.3", "tar": "^7.4.3",
"typescript": "^5.8.3", "typescript": "^5.8.3",
"typescript-eslint": "^8.35.0", "typescript-eslint": "^8.35.1",
"vite": "^7.0.0", "vite": "^7.0.0",
"vue-tsc": "^2.2.10" "vue-tsc": "^3.0.1"
} }
} }

182
src-tauri/Cargo.lock generated
View File

@@ -67,56 +67,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "anstream"
version = "0.6.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.98" version = "1.0.98"
@@ -641,12 +591,6 @@ dependencies = [
"inout", "inout",
] ]
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]] [[package]]
name = "combine" name = "combine"
version = "4.6.7" version = "4.6.7"
@@ -1173,29 +1117,6 @@ dependencies = [
"syn 2.0.104", "syn 2.0.104",
] ]
[[package]]
name = "env_filter"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
dependencies = [
"log",
"regex",
]
[[package]]
name = "env_logger"
version = "0.11.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
dependencies = [
"anstream",
"anstyle",
"env_filter",
"jiff",
"log",
]
[[package]] [[package]]
name = "equivalent" name = "equivalent"
version = "1.0.2" version = "1.0.2"
@@ -2196,12 +2117,6 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.15" version = "1.0.15"
@@ -2231,30 +2146,6 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "jiff"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
dependencies = [
"jiff-static",
"log",
"portable-atomic",
"portable-atomic-util",
"serde",
]
[[package]]
name = "jiff-static"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.104",
]
[[package]] [[package]]
name = "jni" name = "jni"
version = "0.21.1" version = "0.21.1"
@@ -2699,15 +2590,6 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "ntapi"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "num-conv" name = "num-conv"
version = "0.1.0" version = "0.1.0"
@@ -2897,16 +2779,6 @@ dependencies = [
"objc2-core-foundation", "objc2-core-foundation",
] ]
[[package]]
name = "objc2-io-kit"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a"
dependencies = [
"libc",
"objc2-core-foundation",
]
[[package]] [[package]]
name = "objc2-io-surface" name = "objc2-io-surface"
version = "0.3.1" version = "0.3.1"
@@ -2995,12 +2867,6 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
version = "0.3.1" version = "0.3.1"
@@ -3028,7 +2894,6 @@ dependencies = [
"chrono", "chrono",
"deelevate", "deelevate",
"dirs 6.0.0", "dirs 6.0.0",
"env_logger",
"flate2", "flate2",
"lazy_static", "lazy_static",
"log", "log",
@@ -3041,7 +2906,6 @@ dependencies = [
"runas", "runas",
"serde", "serde",
"serde_json", "serde_json",
"sysinfo",
"tar", "tar",
"tauri", "tauri",
"tauri-build", "tauri-build",
@@ -3052,7 +2916,6 @@ dependencies = [
"tauri-plugin-process", "tauri-plugin-process",
"tauri-plugin-shell", "tauri-plugin-shell",
"tauri-plugin-single-instance", "tauri-plugin-single-instance",
"tauri-plugin-store",
"thiserror 2.0.12", "thiserror 2.0.12",
"tokio", "tokio",
"url", "url",
@@ -3441,21 +3304,6 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "portable-atomic"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
[[package]]
name = "portable-atomic-util"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
dependencies = [
"portable-atomic",
]
[[package]] [[package]]
name = "potential_utf" name = "potential_utf"
version = "0.1.2" version = "0.1.2"
@@ -4633,20 +4481,6 @@ dependencies = [
"syn 2.0.104", "syn 2.0.104",
] ]
[[package]]
name = "sysinfo"
version = "0.35.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c3ffa3e4ff2b324a57f7aeb3c349656c7b127c3c189520251a648102a92496e"
dependencies = [
"libc",
"memchr",
"ntapi",
"objc2-core-foundation",
"objc2-io-kit",
"windows",
]
[[package]] [[package]]
name = "system-configuration" name = "system-configuration"
version = "0.6.1" version = "0.6.1"
@@ -5000,22 +4834,6 @@ dependencies = [
"zbus", "zbus",
] ]
[[package]]
name = "tauri-plugin-store"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5916c609664a56c82aeaefffca9851fd072d4d41f73d63f22ee3ee451508194f"
dependencies = [
"dunce",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"thiserror 2.0.12",
"tokio",
"tracing",
]
[[package]] [[package]]
name = "tauri-runtime" name = "tauri-runtime"
version = "2.7.0" version = "2.7.0"

View File

@@ -24,9 +24,7 @@ tauri-plugin-process = "2.3.0"
tauri-plugin-fs = "2.4.0" tauri-plugin-fs = "2.4.0"
tauri-plugin-dialog = "2.3.0" tauri-plugin-dialog = "2.3.0"
tauri-plugin-shell = "2.3.0" tauri-plugin-shell = "2.3.0"
tauri-plugin-store = "2.3.0"
tauri-plugin-autostart = "2.5.0" tauri-plugin-autostart = "2.5.0"
tauri-plugin-single-instance = "2.3.0"
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140" serde_json = "1.0.140"
tokio = { version = "1.45.1", features = ["full"] } tokio = { version = "1.45.1", features = ["full"] }
@@ -35,14 +33,12 @@ thiserror = "2.0.12"
chrono = { version = "0.4.41", features = ["serde"] } chrono = { version = "0.4.41", features = ["serde"] }
log = "0.4.27" log = "0.4.27"
log4rs = "1.3.0" log4rs = "1.3.0"
env_logger = "0.11.8"
dirs = "6.0.0" dirs = "6.0.0"
open = "5.3.2" open = "5.3.2"
reqwest = { version = "0.12.20", features = ["json", "rustls-tls", "cookies"] } reqwest = { version = "0.12.20", features = ["json", "rustls-tls", "cookies"] }
once_cell = "1.21.3" once_cell = "1.21.3"
parking_lot = "0.12.4" parking_lot = "0.12.4"
url = "2.5.4" url = "2.5.4"
sysinfo = "0.35.2"
lazy_static = "1.5.0" lazy_static = "1.5.0"
base64 = "0.22.1" base64 = "0.22.1"
zip = "4.2.0" zip = "4.2.0"

View File

@@ -18,6 +18,7 @@
"autostart:allow-enable", "autostart:allow-enable",
"autostart:allow-disable", "autostart:allow-disable",
"autostart:allow-is-enabled", "autostart:allow-is-enabled",
"dialog:default" "dialog:default",
"process:default"
] ]
} }

View File

@@ -102,6 +102,7 @@ pub fn run() {
.expect("no main window") .expect("no main window")
.set_focus(); .set_focus();
})) }))
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_autostart::init( .plugin(tauri_plugin_autostart::init(

View File

@@ -2,295 +2,122 @@ import { invoke } from '@tauri-apps/api/core'
import { listen } from '@tauri-apps/api/event' import { listen } from '@tauri-apps/api/event'
import { appDataDir, join } from '@tauri-apps/api/path' import { appDataDir, join } from '@tauri-apps/api/path'
import { const call = <T>(cmd: string, args?: any): Promise<T> => invoke(cmd, args)
DownloadProgress,
FileItem,
MergedSettings,
OpenListCoreStatus,
ProcessConfig,
ProcessStatus,
RcloneMountInfo,
RcloneWebdavConfig,
TauriResponse,
UpdateCheck
} from '../types'
export class TauriAPI { export class TauriAPI {
// openlist desktop service management // --- service management ---
static async checkServiceStatus(): Promise<string> { static service = {
return await invoke('check_service_status') status: (): Promise<string> => call('check_service_status'),
install: (): Promise<boolean> => call('install_service'),
uninstall: (): Promise<boolean> => call('uninstall_service'),
start: (): Promise<boolean> => call('start_service'),
stop: (): Promise<boolean> => call('stop_service')
} }
static async installOpenListService(): Promise<boolean> { // --- process management ---
return await invoke('install_service') static process = {
list: (): Promise<ProcessStatus[]> => call('get_process_list'),
start: (id: string): Promise<boolean> => call('start_process', { id }),
stop: (id: string): Promise<boolean> => call('stop_process', { id }),
restart: (id: string): Promise<boolean> => call('restart_process', { id }),
update: (id: string, cfg: Partial<ProcessConfig>): Promise<boolean> =>
call('update_process', { id, updateConfig: cfg }),
delete: (id: string): Promise<boolean> => call('delete_process', { id })
} }
static async uninstallOpenListService(): Promise<boolean> { // --- OpenList Core management ---
return await invoke('uninstall_service') static core = {
create: (autoStart: boolean): Promise<ProcessConfig> => call('create_openlist_core_process', { autoStart }),
getStatus: (): Promise<OpenListCoreStatus> => call('get_openlist_core_status')
} }
static async startOpenListService(): Promise<boolean> { // --- Rclone management ---
return await invoke('start_service') static rclone = {
backend: {
create: (): Promise<boolean> => call('create_rclone_backend_process'),
createAndStart: (): Promise<ProcessConfig> => call('create_and_start_rclone_backend'),
isRunning: (): Promise<boolean> => call('get_rclone_backend_status')
},
remotes: {
list: (): Promise<string[]> => call('rclone_list_remotes'),
create: (name: string, type: string, config: RcloneWebdavConfig): Promise<boolean> =>
call('rclone_create_remote', { name, type, config }),
update: (name: string, type: string, config: RcloneWebdavConfig): Promise<boolean> =>
call('rclone_update_remote', { name, type, config }),
delete: (name: string): Promise<boolean> => call('rclone_delete_remote', { name }),
listConfig: (t: string): Promise<IRemoteConfig> => call('rclone_list_config', { remoteType: t })
},
mounts: {
list: (): Promise<RcloneMountInfo[]> => call('get_mount_info_list'),
check: (mp: string): Promise<boolean> => call('check_mount_status', { mountPoint: mp }),
createProcess: (cfg: ProcessConfig): Promise<ProcessConfig> =>
call('create_rclone_mount_remote_process', { config: cfg })
}
} }
static async stopOpenListService(): Promise<boolean> { // -- File management ---
return await invoke('stop_service') static files = {
list: (path: string): Promise<FileItem[]> => call('list_files', { path }),
open: (path: string): Promise<boolean> => call('open_file', { path }),
folder: (path: string): Promise<boolean> => call('open_folder', { path }),
url: (path: string): Promise<boolean> => call('open_url', { path })
} }
// http API management // --- Settings management ---
static async getProcessList(): Promise<ProcessStatus[]> { static settings = {
return await invoke('get_process_list') load: (): Promise<MergedSettings | null> => call('load_settings'),
save: (s: MergedSettings): Promise<boolean> => call('save_settings', { settings: s }),
saveWithUpdatePort: (s: MergedSettings): Promise<boolean> =>
call('save_settings_with_update_port', { settings: s }),
reset: (): Promise<MergedSettings | null> => call('reset_settings')
} }
static async startProcess(id: string): Promise<boolean> { // --- Logs management ---
return await invoke('start_process', { id }) static logs = {
get: (src?: 'openlist' | 'rclone' | 'app' | 'openlist_core'): Promise<string[]> =>
call('get_logs', { source: src }),
clear: (src?: 'openlist' | 'rclone' | 'app' | 'openlist_core'): Promise<boolean> =>
call('clear_logs', { source: src }),
adminPassword: (): Promise<string> => call('get_admin_password')
} }
static async stopProcess(id: string): Promise<boolean> { // --- Binary management ---
return await invoke('stop_process', { id }) static bin = {
version: (name: 'openlist' | 'rclone'): Promise<string> => call('get_binary_version', { binaryName: name }),
availableVersions: (tool: string): Promise<string[]> => call('get_available_versions', { tool }),
updateVersion: (tool: string, version: string): Promise<string> => call('update_tool_version', { tool, version })
} }
static async restartProcess(id: string): Promise<boolean> { // --- Utility functions ---
return await invoke('restart_process', { id }) static util = {
defaultDataDir: (): Promise<string> => appDataDir().then(d => join(d, 'openlist-desktop')),
defaultConfig: (): Promise<string> => appDataDir().then(d => join(d, 'openlist-desktop', 'rclone.conf')),
selectDirectory: (title: string): Promise<string | null> => call('select_directory', { title })
} }
static async updateProcess(id: string, config: Partial<ProcessConfig>): Promise<boolean> { // --- Tray management ---
return await invoke('update_process', { id, updateConfig: config }) static tray = {
update: (r: boolean): Promise<void> => call('update_tray_menu', { serviceRunning: r }),
updateDelayed: (r: boolean): Promise<void> => call('update_tray_menu_delayed', { serviceRunning: r }),
forceUpdate: (r: boolean): Promise<void> => call('force_update_tray_menu', { serviceRunning: r }),
listen: (cb: (action: string) => void) => listen('tray-core-action', e => cb(e.payload as string))
} }
static async deleteProcess(id: string): Promise<boolean> { // --- Update management ---
return await invoke('delete_process', { id }) static updater = {
} check: (): Promise<UpdateCheck> => call('check_for_updates'),
download: (url: string, name: string): Promise<string> =>
// OpenList Core management call('download_update', { assetUrl: url, assetName: name }),
installAndRestart: (path: string): Promise<void> => call('install_update_and_restart', { installerPath: path }),
static async createOpenListCore(autoStart: boolean): Promise<ProcessConfig> { currentVersion: (): Promise<string> => call('get_current_version'),
return await invoke('create_openlist_core_process', { autoStart }) setAutoCheck: (e: boolean): Promise<void> => call('set_auto_check_enabled', { enabled: e }),
} isAutoCheckEnabled: (): Promise<boolean> => call('is_auto_check_enabled'),
onBackgroundUpdate: (cb: (u: UpdateCheck) => void) =>
static async getOpenListCoreStatus(): Promise<OpenListCoreStatus> { listen('background-update-available', e => cb(e.payload as UpdateCheck)),
return await invoke('get_openlist_core_status') onDownloadProgress: (cb: (p: DownloadProgress) => void) =>
} listen('download-progress', e => cb(e.payload as DownloadProgress)),
onInstallStarted: (cb: () => void) => listen('update-install-started', () => cb()),
// Rclone management onInstallError: (cb: (err: string) => void) => listen('update-install-error', e => cb(e.payload as string)),
onAppRestarting: (cb: () => void) => listen('app-restarting', () => cb())
static async createRcloneBackend(): Promise<boolean> {
return await invoke('create_rclone_backend_process')
}
static async createAndStartRcloneBackend(): Promise<ProcessConfig> {
return await invoke('create_and_start_rclone_backend')
}
static async isRcloneRunning(): Promise<boolean> {
return await invoke('get_rclone_backend_status')
}
static async createRemoteConfig(name: string, type: string, config: RcloneWebdavConfig): Promise<boolean> {
return await invoke('rclone_create_remote', { name, type, config })
}
static async updateRemoteConfig(name: string, type: string, config: RcloneWebdavConfig): Promise<boolean> {
return await invoke('rclone_update_remote', { name, type, config })
}
static async deleteRemoteConfig(name: string): Promise<boolean> {
return await invoke('rclone_delete_remote', { name })
}
static async listRcloneRemotes(): Promise<string[]> {
return await invoke('rclone_list_remotes')
}
static async listRcloneMounts(): Promise<any> {
return await invoke('rclone_list_mounts')
}
static async checkMountStatus(mountPoint: string): Promise<boolean> {
return await invoke('check_mount_status', { mountPoint })
}
static async getMountInfoList(): Promise<RcloneMountInfo[]> {
return await invoke('get_mount_info_list')
}
static async rcloneListConfig(remoteType: string): Promise<IRemoteConfig> {
return await invoke('rclone_list_config', { remoteType })
}
static async getRcloneBackendStatus(): Promise<boolean> {
return await invoke('get_rclone_backend_status')
}
static async createRcloneMountRemoteProcess(config: ProcessConfig): Promise<ProcessConfig> {
return await invoke('create_rclone_mount_remote_process', { config })
}
// File operations
static async listFiles(path: string): Promise<FileItem[]> {
return await invoke('list_files', { path })
}
static async openFile(path: string): Promise<boolean> {
return await invoke('open_file', { path })
}
static async openFolder(path: string): Promise<boolean> {
return await invoke('open_folder', { path })
}
static async openUrl(path: string): Promise<boolean> {
return await invoke('open_url', { path })
}
// Settings management
static async loadSettings(): Promise<MergedSettings | null> {
return await invoke('load_settings')
}
static async saveSettings(settings: MergedSettings): Promise<boolean> {
return await invoke('save_settings', { settings })
}
static async saveSettingsWithUpdatePort(settings: MergedSettings): Promise<boolean> {
return await invoke('save_settings_with_update_port', { settings })
}
static async resetSettings(): Promise<MergedSettings | null> {
return await invoke('reset_settings')
}
// Logs
static async getLogs(source?: 'openlist' | 'rclone' | 'app' | 'openlist_core'): Promise<string[]> {
return await invoke('get_logs', { source })
}
static async clearLogs(source?: 'openlist' | 'rclone' | 'app' | 'openlist_core'): Promise<boolean> {
return await invoke('clear_logs', { source })
}
static async getAdminPassword(): Promise<string> {
return await invoke('get_admin_password')
}
// Binary management
static async getBinaryVersion(binary_name: 'openlist' | 'rclone'): Promise<string> {
return await invoke('get_binary_version', { binaryName: binary_name })
}
static async selectDirectory(title: string): Promise<string | null> {
return await invoke('select_directory', { title })
}
static async getAvailableVersions(tool: string): Promise<string[]> {
return await invoke('get_available_versions', { tool })
}
static async updateToolVersion(tool: string, version: string): Promise<string> {
return await invoke('update_tool_version', { tool, version })
}
static async getAppVersion(): Promise<TauriResponse<string>> {
return await invoke('get_app_version')
}
// Utility methods
static async getDefaultDataDir(): Promise<string> {
const appData = await appDataDir()
return await join(appData, 'openlist-desktop')
}
static async getDefaultConfigPath(): Promise<string> {
const appData = await appDataDir()
return await join(appData, 'openlist-desktop', 'rclone.conf')
}
// Auto-startup management
static async enableAutoStart(): Promise<TauriResponse<void>> {
return await invoke('enable_auto_start')
}
static async disableAutoStart(): Promise<TauriResponse<void>> {
return await invoke('disable_auto_start')
}
static async isAutoStartEnabled(): Promise<TauriResponse<boolean>> {
return await invoke('is_auto_start_enabled')
}
// System tray management
static async updateTrayMenu(serviceRunning: boolean): Promise<void> {
return await invoke('update_tray_menu', { serviceRunning })
}
static async updateTrayMenuDelayed(serviceRunning: boolean): Promise<void> {
return await invoke('update_tray_menu_delayed', { serviceRunning })
}
static async forceUpdateTrayMenu(serviceRunning: boolean): Promise<void> {
return await invoke('force_update_tray_menu', { serviceRunning })
}
// Tray event listeners
static async listenToTrayServiceActions(callback: (action: string) => void) {
return await listen('tray-core-action', event => {
callback(event.payload as string)
})
}
// Custom Updater management
static async checkForUpdates(): Promise<UpdateCheck> {
return await invoke('check_for_updates')
}
static async downloadUpdate(assetUrl: string, assetName: string): Promise<string> {
return await invoke('download_update', { assetUrl, assetName })
}
static async installUpdateAndRestart(installerPath: string): Promise<void> {
return await invoke('install_update_and_restart', { installerPath })
}
static async getCurrentVersion(): Promise<string> {
return await invoke('get_current_version')
}
static async setAutoCheckEnabled(enabled: boolean): Promise<void> {
return await invoke('set_auto_check_enabled', { enabled })
}
static async isAutoCheckEnabled(): Promise<boolean> {
return await invoke('is_auto_check_enabled')
}
// Update event listeners
static async listenToBackgroundUpdateAvailable(callback: (updateCheck: UpdateCheck) => void) {
return await listen('background-update-available', event => {
callback(event.payload as UpdateCheck)
})
}
static async listenToDownloadProgress(callback: (progress: DownloadProgress) => void) {
return await listen('download-progress', event => {
callback(event.payload as DownloadProgress)
})
}
static async listenToUpdateInstallStarted(callback: () => void) {
return await listen('update-install-started', () => {
callback()
})
}
static async listenToUpdateInstallError(callback: (error: string) => void) {
return await listen('update-install-error', event => {
callback(event.payload as string)
})
}
static async listenToAppRestarting(callback: () => void) {
return await listen('app-restarting', () => {
callback()
})
} }
} }

View File

@@ -27,7 +27,7 @@ const navigationItems = computed(() => [
const openLink = async (url: string) => { const openLink = async (url: string) => {
try { try {
await TauriAPI.openUrl(url) await TauriAPI.files.url(url)
} catch (error) { } catch (error) {
console.error('Failed to open link:', error) console.error('Failed to open link:', error)
window.open(url, '_blank') window.open(url, '_blank')

View File

@@ -100,7 +100,7 @@ const openRcloneGitHub = () => {
const openLink = async (url: string) => { const openLink = async (url: string) => {
try { try {
await TauriAPI.openUrl(url) await TauriAPI.files.url(url)
} catch (error) { } catch (error) {
console.error('Failed to open link:', error) console.error('Failed to open link:', error)
window.open(url, '_blank') window.open(url, '_blank')

View File

@@ -164,7 +164,7 @@ const statusIcon = computed(() => {
const checkServiceStatus = async () => { const checkServiceStatus = async () => {
try { try {
const status = await TauriAPI.checkServiceStatus() const status = await TauriAPI.service.status()
serviceStatus.value = status as 'not-installed' | 'installed' | 'running' | 'error' | 'stopped' serviceStatus.value = status as 'not-installed' | 'installed' | 'running' | 'error' | 'stopped'
return status return status
} catch (error) { } catch (error) {
@@ -178,7 +178,7 @@ const installService = async () => {
actionLoading.value = true actionLoading.value = true
currentAction.value = 'install' currentAction.value = 'install'
try { try {
const result = await TauriAPI.installOpenListService() const result = await TauriAPI.service.install()
if (!result) { if (!result) {
throw new Error('Installation failed') throw new Error('Installation failed')
} }
@@ -188,7 +188,7 @@ const installService = async () => {
throw new Error('Service installation did not complete successfully') throw new Error('Service installation did not complete successfully')
} }
try { try {
await TauriAPI.createAndStartRcloneBackend() await TauriAPI.rclone.backend.createAndStart()
await rcloneStore.checkRcloneBackendStatus() await rcloneStore.checkRcloneBackendStatus()
} catch (stopError) { } catch (stopError) {
console.warn('Failed to stop service during installation:', stopError) console.warn('Failed to stop service during installation:', stopError)
@@ -205,7 +205,7 @@ const startService = async () => {
actionLoading.value = true actionLoading.value = true
currentAction.value = 'start' currentAction.value = 'start'
try { try {
const result = await TauriAPI.startOpenListService() const result = await TauriAPI.service.start()
if (!result) { if (!result) {
throw new Error('Service start failed') throw new Error('Service start failed')
} }
@@ -223,7 +223,7 @@ const stopService = async () => {
actionLoading.value = true actionLoading.value = true
currentAction.value = 'stop' currentAction.value = 'stop'
try { try {
const result = await TauriAPI.stopOpenListService() const result = await TauriAPI.service.stop()
if (!result) { if (!result) {
throw new Error('Service stop failed') throw new Error('Service stop failed')
} }
@@ -241,7 +241,7 @@ const uninstallService = async () => {
actionLoading.value = true actionLoading.value = true
currentAction.value = 'uninstall' currentAction.value = 'uninstall'
try { try {
const result = await TauriAPI.uninstallOpenListService() const result = await TauriAPI.service.uninstall()
if (!result) { if (!result) {
throw new Error('Uninstallation failed') throw new Error('Uninstallation failed')
} }

View File

@@ -139,8 +139,8 @@ import { ref, onMounted, onUnmounted, computed } from 'vue'
import { useTranslation } from '../../composables/useI18n' import { useTranslation } from '../../composables/useI18n'
import { useAppStore } from '../../stores/app' import { useAppStore } from '../../stores/app'
import { TauriAPI } from '../../api/tauri' import { TauriAPI } from '../../api/tauri'
import type { UpdateCheck, UpdateAsset, DownloadProgress } from '../../types'
import Card from '../ui/Card.vue' import Card from '../ui/Card.vue'
import { formatBytes } from '@/utils/formatters'
import { RefreshCw, Download, ArrowRight, CheckCircle, AlertCircle, Info, CheckCircle2 } from 'lucide-vue-next' import { RefreshCw, Download, ArrowRight, CheckCircle, AlertCircle, Info, CheckCircle2 } from 'lucide-vue-next'
interface Props { interface Props {
@@ -186,7 +186,7 @@ const checkForUpdates = async () => {
checking.value = true checking.value = true
error.value = null error.value = null
const result = await TauriAPI.checkForUpdates() const result = await TauriAPI.updater.check()
updateCheck.value = result updateCheck.value = result
if (result.hasUpdate && result.assets.length > 0) { if (result.hasUpdate && result.assets.length > 0) {
@@ -222,7 +222,7 @@ const downloadAndInstall = async () => {
installationStatus.value = t('update.startingDownload') installationStatus.value = t('update.startingDownload')
installationStatusType.value = 'info' installationStatusType.value = 'info'
const filePath = await TauriAPI.downloadUpdate(selectedAsset.value.url, selectedAsset.value.name) const filePath = await TauriAPI.updater.download(selectedAsset.value.url, selectedAsset.value.name)
downloading.value = false downloading.value = false
installing.value = true installing.value = true
@@ -230,7 +230,7 @@ const downloadAndInstall = async () => {
installationStatus.value = t('update.installingUpdate') installationStatus.value = t('update.installingUpdate')
installationStatusType.value = 'info' installationStatusType.value = 'info'
await TauriAPI.installUpdateAndRestart(filePath) await TauriAPI.updater.installAndRestart(filePath)
} catch (err: any) { } catch (err: any) {
console.error('Failed to download/install update:', err) console.error('Failed to download/install update:', err)
downloading.value = false downloading.value = false
@@ -246,7 +246,7 @@ const toggleAutoCheck = async () => {
try { try {
settingsLoading.value = true settingsLoading.value = true
await TauriAPI.setAutoCheckEnabled(autoCheckEnabled.value) await TauriAPI.updater.setAutoCheck(autoCheckEnabled.value)
} catch (err: any) { } catch (err: any) {
console.error('Failed to update auto-check setting:', err) console.error('Failed to update auto-check setting:', err)
autoCheckEnabled.value = !autoCheckEnabled.value autoCheckEnabled.value = !autoCheckEnabled.value
@@ -296,14 +296,6 @@ const formatReleaseNotes = (notes: string) => {
.replace(/\n/g, '<br>') .replace(/\n/g, '<br>')
} }
const formatBytes = (bytes: number) => {
if (bytes === 0) return '0 Bytes'
const k = 1024
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}
const formatSpeed = (bytesPerSecond: number) => { const formatSpeed = (bytesPerSecond: number) => {
if (bytesPerSecond === 0) return '0 B/s' if (bytesPerSecond === 0) return '0 B/s'
const k = 1024 const k = 1024
@@ -321,10 +313,10 @@ onMounted(async () => {
} }
} }
appStore.clearUpdateStatus() appStore.clearUpdateStatus()
currentVersion.value = await TauriAPI.getCurrentVersion() currentVersion.value = await TauriAPI.updater.currentVersion()
autoCheckEnabled.value = await TauriAPI.isAutoCheckEnabled() autoCheckEnabled.value = await TauriAPI.updater.isAutoCheckEnabled()
try { try {
backgroundUpdateUnlisten = await TauriAPI.listenToBackgroundUpdateAvailable(updateInfo => { backgroundUpdateUnlisten = await TauriAPI.updater.onBackgroundUpdate(updateInfo => {
console.log('Background update available:', updateInfo) console.log('Background update available:', updateInfo)
backgroundUpdateCheck.value = updateInfo backgroundUpdateCheck.value = updateInfo
}) })
@@ -334,7 +326,7 @@ onMounted(async () => {
} }
try { try {
downloadProgressUnlisten = await TauriAPI.listenToDownloadProgress(progress => { downloadProgressUnlisten = await TauriAPI.updater.onDownloadProgress(progress => {
downloadProgress.value = progress downloadProgress.value = progress
}) })
} catch (err) { } catch (err) {
@@ -343,7 +335,7 @@ onMounted(async () => {
} }
try { try {
installStartedUnlisten = await TauriAPI.listenToUpdateInstallStarted(() => { installStartedUnlisten = await TauriAPI.updater.onInstallStarted(() => {
installing.value = true installing.value = true
installationStatus.value = t('update.installingUpdate') installationStatus.value = t('update.installingUpdate')
installationStatusType.value = 'info' installationStatusType.value = 'info'
@@ -354,7 +346,7 @@ onMounted(async () => {
} }
try { try {
installErrorUnlisten = await TauriAPI.listenToUpdateInstallError(errorMsg => { installErrorUnlisten = await TauriAPI.updater.onInstallError(errorMsg => {
installing.value = false installing.value = false
error.value = errorMsg error.value = errorMsg
installationStatus.value = t('update.installError') installationStatus.value = t('update.installError')
@@ -366,7 +358,7 @@ onMounted(async () => {
} }
try { try {
appRestartingUnlisten = await TauriAPI.listenToAppRestarting(() => { appRestartingUnlisten = await TauriAPI.updater.onAppRestarting(() => {
installationStatus.value = t('update.restartingApp') installationStatus.value = t('update.restartingApp')
installationStatusType.value = 'success' installationStatusType.value = 'success'
}) })

View File

@@ -99,8 +99,8 @@ const refreshing = ref(false)
const getCurrentVersions = async () => { const getCurrentVersions = async () => {
try { try {
const [openlistVersion, rcloneVersion] = await Promise.all([ const [openlistVersion, rcloneVersion] = await Promise.all([
TauriAPI.getBinaryVersion('openlist'), TauriAPI.bin.version('openlist'),
TauriAPI.getBinaryVersion('rclone') TauriAPI.bin.version('rclone')
]) ])
currentVersions.value.openlist = openlistVersion || 'unknown' currentVersions.value.openlist = openlistVersion || 'unknown'
currentVersions.value.rclone = rcloneVersion || 'unknown' currentVersions.value.rclone = rcloneVersion || 'unknown'
@@ -111,7 +111,7 @@ const getCurrentVersions = async () => {
const fetchOpenListVersions = async () => { const fetchOpenListVersions = async () => {
try { try {
return await TauriAPI.getAvailableVersions('openlist') return await TauriAPI.bin.availableVersions('openlist')
} catch (error) { } catch (error) {
console.error('Failed to fetch OpenList versions:', error) console.error('Failed to fetch OpenList versions:', error)
return [] return []
@@ -120,7 +120,7 @@ const fetchOpenListVersions = async () => {
const fetchRcloneVersions = async () => { const fetchRcloneVersions = async () => {
try { try {
const versions = await TauriAPI.getAvailableVersions('rclone') const versions = await TauriAPI.bin.availableVersions('rclone')
return versions return versions
} catch (error) { } catch (error) {
return [] return []
@@ -145,7 +145,7 @@ const refreshVersions = async () => {
const updateVersion = async (type: 'openlist' | 'rclone') => { const updateVersion = async (type: 'openlist' | 'rclone') => {
loading.value[type] = true loading.value[type] = true
try { try {
const result = await TauriAPI.updateToolVersion(type, selectedVersions.value[type]) const result = await TauriAPI.bin.updateVersion(type, selectedVersions.value[type])
currentVersions.value[type] = selectedVersions.value[type] currentVersions.value[type] = selectedVersions.value[type]
selectedVersions.value[type] = '' selectedVersions.value[type] = ''

View File

@@ -11,7 +11,7 @@ export const useTray = () => {
let unlistenTrayActions: (() => void) | null = null let unlistenTrayActions: (() => void) | null = null
const updateTrayMenu = async (serviceRunning: boolean) => { const updateTrayMenu = async (serviceRunning: boolean) => {
try { try {
await TauriAPI.updateTrayMenuDelayed(serviceRunning) await TauriAPI.tray.update(serviceRunning)
} catch (error) { } catch (error) {
console.error('Failed to update tray menu:', error) console.error('Failed to update tray menu:', error)
} }
@@ -50,9 +50,9 @@ export const useTray = () => {
} }
const initTrayListeners = async () => { const initTrayListeners = async () => {
try { try {
unlistenTrayActions = await TauriAPI.listenToTrayServiceActions(handleTrayServiceAction) unlistenTrayActions = await TauriAPI.tray.listen(handleTrayServiceAction)
await TauriAPI.forceUpdateTrayMenu(store.openlistCoreStatus.running) await TauriAPI.tray.forceUpdate(store.openlistCoreStatus.running)
console.log('Tray listeners initialized and menu updated') console.log('Tray listeners initialized and menu updated')
} catch (error) { } catch (error) {
console.error('Failed to initialize tray listeners:', error) console.error('Failed to initialize tray listeners:', error)

View File

@@ -2,16 +2,6 @@ import { defineStore } from 'pinia'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import { TauriAPI } from '../api/tauri' import { TauriAPI } from '../api/tauri'
import type {
FileItem,
MergedSettings,
OpenListCoreStatus,
ProcessConfig,
RcloneFormConfig,
RcloneMountInfo,
RcloneWebdavConfig,
UpdateCheck
} from '../types'
export const useAppStore = defineStore('app', () => { export const useAppStore = defineStore('app', () => {
const settings = ref<MergedSettings>({ const settings = ref<MergedSettings>({
@@ -55,7 +45,7 @@ export const useAppStore = defineStore('app', () => {
async function loadMountInfos() { async function loadMountInfos() {
try { try {
mountInfos.value = await TauriAPI.getMountInfoList() mountInfos.value = await TauriAPI.rclone.mounts.list()
} catch (err: any) { } catch (err: any) {
error.value = 'Failed to load mount information' error.value = 'Failed to load mount information'
console.error('Failed to load mount infos:', err) console.error('Failed to load mount infos:', err)
@@ -83,7 +73,7 @@ export const useAppStore = defineStore('app', () => {
user: fullConfig.user, user: fullConfig.user,
pass: fullConfig.pass pass: fullConfig.pass
} }
const result = await TauriAPI.createRemoteConfig(name, type, createdConfig) const result = await TauriAPI.rclone.remotes.create(name, type, createdConfig)
if (!result) { if (!result) {
throw new Error('Failed to create remote configuration') throw new Error('Failed to create remote configuration')
} }
@@ -126,12 +116,12 @@ export const useAppStore = defineStore('app', () => {
if (!result) { if (!result) {
throw new Error('Failed to create remote configuration') throw new Error('Failed to create remote configuration')
} }
const deleteResult = await TauriAPI.deleteRemoteConfig(name) const deleteResult = await TauriAPI.rclone.remotes.delete(name)
if (!deleteResult) { if (!deleteResult) {
throw new Error('Failed to delete old remote configuration') throw new Error('Failed to delete old remote configuration')
} }
} else { } else {
const result = await TauriAPI.updateRemoteConfig(name, type, updatedConfig) const result = await TauriAPI.rclone.remotes.update(name, type, updatedConfig)
if (!result) { if (!result) {
throw new Error('Failed to update remote configuration') throw new Error('Failed to update remote configuration')
} }
@@ -144,8 +134,8 @@ export const useAppStore = defineStore('app', () => {
const oldProcessId = await getRcloneMountProcessId(name) const oldProcessId = await getRcloneMountProcessId(name)
if (oldProcessId) { if (oldProcessId) {
try { try {
await TauriAPI.stopProcess(oldProcessId) await TauriAPI.process.stop(oldProcessId)
await TauriAPI.deleteProcess(oldProcessId) await TauriAPI.process.delete(oldProcessId)
const mountArgs = [ const mountArgs = [
`${fullConfig.name}:${fullConfig.volumeName || ''}`, `${fullConfig.name}:${fullConfig.volumeName || ''}`,
@@ -164,7 +154,7 @@ export const useAppStore = defineStore('app', () => {
created_at: 0, created_at: 0,
updated_at: 0 updated_at: 0
} }
await TauriAPI.createRcloneMountRemoteProcess(newProcessConfig) await TauriAPI.rclone.mounts.createProcess(newProcessConfig)
} catch (err) { } catch (err) {
console.warn(`Failed to update mount process for renamed config ${name} -> ${config.name}:`, err) console.warn(`Failed to update mount process for renamed config ${name} -> ${config.name}:`, err)
} }
@@ -187,13 +177,13 @@ export const useAppStore = defineStore('app', () => {
const processId = await getRcloneMountProcessId(name) const processId = await getRcloneMountProcessId(name)
if (processId) { if (processId) {
try { try {
await TauriAPI.stopProcess(processId) await TauriAPI.process.stop(processId)
await TauriAPI.deleteProcess(processId) await TauriAPI.process.delete(processId)
} catch (err) { } catch (err) {
console.warn(`Failed to stop/delete mount process for ${name}:`, err) console.warn(`Failed to stop/delete mount process for ${name}:`, err)
} }
} }
await TauriAPI.deleteRemoteConfig(name) await TauriAPI.rclone.remotes.delete(name)
await loadRemoteConfigs() await loadRemoteConfigs()
if (settings.value.rclone.config[name]) { if (settings.value.rclone.config[name]) {
delete settings.value.rclone.config[name] delete settings.value.rclone.config[name]
@@ -213,7 +203,7 @@ export const useAppStore = defineStore('app', () => {
async function loadRemoteConfigs() { async function loadRemoteConfigs() {
try { try {
loading.value = true loading.value = true
remoteConfigs.value = await TauriAPI.rcloneListConfig('webdav') remoteConfigs.value = await TauriAPI.rclone.remotes.listConfig('webdav')
} catch (err: any) { } catch (err: any) {
error.value = 'Failed to load remote configurations' error.value = 'Failed to load remote configurations'
console.error('Failed to load remote configs:', err) console.error('Failed to load remote configs:', err)
@@ -274,9 +264,9 @@ export const useAppStore = defineStore('app', () => {
if (!config.mountPoint) { if (!config.mountPoint) {
throw new Error(`Mount point is not set for remote: ${name}`) throw new Error(`Mount point is not set for remote: ${name}`)
} }
const mountResult = await TauriAPI.checkMountStatus(config.mountPoint) const mountResult = await TauriAPI.rclone.mounts.check(config.mountPoint)
if (!mountResult) { if (!mountResult) {
const startResult = await TauriAPI.startProcess(processId) const startResult = await TauriAPI.process.start(processId)
if (!startResult) { if (!startResult) {
throw new Error(`Failed to start mount process for remote: ${name}`) throw new Error(`Failed to start mount process for remote: ${name}`)
} }
@@ -304,11 +294,11 @@ export const useAppStore = defineStore('app', () => {
created_at: 0, created_at: 0,
updated_at: 0 updated_at: 0
} }
const createResponse = await TauriAPI.createRcloneMountRemoteProcess(createRemoteConfig) const createResponse = await TauriAPI.rclone.mounts.createProcess(createRemoteConfig)
if (!createResponse || !createResponse.id) { if (!createResponse || !createResponse.id) {
throw new Error('Failed to create mount process') throw new Error('Failed to create mount process')
} }
const startResponse = await TauriAPI.startProcess(createResponse.id) const startResponse = await TauriAPI.process.start(createResponse.id)
if (!startResponse) { if (!startResponse) {
throw new Error('Failed to start mount process') throw new Error('Failed to start mount process')
} }
@@ -328,7 +318,7 @@ export const useAppStore = defineStore('app', () => {
loading.value = true loading.value = true
const processId = await getRcloneMountProcessId(name) const processId = await getRcloneMountProcessId(name)
if (processId) { if (processId) {
const stopResult = await TauriAPI.stopProcess(processId) const stopResult = await TauriAPI.process.stop(processId)
if (!stopResult) { if (!stopResult) {
throw new Error(`Failed to stop mount process for remote: ${name}`) throw new Error(`Failed to stop mount process for remote: ${name}`)
} }
@@ -367,7 +357,7 @@ export const useAppStore = defineStore('app', () => {
async function loadSettings() { async function loadSettings() {
try { try {
loading.value = true loading.value = true
const response = await TauriAPI.loadSettings() const response = await TauriAPI.settings.load()
if (response) { if (response) {
settings.value = response settings.value = response
} }
@@ -383,7 +373,7 @@ export const useAppStore = defineStore('app', () => {
async function saveSettings() { async function saveSettings() {
try { try {
console.log('value:', JSON.stringify(settings.value)) console.log('value:', JSON.stringify(settings.value))
await TauriAPI.saveSettings(settings.value) await TauriAPI.settings.save(settings.value)
} catch (err) { } catch (err) {
error.value = 'Failed to save settings' error.value = 'Failed to save settings'
console.error('Failed to save settings:', err) console.error('Failed to save settings:', err)
@@ -393,7 +383,7 @@ export const useAppStore = defineStore('app', () => {
async function saveSettingsWithUpdatePort(): Promise<boolean> { async function saveSettingsWithUpdatePort(): Promise<boolean> {
try { try {
await TauriAPI.saveSettingsWithUpdatePort(settings.value) await TauriAPI.settings.saveWithUpdatePort(settings.value)
return true return true
} catch (err) { } catch (err) {
error.value = 'Failed to save settings' error.value = 'Failed to save settings'
@@ -405,7 +395,7 @@ export const useAppStore = defineStore('app', () => {
async function resetSettings() { async function resetSettings() {
try { try {
loading.value = true loading.value = true
const response = await TauriAPI.resetSettings() const response = await TauriAPI.settings.reset()
if (response) { if (response) {
settings.value = response settings.value = response
} }
@@ -419,7 +409,7 @@ export const useAppStore = defineStore('app', () => {
async function getRcloneMountProcessId(name: string): Promise<string | undefined> { async function getRcloneMountProcessId(name: string): Promise<string | undefined> {
try { try {
const processList = await TauriAPI.getProcessList() const processList = await TauriAPI.process.list()
const mountName = `rclone_mount_${name}_process` const mountName = `rclone_mount_${name}_process`
const findRcloneBackend = processList.find(p => p.config?.name === mountName) const findRcloneBackend = processList.find(p => p.config?.name === mountName)
if (findRcloneBackend) { if (findRcloneBackend) {
@@ -437,14 +427,14 @@ export const useAppStore = defineStore('app', () => {
let processId: string | undefined let processId: string | undefined
let createResponse: ProcessConfig | undefined let createResponse: ProcessConfig | undefined
const processList = await TauriAPI.getProcessList() const processList = await TauriAPI.process.list()
const findOpenListCore = processList.find(p => p.config?.name === 'single_openlist_core_process') const findOpenListCore = processList.find(p => p.config?.name === 'single_openlist_core_process')
if (!findOpenListCore) { if (!findOpenListCore) {
createResponse = await TauriAPI.createOpenListCore(settings.value.openlist.auto_launch) createResponse = await TauriAPI.core.create(settings.value.openlist.auto_launch)
if (!createResponse || !createResponse.id) { if (!createResponse || !createResponse.id) {
throw new Error('Invalid response from createOpenListCore: missing process ID') throw new Error('Invalid response from TauriAPI.core.create: missing process ID')
} }
processId = createResponse.id processId = createResponse.id
@@ -455,7 +445,7 @@ export const useAppStore = defineStore('app', () => {
if (!processId) { if (!processId) {
throw new Error('Failed to create or retrieve OpenList Core process ID') throw new Error('Failed to create or retrieve OpenList Core process ID')
} }
const startResponse = await TauriAPI.startProcess(processId) const startResponse = await TauriAPI.process.start(processId)
if (!startResponse) { if (!startResponse) {
throw new Error('Failed to start OpenList Core service - service returned false') throw new Error('Failed to start OpenList Core service - service returned false')
} }
@@ -463,7 +453,7 @@ export const useAppStore = defineStore('app', () => {
openlistProcessId.value = processId openlistProcessId.value = processId
await refreshOpenListCoreStatus() await refreshOpenListCoreStatus()
await TauriAPI.updateTrayMenu(openlistCoreStatus.value.running) await TauriAPI.tray.update(openlistCoreStatus.value.running)
} catch (err: any) { } catch (err: any) {
openlistCoreStatus.value = { running: false } openlistCoreStatus.value = { running: false }
let errorMessage = 'Failed to start service' let errorMessage = 'Failed to start service'
@@ -482,7 +472,7 @@ export const useAppStore = defineStore('app', () => {
async function getOpenListProcessId() { async function getOpenListProcessId() {
try { try {
const processList = await TauriAPI.getProcessList() const processList = await TauriAPI.process.list()
const findOpenListCore = processList.find(p => p.config?.name === 'single_openlist_core_process') const findOpenListCore = processList.find(p => p.config?.name === 'single_openlist_core_process')
if (findOpenListCore) { if (findOpenListCore) {
return findOpenListCore.id return findOpenListCore.id
@@ -499,17 +489,17 @@ export const useAppStore = defineStore('app', () => {
const id = await getOpenListProcessId() const id = await getOpenListProcessId()
if (!id) { if (!id) {
openlistCoreStatus.value = { running: false } openlistCoreStatus.value = { running: false }
await TauriAPI.updateTrayMenu(false) await TauriAPI.tray.update(false)
return return
} }
const result = await TauriAPI.stopProcess(id) const result = await TauriAPI.process.stop(id)
if (!result) { if (!result) {
throw new Error('Failed to stop OpenList Core service - service returned false') throw new Error('Failed to stop OpenList Core service - service returned false')
} }
openlistCoreStatus.value = { running: false } openlistCoreStatus.value = { running: false }
await TauriAPI.updateTrayMenu(false) await TauriAPI.tray.update(false)
} catch (err: any) { } catch (err: any) {
const errorMessage = `Failed to stop service: ${formatError(err)}` const errorMessage = `Failed to stop service: ${formatError(err)}`
error.value = errorMessage error.value = errorMessage
@@ -529,7 +519,7 @@ export const useAppStore = defineStore('app', () => {
try { try {
const id = await getOpenListProcessId() const id = await getOpenListProcessId()
if (!id) return if (!id) return
const result = await TauriAPI.updateProcess(id, { const result = await TauriAPI.process.update(id, {
auto_start: autoLaunch auto_start: autoLaunch
}) })
if (!result) { if (!result) {
@@ -549,15 +539,15 @@ export const useAppStore = defineStore('app', () => {
const id = await getOpenListProcessId() const id = await getOpenListProcessId()
if (!id) { if (!id) {
openlistCoreStatus.value = { running: false } openlistCoreStatus.value = { running: false }
await TauriAPI.updateTrayMenu(false) await TauriAPI.tray.update(false)
return return
} }
const result = await TauriAPI.restartProcess(id) const result = await TauriAPI.process.restart(id)
if (!result) { if (!result) {
throw new Error('Failed to restart OpenList Core - service returned false') throw new Error('Failed to restart OpenList Core - service returned false')
} }
await refreshOpenListCoreStatus() await refreshOpenListCoreStatus()
await TauriAPI.updateTrayMenu(openlistCoreStatus.value.running) await TauriAPI.tray.update(openlistCoreStatus.value.running)
} catch (err: any) { } catch (err: any) {
const errorMessage = `Failed to restart core: ${formatError(err)}` const errorMessage = `Failed to restart core: ${formatError(err)}`
error.value = errorMessage error.value = errorMessage
@@ -576,17 +566,17 @@ export const useAppStore = defineStore('app', () => {
async function refreshOpenListCoreStatus() { async function refreshOpenListCoreStatus() {
try { try {
const status = await TauriAPI.getOpenListCoreStatus() const status = await TauriAPI.core.getStatus()
const statusChanged = openlistCoreStatus.value.running !== status.running const statusChanged = openlistCoreStatus.value.running !== status.running
openlistCoreStatus.value = status openlistCoreStatus.value = status
if (statusChanged) { if (statusChanged) {
await TauriAPI.updateTrayMenuDelayed(status.running) await TauriAPI.tray.updateDelayed(status.running)
} }
} catch (err) { } catch (err) {
const wasRunning = openlistCoreStatus.value.running const wasRunning = openlistCoreStatus.value.running
openlistCoreStatus.value = { running: false } openlistCoreStatus.value = { running: false }
if (wasRunning) { if (wasRunning) {
await TauriAPI.updateTrayMenuDelayed(false) await TauriAPI.tray.updateDelayed(false)
} }
} }
} }
@@ -594,7 +584,7 @@ export const useAppStore = defineStore('app', () => {
async function loadLogs(source?: 'openlist' | 'rclone' | 'app') { async function loadLogs(source?: 'openlist' | 'rclone' | 'app') {
try { try {
source = source || 'openlist' source = source || 'openlist'
const logEntries = await TauriAPI.getLogs(source) const logEntries = await TauriAPI.logs.get(source)
logs.value = logEntries logs.value = logEntries
} catch (err) { } catch (err) {
console.error('Failed to load logs:', err) console.error('Failed to load logs:', err)
@@ -604,7 +594,7 @@ export const useAppStore = defineStore('app', () => {
async function clearLogs(source?: 'openlist' | 'rclone' | 'app') { async function clearLogs(source?: 'openlist' | 'rclone' | 'app') {
try { try {
loading.value = true loading.value = true
const result = await TauriAPI.clearLogs(source) const result = await TauriAPI.logs.clear(source)
if (result) { if (result) {
logs.value = [] logs.value = []
} else { } else {
@@ -621,7 +611,7 @@ export const useAppStore = defineStore('app', () => {
async function listFiles(path: string) { async function listFiles(path: string) {
try { try {
loading.value = true loading.value = true
const fileList = await TauriAPI.listFiles(path) const fileList = await TauriAPI.files.list(path)
files.value = fileList files.value = fileList
currentPath.value = path currentPath.value = path
} catch (err) { } catch (err) {
@@ -634,7 +624,7 @@ export const useAppStore = defineStore('app', () => {
async function openFile(path: string) { async function openFile(path: string) {
try { try {
await TauriAPI.openFile(path) await TauriAPI.files.open(path)
} catch (err) { } catch (err) {
error.value = 'Failed to open file' error.value = 'Failed to open file'
console.error('Failed to open file:', err) console.error('Failed to open file:', err)
@@ -643,7 +633,7 @@ export const useAppStore = defineStore('app', () => {
async function openFolder(path: string) { async function openFolder(path: string) {
try { try {
await TauriAPI.openFolder(path) await TauriAPI.files.folder(path)
} catch (err) { } catch (err) {
error.value = 'Failed to open folder' error.value = 'Failed to open folder'
console.error('Failed to open folder:', err) console.error('Failed to open folder:', err)
@@ -652,7 +642,7 @@ export const useAppStore = defineStore('app', () => {
async function selectDirectory(title: string): Promise<string | null> { async function selectDirectory(title: string): Promise<string | null> {
try { try {
const response = await TauriAPI.selectDirectory(title) const response = await TauriAPI.util.selectDirectory(title)
return response return response
} catch (err) { } catch (err) {
console.error('Failed to select directory:', err) console.error('Failed to select directory:', err)
@@ -676,7 +666,7 @@ export const useAppStore = defineStore('app', () => {
async function safeUpdateTrayMenu(running: boolean) { async function safeUpdateTrayMenu(running: boolean) {
try { try {
await TauriAPI.updateTrayMenu(running) await TauriAPI.tray.update(running)
} catch (err) { } catch (err) {
console.warn('Failed to update tray menu:', err) console.warn('Failed to update tray menu:', err)
} }
@@ -732,7 +722,7 @@ export const useAppStore = defineStore('app', () => {
initTutorial() initTutorial()
await loadSettings() await loadSettings()
await refreshOpenListCoreStatus() await refreshOpenListCoreStatus()
await TauriAPI.updateTrayMenuDelayed(openlistCoreStatus.value.running) await TauriAPI.tray.updateDelayed(openlistCoreStatus.value.running)
await loadLogs() await loadLogs()
await autoStartCoreIfEnabled() await autoStartCoreIfEnabled()
await loadRemoteConfigs() await loadRemoteConfigs()
@@ -782,7 +772,7 @@ export const useAppStore = defineStore('app', () => {
async function getAdminPassword(): Promise<string | null> { async function getAdminPassword(): Promise<string | null> {
try { try {
const password = await TauriAPI.getAdminPassword() const password = await TauriAPI.logs.adminPassword()
return password return password
} catch (err) { } catch (err) {
console.error('Failed to get admin password:', err) console.error('Failed to get admin password:', err)

View File

@@ -15,12 +15,12 @@ export const useRcloneStore = defineStore('rclone', () => {
async function startRcloneBackend() { async function startRcloneBackend() {
try { try {
loading.value = true loading.value = true
const isRunning = await TauriAPI.isRcloneRunning() const isRunning = await TauriAPI.rclone.backend.isRunning()
if (isRunning) { if (isRunning) {
serviceRunning.value = true serviceRunning.value = true
return true return true
} }
const result = await TauriAPI.createAndStartRcloneBackend() const result = await TauriAPI.rclone.backend.createAndStart()
if (result) { if (result) {
serviceRunning.value = true serviceRunning.value = true
} }
@@ -35,7 +35,7 @@ export const useRcloneStore = defineStore('rclone', () => {
async function getRcloneProcessId() { async function getRcloneProcessId() {
try { try {
const processList = await TauriAPI.getProcessList() const processList = await TauriAPI.process.list()
const findRcloneBackend = processList.find(p => p.config?.name === 'single_rclone_backend_process') const findRcloneBackend = processList.find(p => p.config?.name === 'single_rclone_backend_process')
if (findRcloneBackend) { if (findRcloneBackend) {
return findRcloneBackend.id return findRcloneBackend.id
@@ -54,7 +54,7 @@ export const useRcloneStore = defineStore('rclone', () => {
serviceRunning.value = false serviceRunning.value = false
return return
} }
const result = await TauriAPI.stopProcess(id) const result = await TauriAPI.process.stop(id)
if (result) { if (result) {
serviceRunning.value = false serviceRunning.value = false
} }
@@ -69,7 +69,7 @@ export const useRcloneStore = defineStore('rclone', () => {
async function checkRcloneBackendStatus() { async function checkRcloneBackendStatus() {
try { try {
const isRunning = await TauriAPI.getRcloneBackendStatus() const isRunning = await TauriAPI.rclone.backend.isRunning()
serviceRunning.value = isRunning serviceRunning.value = isRunning
return isRunning return isRunning
} catch (err: any) { } catch (err: any) {

View File

@@ -1,204 +0,0 @@
export interface OpenListCoreConfig {
port: number
api_token: string
auto_launch: boolean
ssl_enabled: boolean
}
export interface RcloneConfig {
config?: any // Flexible JSON object for rclone configuration
}
export interface RcloneWebdavConfig {
url: string
vendor?: string
user: string
pass: string
}
export interface RcloneFormConfig {
name: string
type: string
url: string
vendor?: string
user: string
pass: string
mountPoint?: string
volumeName?: string
extraFlags?: string[]
autoMount: boolean
}
export interface RcloneMountInfo {
name: string
processId: string
remotePath: string
mountPoint: string
status: 'mounted' | 'unmounted' | 'mounting' | 'unmounting' | 'error'
}
export interface RcloneCreateRemoteRequest {
name: string
type: string
parameters: {
url: string
vendor?: string
user: string
pass: string
}
}
export interface RcloneMountRequest {
fs: string
mountPoint: string
mountType?: string
vfsOpt?: Record<string, any>
mountOpt?: {
ExtraFlags?: string[]
ExtraOptions?: string[]
VolumeName?: string
}
}
export interface AppConfig {
theme?: 'light' | 'dark' | 'auto'
monitor_interval?: number
auto_update_enabled?: boolean
}
export interface MergedSettings {
openlist: OpenListCoreConfig
rclone: RcloneConfig
app: AppConfig
}
export interface OpenListCoreStatus {
running: boolean
pid?: number
port?: number
}
export interface MountStatus {
mounted: boolean
mount_path?: string
remote_name?: string
}
export interface FileItem {
name: string
path: string
isDir: boolean
size?: number
modified?: string
type?: string
}
export interface AppState {
serviceStatus: OpenListCoreStatus
mountStatus: MountStatus
logs: string[]
settings: MergedSettings
currentPath: string
files: FileItem[]
loading: boolean
error?: string
}
export interface TauriResponse<T = any> {
success: boolean
data?: T
error?: string
}
// Events
export interface LogEvent {
timestamp: string
level: string
source: string
message: string
}
export interface ServiceEvent {
type: 'started' | 'stopped' | 'error'
data?: any
}
export interface MountEvent {
type: 'mounted' | 'unmounted' | 'error'
data?: any
}
export interface ProcessConfig {
id: string
name: string
bin_path: string
args: string[]
log_file: string
working_dir?: string
env_vars?: Record<string, string>
auto_restart: boolean
auto_start: boolean
run_as_admin: boolean
created_at: number
updated_at: number
}
export interface ProcessStatus {
id: string
name: string
is_running: boolean
pid?: number
started_at?: number
restart_count: number
last_exit_code?: number
config: ProcessConfig
}
export interface GitHubRelease {
tag_name: string
name: string
body: string
published_at: string
assets: GitHubAsset[]
prerelease: boolean
draft: boolean
}
export interface GitHubAsset {
id: number
name: string
size: number
download_count: number
browser_download_url: string
content_type: string
}
export interface UpdateAsset {
name: string
url: string
size: number
platform: string
type: 'exe' | 'deb' | 'rpm' | 'dmg' | string
}
export interface UpdateCheck {
hasUpdate: boolean
currentVersion: string
latestVersion: string
releaseDate: string
releaseNotes: string
assets: UpdateAsset[]
}
export interface DownloadProgress {
downloaded: number
total: number
percentage: number
speed: number
}
export interface UpdateInfo {
version: string
date?: string
body: string
available: boolean
}

205
src/types/types.d.ts vendored
View File

@@ -7,3 +7,208 @@ interface IStringMap {
interface IRemoteConfig { interface IRemoteConfig {
[key: string]: RcloneWebdavConfig [key: string]: RcloneWebdavConfig
} }
interface OpenListCoreConfig {
port: number
api_token: string
auto_launch: boolean
ssl_enabled: boolean
}
interface RcloneConfig {
config?: any // Flexible JSON object for rclone configuration
}
interface RcloneWebdavConfig {
url: string
vendor?: string
user: string
pass: string
}
interface RcloneFormConfig {
name: string
type: string
url: string
vendor?: string
user: string
pass: string
mountPoint?: string
volumeName?: string
extraFlags?: string[]
autoMount: boolean
}
interface RcloneMountInfo {
name: string
processId: string
remotePath: string
mountPoint: string
status: 'mounted' | 'unmounted' | 'mounting' | 'unmounting' | 'error'
}
interface RcloneCreateRemoteRequest {
name: string
type: string
parameters: {
url: string
vendor?: string
user: string
pass: string
}
}
interface RcloneMountRequest {
fs: string
mountPoint: string
mountType?: string
vfsOpt?: Record<string, any>
mountOpt?: {
ExtraFlags?: string[]
ExtraOptions?: string[]
VolumeName?: string
}
}
interface AppConfig {
theme?: 'light' | 'dark' | 'auto'
monitor_interval?: number
auto_update_enabled?: boolean
}
interface MergedSettings {
openlist: OpenListCoreConfig
rclone: RcloneConfig
app: AppConfig
}
interface OpenListCoreStatus {
running: boolean
pid?: number
port?: number
}
interface MountStatus {
mounted: boolean
mount_path?: string
remote_name?: string
}
interface FileItem {
name: string
path: string
isDir: boolean
size?: number
modified?: string
type?: string
}
interface AppState {
serviceStatus: OpenListCoreStatus
mountStatus: MountStatus
logs: string[]
settings: MergedSettings
currentPath: string
files: FileItem[]
loading: boolean
error?: string
}
interface TauriResponse<T = any> {
success: boolean
data?: T
error?: string
}
// Events
interface LogEvent {
timestamp: string
level: string
source: string
message: string
}
interface ServiceEvent {
type: 'started' | 'stopped' | 'error'
data?: any
}
interface MountEvent {
type: 'mounted' | 'unmounted' | 'error'
data?: any
}
interface ProcessConfig {
id: string
name: string
bin_path: string
args: string[]
log_file: string
working_dir?: string
env_vars?: Record<string, string>
auto_restart: boolean
auto_start: boolean
run_as_admin: boolean
created_at: number
updated_at: number
}
interface ProcessStatus {
id: string
name: string
is_running: boolean
pid?: number
started_at?: number
restart_count: number
last_exit_code?: number
config: ProcessConfig
}
interface GitHubRelease {
tag_name: string
name: string
body: string
published_at: string
assets: GitHubAsset[]
prerelease: boolean
draft: boolean
}
interface GitHubAsset {
id: number
name: string
size: number
download_count: number
browser_download_url: string
content_type: string
}
interface UpdateAsset {
name: string
url: string
size: number
platform: string
type: 'exe' | 'deb' | 'rpm' | 'dmg' | string
}
interface UpdateCheck {
hasUpdate: boolean
currentVersion: string
latestVersion: string
releaseDate: string
releaseNotes: string
assets: UpdateAsset[]
}
interface DownloadProgress {
downloaded: number
total: number
percentage: number
speed: number
}
interface UpdateInfo {
version: string
date?: string
body: string
available: boolean
}

View File

@@ -9,52 +9,3 @@ export const formatBytes = (bytes: number, decimals = 2): string => {
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i] return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]
} }
export const formatPercentage = (value: number, decimals = 1): string => {
return (Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals)).toFixed(decimals)
}
export const formatNumber = (value: number, decimals = 1): string => {
return (Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals)).toFixed(decimals)
}
export const formatDuration = (seconds: number): string => {
const hours = Math.floor(seconds / 3600)
const minutes = Math.floor((seconds % 3600) / 60)
const secs = seconds % 60
if (hours > 0) {
return `${hours}h ${minutes}m`
} else if (minutes > 0) {
return `${minutes}m ${secs}s`
} else {
return `${secs}s`
}
}
export const formatTimestamp = (timestamp: string | Date): string => {
const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp
return date.toLocaleTimeString()
}
export const formatDate = (timestamp: string | Date): string => {
const date = typeof timestamp === 'string' ? new Date(timestamp) : timestamp
return date.toLocaleDateString()
}
export const truncateText = (text: string, maxLength: number): string => {
if (text.length <= maxLength) return text
return text.substring(0, maxLength) + '...'
}
export const debounce = <T extends (...args: any[]) => any>(
func: T,
wait: number
): ((...args: Parameters<T>) => void) => {
let timeout: NodeJS.Timeout | null = null
return (...args: Parameters<T>) => {
if (timeout) clearTimeout(timeout)
timeout = setTimeout(() => func(...args), wait)
}
}

View File

@@ -1,12 +0,0 @@
export default function getSystem() {
const ua = navigator.userAgent
const platform = OS_PLATFORM
if (ua.includes('Mac OS X') || platform === 'darwin') return 'macos'
if (/win64|win32/i.test(ua) || platform === 'win32') return 'windows'
if (/linux/i.test(ua)) return 'linux'
return 'unknown'
}

View File

@@ -20,7 +20,6 @@ import {
Settings, Settings,
FolderOpen FolderOpen
} from 'lucide-vue-next' } from 'lucide-vue-next'
import type { RcloneFormConfig } from '../types'
import { useAppStore } from '@/stores/app' import { useAppStore } from '@/stores/app'
import ConfirmDialog from '@/components/ui/ConfirmDialog.vue' import ConfirmDialog from '@/components/ui/ConfirmDialog.vue'