From eef296942fe32ee7bbd9769b8e6a21a7788983d3 Mon Sep 17 00:00:00 2001 From: "jif2.zhang" Date: Mon, 26 Oct 2026 20:53:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(0.2.1):=20=E5=90=88=E5=B9=B6=20Windows=20?= =?UTF-8?q?=E5=A4=96=E5=A3=B3=20+=20=E7=A6=BB=E7=BA=BF=E7=BC=96=E8=BE=91,?= =?UTF-8?q?=20=E7=89=88=E6=9C=AC=200.2.1,=20=E6=AD=A3=E5=BC=8F=E5=9F=9F?= =?UTF-8?q?=E5=90=8D=20https://iboard.honor3.com?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.shell | 10 + .esbuild-tmp/build2.log | Bin 0 -> 7254 bytes .gitea/workflows/android-build.yml | 2 +- .gitea/workflows/docker-build.yml | 2 +- .../任务模块/视图切换移入项目栏-设计稿.html | 108 ++ package-lock.json | 1 + package.json | 9 +- public/dock.html | 34 + public/dock.js | 65 + scripts/build-windows.mjs | 152 +++ scripts/gen-tray-icons.mjs | 49 + scripts/wsl/build-apk.sh | 286 ++--- src-tauri/Cargo.lock | 1055 ++++++++++++----- src-tauri/Cargo.toml | 16 +- src-tauri/icons/128x128.png | Bin 1478 -> 2505 bytes src-tauri/icons/128x128@2x.png | Bin 3689 -> 4990 bytes src-tauri/icons/32x32.png | Bin 344 -> 731 bytes src-tauri/icons/64x64.png | Bin 0 -> 1261 bytes src-tauri/icons/Square107x107Logo.png | Bin 0 -> 2047 bytes src-tauri/icons/Square142x142Logo.png | Bin 0 -> 2634 bytes src-tauri/icons/Square150x150Logo.png | Bin 0 -> 2837 bytes src-tauri/icons/Square284x284Logo.png | Bin 0 -> 5327 bytes src-tauri/icons/Square30x30Logo.png | Bin 0 -> 664 bytes src-tauri/icons/Square310x310Logo.png | Bin 0 -> 5969 bytes src-tauri/icons/Square44x44Logo.png | Bin 0 -> 942 bytes src-tauri/icons/Square71x71Logo.png | Bin 0 -> 1406 bytes src-tauri/icons/Square89x89Logo.png | Bin 0 -> 1578 bytes src-tauri/icons/StoreLogo.png | Bin 0 -> 1038 bytes .../android/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../icons/android/mipmap-hdpi/ic_launcher.png | Bin 0 -> 1029 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 0 -> 3052 bytes .../android/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 730 bytes .../icons/android/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 0 -> 2122 bytes .../android/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 753 bytes .../android/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 1928 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 0 -> 4048 bytes .../mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 1183 bytes .../android/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 2988 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 0 -> 6163 bytes .../mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 1531 bytes .../android/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 3956 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 0 -> 8433 bytes .../mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 1649 bytes .../android/values/ic_launcher_background.xml | 4 + src-tauri/icons/icon.icns | Bin 30855 -> 52804 bytes src-tauri/icons/icon.ico | Bin 3689 -> 9498 bytes src-tauri/icons/icon.png | Bin 30855 -> 10175 bytes src-tauri/icons/ios/AppIcon-20x20@1x.png | Bin 0 -> 468 bytes src-tauri/icons/ios/AppIcon-20x20@2x-1.png | Bin 0 -> 772 bytes src-tauri/icons/ios/AppIcon-20x20@2x.png | Bin 0 -> 772 bytes src-tauri/icons/ios/AppIcon-20x20@3x.png | Bin 0 -> 1089 bytes src-tauri/icons/ios/AppIcon-29x29@1x.png | Bin 0 -> 606 bytes src-tauri/icons/ios/AppIcon-29x29@2x-1.png | Bin 0 -> 1117 bytes src-tauri/icons/ios/AppIcon-29x29@2x.png | Bin 0 -> 1117 bytes src-tauri/icons/ios/AppIcon-29x29@3x.png | Bin 0 -> 1524 bytes src-tauri/icons/ios/AppIcon-40x40@1x.png | Bin 0 -> 772 bytes src-tauri/icons/ios/AppIcon-40x40@2x-1.png | Bin 0 -> 1406 bytes src-tauri/icons/ios/AppIcon-40x40@2x.png | Bin 0 -> 1406 bytes src-tauri/icons/ios/AppIcon-40x40@3x.png | Bin 0 -> 2044 bytes src-tauri/icons/ios/AppIcon-512@2x.png | Bin 0 -> 14811 bytes src-tauri/icons/ios/AppIcon-60x60@2x.png | Bin 0 -> 2044 bytes src-tauri/icons/ios/AppIcon-60x60@3x.png | Bin 0 -> 3247 bytes src-tauri/icons/ios/AppIcon-76x76@1x.png | Bin 0 -> 1392 bytes src-tauri/icons/ios/AppIcon-76x76@2x.png | Bin 0 -> 2759 bytes src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png | Bin 0 -> 2977 bytes src-tauri/icons/tray-dark.png | Bin 0 -> 345 bytes src-tauri/icons/tray-light.png | Bin 0 -> 414 bytes src-tauri/src/lib.rs | 97 +- src-tauri/src/shell/config.rs | 160 +++ src-tauri/src/shell/mod.rs | 960 +++++++++++++++ src-tauri/src/shell/win.rs | 117 ++ src-tauri/tauri.conf.json | 25 +- src/main.jsx | 14 +- 74 files changed, 2734 insertions(+), 437 deletions(-) create mode 100644 .env.shell create mode 100644 .esbuild-tmp/build2.log create mode 100644 docs/V0.2/任务模块/视图切换移入项目栏-设计稿.html create mode 100644 public/dock.html create mode 100644 public/dock.js create mode 100644 scripts/build-windows.mjs create mode 100644 scripts/gen-tray-icons.mjs create mode 100644 src-tauri/icons/64x64.png create mode 100644 src-tauri/icons/Square107x107Logo.png create mode 100644 src-tauri/icons/Square142x142Logo.png create mode 100644 src-tauri/icons/Square150x150Logo.png create mode 100644 src-tauri/icons/Square284x284Logo.png create mode 100644 src-tauri/icons/Square30x30Logo.png create mode 100644 src-tauri/icons/Square310x310Logo.png create mode 100644 src-tauri/icons/Square44x44Logo.png create mode 100644 src-tauri/icons/Square71x71Logo.png create mode 100644 src-tauri/icons/Square89x89Logo.png create mode 100644 src-tauri/icons/StoreLogo.png create mode 100644 src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 src-tauri/icons/android/mipmap-hdpi/ic_launcher.png create mode 100644 src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png create mode 100644 src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png create mode 100644 src-tauri/icons/android/mipmap-mdpi/ic_launcher.png create mode 100644 src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png create mode 100644 src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png create mode 100644 src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png create mode 100644 src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png create mode 100644 src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png create mode 100644 src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png create mode 100644 src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png create mode 100644 src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png create mode 100644 src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png create mode 100644 src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 src-tauri/icons/android/values/ic_launcher_background.xml create mode 100644 src-tauri/icons/ios/AppIcon-20x20@1x.png create mode 100644 src-tauri/icons/ios/AppIcon-20x20@2x-1.png create mode 100644 src-tauri/icons/ios/AppIcon-20x20@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-20x20@3x.png create mode 100644 src-tauri/icons/ios/AppIcon-29x29@1x.png create mode 100644 src-tauri/icons/ios/AppIcon-29x29@2x-1.png create mode 100644 src-tauri/icons/ios/AppIcon-29x29@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-29x29@3x.png create mode 100644 src-tauri/icons/ios/AppIcon-40x40@1x.png create mode 100644 src-tauri/icons/ios/AppIcon-40x40@2x-1.png create mode 100644 src-tauri/icons/ios/AppIcon-40x40@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-40x40@3x.png create mode 100644 src-tauri/icons/ios/AppIcon-512@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-60x60@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-60x60@3x.png create mode 100644 src-tauri/icons/ios/AppIcon-76x76@1x.png create mode 100644 src-tauri/icons/ios/AppIcon-76x76@2x.png create mode 100644 src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png create mode 100644 src-tauri/icons/tray-dark.png create mode 100644 src-tauri/icons/tray-light.png create mode 100644 src-tauri/src/shell/config.rs create mode 100644 src-tauri/src/shell/mod.rs create mode 100644 src-tauri/src/shell/win.rs diff --git a/.env.shell b/.env.shell new file mode 100644 index 0000000..e296220 --- /dev/null +++ b/.env.shell @@ -0,0 +1,10 @@ +# Windows 外壳构建模式 (npm run build:shell / vite build --mode shell) +# 外壳内前端跑在 tauri://localhost, 没有同源后端, API 必须指向远端 Express。 +# 与 android 打包脚本 (scripts/wsl/build-apk.sh) 注入的值保持一致; +# 进程环境变量优先级高于本文件, android 流程不受影响。 +# +# 0.2.1 起正式域名: https://iboard.honor3.com (NPM 反代 -> baihu:3001, 受信证书) +# PowerSync 同步端点默认同域 (NPM 把 /sync 反代到同步服务); 若改用独立子域, +# 打包时用 VITE_POWERSYNC_URL=https://sync.example.com 覆盖即可。 +VITE_API_BASE=https://iboard.honor3.com +VITE_POWERSYNC_URL=https://iboard.honor3.com diff --git a/.esbuild-tmp/build2.log b/.esbuild-tmp/build2.log new file mode 100644 index 0000000000000000000000000000000000000000..10db7d15237de8039a6db650f007f8f1002d79fd GIT binary patch literal 7254 zcmdU!TW=dh7=}k&B5}nZSPGOPaN<*(!$n0LCp035rfF-M7F9Vosav0F$4wI?xaC&^ z&pVU#9x`ih0Et#BuXkr==X<~NH#2|z`OdV>xoMfeyfX`C&Q$r8O^Np-Gp4U&PPq5X z87-%#Z-)F2xc6xvn`6Fh^W5VrU7wjxX&IVBT1MC7yVu`GBR>BofWnfgnF_OYujlH3 zV#NE+?_1Dva}OEQEt?+xy7(KV3CVs{73Gb)8iEd!- zfO*8#qHkp88Fy?7=7QD&?{699K z{!AZYTR!VD_nEokd4NBU_`d>u z6oZxDM~t1fqm?7x)BB2+F4h^3asT|e$czj4bAaUP+&}p`AgVe{iZHq~rpn!oQ6!0w zC3EvO7!~allb@OmqN1|$h=?&ZFX3`b#0WFiEX*ZFE=`b4qq>UT6<1XyJh+a3%A5~D z(nnGuk~(tSBp19jO?Xu0qWU0-LzPyUYc{VNP&(!(y@V7RSlTWe_u>DDyN^PWo_kxg zye{XUx(ip5t7!C*=>B!giV)PzG8$DSrQ9-7T8hBl52vEBy0P=o3-EasAb|NK6k21r)cv{rElQg^yzdYV zm1~b}%<^k9-KtnPhnz!e^2KWBUDC#EdH7@Xkoaop1eqUy$x5P# zRnEpAw~Pk(-(p#^xDr;8SMDJX4u2R^v+*xYGMgWNfE4oPKUFhYGpo|lx=MDv#X9rg z*60K43&n{SPs5+&F>OE2{uguEfBvdr7w)vis8LBCdbx8|!!*xyJeDVU&o6&f9R8W!O!XSyeRqpmD_MW|XrS3m7ZVzC5wOIU&=qug@1n}$%Vtekcus7`w{*cvdxa4 z;!&%k8rN+9z0Iyi5^wTNHH)yNZ99!$$jT`mllD`!$TccY{T8o(>g?3)vC`7Iw#nLZ zTC9(w*V;pCNma(xiPmr0zv8;^r^iJ2tISjbxjSWv#~=B?J@bXpuI|2F^=hv^ezu_# z1XV%-D+fKD@vPGroepR>Hoz*2G0h*cveAC9#<(*Wx67;Dgm7ngjy|pNbz0N5D~KUG zzQR(V=ZS4~J4h#X2SBF|T8#(XyVL-x&CbCs)LN?xu{&MRsmTDOT2V*4+OC>bYaB(K zp7@JSp5~Zedn+CGbO!8sM0?sganTvdIc>VT^Oqja+Rt7?CgGV-h|D3@d^(+p%hv6Z zX?>twFU>eY3iDiX>h6?B9G}r6K6M(<=50({B+~*tah&t!%LLK_k`u?$nL``bawv;c zwDFpL?aaloMmu=21M%b}9G=a|8nmAm*j4-x8jd@i@3o + + + + +设计稿 · 视图切换移入项目栏 (T-VW-02/03 调整) + + + + +
+

状态 1 · 列表视图(默认)

+
切换段控放在项目名右侧, 与名称同一行
+
+
我的看板项目
+
列表
看板
+
已归档
+
管理
+
+ 新增
+
+
「项目管理」按钮文案收窄为「管理」, 与「已归档」同为次级样式, 突出右侧主操作
+
+
梳理 V0.2 归档需求
+
OTA 发布说明样式修复
+
看板列滚动条位置调整
+
+
+ 规格
+ · 分段控件高 26px, 选中项白底浮起(复用现有 .seg 体系收窄版)
+ · 项目名 flex:1 + 单行省略, 最短保留 4 字符
+ · 段控始终紧贴名称右侧, 距离 8px +
+
+ +
+

状态 2 · 看板视图

+
点「看板」后段控选中项滑换, 其余布局不变
+
+
我的看板项目
+
列表
看板
+
已归档
+
管理
+
+ 新增
+
+
+
+
Plan · 2
梳理归档需求
OTA 说明修复
+
Doing · 1
滚动条调整
+
Done · 1
版本方案落地
+
+
+
+ 交互
+ · 点按即切换并持久化(设备端记忆, T-VW-02/03 不变)
+ · 切换不引发项目栏高度变化, 下方视图平滑重排
+ · 长按/拖动手势不受影响(段控独立控件, 不在卡片上) +
+
+ +
+

状态 3 · 长项目名

+
名称被压缩时单行省略, 段控与按钮永不换行/收缩
+
+
经济数据整理与策略研究-2026年第一季度重点项目
+
列表
看板
+
已归档
+
管理
+
+ 新增
+
+
+
完整项目名在详情/管理页仍可见
+
+
+ 宽度预算 (375px)
+ · 左右内边距 24 + 段控 90 + 已归档 48 + 管理 42 + 新增 54 + 间距 32 ≈ 290
+ · 名称可用 ≈ 85px(约 6 个汉字)起, 不足部分省略
+ · 若仍嫌拥挤, 备选:「已归档」「管理」收进 ⋯ 溢出菜单(二期可选, 本稿未采用) +
+
+ + + diff --git a/package-lock.json b/package-lock.json index 7d94b7b..b040951 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3228,6 +3228,7 @@ "version": "13.0.3", "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-13.0.3.tgz", "integrity": "sha512-RbOBxmLBG8uvFUc15X9+9SFemKcQ0WBuISBVkpuiaUB2qblC8UWlHEjdWVoZ8AdhSwmoEgsiXKfopX0CQxaACQ==", + "hasInstallScript": true, "license": "MIT", "optional": true, "peer": true, diff --git a/package.json b/package.json index f9245ac..924b717 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iboard", - "version": "0.2.0", + "version": "0.2.1", "type": "module", "scripts": { "tauri": "tauri", @@ -8,6 +8,9 @@ "dev:server": "node --watch --experimental-strip-types --no-warnings server/index.js", "dev": "concurrently -n web,api -c blue,green \"npm run dev:web\" \"npm run dev:server\"", "build": "vite build", + "build:shell": "vite build --mode shell", + "build:win": "node scripts/build-windows.mjs", + "build:win:debug": "node scripts/build-windows.mjs --debug", "build:ota": "node scripts/build-ota.mjs", "preview": "vite preview", "start": "node --experimental-strip-types --no-warnings server/index.js", @@ -55,8 +58,8 @@ "ws": "^8.21.2" }, "devDependencies": { - "@tauri-apps/api": "^2.0.0", - "@tauri-apps/cli": "^2.0.0", + "@tauri-apps/api": "^2.12.4", + "@tauri-apps/cli": "^2.12.4", "@vitejs/plugin-react": "^4.3.1", "cheerio": "^1.2.0", "concurrently": "^9.0.0", diff --git a/public/dock.html b/public/dock.html new file mode 100644 index 0000000..31277d8 --- /dev/null +++ b/public/dock.html @@ -0,0 +1,34 @@ + + + + + + + + +
+ + + diff --git a/public/dock.js b/public/dock.js new file mode 100644 index 0000000..57b6a5a --- /dev/null +++ b/public/dock.js @@ -0,0 +1,65 @@ +// 悬浮球交互 (W-SNP-04/05/12/13/14): +// mouseenter/leave → hover 延时恢复 (Rust 侧计时 150ms) +// 单击 (位移 ≤4px) → 立即恢复, 触屏点按等效 +// 拖动 → dock_drag_move 增量移动, 结束时按最近边停靠/换边/拖出 +const { invoke } = window.__TAURI__.core +const ball = document.getElementById('ball') + +let dragging = false +let moved = 0 +let lastX = 0 +let lastY = 0 + +ball.addEventListener('mouseenter', () => invoke('dock_hover_start')) +ball.addEventListener('mouseleave', () => invoke('dock_hover_end')) +ball.addEventListener('contextmenu', (e) => e.preventDefault()) + +ball.addEventListener('pointerdown', (e) => { + dragging = true + moved = 0 + lastX = e.clientX + lastY = e.clientY + ball.setPointerCapture(e.pointerId) + invoke('dock_drag_start') +}) + +ball.addEventListener('pointermove', (e) => { + if (!dragging) return + const dx = e.clientX - lastX + const dy = e.clientY - lastY + if (dx === 0 && dy === 0) return + lastX = e.clientX + lastY = e.clientY + moved += Math.abs(dx) + Math.abs(dy) + if (moved > 4) { + // clientX 为逻辑像素, 增量按 DPI 缩放换算成物理像素 (Rust 注入 __SCALE) + const s = window.__SCALE || 1 + invoke('dock_drag_move', { dx: Math.round(dx * s), dy: Math.round(dy * s) }) + } +}) + +ball.addEventListener('pointerup', (e) => { + if (!dragging) return + dragging = false + try { ball.releasePointerCapture(e.pointerId) } catch { /* 已释放 */ } + if (moved <= 4) { + invoke('dock_click') + } else { + invoke('dock_drag_end') + } +}) + +ball.addEventListener('pointercancel', () => { + dragging = false + invoke('dock_drag_end') +}) + +// Rust 在停靠/换边/主题变化时调用 +window.applyDock = (edge, theme) => { + document.body.className = 'dock-' + edge + ' theme-' + theme +} +window.applyTheme = (theme) => { + const edge = [...document.body.classList].find((c) => c.startsWith('dock-')) || 'dock-left' + document.body.className = edge + ' theme-' + theme +} +window.__SCALE = 1 diff --git a/scripts/build-windows.mjs b/scripts/build-windows.mjs new file mode 100644 index 0000000..2ece216 --- /dev/null +++ b/scripts/build-windows.mjs @@ -0,0 +1,152 @@ +#!/usr/bin/env node +// Windows 外壳一键构建 (开发用): 安装包 (NSIS) + 便携版 (portable zip) +// +// 用法: +// npm run build:win # 完整流程 +// node scripts/build-windows.mjs --skip-check # 跳过版本一致性校验 +// node scripts/build-windows.mjs --debug # debug 构建 (快速验证, 产物带 -debug 后缀) +// +// 流程: +// 1) 版本一致性校验 (scripts/ci/check-version.mjs, 外壳三件套) +// 2) 前端构建 (build:shell, 注入 VITE_API_BASE 指向远端后端) +// 3) tauri build --bundles nsis → 编译一次 release exe + NSIS 安装包 +// 4) 复用同一个 exe 组装便携版目录并压成 zip (不二次编译) +// +// 产物 (artifacts/windows/): +// iBoard__x64-setup.exe 安装包 (当前用户安装, 免管理员) +// iBoard__x64-portable.zip 便携版 (解压即用) +// portable/ 便携版解压目录 (iBoard.exe + README.txt) +// +// 说明: 便携版不内置 WebView2 —— 目标机需 Win10 19041+ / Win11 (系统自带 WebView2 Runtime)。 +import { spawnSync } from 'node:child_process' +import fs from 'node:fs' +import path from 'node:path' +import { fileURLToPath } from 'node:url' + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..') +const args = process.argv.slice(2) +const skipCheck = args.includes('--skip-check') +const isDebug = args.includes('--debug') +const profile = isDebug ? 'debug' : 'release' + +const conf = JSON.parse(fs.readFileSync(path.join(root, 'src-tauri', 'tauri.conf.json'), 'utf8')) +const version = String(conf.version || '0.0.0') +const product = conf.productName || 'iBoard' +const suffix = isDebug ? '-debug' : '' + +const artifactsDir = path.join(root, 'artifacts', 'windows') +const targetDir = path.join(root, 'src-tauri', 'target', profile) + +function log(msg) { + console.log(`\x1b[36m[build-win]\x1b[0m ${msg}`) +} +function fail(msg) { + console.error(`\x1b[31m[build-win] 失败: ${msg}\x1b[0m`) + process.exit(1) +} +function run(cmd, cmdArgs, opts = {}) { + log(`$ ${cmd} ${cmdArgs.join(' ')}`) + const res = spawnSync(cmd, cmdArgs, { + cwd: root, + stdio: 'inherit', + shell: process.platform === 'win32', + ...opts, + }) + if (res.status !== 0) fail(`${cmd} ${cmdArgs.join(' ')} 退出码 ${res.status}`) +} + +// ---------- 0. 前置检查 ---------- +if (process.platform !== 'win32') fail('本脚本仅支持 Windows') +if (!fs.existsSync(path.join(root, 'node_modules'))) fail('缺少 node_modules, 请先运行 npm ci') + +log(`项目 ${product} 外壳版本 ${version} (${profile})`) + +// ---------- 1. 版本一致性 ---------- +if (!skipCheck) { + log('校验版本一致性 (外壳 tauri.conf.json / Cargo.toml / Cargo.lock)') + run('node', ['scripts/ci/check-version.mjs'], { + env: { ...process.env, BRANCH: process.env.BRANCH || '' }, + }) +} else { + log('跳过版本一致性校验 (--skip-check)') +} + +// ---------- 2. 前端构建 ---------- +log('构建前端 (build:shell, VITE_API_BASE 指向远端后端)') +run('npm', ['run', 'build:shell']) + +// ---------- 3. 安装包 (NSIS) ---------- +const tauriArgs = ['tauri', 'build'] +if (isDebug) tauriArgs.push('--debug') +// 只出 NSIS: 避免 bundle.targets="all" 在 Windows 上拉 WiX 打 MSI +tauriArgs.push('--bundles', 'nsis') +log('编译外壳并生成 NSIS 安装包') +run('npx', tauriArgs) + +// ---------- 4. 便携版 ---------- +const exePath = path.join(targetDir, `iboard${suffix}.exe`) +if (!fs.existsSync(exePath)) fail(`未找到构建产物 ${exePath}`) + +fs.rmSync(artifactsDir, { recursive: true, force: true }) +fs.mkdirSync(artifactsDir, { recursive: true }) + +const portableDir = path.join(artifactsDir, 'portable') +fs.mkdirSync(portableDir, { recursive: true }) +const portableExe = path.join(portableDir, `${product}.exe`) +fs.copyFileSync(exePath, portableExe) + +const readme = `${product} ${version} 便携版 (Windows x64) +================================================= + +免安装: 双击 ${product}.exe 即可运行。 + +系统要求 + - Windows 10 19041+ 或 Windows 11 (x64) + - WebView2 Runtime: Win10/11 系统自带; 若提示缺失, 请安装 + https://developer.microsoft.com/microsoft-edge/webview2/ + +使用说明 + - 关闭窗口 = 隐藏到托盘, 不会退出; 退出请用托盘右键菜单「退出」。 + - 窗口贴屏幕边缘会自动收起为半圆悬浮球, 鼠标停留或单击唤回。 + - 托盘菜单可开关「开机启动」「边缘吸附」。 + - 配置保存在 %APPDATA%\\com.iboard.app\\shell-config.json (删除即恢复默认)。 + +注意: 便携版不写注册表、不装服务; 但若开启了「开机启动」, 会在 + HKCU\\...\\Run 写入自启动项, 关闭开关即可移除。 +` +fs.writeFileSync(path.join(portableDir, 'README.txt'), readme, 'utf8') + +const zipName = `${product}_${version}_x64-portable${suffix}.zip` +const zipPath = path.join(artifactsDir, zipName) +log('打包便携版 zip') +const psZip = `Compress-Archive -Path '${portableDir}\\*' -DestinationPath '${zipPath}' -Force` +const res = spawnSync('powershell', ['-NoProfile', '-NonInteractive', '-Command', psZip], { + cwd: root, + stdio: 'inherit', +}) +if (res.status !== 0) fail('压缩便携版失败 (Compress-Archive)') + +// ---------- 5. 汇总 ---------- +const setupExe = path.join( + targetDir, + 'bundle', + 'nsis', + `${product}_${version}_x64-setup${suffix}.exe`, +) +const outputs = [] +if (fs.existsSync(setupExe)) { + const dest = path.join(artifactsDir, path.basename(setupExe)) + fs.copyFileSync(setupExe, dest) + outputs.push(['安装包 (NSIS)', dest]) +} else { + outputs.push(['安装包 (NSIS)', `未找到: ${setupExe}`]) +} +outputs.push(['便携版 (zip)', zipPath]) +outputs.push(['便携版 (目录)', `${portableDir} (${fs.readdirSync(portableDir).length} 个文件)`]) + +log('构建完成:') +for (const [label, p] of outputs) { + const size = fs.existsSync(p) ? `${(fs.statSync(p).size / 1024 / 1024).toFixed(1)} MB` : '' + console.log(` ${label.padEnd(14)} ${p}${size ? ' (' + size + ')' : ''}`) +} +process.exit(0) diff --git a/scripts/gen-tray-icons.mjs b/scripts/gen-tray-icons.mjs new file mode 100644 index 0000000..d492a0c --- /dev/null +++ b/scripts/gen-tray-icons.mjs @@ -0,0 +1,49 @@ +#!/usr/bin/env node +// 生成托盘深浅色单色图标 (W-THE-01): +// src-tauri/icons/tray-light.png 深色字形 —— 浅色任务栏用 +// src-tauri/icons/tray-dark.png 白色字形 —— 深色任务栏用 +// +// 做法: 不能只用 alpha 通道做剪影 —— 源图标是「深色圆角方块 + 白色 i」, +// 整个方块都是不透明的, 只取 alpha 会得到一块纯色方块, i 字母细节全丢。 +// 这里按**亮度**映射, 保留字母结构: +// 深色字形: alpha = (255-L)/255 → 方块保留深色, 白色 i 镂空透出任务栏 +// 浅色字形: alpha = max(L,40)/255 → i 白色高亮, 方块留一点淡淡衬底 +// 产物已提交进仓库, 仅图标变更时需要重跑: node scripts/gen-tray-icons.mjs +import sharp from 'sharp' +import { fileURLToPath } from 'node:url' +import path from 'node:path' + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..') +const src = path.join(root, 'src-tauri', 'icons', '128x128.png') +const outDir = path.join(root, 'src-tauri', 'icons') + +const targets = [ + { file: 'tray-light.png', rgb: [31, 31, 31], mode: 'dark-glyph' }, // 深色字形 (浅色任务栏) + { file: 'tray-dark.png', rgb: [250, 250, 250], mode: 'light-glyph' }, // 白色字形 (深色任务栏) +] + +for (const t of targets) { + const { data, info } = await sharp(src) + .resize(32, 32, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } }) + .ensureAlpha() + .raw() + .toBuffer({ resolveWithObject: true }) + const out = Buffer.alloc(info.width * info.height * 4) + for (let i = 0; i < info.width * info.height; i++) { + const r = data[i * 4] + const g = data[i * 4 + 1] + const b = data[i * 4 + 2] + const a = data[i * 4 + 3] + const lumi = 0.2126 * r + 0.7152 * g + 0.0722 * b + const alpha = + t.mode === 'dark-glyph' ? (a * (255 - lumi)) / 255 : (a * Math.max(lumi, 40)) / 255 + out[i * 4] = t.rgb[0] + out[i * 4 + 1] = t.rgb[1] + out[i * 4 + 2] = t.rgb[2] + out[i * 4 + 3] = Math.round(alpha) + } + await sharp(out, { raw: { width: info.width, height: info.height, channels: 4 } }) + .png() + .toFile(path.join(outDir, t.file)) + console.log('generated', t.file) +} diff --git a/scripts/wsl/build-apk.sh b/scripts/wsl/build-apk.sh index b723dae..12cc790 100644 --- a/scripts/wsl/build-apk.sh +++ b/scripts/wsl/build-apk.sh @@ -1,143 +1,143 @@ -#!/usr/bin/env bash -# iBoard Android APK 打包 -# 用法: bash scripts/wsl/build-apk.sh [debug|release] -# release 模式自动构建 4 个 ABI 并出 universal APK -set -euo pipefail - -WIN_PROJECT='/mnt/d/workbench/iboard' -cd "$WIN_PROJECT" - -VARIANT="${1:-debug}" -echo "构建变体: $VARIANT" - -# 环境变量 -export ANDROID_HOME="${ANDROID_HOME:-$HOME/android-sdk}" -export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_HOME/ndk/27.2.12479018}" -# 关键: 把 NDK toolchain bin 加进 PATH, .cargo/config.toml 里 -# linker = "aarch64-linux-android24-clang" 这种短名才能被解析到 -NDK_TOOLCHAIN_BIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin" -if [ ! -d "$NDK_TOOLCHAIN_BIN" ]; then - echo "ERROR: NDK toolchain bin 不存在: $NDK_TOOLCHAIN_BIN" - echo "请确认 ANDROID_NDK_HOME 正确指向 NDK 27.2.x 目录" - exit 1 -fi -export PATH="$NDK_TOOLCHAIN_BIN:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$HOME/.cargo/bin:$PATH" - -# 0. 首次需要 android 工程 -cd src-tauri -if [ ! -d "gen/android" ]; then - echo "=== 0. 初始化 Android 工程 (一次性) ===" - npx tauri android init -fi -cd "$WIN_PROJECT" - -# Android 后端地址, 写到前端 bundle 里 (覆盖默认的 /api 相对路径) -export VITE_API_BASE="${VITE_API_BASE:-http://bh.vps.honor3.com:3001}" -echo "VITE_API_BASE=$VITE_API_BASE" - -# 1. 先构建前端, 让 Tauri android 工程能拿到 dist/ -echo "=== 1. 构建前端 ===" -npm run build - -# 1.5 拷贝 dist/ 到 Android 工程 assets/, 绕过 Tauri CLI 时这步要做 -# Tauri CLI 默认在 android build 前会干这事, 我们走直 gradle 要自己补上 -ANDROID_ASSETS="$WIN_PROJECT/src-tauri/gen/android/app/src/main/assets" -mkdir -p "$ANDROID_ASSETS" -# 清空旧的 (避免上次的残余) -find "$ANDROID_ASSETS" -mindepth 1 -maxdepth 1 ! -name dexopt ! -name tauri.conf.json -exec rm -rf {} + -cp -r dist/. "$ANDROID_ASSETS/" -echo "前端 bundle 已拷贝到 $ANDROID_ASSETS" -ls -la "$ANDROID_ASSETS" | head -10 - -# 2. 走不同路径 -cd src-tauri - -# 全部 4 个 Android 架构的 rustBuild 任务 (Tauri 2 默认会编 4 个) -RUST_BUILD_TASKS=( - ":app:rustBuildArm64Release" - ":app:rustBuildArmRelease" - ":app:rustBuildX86_64Release" - ":app:rustBuildX86Release" -) -SKIP_ARGS=() -for t in "${RUST_BUILD_TASKS[@]}"; do SKIP_ARGS+=(-x "${t#:}"); done - -# 4 个 Android 目标的 cargo target triple -ANDROID_TARGETS=( - "aarch64-linux-android" - "armv7-linux-androideabi" - "x86_64-linux-android" - "i686-linux-android" -) - -if [ "$VARIANT" = "release" ]; then - echo "[release] 手工 cargo 编 lib (4 个 ABI), gradle 只跑 packaging (跳过 rustBuild* 避免 --release 重复 bug)" - - for target in "${ANDROID_TARGETS[@]}"; do - echo " [cargo] build lib release for $target ..." - cargo build \ - --target "$target" \ - --features custom-protocol \ - --lib \ - --release - done - - echo " [gradle] assembleRelease -x rustBuild* ..." - cd gen/android - ./gradlew --no-daemon assembleRelease "${SKIP_ARGS[@]}" - - APK_DIR="$WIN_PROJECT/src-tauri/gen/android/app/build/outputs/apk/universal/release" - # Gradle 配了 signingConfig 就输出 app-universal-release.apk, - # 否则输出 app-universal-release-unsigned.apk, 按文件名判断是否已签名 - SIGNED_APK="$APK_DIR/app-universal-release.apk" - UNSIGNED_APK="$APK_DIR/app-universal-release-unsigned.apk" - - if [ -f "$SIGNED_APK" ]; then - APK_PATH="$SIGNED_APK" - APK_STATUS="已签名" - elif [ -f "$UNSIGNED_APK" ]; then - APK_PATH="$UNSIGNED_APK" - APK_STATUS="未签名" - else - APK_PATH="" - APK_STATUS="未找到" - fi - - echo - echo "=== 产物 ($APK_STATUS) ===" - if [ -n "$APK_PATH" ]; then - ls -lh "$APK_PATH" - else - ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)" - fi - - if [ "$APK_STATUS" = "已签名" ]; then - echo - echo "=== 安装到设备 ===" - echo " adb install -r $APK_PATH" - elif [ "$APK_STATUS" = "未签名" ]; then - echo - echo "=== Release 签名 (按需) ===" - echo "1. 生成 keystore (一次性):" - echo " keytool -genkey -v -keystore ~/iboard-release.keystore -alias iboard -keyalg RSA -keysize 2048 -validity 10000" - echo "2. 在 ~/.gradle/gradle.properties 写:" - echo " IBOARD_UPLOAD_STORE_FILE=/home/$(whoami)/iboard-release.keystore" - echo " IBOARD_UPLOAD_KEY_ALIAS=iboard" - echo " IBOARD_UPLOAD_STORE_PASSWORD=..." - echo " IBOARD_UPLOAD_KEY_PASSWORD=..." - echo "3. 重跑本脚本 (Gradle 读 gradle.properties 里的 IBOARD_UPLOAD_* 自动用 releaseSigning)" - echo - echo "=== 临时用 debug keystore 手动签 (仅测试) ===" - echo " \$ANDROID_HOME/build-tools/*/apksigner sign --ks ~/.android/debug.keystore \" - echo " --ks-pass pass:android --key-pass pass:android \" - echo " $APK_PATH" - fi -else - echo "[debug] Tauri CLI debug 路径 (不传 --release 不会触发 bug), 直接走" - npx tauri android build --apk - - APK_DIR="$WIN_PROJECT/src-tauri/target/debug/bundle/android/app/build/outputs/apk/debug" - echo - echo "=== 产物 ===" - ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)" -fi +#!/usr/bin/env bash +# iBoard Android APK 打包 +# 用法: bash scripts/wsl/build-apk.sh [debug|release] +# release 模式自动构建 4 个 ABI 并出 universal APK +set -euo pipefail + +WIN_PROJECT='/mnt/d/workbench/iboard' +cd "$WIN_PROJECT" + +VARIANT="${1:-debug}" +echo "构建变体: $VARIANT" + +# 环境变量 +export ANDROID_HOME="${ANDROID_HOME:-$HOME/android-sdk}" +export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_HOME/ndk/27.2.12479018}" +# 关键: 把 NDK toolchain bin 加进 PATH, .cargo/config.toml 里 +# linker = "aarch64-linux-android24-clang" 这种短名才能被解析到 +NDK_TOOLCHAIN_BIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin" +if [ ! -d "$NDK_TOOLCHAIN_BIN" ]; then + echo "ERROR: NDK toolchain bin 不存在: $NDK_TOOLCHAIN_BIN" + echo "请确认 ANDROID_NDK_HOME 正确指向 NDK 27.2.x 目录" + exit 1 +fi +export PATH="$NDK_TOOLCHAIN_BIN:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$HOME/.cargo/bin:$PATH" + +# 0. 首次需要 android 工程 +cd src-tauri +if [ ! -d "gen/android" ]; then + echo "=== 0. 初始化 Android 工程 (一次性) ===" + npx tauri android init +fi +cd "$WIN_PROJECT" + +# Android 后端地址, 写到前端 bundle 里 (覆盖默认的 /api 相对路径) +export VITE_API_BASE="${VITE_API_BASE:-https://iboard.honor3.com}" +echo "VITE_API_BASE=$VITE_API_BASE" + +# 1. 先构建前端, 让 Tauri android 工程能拿到 dist/ +echo "=== 1. 构建前端 ===" +npm run build + +# 1.5 拷贝 dist/ 到 Android 工程 assets/, 绕过 Tauri CLI 时这步要做 +# Tauri CLI 默认在 android build 前会干这事, 我们走直 gradle 要自己补上 +ANDROID_ASSETS="$WIN_PROJECT/src-tauri/gen/android/app/src/main/assets" +mkdir -p "$ANDROID_ASSETS" +# 清空旧的 (避免上次的残余) +find "$ANDROID_ASSETS" -mindepth 1 -maxdepth 1 ! -name dexopt ! -name tauri.conf.json -exec rm -rf {} + +cp -r dist/. "$ANDROID_ASSETS/" +echo "前端 bundle 已拷贝到 $ANDROID_ASSETS" +ls -la "$ANDROID_ASSETS" | head -10 + +# 2. 走不同路径 +cd src-tauri + +# 全部 4 个 Android 架构的 rustBuild 任务 (Tauri 2 默认会编 4 个) +RUST_BUILD_TASKS=( + ":app:rustBuildArm64Release" + ":app:rustBuildArmRelease" + ":app:rustBuildX86_64Release" + ":app:rustBuildX86Release" +) +SKIP_ARGS=() +for t in "${RUST_BUILD_TASKS[@]}"; do SKIP_ARGS+=(-x "${t#:}"); done + +# 4 个 Android 目标的 cargo target triple +ANDROID_TARGETS=( + "aarch64-linux-android" + "armv7-linux-androideabi" + "x86_64-linux-android" + "i686-linux-android" +) + +if [ "$VARIANT" = "release" ]; then + echo "[release] 手工 cargo 编 lib (4 个 ABI), gradle 只跑 packaging (跳过 rustBuild* 避免 --release 重复 bug)" + + for target in "${ANDROID_TARGETS[@]}"; do + echo " [cargo] build lib release for $target ..." + cargo build \ + --target "$target" \ + --features custom-protocol \ + --lib \ + --release + done + + echo " [gradle] assembleRelease -x rustBuild* ..." + cd gen/android + ./gradlew --no-daemon assembleRelease "${SKIP_ARGS[@]}" + + APK_DIR="$WIN_PROJECT/src-tauri/gen/android/app/build/outputs/apk/universal/release" + # Gradle 配了 signingConfig 就输出 app-universal-release.apk, + # 否则输出 app-universal-release-unsigned.apk, 按文件名判断是否已签名 + SIGNED_APK="$APK_DIR/app-universal-release.apk" + UNSIGNED_APK="$APK_DIR/app-universal-release-unsigned.apk" + + if [ -f "$SIGNED_APK" ]; then + APK_PATH="$SIGNED_APK" + APK_STATUS="已签名" + elif [ -f "$UNSIGNED_APK" ]; then + APK_PATH="$UNSIGNED_APK" + APK_STATUS="未签名" + else + APK_PATH="" + APK_STATUS="未找到" + fi + + echo + echo "=== 产物 ($APK_STATUS) ===" + if [ -n "$APK_PATH" ]; then + ls -lh "$APK_PATH" + else + ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)" + fi + + if [ "$APK_STATUS" = "已签名" ]; then + echo + echo "=== 安装到设备 ===" + echo " adb install -r $APK_PATH" + elif [ "$APK_STATUS" = "未签名" ]; then + echo + echo "=== Release 签名 (按需) ===" + echo "1. 生成 keystore (一次性):" + echo " keytool -genkey -v -keystore ~/iboard-release.keystore -alias iboard -keyalg RSA -keysize 2048 -validity 10000" + echo "2. 在 ~/.gradle/gradle.properties 写:" + echo " IBOARD_UPLOAD_STORE_FILE=/home/$(whoami)/iboard-release.keystore" + echo " IBOARD_UPLOAD_KEY_ALIAS=iboard" + echo " IBOARD_UPLOAD_STORE_PASSWORD=..." + echo " IBOARD_UPLOAD_KEY_PASSWORD=..." + echo "3. 重跑本脚本 (Gradle 读 gradle.properties 里的 IBOARD_UPLOAD_* 自动用 releaseSigning)" + echo + echo "=== 临时用 debug keystore 手动签 (仅测试) ===" + echo " \$ANDROID_HOME/build-tools/*/apksigner sign --ks ~/.android/debug.keystore \" + echo " --ks-pass pass:android --key-pass pass:android \" + echo " $APK_PATH" + fi +else + echo "[debug] Tauri CLI debug 路径 (不传 --release 不会触发 bug), 直接走" + npx tauri android build --apk + + APK_DIR="$WIN_PROJECT/src-tauri/target/debug/bundle/android/app/build/outputs/apk/debug" + echo + echo "=== 产物 ===" + ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)" +fi diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 536cfbb..1f6ca45 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -19,15 +19,15 @@ dependencies = [ [[package]] name = "alloc-no-stdlib" -version = "2.0.4" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" +checksum = "c2fb6cfd47bf496ff64095c20eaba0c201404ee38714d4142fcfa1dc334fcc7a" [[package]] name = "alloc-stdlib" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e76a019e91224d279006ff972f1e984179a6e9feb050adba6ce8274aef23195" +checksum = "0b5c1865780388bfa186411ab5f247819487fc4864c6e9c3106611fa347586e1" dependencies = [ "alloc-no-stdlib", ] @@ -47,6 +47,137 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96bf972d85afc50bf5ab8fe2d54d1586b4e0b46c97c50a0c9e71e2f7bcd812a" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", +] + +[[package]] +name = "async-io" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" +dependencies = [ + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-lock" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" +dependencies = [ + "event-listener", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" +dependencies = [ + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix", +] + +[[package]] +name = "async-recursion" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f8abc12baad266b1c8cec146854c195b5864b4221d4b2ca7296a7ae82d9e451" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "async-signal" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52b5aaafa020cf5053a01f2a60e8ff5dccf550f0f77ec54a4e47285ac2bab485" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.61.2", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + [[package]] name = "atk" version = "0.18.2" @@ -76,6 +207,20 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "auto-launch" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17918dba7ecf78b9a14507ec9f984e7977d13fad87dc86d61038980a45d128cf" +dependencies = [ + "dirs 6.0.0", + "os_info", + "smappservice-rs", + "thiserror 2.0.19", + "windows-registry", + "windows-result", +] + [[package]] name = "autocfg" version = "1.5.1" @@ -94,6 +239,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "bit-set" version = "0.8.0" @@ -143,10 +294,23 @@ dependencies = [ ] [[package]] -name = "brotli" -version = "8.0.4" +name = "blocking" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc91aac060a7a1e25823bdccbfb6af1875b88f17c6daac97894eed8207166b3" +checksum = "a70e4329df6cb94385eed412ec92375c3cdd8a6e502493d1229b6414e4036dfa" +dependencies = [ + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[package]] +name = "brotli" +version = "9.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6737ce8b81460bf9407909f73ff50bf13f7cb8577e1e76715f57ed0eba58ba44" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -155,9 +319,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "5.0.3" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a32acac15fe1967bc3986b2a6347dffc965602354ea6f450ad07e8bfd253583" +checksum = "34c6783f42c21c952ad7112b354f0ba2f10760e9decea5b1b60523d6e270faaf" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -190,6 +354,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.12.1" @@ -258,12 +428,13 @@ dependencies = [ [[package]] name = "cargo_toml" -version = "0.22.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +checksum = "82f4b26e751e711a5302649417f2da046dce6391b2ea30a4820f37462314f0b9" dependencies = [ + "semver", "serde", - "toml 0.9.12+spec-1.1.0", + "toml 1.1.4+spec-1.1.0", ] [[package]] @@ -284,13 +455,13 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfb" -version = "0.7.3" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +checksum = "a347dcabdae9c31b0825fd6a8bed285ec9c2acb89c47827126d52fa4f59cece3" dependencies = [ - "byteorder", "fnv", "uuid", + "web-time", ] [[package]] @@ -335,7 +506,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -348,6 +519,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "cookie" version = "0.18.1" @@ -462,9 +642,9 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dae61cf9c0abb83bd659dab65b7e4e38d8236824c85f0f804f173567bda257d2" +checksum = "8c9cdaae01d5ed7882b04d795e7f752f46ff52d2fa3b50a20d28c464510bba98" dependencies = [ "cssparser-macros", "dtoa-short", @@ -475,29 +655,19 @@ dependencies = [ [[package]] name = "cssparser-macros" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +checksum = "d045de693cb712d0b22c6a64be5b953f67b3ce00ab5ad3dd5d8b441886ab8e1a" dependencies = [ "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] name = "ctor" -version = "0.8.0" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98" -dependencies = [ - "ctor-proc-macro", - "dtor", -] - -[[package]] -name = "ctor-proc-macro" -version = "0.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" +checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d" [[package]] name = "darling" @@ -593,6 +763,15 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "dirs" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d57d423b3c82e89b9a24ca3091fee61f456a26edbd28d26c65906f4bc1dcd8f" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-sys" version = "0.5.0" @@ -653,9 +832,9 @@ dependencies = [ [[package]] name = "dom_query" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89" +checksum = "fac5fca71e65e94cc718a6e2af65d6e0f9c6027751c2aa562fbb5087fda639bc" dependencies = [ "bit-set", "cssparser", @@ -690,21 +869,6 @@ dependencies = [ "dtoa", ] -[[package]] -name = "dtor" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1057d6c64987086ff8ed0fd3fbf377a6b7d205cc7715868cd401705f715cbe4" -dependencies = [ - "dtor-proc-macro", -] - -[[package]] -name = "dtor-proc-macro" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" - [[package]] name = "dunce" version = "1.0.5" @@ -746,6 +910,33 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "endi" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" + +[[package]] +name = "enumflags2" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -773,6 +964,26 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "event-listener" +version = "5.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a23add41df1562121a9393cb065eab5146a1242410f23a644851e90cfd669d2" +dependencies = [ + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + [[package]] name = "fastrand" version = "2.5.0" @@ -919,6 +1130,19 @@ version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.33" @@ -1297,6 +1521,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" + [[package]] name = "hex" version = "0.4.3" @@ -1305,9 +1535,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "html5ever" -version = "0.38.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1054432bae2f14e0061e33d23402fbaa67a921d319d56adc6bcf887ddad1cbc2" +checksum = "46a1761807faccc9a19e86944bbf40610014066306f96edcdedc2fb714bcb7b8" dependencies = [ "log", "markup5ever", @@ -1442,7 +1672,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core", ] [[package]] @@ -1456,23 +1686,26 @@ dependencies = [ [[package]] name = "iboard" -version = "0.2.0" +version = "0.2.1" dependencies = [ "serde", "serde_json", "tauri", "tauri-build", + "tauri-plugin-autostart", "tauri-plugin-hotswap", + "tauri-plugin-single-instance", + "windows-sys 0.60.2", ] [[package]] name = "ico" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" +checksum = "d75e94d66081e4d8dcd098bd8dc5254800fea14a26389b298410158d834de167" dependencies = [ "byteorder", - "png 0.17.16", + "png", ] [[package]] @@ -1584,6 +1817,19 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "image" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85ab80394333c02fe689eaf900ab500fbd0c2213da414687ebf995a65d5a6104" +dependencies = [ + "bytemuck", + "byteorder-lite", + "moxcms", + "num-traits", + "png", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -1609,9 +1855,9 @@ dependencies = [ [[package]] name = "infer" -version = "0.19.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" +checksum = "f4200d433cbd5178df7797c9c2e75b348b728e39631cf14520d1e2fc424201f4" dependencies = [ "cfb", ] @@ -1708,21 +1954,21 @@ dependencies = [ [[package]] name = "json-patch" -version = "3.0.1" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" +checksum = "7421438de105a0827e44fadd05377727847d717c80ce29a229f85fd04c427b72" dependencies = [ "jsonptr", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.19", ] [[package]] name = "jsonptr" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" +checksum = "a5a3cc660ba5d72bce0b3bb295bf20847ccbb40fd423f3f05b61273672e561fe" dependencies = [ "serde", "serde_json", @@ -1730,13 +1976,12 @@ dependencies = [ [[package]] name = "keyboard-types" -version = "0.7.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +checksum = "0fbe853b403ae61a04233030ae8a79d94975281ed9770a1f9e246732b534b28d" dependencies = [ "bitflags 2.13.1", "serde", - "unicode-segmentation", ] [[package]] @@ -1832,9 +2077,9 @@ checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] name = "markup5ever" -version = "0.38.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8983d30f2915feeaaab2d6babdd6bc7e9ed1a00b66b5e6d74df19aa9c0e91862" +checksum = "7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de" dependencies = [ "log", "tendril", @@ -1890,10 +2135,20 @@ dependencies = [ ] [[package]] -name = "muda" -version = "0.19.3" +name = "moxcms" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd04e60bc0b07438a6771710ee1698f98f6ebbc7f89b61264af1563b8aeb878" +checksum = "bb85c154ba489f01b25c0d36ae69a87e4a1c73a72631fc6c0eb6dde34a73e44b" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "muda" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cca139e57da4383727f189e43e66e84fa372347027fc996f9f1a007ec0a37996" dependencies = [ "crossbeam-channel", "dpi", @@ -1904,7 +2159,7 @@ dependencies = [ "objc2-core-foundation", "objc2-foundation", "once_cell", - "png 0.18.1", + "png", "serde", "thiserror 2.0.19", "windows-sys 0.61.2", @@ -1942,6 +2197,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + [[package]] name = "ndk-sys" version = "0.6.0+11769913" @@ -1957,6 +2218,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.13.1", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "num-conv" version = "0.2.2" @@ -2015,6 +2288,7 @@ dependencies = [ "objc2", "objc2-core-foundation", "objc2-foundation", + "objc2-quartz-core", ] [[package]] @@ -2117,6 +2391,7 @@ checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.13.1", "block2", + "libc", "objc2", "objc2-core-foundation", ] @@ -2144,6 +2419,30 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "objc2-security" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a" +dependencies = [ + "bitflags 2.13.1", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-service-management" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b213642d6959cc6023ceb1217aa595eaaf09b8094ce95127c103cab611fe65e8" +dependencies = [ + "block2", + "objc2", + "objc2-core-foundation", + "objc2-foundation", + "objc2-security", +] + [[package]] name = "objc2-ui-kit" version = "0.3.2" @@ -2244,6 +2543,31 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "os_info" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf20a545b305cf1da722b236b5155c9bb35f1d5ceb28c048bd96ca842f41b5b" +dependencies = [ + "android_system_properties", + "log", + "nix", + "objc2", + "objc2-foundation", + "objc2-ui-kit", + "windows-sys 0.61.2", +] + [[package]] name = "pango" version = "0.18.3" @@ -2269,6 +2593,12 @@ dependencies = [ "system-deps", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.5" @@ -2289,7 +2619,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -2357,6 +2687,17 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "piper" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + [[package]] name = "pkg-config" version = "0.3.33" @@ -2376,19 +2717,6 @@ dependencies = [ "time", ] -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - [[package]] name = "png" version = "0.18.1" @@ -2402,6 +2730,20 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polling" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix", + "windows-sys 0.61.2", +] + [[package]] name = "potential_utf" version = "0.1.5" @@ -2485,6 +2827,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pxfm" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea" + [[package]] name = "quick-xml" version = "0.41.0" @@ -2942,9 +3290,9 @@ dependencies = [ [[package]] name = "selectors" -version = "0.36.1" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" +checksum = "8adfa1c298912827b8a28b223b3b874357397ae706e6190acd9bf28cee99114d" dependencies = [ "bitflags 2.13.1", "cssparser", @@ -3156,6 +3504,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + [[package]] name = "simd-adler32" version = "0.3.10" @@ -3180,6 +3538,18 @@ version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +[[package]] +name = "smappservice-rs" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52703b97a53101cf5d4580e0737aaa634ce1fdcfc123c16b2a9658e358013488" +dependencies = [ + "objc2", + "objc2-foundation", + "objc2-service-management", + "thiserror 2.0.19", +] + [[package]] name = "socket2" version = "0.6.5" @@ -3244,6 +3614,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +[[package]] +name = "static_vcruntime" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff7589a1859b09232522bb9edf076ca7fcf14ded96685d3fa629db73023ffbb7" + [[package]] name = "string_cache" version = "0.9.0" @@ -3282,9 +3658,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "swift-rs" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7" +checksum = "cefd87076fd385308ee4aff597256c902f1fbb4d031de1558efc12f8ffefadd9" dependencies = [ "base64 0.21.7", "serde", @@ -3379,9 +3755,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.35.3" +version = "0.37.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1c93047acf68669466a34690ac58cca7010bd1b201e1ec86f1fd0a75d3dd4a9" +checksum = "d5777b06fe6435126ae8d816eba269e050e1e10d302cf5461e9c49eccabc3548" dependencies = [ "bitflags 2.13.1", "block2", @@ -3399,12 +3775,12 @@ dependencies = [ "libc", "log", "ndk", + "ndk-context", "ndk-sys", "objc2", "objc2-app-kit", "objc2-foundation", "objc2-ui-kit", - "once_cell", "parking_lot", "percent-encoding", "raw-window-handle", @@ -3412,7 +3788,7 @@ dependencies = [ "unicode-segmentation", "url", "windows", - "windows-core 0.61.2", + "windows-core", "windows-version", "x11-dl", ] @@ -3447,14 +3823,14 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.11.5" +version = "2.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "667b20e2726d572dea2de7370da16e188eb06008faf9a92fab7cdc46791190b5" +checksum = "5fb0244332cfb9cee7e2a568bf5da29a36ed8fdbd717f6f47a66b6b7b358c072" dependencies = [ "anyhow", "bytes", "cookie", - "dirs", + "dirs 7.0.0", "dunce", "embed_plist", "getrandom 0.3.4", @@ -3462,6 +3838,7 @@ dependencies = [ "gtk", "heck 0.5.0", "http", + "image", "jni", "libc", "log", @@ -3498,13 +3875,13 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.6.3" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc9ce40b16101cb6ea63d3e221567affd1c3a9205f95d7bc574941a10636b632" +checksum = "adddb0e648752aaac5da9c3c3c6a68e1e87cab55e3b757b18a9441ef8c3ac614" dependencies = [ "anyhow", "cargo_toml", - "dirs", + "dirs 7.0.0", "glob", "heck 0.5.0", "json-patch", @@ -3512,6 +3889,8 @@ dependencies = [ "semver", "serde", "serde_json", + "static_vcruntime", + "strsim", "tauri-utils", "tauri-winres", "walkdir", @@ -3519,16 +3898,16 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.6.3" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08279169ff42f8fc45a1dbc9dcae888893ba95288142e5880c59b93a26d2cfc5" +checksum = "fb37631cf71dab5e8ab55e1bdd701e18a52653d90b78e71d0e5598b1e0a61316" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "brotli", "ico", "json-patch", "plist", - "png 0.17.16", + "png", "proc-macro2", "quote", "semver", @@ -3546,9 +3925,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.6.3" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8b394794f399a421811d06966343e7933fcae92d59f5180b9388d1174497a45" +checksum = "0cc38db58854c10fb5f91a887ed8bf82d3239bb92b5d8db86eda09e96d9963d1" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -3560,9 +3939,9 @@ dependencies = [ [[package]] name = "tauri-plugin" -version = "2.6.3" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74be5dd4bed9afbd145e5716b5fa2ec28cbc29c34ffa61c258c9273d896c8020" +checksum = "67fb21a77e8f94e8beb3325e583102488659365af0a3948b7ea244c5b779c291" dependencies = [ "anyhow", "glob", @@ -3574,6 +3953,20 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tauri-plugin-autostart" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bce56ceb0a99b8ab5eebc977ba9ffc62391b862648cb9ab76fc8bc7231b8f7e2" +dependencies = [ + "auto-launch", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "thiserror 2.0.19", +] + [[package]] name = "tauri-plugin-hotswap" version = "0.0.4" @@ -3581,7 +3974,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3550b0b6727104637a12c6c1c5270714d4a8d935de3b2b71a5fe5a111d7ffc5" dependencies = [ "base64 0.22.1", - "dirs", + "dirs 6.0.0", "flate2", "log", "minisign-verify", @@ -3598,10 +3991,26 @@ dependencies = [ ] [[package]] -name = "tauri-runtime" -version = "2.11.3" +name = "tauri-plugin-single-instance" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b4bc95aed361b0019067d189a1174a603d460d0f6c72606512d59fc9c12ec8" +checksum = "561cd99484561bc39c954768e7b41a66cebbe1ac3d9d081c34361f740c489e2c" +dependencies = [ + "serde", + "serde_json", + "tauri", + "thiserror 2.0.19", + "tokio", + "tracing", + "windows-sys 0.61.2", + "zbus", +] + +[[package]] +name = "tauri-runtime" +version = "2.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c55766d99cea69055904d1735b93c2049302b2e09effd462120deb5581d78e9" dependencies = [ "cookie", "dpi", @@ -3624,9 +4033,9 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.11.4" +version = "2.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e6fac707727b7a2f48e4ded90976324267371073edbb415ffb73bb0458d203f" +checksum = "e1aa9d8b7a120f879f44fdc1053f7b7dbf416bf0bbc6a72b714dec46b782b52f" dependencies = [ "gtk", "http", @@ -3634,7 +4043,6 @@ dependencies = [ "log", "objc2", "objc2-app-kit", - "once_cell", "percent-encoding", "raw-window-handle", "softbuffer", @@ -3650,9 +4058,9 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.9.3" +version = "2.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e176a18e67764923c4f1ce66f25ae4abe5f688384d5eb1a0fa6c77f3d90f887" +checksum = "362ab21cd4cc713f2a02b1a9b5688198b1541cfb6907c4281e9190e0f0ef4aa3" dependencies = [ "anyhow", "brotli", @@ -3874,21 +4282,6 @@ dependencies = [ "toml_edit 0.20.2", ] -[[package]] -name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "indexmap 2.14.0", - "serde_core", - "serde_spanned 1.1.1", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 0.7.15", -] - [[package]] name = "toml" version = "1.1.4+spec-1.1.0" @@ -3913,15 +4306,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - [[package]] name = "toml_datetime" version = "1.1.1+spec-1.1.0" @@ -4034,9 +4418,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "tracing-core" version = "0.1.36" @@ -4048,12 +4444,12 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045979e3f037cd18ad1cb2a419dfda133c5c29c9f3453370079f2255d46c257e" +checksum = "b2b9c52859a94554803ccd4a24b98f74148ebc73b90676d783f3490b1bff9d72" dependencies = [ "crossbeam-channel", - "dirs", + "dirs 7.0.0", "libappindicator", "muda", "objc2", @@ -4062,7 +4458,7 @@ dependencies = [ "objc2-core-graphics", "objc2-foundation", "once_cell", - "png 0.18.1", + "png", "serde", "thiserror 2.0.19", "windows-sys 0.61.2", @@ -4087,44 +4483,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] -name = "unic-char-property" -version = "0.9.0" +name = "uds_windows" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-ucd-ident" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", + "memoffset", + "tempfile", + "windows-sys 0.61.2", ] [[package]] @@ -4160,13 +4526,13 @@ dependencies = [ [[package]] name = "urlpattern" -version = "0.3.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" +checksum = "df16f50ef4cc145211879a3867ba757076b25dfee812040dcb0658bd9ae7904b" dependencies = [ + "icu_properties", "regex", "serde", - "unic-ucd-ident", "url", ] @@ -4428,16 +4794,14 @@ dependencies = [ [[package]] name = "webview2-com" -version = "0.38.2" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7130243a7a5b33c54a444e54842e6a9e133de08b5ad7b5861cd8ed9a6a5bc96a" +checksum = "3f89fca7a704cee10dcb3654c1dbb8941d1783132f1917358af75bec37a7d7e6" dependencies = [ "webview2-com-macros", "webview2-com-sys", "windows", - "windows-core 0.61.2", - "windows-implement", - "windows-interface", + "windows-core", ] [[package]] @@ -4453,13 +4817,13 @@ dependencies = [ [[package]] name = "webview2-com-sys" -version = "0.38.2" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "381336cfffd772377d291702245447a5251a2ffa5bad679c99e61bc48bacbf9c" +checksum = "b3a07132775117d6065853d9d1178157b8c90e228de47129d6bce2c7edebedfb" dependencies = [ "thiserror 2.0.19", "windows", - "windows-core 0.61.2", + "windows-core", ] [[package]] @@ -4495,52 +4859,39 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window-vibrancy" -version = "0.6.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" +checksum = "111e51caca442cafd9bab396628ac4d814880eaea4e63dfd76a12e9f342b5580" dependencies = [ "objc2", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation", + "objc2-quartz-core", "raw-window-handle", - "windows-sys 0.59.0", + "windows-sys 0.61.2", "windows-version", ] [[package]] name = "windows" -version = "0.61.3" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" dependencies = [ "windows-collections", - "windows-core 0.61.2", + "windows-core", "windows-future", - "windows-link 0.1.3", "windows-numerics", ] [[package]] name = "windows-collections" -version = "0.2.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ - "windows-core 0.61.2", -] - -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", + "windows-core", ] [[package]] @@ -4551,19 +4902,19 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] name = "windows-future" -version = "0.2.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", + "windows-core", + "windows-link", "windows-threading", ] @@ -4589,12 +4940,6 @@ dependencies = [ "syn 2.0.119", ] -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" @@ -4603,12 +4948,12 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-numerics" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", + "windows-core", + "windows-link", ] [[package]] @@ -4617,18 +4962,9 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", + "windows-link", + "windows-result", + "windows-strings", ] [[package]] @@ -4637,16 +4973,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link 0.2.1", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] @@ -4655,7 +4982,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -4685,13 +5012,22 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + [[package]] name = "windows-sys" version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -4718,7 +5054,7 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", @@ -4726,12 +5062,29 @@ dependencies = [ ] [[package]] -name = "windows-threading" -version = "0.1.0" +name = "windows-targets" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.1.3", + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows-threading" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" +dependencies = [ + "windows-link", ] [[package]] @@ -4740,7 +5093,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -4755,6 +5108,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -4767,6 +5126,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -4779,12 +5144,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -4797,6 +5174,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -4809,6 +5192,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -4821,6 +5210,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -4833,6 +5228,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + [[package]] name = "winnow" version = "0.5.40" @@ -4842,12 +5243,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" - [[package]] name = "winnow" version = "1.0.4" @@ -4881,15 +5276,15 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "wry" -version = "0.55.1" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186f9871daa55fd9c016578b810d149de58367113db7fb72b462d2323ce19514" +checksum = "759c50ddad0ef9913bb5496cb9d509a50433a3b78cb0238d61105526589cf0e9" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "block2", "cookie", "crossbeam-channel", - "dirs", + "dirs 7.0.0", "dom_query", "dpi", "dunce", @@ -4906,7 +5301,6 @@ dependencies = [ "objc2-foundation", "objc2-ui-kit", "objc2-web-kit", - "once_cell", "percent-encoding", "raw-window-handle", "sha2", @@ -4918,7 +5312,7 @@ dependencies = [ "webkit2gtk-sys", "webview2-com", "windows", - "windows-core 0.61.2", + "windows-core", "windows-version", "x11-dl", ] @@ -4977,6 +5371,76 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zbus" +version = "5.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db4be7c075cb421e4b7ee645541604239bd243ba7c357511f4ff3a74b555907" +dependencies = [ + "async-broadcast", + "async-executor", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "libc", + "ordered-stream", + "rustix", + "serde", + "serde_repr", + "tracing", + "uds_windows", + "uuid", + "windows-sys 0.61.2", + "winnow 1.0.4", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2990635d09ade6df1868f72f8cac69a876a90981e8bd3c40b1be413f8dc88f40" +dependencies = [ + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 3.0.3", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812a12be4ead7a59e18ea8f047d08add0066b73bc62fc1467066a2472ae088dd" +dependencies = [ + "serde", + "winnow 1.0.4", + "zvariant", +] + +[[package]] +name = "zcheapstr" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1afec51604565183aeb5c54c20aeab286120d4e4460f7f76e3e8bb8c0d99473" +dependencies = [ + "serde", +] + [[package]] name = "zerofrom" version = "0.1.8" @@ -5042,3 +5506,44 @@ name = "zmij" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + +[[package]] +name = "zvariant" +version = "5.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80bf6d6cd6a4b601acb64cfb8284cdc643fcfa75ef26ae3c46ec8aa4e8a1fbb7" +dependencies = [ + "endi", + "enumflags2", + "serde", + "winnow 1.0.4", + "zcheapstr", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2672456ba1cb54b5eaec136e63135b3c7495fb938e53b28a62e633496d486d" +dependencies = [ + "proc-macro-crate 3.5.0", + "proc-macro2", + "quote", + "syn 3.0.3", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad0294361a320b694a328460dc73add56c306150f5cb6bfafc44446120008a3" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 3.0.3", + "winnow 1.0.4", +] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index f19b1ee..b274c56 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iboard" -version = "0.2.0" +version = "0.2.1" description = "iBoard - 经济数据与策略" authors = ["iBoard Team"] edition = "2021" @@ -27,6 +27,20 @@ tauri-plugin-hotswap = "0.0.4" [target."cfg(target_os = \"android\")".dependencies] tauri = { version = "2", features = [] } +# Windows 外壳能力 (W-M1~M4): 托盘 / 自启动 / 单实例 / Win32 辅助 +# 仅加在 Windows 目标上, Android 构建不受影响 (W-NF-05) +[target."cfg(windows)".dependencies] +tauri = { version = "2", features = ["tray-icon", "image-png"] } +tauri-plugin-autostart = "2" +tauri-plugin-single-instance = "2" +windows-sys = { version = "0.60", features = [ + "Win32_Foundation", + "Win32_Graphics_Gdi", + "Win32_System_Registry", + "Win32_UI_Shell", + "Win32_UI_WindowsAndMessaging", +] } + [features] # Tauri 的"自定义协议"模式让打包后的 webview 能从 tauri:// 加载资源 # 用于生产构建, dev 模式不需要 diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png index 145eb8a8e86fbb949af47f644d2cfbddbf6db38d..f3c5bcf220d291eb7734705fa13f6e89f1bc8478 100644 GIT binary patch literal 2505 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 Bta&N9#$(;y0Q>Q~ZF-M8qHg@EGDIrEn^`vu- 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 JDs3?(3ZE{$0;~-Pd*f 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 ON5I?TpgYSgEdAeaqSwLz diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png index 1bc47b2e7f93384a74594ea0684478b8e83d13b4..5da18449036720e4bfbe8ca7b7908d128618f946 100644 GIT binary patch delta 708 zcmV;#0z3WK0^0?UBYy&-Nkl#b~2~X|rie_Q&|%Bx&{5U9t;8 zA0%XFlKsB@-ZwMvMPYhcVqqZwVC5&y-Pc;o2%rEV6owgE`+xLarTfl*{!n@ZJPa9I z@Lb_^@lfESER~wnVL;#2NFsy~5SB#X`%6-xRDEBmTm0kum~~?!!D_PBsX^0Q=pu)>@;B`rC_XHs>KW&taNqZFypYGiu>)r8S7RM3 z)m11W5|u<`0+waLZMAT3_Aahpy<)}|U%bZ6JG0oI%OMDYWC`?gPO{U6G6*T98H*FK z2v`L8b*+xI`VS-dm)bWPvtoHbq0(oMn|*AIF7mQdLCLtXsbqy&@C}=m40}l-;ju%9>)yWY`Xnx>z|bD z1e)$4NWH2>1@b(%O9bylxdZ3jwr%s`S}>x8JjN7^&F9Lo@!~sfmweyr_8SzDTz3YK zupGi#TK!l#%esZ!DDnWcOOA+~$VioxV2mCXN<9XfTja*8#pe3Y+GFn3h~ZIUkTZ!L qc6+Y%GD$E;Pky`cz2@>?1AhQLdL#C-+4p_`0000E16>FG(0hukQWswWAivbzPs9H$NX_#N2x}`Xc1%App6o2z^XW%dyW5?ayx;8X8JlyOh%q-ev$DN+p1a-O?|tsPd73ti z+1XjWxVTv2eE*^8L&DPgj_8CSdW!_@CK8ff>ftOodd&BHn_pZZNf(!I-MF<8TRp_O z&(6&$nx8jsOdX%JWKWZGb4qFLoFg3knucNsLH^*s#*`(W%uAA|?k!z!*BA#7!2h6m zvwv#lLk4<5>4vtZ1Zd;GshTT>g8@hjGGmDep`_Ae%c68boLpY|`MVk`Cd$6#J^1O5 zS>oRcAvF_M1U6NeH!R?5!OC#&ns+gitpcgRxe*4V{1&Jm^n{E6n|G z3V<2et>)hoA;TLf0z76;?e)u_+rLmAq^1!cnSd>Dz@(%kHz0X8*81m{WC;NHqA2O% z%F1(57r}id!5HO#xfx)dIX3|fT*0ER@EgNdhOBxkI`&4s%5+s34m}l zgTDXZAzl0FSL$?oOS>VoAYqM3Fv@^keDjaNn<3Kn}mH>pjCr?)B?PEvj{Mj?Ky2@t2?}-3> zVqzD4_T@M9{SOPYo6k*Zi4g4H@{0R*&hqxY_Ugbn8)Frl>JoLIYC>sCYKjPG69)@Oh6_e6OakW1Y`m-0hxeIKqep)kO{~H zWCAh)6m6$wzx}{%VIP8yy@|iB0HZqGzll&M6f)uJunSA$*dNg8c70ty1~O17MlGP* z?L{wSQ6XD~#QGDJ1HihsgS+oMYNXjhn4Vq zS%#>oN?`D&9KLs8U@Vt_$%CI;13z$2!m};rlZR)f$hZ%Nuzmg!-}4>Bd4#(EYM=iX X^`cMnZoLO|00000NkvXXu0mjfPt91J literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..335432529a3875af821bc33982a65a9fcd8010b4 GIT binary patch literal 2047 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∋ zU)*`2X7H*CZB}$jP!(`?WFxrNSifz|$1hdq>TKPg{0)SPD!)K9l+wekzwQz@;bxrq z1SuXD-Zxk>$wAdakEET{-fy zB7999+AFAPtnd6PrAATL;jE2+VX^!*Rga1*N>YW-m=s$aIIJw!ghZJO1(`(I=kx$< zr!;`g(UMWjKk=c(K<-|(^_s?;3z&y<(Q7^?6AoiE{`P+#{63dW0uc# z5~2`sK$A~#oZ3qEq*ryc%6#sya}n^0*e%}Fg0N!Uh4ZrbZXF!7Q|A)N)tAn3FlE}C zDDed%)*8?TBi@A=dfrphRQ9)_wmKiS0CJ0p@;K48w+F!>peVD*|K6*==SMd(b_&l~ zg1aeS6C~hj`0b+L{rl7H4XnAU-%feW-wd+mU;j8{cPYRuicc799KJJ{`d2^W!*HlY z+5DntgpV#n@_1`QV362rT_+72kfEEc=#E`x9)G6L8&V$#aw1FHSMT_pF&eVJr6?`& zI$`3b(nFWx)#a{7LS&&ZZ@^g=>~RutZTVdRYyS$MpumBbG|F`Lq!O3&9ggH6nv)4kI~>_lgSd;ri24}PBcUp(>XU;Nv$U#S1f!N2ie;Q(jPGW}oECY5C+7oMTxzMd*= z7;%?F&rXhT7%H;WzZVowIw$IKFqwHUG)TBL*by*%R0+h`>pFIFCJLq;?PE5bTwzMn zwesY{V@~IbjssJ>gVlaN78vest7C6#;y1(O;`RuU2CJ!y?oQ25?6yl08Fuf~-@V|D zEwGI_JUndM9#&O$w2TZGrQWtb2Vba=k(>ve2wz<~(c3e8yPM8FFFNp1gFaJ{3pq0U z9Xe~lhlJIsR}f`0g% zuGEmCp-eTt!i+THy#hw;3p3V!i`C|EVRIax0?PDpTzRqB8yS&oD+?UV;=kubZaEP-x`YFJkirmj&uwb)b5$Iu>PfI**9rel3d5ugNk%lP-gP603Ppfrh7iayg~w`Ia2<0Bj-y7Yqyqv zT6}BnV~_~R)SL96-so0Jn4qB7hMK*#MF{kKtlZ1*iS1mRj@>gV3SG=1!G3(T_H;K= zPRRH6E6BT&L%^w%?q^lAYief@pZM{DBj?376R{dHF?h@X zS0#2^BDeQ$OF3UxB0Zqasj*-qoRF#;C3g}XcKZMnU?ysKh4Sj^?4J!SYzqOumn+PJ zKQtQ61c06V1AyO3*!*|ftJNkq)9pe!CwHaFZl7yk;dVwp_U=^|oxB@CT ztfxJa&xcErByI8$t&{>KU_|xI?o15j^OFZeVPUbz)Y)aOI*OE+4bBI!{O&ZqhaC=r zZPZob(uP#JmX?&s=$iddE6jPpX2}{OEnUV1-gFx6@#MYtFSnoin5P(RECsq~x{0Ke zP9SOL@jlB#D>th1#5t)WU%>$~DCjsj&r`XnAjnN4_<-dkEO@3$*Gu>=ZRHje_;*4n z#XxcIud6o*x&aa});uJM8rWe7C(X*D8_V*KrHCY&kD?~Vk#RG1MIclmEG_$RPtew9 z&il2eXnwYZRb8G?7BF&lbAFKRl6qqs#diX$Xeim19rg{c}Kagq@MrbaMmnStAb{{S9W==uNv literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e93f9b8438a2d9aae1bc1dff572b74902d0fd519 GIT binary patch literal 2837 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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f32874650bbaa55a94fd5f938db00c181ba099f7 GIT binary patch literal 664 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 M07*qoM6N<$g0tnIx&QzG literal 0 HcmV?d00001 diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5e7d527ea37e84210f821cd8508be9d9c2856cf3 GIT binary patch literal 1578 zcmV+_2G#kAP)A355XWafp555QMdhnPX~QW=DdN;7Jy03Ap-M;`2p2#gBr2u!hB$Bri7OJVxF94D zhXN9(TnkZJL{hj>NP9qXT2PDJkF+Fw_`O|b_B}hVjz5yvhIKtty~MVj?fU1*?99HM z{cC7t#iE9}xv+Y7WbD8}A;b|W#eUmTYLo;~tAt@E$o5pXA$DkNG7ySVGXG}z&eE~oH$xBO% zpQJ!X^rdVDvP@32qvKOg;u#-Et@jgDdU1R>a_<&DSHR$yjSuoHp~%??g9*c*@X=$X z3k%<*n3(hvRRh58guN4!??|ma5>h;9q7XgW(2L9X7&ySN{+Zq9N7N=VXi}+%kkKoJ z`yLKf%DT7GRY&J1YG?b_fdq?9%^Pr1Pm`PM*=PE7rXW9EK~Ng&7I z&SJDsO4-PqFD)%RRtpz1R7US!WHh}ojJ}f+z59r(UR))|*2Ul)5m%b)(Ne%+Hy06?%4}T>8pIVR)1J_H zZ!C@<9FMzRhR0mTHBDD0RW?KJGGv;OAig@84`%C`JBzGl5AHo@%?x^P44EM_WVX8n zGM4;p%cLkWUSHJJe$N_OxPJWxUR|_JQy@ZH7`_Lz*4~2l7BXEs7#bRaqp!UPIs8rD z+Q_4EejGkK^%eYf>%<@dVM9*M?ZQb^A6{CxIyT)*mh=8=fHQ2z0dwQEFob(Jvit zy6^ju7&03}X2=YgjUh8+hRnv088RC~X2=YgjUh8+HipcQ88RC~X2=YgjUh8+HipcQ z88RC~X2^qXvfsD#XHV`zn_0ZmFeJMKhz(7@)wW=UyiLFawJ#c73=O~r;JtNk) zMW_UfJalz!4PHO~mTPA)#zF%}b{(mu z-w|J#bP=6!TOatmX+)oC%fnLy@Q==A9KMuEn<1Fo7alfkrKtchQSKu1Y?My53G(m5B>0PGl?K zox(R=oK|!YWKd)4bCipFA3KK2wN5z%%uNhix@dADK8*L{~n+8mTQc zQqNP;&`Kkf)qXor`=$C~`RBz?x1;t8&GeY}j2}EeT1NOrC}o67JHkFNXu8!nO3h;! c-jZ(hznA#YAIghzDF6Tf07*qoM6N<$g1Hp(v;Y7A literal 0 HcmV?d00001 diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..df7d3c7fb069720e292d9a3aedc054ee450e6360 GIT binary patch literal 1038 zcmV+p1o8WcP)ZtPD;hytm^qJ=?!L#uYtGO>TaMMN!XA%qbc zr4=oTq8Cb05tN3{_netKw{z~i@oUj)2H%xA@bt_)l;7{3dp_>D$A(BoMg&YxOIEvj zPoGdqj+1%@5K0J`g*_AnYJ+|(lR5)nO)h_!U)+rux4&o`7$`Uu`wqPwvn&Bh1@uwS z2!cq=-E>#|GPlt!9Ot>5;xi%b=wG%ZTjWi_$BLC6!!hjxil@J8V93o6&W5Wg4b+sM_7zLS3 z26DM`k7J%1Li zT)MF1y9bY+z{RUKprz#yP-c!dB_>eX)ve;|N48F+yQBl6S z#T9`s7V`Qro83xN%}qrJR5D~@C&CuU<#X`#*__^DmG!EAU&!a-<>DJ1wSokq7IyWX zQb|OvYPAN{T5U)8&1N04RKbk!8-eDP&vVY$EF*LrNbKmGK=>7~va$*j*Dk}@=s8$f z{j1*}JkSjHA3lbgw{B})%AnB`B7jdhqP?vZIy;W)PbA%4opjcgi4@w2|rxb?H`;27v@ zg;@PW(L&L!6)f?YeMVm&)-U7Y++y5>ko6Diu{%3qu4A8}W3;%-V-Y-20OnnW3dT;q zCatCSbFaz%Q#=;I69r(*%{1`906WMObI|P|x9DG&o>vyOa7-W*k`NAKX6&H*S~QTt zvm8?5P~gk5oyj=SWqduoK?4od=-VO2$XFS3G$CZ^c_&hM%7)nW5z8sfkSHS}HjX=x zTN5T-Ef7Y=8cha;V@~j&!862RS_mFI%Qed283!lr*Sj$P1JhCF3Y{Z-c>n+a07*qo IM6N<$g1!yn*Z=?k literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml b/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..2ffbf24 --- /dev/null +++ b/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..b147d295a6886e62619001fe9e29cfb151882092 GIT binary patch literal 1029 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 BPh8L zFP!02gBuiqvQhjKwjOAg2BcEdZfWgyXWsModpo(?HuoJ<_euXDpDmINNY`?gn|{VKr3g2?>LUfnl(XiIFr6`bUursxaDANjqm!*Q{F+cDvL`> z30N!Cz>y&k2Xlgjf- zdA-cwP9_U1j2pX5=6JwvkS&X05qS?*_28|In;(MK+1RoOu`~ zXz)A2q=j@igTWtjKZ`>5b~Z=As*N^{SuhjZ2QFkplq_a2lyt6;18ufJCR}0dxJH6P zNV2}s+c+a)qeM znPV9dEAE4}8kkrF8Zf)rs3^!^69)1K=WDrS%}$Y6DU890RAyKys3BScU;qXIFbIGF z7zDs79Rxwi>k394OPf8_S_4=$VdZ9LMJ|`K`(>HQLaLhv7m51%N5UE{fIVlmd%#eXG*@2EeKtWDp1^96RJKQHxdKXO8Ot zSTzTw6jM_y|4d|;?1!yg+bpK1{|&nV(KR*M_DrXV@=(}@`g*aZv4MXqzkJ@2a*o-_ z+vQVOu&|ZyG*3-W6NE`S2z{yKFMr0rk8@oYE>ToDr+7CIOvDFas@0I!Q_U;qXIFbIIn6CM8GT+>VeL75*q2Z6TJ8`%lOFpGew-Xenp zt1cF^hp})g%FOA(QdkuNz(lpC-s2f~<6Y_#X`Tpm%L zx=6Ogcll9W2eY`)z*5r|-3gds)z!r!Yi0C*@RgBrN($K=E<7uvXJy`!?r@dN=4R*p zAv#m+5^vCMbA+F|$WN(PnK!W}HAX9Nn{;83bfX2NRv$}k84)Y`SDwX++fkXBNuE{4 z=x->9VjqbGxN8@et98JBf4~_X8oWqtz)!L;6B^uN4Z1^S!;G$`&!;RUX=J~Y{H6$? zpjr#6WWa2g5g%J%d8xk&0zXUh33{tz!Hd; zR5Pnz_{@aaFe7Fqi_`G)!T7WqBJ*oEh9|^D5K?7aQej$`N_8n@uPI$8mpe!aF_)#*>7RJ{yH0wDOgb^qq_*&rPTMsP3s@e(P}_FlrZ(F zcMU76k}D(zt{()4C^GD4HknhWY(Q87k|Ah9^f}q_{xeN2n_88MbrQ5ZFGT+E%&1!v znKoZhg4Fl(pO2<59AYM!%<-Vy)W)T?nzqJwed;RjfDU|9NL!&zTj@57-Jt6#$*``b zFC3W9m50!b^681Pr zeGd80PehRKHdJE^Q7rD)=muNJW8G3TI4lCwJ(@oMG3$OYSml6)(2m$Z zWF&ntxnYeT5Bz)|JqlUAxGb$r$Y#thdtpSCOGbVCD(Q=yAKMgzGFj5?hZMSZjHJ&c zS?8?#a{64}y>U2s;)K1)6VL8$akbe;vF2X->JGZ4G+|g%s7ZmDD3fcq1@S_pE;x~E z^S6|4;tYmOT(B^#WYWJM>nTX;SgWw}CJI4GXM%3sLm%y-zovuUY9)W!7}enhE7(H$ zRMnrRy&GK5GD7}9Ey@5V-HWGi(t>pBSMtRF2SJ0FT)<^Mr2qf`07*qoM6N<$f`pgn AJOBUy literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..16101ec8630d9d8cd1214165b46cf2d932a1167b GIT binary patch literal 753 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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..9fbf717c2b4898c1aefa8a3834c50968b97ea293 GIT binary patch literal 1183 zcmV;Q1YrA#P)B%4j+zaU6a^y;Aq9t2OGDthZ{Ekeoi{HaG^Z^91Rwwept)<3`vA^gUQwL; zFBS#dZ(p|r2=Hh&`$C9VbT#6d2m#&gmJ9*l-4Y=Hyjvn9z<1kk0pQ(Ag9P|)$0Gs0 z+i?j1?^Y#AfbVv^65zWXw*>fZ$1efCTN3az6*uqq5JhrDM{MfYuWeRUQb_r4Rma;UcXPBPS@URHd`bI zlHmjR$Ke<7(f_)$<*d8qAUI@bW0_?4%H$_-88OwA-oLWu@i`z1OJM^lJkK79H@FJ8W) zu69Y){$+q&2N;6hZEodca9EcKF8bf7n@*=gZS8J~V(6g|f>5cVYPDh)Vah}FM=i?u zxS<-{D2k}jSSmU?hvGoiJ|qe6P=v2Bf1_q%V~EG-_L5#7l(bzSCi{t4c|m4|S1aYQ z-i;!KEXk<^<9_YZ+Pzh}yLu}RI~3i`G|7T-Z#OpS$+A-Y!S$yqFX5?vbVzxJw@-$VUx2&6t87gef4Rp4oVs>JR z7GzoPls145udtfktJfo)Pjrm6mEw{@rG$TZ1R|Af_$>JHLW z&#D;$PN!vsIs?Y$ekpOJflz~NN?MdcZnNG^eG(*D0riJa#$fgFlB z$a$~T=z9eXff_PyCz_n+LYW-KCFi|bsqf8Qwxn8YA0S^Qrf|-#Ono?;rQxbI-Zwo^zk`JkRgq?CmUhIK?;t0057*6$E~? zrv4fnY)A7V^vi1ifGflrV(N&Qq!SQ65@V+*3__#!UID^Y#kXbfZ225tu3kZhj;vk5 zwz9gl&0uP(nQUBty4kFa)Sf*j&0M*tPF85rOdJkW#sUjo^L3dcI0J0qxo04_oX*#z zI?{Z`4Z5GP_saBCh`000W66~W|C{uc!xRzgffcCsV#8wIz22w#HYWY5R-c7T033gq z@B?B1{H!c8901ebTh?e904tBCiT2QCKU8bc&YmMkH}g3t(otbU*>~Q07e=Xibs3&m z$v^l&ACy{OaEfTQ81OjqS$(ph|MHhh*dP0p&0UwB$wm*COu1pt>Yv;bISr~Hxt14@ zD&bXFBq+qg^XvBeZWtI9ifL0oZhHnqoLQnB6`J5hNt zTeC9v&C!vio8$Yepik+7Q6CGPEXf<8P^_F<+PiUORn;dFm1oRLEz~@K`vg8CtdlKTZ!zfNUwQi<07A zFiMy=DR}~&xz%H%w`gPB15$v}`X@t;?+6~!IiUS=-fw#!s(oW9@8R{%$N*mP$_tNs zZv@9FE$wk_Ce@>-$l48jGVU;yj0D3zy|;oF{H?oQKBmQQiCIcSK_8F0d+Qtmu|(## z`ij~B@ks=G0@`(%t2n_+%AIVs23Ey{wO5$7oTLbyEQWIsaSzQXSZ!cW2Ir1uy+cI~ zf}4m>X28Y|ys`voHHA^~3``6{0SueHJ&JU-F6+JW@$l!MOJo0V)44ZYf_E2H2S@Q@ zAr9XAy&`F48<*+Pr=QLnx%B$rrJHPQ{pU)%yZ7$kLg#TBkHXmVH4=E|Q^46hu-4KC z&_uK=NA{jN>4Jm8W%)hE73e`@*j-winQ{uUFu6H($Tk4qwsI5?iQ_%`z3ZXtM*Z}Z zhvQ+MwRuy<*d^DR0Ht;Ex-QM$O?1;{8`zLMkn5VqVk~^J3)?G=RqrqX(>SyiZ26959o17 zaTim9KuXXX+dh_O+0Dzqh8yiyHk~|$zA=2BsZiqs#F&1YVlqm~cJ;gVUoyGBH?zqJ zX=S2sPA`pxL>Fc7Sq($kN%~b(#Yxv_;8Ih`2rD3w?SwR0`M^Led{!_($u%kPYAc)n zX?%`&NjNY6!E+MbNCBW@m7_^go+2})tiF81vAB1E-9*?GqY+mbXyrGLs$CES);AK|H(VA^fM({NOu*w zCFYzwmtb@Eff|yd;}!Z$sb{NtVu=tU{o1LAe3C-yZQC&)7N8BWF@z*@k^HNEal4;W zJOrY)=bj^1pY>e#F@>8)JX9a>!xx6xEhN54mOLp>+aP=7owoiVslL5sw`%hKdz=gU zMNO!7J(QcDoihC`^uh6S@xA0@OQ}*mmFC=`s@KCLv8t^ToR9Q;ycvoMPBj+*F{pTn z-<|5$D{(&=%56V;V{{wWWl$D>L>nFFqpCdYK3&y+)xSkif{fTrV8r~97%!fWQL>W( zc3Y)9s!L1ACCntJbt%Y*c}MG|ynlMb_%l9Zz(kfOt>7q{;KokV6KVvy1aqnli zdRTNAt#%Qg-OE3`5wgnZgM1)2{B)~1+}sJw+vQ<`St!xfa~w`lB;Y>)7q zY|HBjz4(>2c5f+!hNh@7@F-JFhihyC}N4 zZj@~Z3%Pt*v}uaQ#XECgVsh(~c&?y~m(Qrm2)*xsxOh`bo;A(*YVEs99`#7fD5H#> zICLebNTN0@XYODZ2~Uylqy$gpj!nDlj^E?q2WK{y7L|=;Ag;cfmow}n8%mQrVwNy= zSCyolG_S9FZ7f z#_{F)_=^@Yg_UkL3!Tq(K%WA6IYS=p_3hd37w$vCi%A;HeP|W9&As|bKow2dggeFR z)_zh&mU?*CCAFu$kxyj?Ss!!dY&>RaLIn*`n|?bb7rCTcok z;{0GiA3}io;KZhwR5#0;NMunBylIsu(X96s&zOh}B5L)HDypnq4L0KMe2cam_i5?A zWfE_Moyv9nse2!V@8yZ+b#TqPU2ED7ce_;Wi1Hl?MCWVcgB{=_x}!50XTsIBpGAGh z23|CE0lE^L#tGD~RAKf{66=`AHO_l^!eIDgI!b>&5MA0*O~;MiGCx9-FnO52T;?li z(VoeDgG(;DZtAc8u!jxbx?xS}!A1>kc~M&K zux@ZuTiVQE&aNdHJ?UBi7Hy>rye+~>CgR6kJG#o34F*{p$GUC=QFlUtYw2nP@3GD1 z@?fpDs&qA@wz}1UJD3Xhb01tev(ZIL;rGshNyahoZK9Qp1@o2{# z3qwU3z04{eY^>Rz|4}Gc02}apUNqN|!`osN1qn+P+eBBe literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png b/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..3f72e4fb4243213c46824af1d311be43584a38c8 GIT binary patch literal 6163 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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..63ba0d8d7fc044ecf2cccf1322d5600bd8931f3c GIT binary patch literal 3956 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 P01ph!?$-PT{`-Fc{LUu8 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png b/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..0d0186a8ae8a97aac14f2c51e51b8f61b35bac92 GIT binary patch literal 1649 zcmZ9NX;f237>4Iw6TAtA)dX-M7p1aV)Ue5tL<9+@5>yte0`aJkMWDDVXf8`xL`6YF zMIi^ZctQ~b6bnKC%VI@Lv222nRBM;W5|w}^Ax-pj{W0&%dA@gM{(SFDc2J-{iMW6W z03Zdhd^c(5X5B#aw7O|{?_2=%+yi{q1Rr@e_B=dx(Qflhc@l55=Q?*y#n!V&o^iwz zR)~+Wq3@)xAyRIq4IEnGr?N_ zsDkf3t?u%oJvBsE9$yP!fCC6H0w`btZi5}EC1y~Ryqh;a)PD!!O6xkzzdzo%6uVS3 zA14+Xr2?3Pz=*d6g3kD&m^eQLq;haDLN{KeuO%!yOk!$vL(9_7>);Yue2~;_+|B`$ zl#X%Rz(nQhy%dqj;fnq>u%VZ(RZ3m|R+e`zU>&N^ga7X)M|HYwD%XK1!7y=7J4U zzbt3ksX84~D9Bc{hEW{~kp*i{mPRGqci#4jMMif6La_RTfCx#jfV=OLLnuV_o-hFU5w192N_Bn9SvibGIN_tUp1QU-D zxeEV2djX6t!o#)9XVjOmX~Ezo;PH1=!1ll~6P7l=0pY2LmJSW}Z5t@omjutLovNlK!y$ zV{HdKvP&H)#hpdeiK!p%CB8lMx_BrtZc^yB;17+NsdRF3 z&fi|ftRxE_u$N9N4h=nd)UzJ9T)Zq4DqLX#vQ9G$1seao()WNYkeO~N6T?^AJz$*s z{&iDwP3h_jn%3z##}wxTiN{&JRzdLh%NB2or-($FM5p%r#3Uctbpz+h{nA$U%0&i_ zHwjf1nT)ch(MgKwr@4$%?81ngv^4*Y4*4GaE5|O~>6xdeo_SNA@bj;pqP8e!>lS-l z6^J;s4tuqzSs6B(U8fk`yEZA0-n4plG&pzSR(S5hx)Z{LJeLC{!<(BDwSChI-y6CA z_BZ(ph3wUc;PL6(fz?*=C(7HRoo5jdCF((7x>~jx>Y(O~>s{s3_}$DMk+#sj3Y%ez zGXOyU$tMPwX7B)#*_j;hGTJ-OQVc`?gctj_J1c}vZO(B2{sP_R3p_?abm?whGT>uw zd7c!NqCK<^^g#plvys|jrx6CU!8i!^O=;{wEi(gbMdOT2?lSB_FjiAb+EO;CwfR+9 zVHDQF^z^Y@A|P`M6i|70iFU;#Guw4_VpX6kyyvPL8Q5d?*r^(k&UJMRSKnRumrF#0 zSlEV#`MThR0E<1EZafP0c{6@-RT;}V@)?I+HT=HhE{f`+W<(XjYo&gkJ#7B0xi2AH zezNTC<}WD$09WWpzTHT+;HuJl94(tybQ_rL|ed z2$>;mBjfSP1%5B{B;VF&&=NLOv&3J`sv^Si$Koy)R@qt7y|NzeTA~_4nac>5#oZ4g z9e)h$T^=mz4<$?M^agAxaY@Df20L=>nRi1GSyF9P*Sij%nf`Uagu8fO5O4OyIZsur z6(FQD8iBRZ>^t}@bLOc&6P9wE{)PhzT8s4C+mdo1Oqn#raIKa29uq + + #fff + \ No newline at end of file diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns index 067233f31424079b84ff1a367f7c5806e1f08bbf..aecff570e843f7784587c0a9034b4061807e109b 100644 GIT binary patch literal 52804 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ℑ)M5jBryY;mb5KA3LvBB9?m<>eUB44kzXZ zfScV^asiSSCdVjAAbXAkK>>I<6R`tV4ipeIQ65dyB%d#fxwVz0OaoK*5Tz9oGR z0_1LOJ%AP!o@?!=iuM4h$13nsg41rZk!|o_82|1%bW#pDaHS^Lae4?lVZx~#6+Kre z1xTRhRo8`Zro)jRq4!P+!#Ga_mQp|WF+&xr$w`1U9jdyzO8^He1(3$(&wxF#qXnLp z5&=-Z@0ZyfAcDXo0gPDFp|-eBz$A`-g&LB^-(V#No*iviER<~c-UKXg*8o6{@Q~y` zBp~1quuQ;9|9$e$RQ7A8SU>TBZ8e;Rk%E9n=`OXI8LuU-Jh0dbrc+!brz8U09!Arf zW*tf+^#&d@jKPbFj#m;j&RYrL%3QuXPuHE0kZ=r_Js&zA_L}%qkRyBjv4tBN(9kFdI|i|k3i1vxYwMgA|?{m)GN7hU}?^#0F8$e!wrVP_tW@vu#z zwG8ySkNStu#1sI+o!17rwiGR}gQcEk+{Y^(VbaivD}+gdGFHRObW+;&AislG9c#ZZ zlpE!6a&j(PP07s{3=JiCqRv`RgGGHlpWk%DSr?Zzx8h@jI+KPZHQIE!^A8#P_Q)wE z0Yn#f3X~8B6oe4{Z-fwo?1aXDlOTYuBWY`Q<4$8S1j=d)?dnoobojTZ;L7o>G!Uw~ zT_@}%IB4S5Di1a!7(&}s$=AGBojKgjU@Agq(5H3)!9;Qmm$?S=j(P2pUm*g7s`gX0 z_8B}SH+_P)=f4!2SH8B}n=zfAfz6%Oz|@pDxpc0D$k9M0X!>PHgiuL(Q*%`Qa{C_aP z|ACutx}69kM^AF+6P%{8AQE69JW73NZp}}25XI3`X|+eq4gj6JX;{a#PSyZvHFfnb zfA-1S>`aqr9X+oGi^b4W+;IR1VdB^PqTWSET)V-S%HvlAgV|u?MfqEfF+)DoWFCs(-dJNlf^+uRL6tu)T(l=Uir+M7ASQjpK9Hb+8}-(CXV6oF`Ba5XFQ z!2>xg)F(s;0t$~?L(Evcm7@iLEGW2u8WyOot1FnM8h+HfAXi;A#VXX}e+@*)D~EBe zwLt78KRi=is}Q zr%~V(^5DW395=&AW68*%B6PIC^a);T1OJkc*lL{3Oq(67Yk=K7^z^80uwfu+2S8|H z7f(}-#V!5%$=^AOv9~2zC#U*-;MRoFYa@)1ZWmwaj4!w-US6&R50|4yq=3Q~v}vdT z(zD`IVKGt?XzTb6em-EmykO!Y-MYmYUGBfx!Ki)(6PY zaGKI){vFh__!SLFSXG>n-+x3vI;!#cZw&OX49*8})3P3Z_$q4L)O2HE_s)pkl(QJk zhVNa%E6MO0IQz?+&I`PTM)@um6VaoN?&{2z9G@sAEAo#v0dkGRM2O#TOk6QuT`Og_ zoMo~K3+s2n!s>|Q{ntrQOOLT#z58I`$|MH<^-K?|gv~I^+Hh1qvrR2CZQRK7>|*iL zDk+%>3)i5z2|(*}CC<3k4pNsjR^!Z33wyJ1Ff;O8h|%Da0F*2}WQX>^XNs2K2KFq> z1T)qc(!`I$CgRl#h=p!Y64D;r}1RPaTKeYDRAFVcp%CllrUN>5$l+#@J6 z@u30$&|7*qUxJOk2IbnS^luN5@|p9hEXI3YPP{0x!7MEJz#q^__=n48eE-=+gS~qC|0BKJQ@Vhne6Kc*lPxD};Y2zt)VhkeL zZXM*zu+W11Ep1kCL7h<#RR7VQU5xkMf#VE~F&c|oc+Y;c;{=Uay$zO9>2N9b(cO*1 zhFZSC7Jz`2tT*8KT&b|>CEKa&3hdYf4jNgwi}LkCC?6I75CsrN9T$z+z9@0 zpPHZA0GLNE8P>autVib^jaTk?3qJt?LXD;Pyb+$Bt^wqH)$;DZdN*EG66mZU?&g5g zwc|r>Ufz(NcO?QIMT|p6r@z)ycQnF%zd)waNuYBQAonFrz0cHBj5h%rV|s?UleeeH zDKF%aGZvOjg{X0!wV7&d4VnQnY}0`0og*h>zV2OsKys3qXsk#nUb+ki_TTSkflLXU zJ38z$Dn?daQ_ApqTWla`IQ1gX(d>Owr2zj`5@?m^9<03%qNhIB0)|-XOg9HCd5U4u zt0jPDSN0FT2&X|w(VSlLY^U%M2w=}Hb;p0H@!q~D2x!M26Xg1U_>4Ysu};IEXDy}y zmQG8}*baGbv6ja`T5Tt$rdmYB+O!#;(=3H@ap}a?<|Nbl4NS}8mY0`zKOxwDpPtM{ zrSIPuyIMY=3T7lrnEg1;1IwZSoC(9?gY3wr_8UF_y|s zfJJQrr{n;1WM<3u;Tx<{!))XL^JJA(&nD|}V*e}+;=yjzDN?#({ReDQ-P<)*EmTsU z3_uhPoC!u*ev*=K?+K9^8&EHvu=O$w5}Q8KBLJ;6d#@x8Y78sge6sW>mE{2->xVi- zvA|e8*wymz*NpbG=oIYOXPj$%VE8OhRrB4qzaez~mBAjWq`o5kd@k~Gn+23WC)<&$ zgY{^yQl-o3n(gWNyd-b6$0_GVyF!Fb%~A+*@67u}ifc*nR+nM7CItxCFWE8|6Me`z z0KOr5)QKWoeazD1s~&A4f0IJRh@G~}%;CW+gV~KP{Ee%bOB+AR2mu@tjZ4nz5_lVw`^|Bptc#O`nR%wZw4|tZe3$19!HnFgD6AlFZ@2q+DqqCmhx=?u)^&oL-^8=I0YS!0lfo_O=h-5aj(u4a}O+a zXFACI9Xjac$U%h$;bq(fg17l$t|x0cJ}b^L9WayHZ+!q>2jvc3As1l@S)C}Er`u+R zr`>2@N;}{t0fgezPq+I{)PmFD#zd*HTQ|nfpZ4>(6yezUSF-u3#hw9iapy($N z$_{mj*srShz@uL7s_XPrKAah)$9tROPk#ickAAmQmwENz?x5D_RH;Z&Qo1?52x43#8{qd=JX4{BEt{ z?lylq@LAW)+?xvwTg}efB@&?}0a=upoQS7l{B$r}VDsej6X%2Z%FpnUpzW;Rr@?#W zwXhmh%ku^`u+FPZA1kIs-h8IPFQs*q5w>i=`Z67Sl-1SXRi7S&?-=jadx#(Hofb8? z+WkgKCp&8EZxt4Y^O3nHAvPkpv7d?D9Ss4fXa6+T%d}npG<%H@RwwA?0CXtb3-Y0o_6z;Dg(vjbrxDYu;jG6GV$T_A~voWZZP<8G4XRxCICll08OR*0)za z(&Kq(U@i3$==WdL@SC$&uZ(lYp>@(_EAjoiY`Ztm-XF|m>{Q01Lokm&&3Z}ITcY+Z zh6pFZb{>P-NnuGzh6HFrk)}>4SX)Qx(iR2aW)lGxJLr?jmNvr1bw;c~_VmXF+8c0! zwdOTl*+qcFL3M0|%rB$0GR zu-btDM)YpEdS^z)1X>bjaAV>Wyzq(suMbhw!6+uHHtn;w{J^LDBVsYv{y4G_ukG>@ zodaB5BHMfR{Uxz+(IXQ7HsZBQz@Y1qZT6Q9aoeHxrOL2_#kfv?TpU}|QOc8%%Xm#^ zHE;>3P@H=@pYyI7ok@fDZXV^93eFGXG|!R`Dj X6oCQL#tpot`M##^UOut+M2Hh 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 r3G5F9>us^ADHv#5Nw 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 diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico index 95a986b223861861a21c0e4d4142c5c7e1c365e2..c9dd1dc835e863f55c020c6eff70c6a91a4d06fd 100644 GIT binary patch literal 9498 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 F-vAdw)Q|uG literal 3689 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 ON5I?TpgYSgEdAeaqSwLz diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png index 067233f31424079b84ff1a367f7c5806e1f08bbf..8e57d01ad83abbd23c94ffcbb8817cd0a5a197ac 100644 GIT binary patch literal 10175 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 afhyPoK7Txcz2Y);z>RAbSF0|&#r+?8xBz?r literal 30855 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 diff --git a/src-tauri/icons/ios/AppIcon-20x20@1x.png b/src-tauri/icons/ios/AppIcon-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..d09ccd876b264027d7f834758d1f4b3709824726 GIT binary patch literal 468 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

yoLcwop~l_2D4R_H zdtX4SEv<*?$+H(++a|x>p|mWUQ2~giF>$}P&6uX?RJ*>K&U73X+V&V3H&Yub2kef9 zW_tgjpEO3oeDhtaf73S1+~T*tvSJzC=sqW)@ycq#6u9g?(3XKsr_%)s>uA^(3}AW3 znP9cvgAl--m#)#%=Pxs`K@krcuPFSIaL9@AaeL#|dK&yTEF4rJYj##=21mAdA@$t7 zOd3KDyfG8*D_F3ed4mm%VAYEkEIrcKKOmk1#wdW|`YFau+}1~jYri-}{uo^VSL;>gYpYe3hFAgBjmE}hanNDMP^t%%mv&KqF zipekxDbR+D7zk$(kH@H`xsf8_Fi+~O3^c~OuH538-VlXCp`1e-vb^eKEpA=oL{}} zrQeB!6m3fZ_Mj&wCw(;;iG;l=T(I8Z^i&#eE@iu9Xg@H(06_?vS6WKP+7D4Q8WEw$ zgU0xYj(A~tt zJ5Tr2YCf!h6|e$UzzSFaD_{kzfEBO;R=^5a0W09b1UALuopW}V@K7H~(pKT+?mRFm z<@>;yjd7Y@6sk*OmIBO6TWOLn!ed)B7Aq1v{!ZnTvrLO!2UNPs*brwGtLtnTl{|n+ zr6zpGB9Vw|+LZG}L<5!NL&Kvvf4a~lssLz~b!!Dj!Su1)3P%jmjtctUM32coGJDnP_pf`D};7uMkr#E>37Ks49z(8HiI&w;< z9nUSpd;d#s?A)(-Zv~473r4W|HfnY9hKN%^Zq%Aft$2R`_R2VOx4)h)00000NkvXX Hu0mjfHrE3T literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-29x29@1x.png b/src-tauri/icons/ios/AppIcon-29x29@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d8d0c910f47cfbebdb51d3754a6935248ff9c8 GIT binary patch literal 606 zcmV-k0-^nhP)f$5v@6lv1gPD{Gv|szp&*42__?-$ z$u}S5^7j>%%^t(82!*Qg_+guTH9WxXwKl`HZ7`|g^OtWJ7#am*9L1sow}W#_uRHbb zHM*WZ1^cnOF1vgC)gz`JGB}R=P|G5yR5OWB^C?(4$3M2YwavT&QmD;TV6KJj{Q51~ zgZ2*T<{6fA#-b7+W9%OlCP6$=$=j-oKc7?Pn}(=FW#VRBB^_mY5$V4fW3|ErX4?+J z;SlC#r*Nmf4!iq*(9`zbZl1G#pi7=v-sbs49yQ*)Qk(Yyvfb=bM0&e;Fx-1C5?f?J)07*qoM6N<$f)6brmjD0& literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-29x29@2x-1.png b/src-tauri/icons/ios/AppIcon-29x29@2x-1.png new file mode 100644 index 0000000000000000000000000000000000000000..abaf338e0e3ae50ed33b791fab8f2b1d4ae16bb9 GIT binary patch literal 1117 zcmV-j1fu(iP)*kUoq~Q$IeXKUr%O}O^kv%!_H(Hnlzzd=hszJU0wZ+kgCym zvmJ-HVd!z+>$i0I+AX?!@4kH5`-)|AKWNg_l4y)Es!ArQX=z$++_0YQ+}=#-#r4xz z^jr_rvMdrp(D3jGo#;3tySlHkyk%=RcS>nNPQul|=%&djv#UiOIdqU!RFoH(3ZULU zp1tU$wgc@n@bN3zwnYXbAhJ@k&Ua~-sDc~b$FS+*@krVw&Iy!Za9@cs*08B=JOQ{;~dnPmCf4SqR6f4UddS@v^s%mG(aQ_s!cD zk?@FYE*DA2Nw|cpPLz5w@V_i8XqGe)a9o)2J&FuyKA)#)Op4tUB08Y3X5IXGIyIYY zL5v5#4UwZZyHJAy5b0QXc{yFWc$U%)^)xy*ii4GgMl@`0-9zu*_fuI}nXhgfj73#X zRaGe%Q};sV!VR?;Mle}Ykcl=L+|+Sg%h{G4*d88OFtQ!H0PI!-xE=?!jf;Q|5mY<3 zMh{JM!gW)rDl*ieUxpnN!3EZ{l#8A`eU578RO`xxSK}EQ%TqR+Q)fr+|5`V$UK@z> zncNi85|tXc`Y4~V7>3ztX>Ef zrF~S4TMX9qtPLwN7O`X6tT~UypfP9+8iU55F=z}LgT|mSXbc*I#-Jrt9P`RSMRg$= z;rmgqru(})(@=wYmh}DtGDukgTe4=I^!o<^m2Oz1uOl1}RCSCYm-VXme*V6I-t~Ld zUu6mw^6B&5=@wLM33V^(uM0!dTS)?<-bat0Fu(N#6%~nJmgfDu?RFQCDdBRXG@xAe z^sauoFYZL$yV2tA^DT%38yF49v!Ps8&k;F^9GFa1M+Tz-4Lao6oQr}iI}(|YV&ST1 zcDG0{&K_YhWY`#7IDbmZvoRsemc_G!0W4qw8yF4f>9LPNdkzgcRzZ&6VnXj4WcKne z(G|~1T6N4cgQuql8yF356+Bp&x-HYH_BYeL#4NtLElHKN?&?{gw%(iBA;I857JUvv jq5i<9Qty+0`oQNW+P?)b=ADa-00000NkvXXu0mjfTL28L literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-29x29@2x.png b/src-tauri/icons/ios/AppIcon-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..abaf338e0e3ae50ed33b791fab8f2b1d4ae16bb9 GIT binary patch literal 1117 zcmV-j1fu(iP)*kUoq~Q$IeXKUr%O}O^kv%!_H(Hnlzzd=hszJU0wZ+kgCym zvmJ-HVd!z+>$i0I+AX?!@4kH5`-)|AKWNg_l4y)Es!ArQX=z$++_0YQ+}=#-#r4xz z^jr_rvMdrp(D3jGo#;3tySlHkyk%=RcS>nNPQul|=%&djv#UiOIdqU!RFoH(3ZULU zp1tU$wgc@n@bN3zwnYXbAhJ@k&Ua~-sDc~b$FS+*@krVw&Iy!Za9@cs*08B=JOQ{;~dnPmCf4SqR6f4UddS@v^s%mG(aQ_s!cD zk?@FYE*DA2Nw|cpPLz5w@V_i8XqGe)a9o)2J&FuyKA)#)Op4tUB08Y3X5IXGIyIYY zL5v5#4UwZZyHJAy5b0QXc{yFWc$U%)^)xy*ii4GgMl@`0-9zu*_fuI}nXhgfj73#X zRaGe%Q};sV!VR?;Mle}Ykcl=L+|+Sg%h{G4*d88OFtQ!H0PI!-xE=?!jf;Q|5mY<3 zMh{JM!gW)rDl*ieUxpnN!3EZ{l#8A`eU578RO`xxSK}EQ%TqR+Q)fr+|5`V$UK@z> zncNi85|tXc`Y4~V7>3ztX>Ef zrF~S4TMX9qtPLwN7O`X6tT~UypfP9+8iU55F=z}LgT|mSXbc*I#-Jrt9P`RSMRg$= z;rmgqru(})(@=wYmh}DtGDukgTe4=I^!o<^m2Oz1uOl1}RCSCYm-VXme*V6I-t~Ld zUu6mw^6B&5=@wLM33V^(uM0!dTS)?<-bat0Fu(N#6%~nJmgfDu?RFQCDdBRXG@xAe z^sauoFYZL$yV2tA^DT%38yF49v!Ps8&k;F^9GFa1M+Tz-4Lao6oQr}iI}(|YV&ST1 zcDG0{&K_YhWY`#7IDbmZvoRsemc_G!0W4qw8yF4f>9LPNdkzgcRzZ&6VnXj4WcKne z(G|~1T6N4cgQuql8yF356+Bp&x-HYH_BYeL#4NtLElHKN?&?{gw%(iBA;I857JUvv jq5i<9Qty+0`oQNW+P?)b=ADa-00000NkvXXu0mjfTL28L literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-29x29@3x.png b/src-tauri/icons/ios/AppIcon-29x29@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..e89c37845aae84e8111e1a4a71f0324b091c781c GIT binary patch literal 1524 zcmVH{CIhJg+{ObNZ*Bjpr3#FRZmP#QDkmjB@zkRs%BXh)z{VP z=B7q^_@M);{n%p^I{GO2{nhLEMxKaM& zvUSXSUcRM1cjMmO)bZ?7`t+&i)jc~KGFTOb8;>W*=S%K5FgQf-y!*b6E-ow0Z=xyn zH6J-V2Tx$%e5GnjV1&p0bRVHF%;1<7?Q}{O0Yy?;sj0K~pBY z93r%~QQg`$MVPx48Vp`=wNW+{uw^IAP|b1P`p=J+?Y%jd*%iw+QQpIyB} zm`Lb^jL_Vs3xR;2?~yU&vVh;8ip5&smg=qSmBv$Fef&^=gu_Q zRaKrG2CJ5Xt)2~9(dc3_9OTSpH3JU@12X(|WA*iQl>XMMtaDgudn_LF>@1b1;m*%5 z@JUM*$YpU=p?I!~a^vAc2e@Wnrl~U`gX6f^{`<8*Xk}$p3OA+B`U4s=g#HiusJUq` z<-fWxPREX)pg(U+c(QO~dAqg{&sYGHo&UxWZ)Ffs`Raqftq4RZ+>lIAiV0kSD<*IS zuD}%&xB^$;iV0kSD{#dGuD}(zVggs-3S2RPD{#dGuD}(zVggs-3S6aN$T@MBVsb1llytt;v_VU`Z%U4EB1NJ>Rt{hJ` zrNnkDN=bHL_Mn?QaOjBkYWu5&Xf$=ml0)7n7)RCZ)l+elcCz3(rkFnqbP5=vT;0KOQ zXiW!Ll!CWmN)SrnvET-NYX#>DD*0XfY?$8edrvPKNtA>r z`DG~i1q0RkY|j~0vXY-@P?o4cX~qSoyI$D11|=0xPlY7P$mkfWr%q1YQnQgc67|&l anbm)J%mpSgYy5%$0000hmA*mf7?_J_Fv|H|oJ>*GeS?9qYzq{|d_nsX|=KDSz#{t`;g$kZL zeSvrHSJ3#=#4s%5rcszagt_x)aA~fj=0Yand7k8(wa;I0?fMP5{Pu$&W=I)em?nfp zL!fwMTHd{VQ%p_nSC9-N8SYf+ifnnFfP(9c;Q|UZ=z>%tA(tu-6{N)v*>enM(Ze7J zh7QNZ@8owg1G6v_&)bFK(emTP=Y%fNZnqJ&F(iAkx?U6eCdOe0PPY8@Ta~{7akJXS z25gbcl}RXwpGnl~bvVNcC4(5VIVM%OebbvTV}Km9`pvfO_yDr^^7-7B7s+|Q8x5t% zNC6p$1;*jv*}^^Ka$^dL!&T|xRjhve1UHpJpt0PJzSaQCvM|1P4>B3IxBqOKQxAn+ z1hZg*kSv)@>^!!5gc0sR24R7`di@63?5^$-2WV|>ssun+&Eml9acSZlZ8lq5Fyu5h zo!$|8qS=G86H*RNP10Tzy}9qz^-j7ZM6@dQeUAh(ftQQ-k?*S5Cl#MOdl@UMYj9ms zaS*YJ88l5x8fN7Qa-n5ld5r~XmCN;|YAg~{xsjQpPW*co8*-l6v-p462yg^A0vrL3 z0L_%JDnSU_7rx()5uog({JW`W3adFaXigf)`LzLU+fo(WtvmBbQGwL)qD1Y-PnF$h zXVkODPDtJE0z=g6zf|=my4gZ*EZg-Wv>KbvOyMxq6U%BD2K`#jWVov9)khMl^psj% z3IS%bE}T2vSA}VG76^#Np@s%re^tnA7Wag??aIp%X2g+(6=vwRf|)J;Enu#^_-3i{ zKon=llMvd)_P}X54Q2@8dQJ2={Dxpb@SfZL8{#kALv{S&yPRhL0000hgMTxi%n^Xs3^3O_yMgx6h9CIp`bokE4X>E;)8-u zf+F_C540LFf}&us)GBBnqy?);L6mBwNounnCCScs{&#l9Np@zEwG?kN=Pb+a-kE*a z-`;c2IrpA>uI;f9wrJMRU)8Nhl8r*R+6$^zH7A@ah3=kh(e&#HTW@ak%+M93D`yYNn6XzyL@dMZW zudEDs5flv4fATM+()x9D-`%_Dk$rn<_3BmBa9y&R*AoG{xQW3*MnC?P%76ocGz&n`Mte!2ys2B?uYyXIs2576i1$27cu)it{ks5KzoKDeD;edUF4s6)HP z=r$pt=K&r@0Z`65ywE0~7cvvD0i!503l;_j17lvGwrCS+^-917jKB)a(56)w)^_05 zA)2XFL+T>&>I_-cQ>0^Gj8YH3Y88g7QmtLo1Eau8S7$JSX98wgg)7yn_VZlso>{fF z?Fblw6__Ewu*Z)c*G{rXdje*N&T^%zuPgub^BLA}FLWS9(#5ir#}16@?ChXiVNIz# zHT}0A%ZRiQJ!{MC*?&y@wL)Xt%WF&^m{hTAJP?ZfCyWGkwsf-8XnOEZ;J* z0nP2~aOnPr9;fe4{6Gc1$6u=vfT3dw_3Z0iPmbdx-i2$fLF1rhT8K0|H%Gz3O|T{t zOsj`$5n@D=L-fEvsF*caabv^}y!^3cqv5MAj7ZP}z2-%vSBM{&XhM7+uczqeqa@{` zmx zTqLq~?V8jKD!srhDxBN{_2PaCpAL>jqS;XbFai&%dHuB;6Bqc=Lx21IEY<2r0#E`l z3TBQYkP?S+V@D2CzPp>E8Dr6GsG&U%)A4V=ry^TxiG}0yM3*%$D6#Mo6Q)rWHaTC% zGB8!S?OAG3VTpwWpojnzfC5keiU>dfC;$bZhyWCT0#E>o2tWZS00p3k02F`%PymVu zz|5rh#$_f%b7KS`r6(CVwi9mYipx&$tE&mX*qjbzTTM+*a~5jBPcmPW;)~osT`kC< zj;J=?u+^B{odtX47H9c-elrp+-kq%&hI zR9yA4o9wIlO5QJLepRNVkvWcS{C;8o4^#wpR{xEgR8YCml>ET7ry*O?JTTkRzlp3{ zc5c(#3Z!aLTke(uv%wwP6ayU41y@Dd6EFiitH4GC)oM|26$7*gEm>C;tiTNH!UBxj zZyTly{3-<)+bqBcp9*iv&pe?EtzIeF@&8*vT4pqI@JY=K>?~|t<$%(B7oDO#FI z08f`i4kkB}O2L0L_8C3*{7acH1z#+5Yx{s9F0~YV(qROzAAXzO`(P}yhY>vb-~-xV zEbA}=N;wV##cH|eDj$b&x_KN%jaEuW435JUtq(HTb>%Q_C@AH;#)Rk_aLOaK4? M07*qoM6N<$f`SN<(f|Me literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-40x40@2x.png b/src-tauri/icons/ios/AppIcon-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2f8bbb15db55006759788e5b3ee343c708b32a74 GIT binary patch literal 1406 zcmV-^1%djBP)hgMTxi%n^Xs3^3O_yMgx6h9CIp`bokE4X>E;)8-u zf+F_C540LFf}&us)GBBnqy?);L6mBwNounnCCScs{&#l9Np@zEwG?kN=Pb+a-kE*a z-`;c2IrpA>uI;f9wrJMRU)8Nhl8r*R+6$^zH7A@ah3=kh(e&#HTW@ak%+M93D`yYNn6XzyL@dMZW zudEDs5flv4fATM+()x9D-`%_Dk$rn<_3BmBa9y&R*AoG{xQW3*MnC?P%76ocGz&n`Mte!2ys2B?uYyXIs2576i1$27cu)it{ks5KzoKDeD;edUF4s6)HP z=r$pt=K&r@0Z`65ywE0~7cvvD0i!503l;_j17lvGwrCS+^-917jKB)a(56)w)^_05 zA)2XFL+T>&>I_-cQ>0^Gj8YH3Y88g7QmtLo1Eau8S7$JSX98wgg)7yn_VZlso>{fF z?Fblw6__Ewu*Z)c*G{rXdje*N&T^%zuPgub^BLA}FLWS9(#5ir#}16@?ChXiVNIz# zHT}0A%ZRiQJ!{MC*?&y@wL)Xt%WF&^m{hTAJP?ZfCyWGkwsf-8XnOEZ;J* z0nP2~aOnPr9;fe4{6Gc1$6u=vfT3dw_3Z0iPmbdx-i2$fLF1rhT8K0|H%Gz3O|T{t zOsj`$5n@D=L-fEvsF*caabv^}y!^3cqv5MAj7ZP}z2-%vSBM{&XhM7+uczqeqa@{` zmx zTqLq~?V8jKD!srhDxBN{_2PaCpAL>jqS;XbFai&%dHuB;6Bqc=Lx21IEY<2r0#E`l z3TBQYkP?S+V@D2CzPp>E8Dr6GsG&U%)A4V=ry^TxiG}0yM3*%$D6#Mo6Q)rWHaTC% zGB8!S?OAG3VTpwWpojnzfC5keiU>dfC;$bZhyWCT0#E>o2tWZS00p3k02F`%PymVu zz|5rh#$_f%b7KS`r6(CVwi9mYipx&$tE&mX*qjbzTTM+*a~5jBPcmPW;)~osT`kC< zj;J=?u+^B{odtX47H9c-elrp+-kq%&hI zR9yA4o9wIlO5QJLepRNVkvWcS{C;8o4^#wpR{xEgR8YCml>ET7ry*O?JTTkRzlp3{ zc5c(#3Z!aLTke(uv%wwP6ayU41y@Dd6EFiitH4GC)oM|26$7*gEm>C;tiTNH!UBxj zZyTly{3-<)+bqBcp9*iv&pe?EtzIeF@&8*vT4pqI@JY=K>?~|t<$%(B7oDO#FI z08f`i4kkB}O2L0L_8C3*{7acH1z#+5Yx{s9F0~YV(qROzAAXzO`(P}yhY>vb-~-xV zEbA}=N;wV##cH|eDj$b&x_KN%jaEuW435JUtq(HTb>%Q_C@AH;#)Rk_aLOaK4? M07*qoM6N<$f`SN<(f|Me literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-40x40@3x.png b/src-tauri/icons/ios/AppIcon-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..752956f266e7d22c460399818cc9bca452e3345a GIT binary patch literal 2044 zcmZ{lX*d*&7RP638fD09sh1{_WS#8GSi%^FFj;G4-}l{!NV25jwUohNOohQnlBFz7 zld;7ZF{qf7?31!&i7>BwpZB@<%e^1Y|D6Bx{J)&vhjZ>)qfvZE#f}0106udwr0qeE z{a5iEK2W%~<}d&NrkNv+>|@8j6M};6O@w;}>64+0+_~vC$VZKPU)8Ga^4vuzUM|0= z>?tgmnVN3s)p&$*p;-2u$coXBwTen^AXl!vJQptMoToC-W<=ok^Tb2;3$#0J@r0-! zjOU{IFTaOEEIjJ>ThQm8w-?B1GcQ4Fm~-D?M?{=NH~SrF`fr>DyHc%p=< zJj9)ndduR{;yqNi%E7+}VR4!*`tkd(;2EEe#v^W z?!S|{iHYd`K;nIATxGmAx@9^CG?FkrZhfg?xe$KVTVI%!pKb7{qUQa%+EFkIYD+zX z5y$`0;OR?0Uk0jlI{!L{AnUpkSKkvdVC82CRhdqG^(rph0u5{y7p-f#HsGe1A4Kw@ z4siFj$4_mf0bbQ<`Q4P%{Xq>2)nqYr#mOeYW=m0_hLrqZ zanCnPMh)gN379%vrn&^rs`S#*s;In#=F+52uz;FVT^&cO3DAD6x$TiteR_c=TKEJE0%Skj$QM2VUPmDI_gL^K ze?4si4;2pCECFIi%kMT$e}bt8+E0P9IctNcg8X5!46*D}{1&s&!nFTQ1b|fXSG`>) z)cs}T*I7q`io*RjU+nxF289B&9(1@Dvn4CB zwa=`Q0e^D2^CU?EZUZp?TSWMrQU=d;Uw?}xoA%vQ_^wUCcpbj`M=x$ z8w2n^F#ea71RVYc)jzTSZ+GU4B4ghQ?#UZtf4vOo`@_VJzi)yB6|;hu1ocHUr?cH| zsMX4$=GJIwX*N2m#=0V{AM(m}ckqd<`n9cQIWWymGM>L6zx91y3b^gc!J+bN(P=g2 z)B~;H2=ouVUIKaZe8`WC-nQV5SoY%g0t3CI#0}S3@YbSpCwS0aWF5%<3eFIzM;4}Dc3RB)I-)d zM~xQ0jF+-gZx}u9@ACa9NFj!H{aauG5zM$`+4}r(=4F`E8L1>=XMtH4%>9qGuKPR= zc?FK&q-Vhw;h52%Cv2QhS`iE4VZ^pX&iP~;hvIV zw1UJJa`~;pOBnjF*c0?JHQ?0K7h-H59i~Ptruxykh9#RLTd5vnXFBy_JuWSDSrny#;aWEvSig=ZGrB z2esXietf`dy_?S$^V?s<6)R3^V)=u_x0^TUk8Ppk5YZ{$C5d3kpY4p&k6sohWI|jk z_y0r`uM<=}ZYLQYx;^ z!*<46g|qEDd2}vmDhQvw)p$r*d%PDYm*u#N8+Zns&=;wD9aA11jb&yLVEd(GDdYje z_d1CDXC)BejE5h)V!1wnKWlvra@9p6L%jX9sp8mwz7wjp&GPP30%?jSLiRE^hnU-7 UIT$jMc<|K$<|b(5Q-pi+-yrqZS^xk5 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-512@2x.png b/src-tauri/icons/ios/AppIcon-512@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bc424239f880aa43b5de5478a9bc1b7b91f6213e GIT binary patch literal 14811 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 li)2zH{aD-Zo9kqTmhhwQ=R`ic$< literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-60x60@2x.png b/src-tauri/icons/ios/AppIcon-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..752956f266e7d22c460399818cc9bca452e3345a GIT binary patch literal 2044 zcmZ{lX*d*&7RP638fD09sh1{_WS#8GSi%^FFj;G4-}l{!NV25jwUohNOohQnlBFz7 zld;7ZF{qf7?31!&i7>BwpZB@<%e^1Y|D6Bx{J)&vhjZ>)qfvZE#f}0106udwr0qeE z{a5iEK2W%~<}d&NrkNv+>|@8j6M};6O@w;}>64+0+_~vC$VZKPU)8Ga^4vuzUM|0= z>?tgmnVN3s)p&$*p;-2u$coXBwTen^AXl!vJQptMoToC-W<=ok^Tb2;3$#0J@r0-! zjOU{IFTaOEEIjJ>ThQm8w-?B1GcQ4Fm~-D?M?{=NH~SrF`fr>DyHc%p=< zJj9)ndduR{;yqNi%E7+}VR4!*`tkd(;2EEe#v^W z?!S|{iHYd`K;nIATxGmAx@9^CG?FkrZhfg?xe$KVTVI%!pKb7{qUQa%+EFkIYD+zX z5y$`0;OR?0Uk0jlI{!L{AnUpkSKkvdVC82CRhdqG^(rph0u5{y7p-f#HsGe1A4Kw@ z4siFj$4_mf0bbQ<`Q4P%{Xq>2)nqYr#mOeYW=m0_hLrqZ zanCnPMh)gN379%vrn&^rs`S#*s;In#=F+52uz;FVT^&cO3DAD6x$TiteR_c=TKEJE0%Skj$QM2VUPmDI_gL^K ze?4si4;2pCECFIi%kMT$e}bt8+E0P9IctNcg8X5!46*D}{1&s&!nFTQ1b|fXSG`>) z)cs}T*I7q`io*RjU+nxF289B&9(1@Dvn4CB zwa=`Q0e^D2^CU?EZUZp?TSWMrQU=d;Uw?}xoA%vQ_^wUCcpbj`M=x$ z8w2n^F#ea71RVYc)jzTSZ+GU4B4ghQ?#UZtf4vOo`@_VJzi)yB6|;hu1ocHUr?cH| zsMX4$=GJIwX*N2m#=0V{AM(m}ckqd<`n9cQIWWymGM>L6zx91y3b^gc!J+bN(P=g2 z)B~;H2=ouVUIKaZe8`WC-nQV5SoY%g0t3CI#0}S3@YbSpCwS0aWF5%<3eFIzM;4}Dc3RB)I-)d zM~xQ0jF+-gZx}u9@ACa9NFj!H{aauG5zM$`+4}r(=4F`E8L1>=XMtH4%>9qGuKPR= zc?FK&q-Vhw;h52%Cv2QhS`iE4VZ^pX&iP~;hvIV zw1UJJa`~;pOBnjF*c0?JHQ?0K7h-H59i~Ptruxykh9#RLTd5vnXFBy_JuWSDSrny#;aWEvSig=ZGrB z2esXietf`dy_?S$^V?s<6)R3^V)=u_x0^TUk8Ppk5YZ{$C5d3kpY4p&k6sohWI|jk z_y0r`uM<=}ZYLQYx;^ z!*<46g|qEDd2}vmDhQvw)p$r*d%PDYm*u#N8+Zns&=;wD9aA11jb&yLVEd(GDdYje z_d1CDXC)BejE5h)V!1wnKWlvra@9p6L%jX9sp8mwz7wjp&GPP30%?jSLiRE^hnU-7 UIT$jMc<|K$<|b(5Q-pi+-yrqZS^xk5 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-60x60@3x.png b/src-tauri/icons/ios/AppIcon-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..47d80fd858b906365aa32e179d1094052f3b66d0 GIT binary patch literal 3247 zcmb_fS5Omb8b!T=s3aDUrWXXHh!91Jgla+}K_C=G0cjFx(xgQQy^115KtKo(rAP?~ zgccARu*5(JHPnDgNgxEJ#ZY8%=gys-+1Y*ChyR>2-_tkqpE+l~L^IQC0*A#8^YHKp zAPfyG_L%Vd9pc?XogQ8l9-gB?2!pFP9*!+x1(I$I2}SmX`D`FZ?bnUdX|Y+J?^3z}ELN*1J#?8B%*n^te+Cyt5*izy@bBlJ zRB~FThpl|Bs3t9_Euxk-pVkI0s*kogmlEoi(hu+fH|O=4=|;sx<+TtGkMh~1s6fA< zot*xQce9h+MHB?26RvxCnQXWYFbyl8Zu=ijRLG#7zsJtS_-_HMiJ`?8+`a2}?ROpr zV`y3@{=h|a6ZO~;(mxb!jTx3Am*C4uzj`9%9!rVd*3hR&TsD$55doc?^y-?vDi=`t z8d5r$+w-&&q^guPrM-i3_qIM~4!~q6XWq&2FSCd_*vg+0CJ;jfBJ>6~Ov>Q%q z7f>J8gffXt74Bnxxqz~3al@}neMo8R-4glf+!P&UafhkAVC|);Ja4_);qS+xj!7D} z9VX$nz?~UumDLjQ*&_obsA4PYXzdQlb;g9laV5oFWzG&Nzm@n!Pgl;5uXxDWa!TYq zX~xPQ-|2U<>yguZ7usi+_+-MlB{M$2nlTeMHjzlzsguZnMTF>v$B1Qm$)HY9>jw>H z0W$m%110w7^oWZ=WmW8~tU>H4n~3gN$cgwULRBcDO>^$FaZl!ZP%IeUy0^F!_AYUxSwj$4yGXI<$ONAb$o$5a2PHUuj_jr z9eTfH!f*8!_{xY9&R;`yajR~Y3F}2|hbr!1>rGdGJM z^WKhgc=T9@i4q*SEoJ(%@LD^-04Y+PHzJ?XojXuwcqZ?HD1*BoxR{P5eL#4#|U zsUGazpRst4qqR&FxDCHtNJ|QD3U>3~jQrKV#)9Z^{aA>*)Jy!r&6o}73Z=y>JWn(S z$H|i+;pYCb_-7uV>BgBOWWb1i}BYN33ahP*}J)C<@&V{Ci@KMHjq zq-9Xu{$sJ)&t?E$;^>pC3#%Pm_=P8kLfWh3@`{DZs%J(o0~}Sj|L~ctRd7m_$jBJ_ zF`0fun2QP2q{fDfZ!{J)ufyJXKAyEO1G^`vEwEJPtH71YTi+)JTR(!_me~7Yk@;}! zO>}NnH8{j#gy0El1?RFvjg+&jT=70xUyy()Otp!9kbt8Kp4U*LaHb!Sg?_XV-uLY3 zAd#m2SUu{C=P{!zMp_A+pX@sdUcExXXam8sQ5o$0_X z6^^7?h^iB)0MKZ_v_hwL-;G0S{CQ;AKzg?MFOcvBzK*XXhJv@!(yl{& z@V;yJLkEXMDWi81VkYWfvzRF^FXpIGboZ{cswU`rm;p;c)Hv`p=CYN-1o6Pqax#5|ICSougcDiCoxOvbL{o9J*{cp{FkzY&2 zhQ%!R0;hJS7nw*oDoY7^ME!B{t2|!sXPu^Am%=trs=Y<5%9hMg zA37fhlPZ0tq^@Q!e3yyLPoYGi&9SE=NOAPO8H4Xd5IKv*TB$RgE#8}gdfE_OfsXFn zp{s%B*c%!ta{dXYZFJup9(B2HUFp zxOA}r`OBwkr{_7j6|!~b){L``!Gh zOS`#R>U~#ZZe+K_DKliY-|6wQ@}pGg6rHo2-8JFSe8D0~Gln2Emm?pt|Fx#S>peDs zilDy)3C2fN-d+bbFD19!`1N zGwr<}bWJ^P=-Ml5gg^N_X=cOw+|{x9X+*vt=b&q9QFY@fL*fG_H***5B4SG8F?DMl z!K>z^DN*$DufvXSK6HPyGPiN2Hh^nn-9O>sU|%=P3dNu|UK2KV305asa6accWHCOq z?|S%#1$^|;4}7CZ7{!aG413pKHe!; VMgY6{&E6rxgMgVDR6!i0{|VLtMmGQe literal 0 HcmV?d00001 diff --git a/src-tauri/icons/ios/AppIcon-76x76@1x.png b/src-tauri/icons/ios/AppIcon-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..333da4b7f30e1aa6ec7091cb9f354758ab6bae5b GIT binary patch literal 1392 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 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/tray-dark.png b/src-tauri/icons/tray-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a8842c4bc9729a4e0c114d81dd0f3c90b20154eb GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?507a+{IwK^!9fq{|R z)5S5QV$R#?)?9}I1YFx2q)%}9h%W9mTjy}6>6%%d8%y;;ufR8dbUk8@ItEMOyO%a=@E z{;bmHpJr!U72BeTBB}ql1iOw+OnmdKI;Vst05fBUSpWb4 literal 0 HcmV?d00001 diff --git a/src-tauri/icons/tray-light.png b/src-tauri/icons/tray-light.png new file mode 100644 index 0000000000000000000000000000000000000000..0ead4c95c4a192e0b888940cd98242a6fb308df4 GIT binary patch literal 414 zcmV;P0b%}$P)ZbLq~kwL8PI7u_b2_Yf({BvLVP7)@NFoP|e;s$sBtZ4HLZA@p+i8zGj z28??nFt60h9w*r|g?S6d`9@s;H`%k5a+g#WM`iriaD>_c(82A9-~6wh2+vLcbZa#J zt!^6P;i}iFw<&5T4PpL-x2)&70UmIHLmc58_jLjE(8osJLqf}VEg6bb2=IZm0f2?N z0p78L*}S7|gO7lSyu&Z{1l~~!m|7!e*qu!d2w0Z zE(|8Ozf>GdT1`i@l*_6JjE#iTDxODV9(6pAw! f64 { + let w = width.clamp(WIDTH_MIN, WIDTH_MAX); + (w * DESIGN_HEIGHT / DESIGN_WIDTH).round() +} + +/// 鍚搁檮杈?(W-SNP-01: 鍥涜竟) +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)] +#[serde(rename_all = "lowercase")] +pub enum Edge { + #[default] + Left, + Right, + Top, + Bottom, +} + +impl Edge { + pub fn css(&self) -> &'static str { + match self { + Edge::Left => "left", + Edge::Right => "right", + Edge::Top => "top", + Edge::Bottom => "bottom", + } + } +} + +/// 涓荤獥鍙h蹇?(W-WIN-07): 灏哄涓洪€昏緫鍍忕礌 (DPI 绋冲畾), 浣嶇疆涓虹墿鐞嗗儚绱?(鍔犺浇鏃舵牎楠屽す鍙? +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(default)] +pub struct WindowCfg { + pub width: f64, + pub height: f64, + pub x: Option, + pub y: Option, +} + +impl Default for WindowCfg { + fn default() -> Self { + // 323x574 = 405:720 姣斾緥 (0.797x of 405x720, 2026-10-26 鏀惧ぇ 12%) + Self { width: 323.0, height: height_for_width(323.0), x: None, y: None } + } +} + +/// 鎮诞鐞冨仠闈?(W-SNP-02/12): 杈?+ 娌胯竟浣嶇疆 (鎮诞鐞冧腑蹇? 鐗╃悊鍍忕礌) +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(default)] +pub struct DockCfg { + pub edge: Edge, + pub offset: i32, +} + +impl Default for DockCfg { + fn default() -> Self { + Self { edge: Edge::Left, offset: 360 } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(default)] +pub struct ShellConfig { + /// 鍚搁檮鎬诲紑鍏?(W-SNP-09, 榛樿寮€鍚? + pub snap_enabled: bool, + pub window: WindowCfg, + pub dock: DockCfg, + /// 绐楀彛瀹藉害 (閫昏緫鍍忕礌) 鈥斺€?**鍞竴灏哄閰嶇疆椤?*銆? /// 楂樺害鎸?405:720 閿佸畾姣斾緥鑷姩鎺ㄥ, 鏃犻渶涔熸棤娉曞崟鐙厤缃? + /// 鐣欑┖鏃跺洖钀藉埌 window.width銆? #[serde(default)] + pub window_width: Option, + /// 閰嶇疆缁撴瀯鐗堟湰: 0 = 鏃х増 (绐楀彛灏哄鎸?405x720 鍙e緞淇濆瓨), + /// 1 = 鏁翠綋缂╁皬 30% (288 鍙e緞), 2 = 鏀惧ぇ 12% (323 鍙e緞) + 鍗曞€煎搴﹂厤缃€? /// load 鏃跺仛涓€娆℃€ц縼绉汇€? /// 娉ㄦ剰蹇呴』鐢ㄥ瓧娈电骇 serde(default) (u8 鈫?0): 瀹瑰櫒绾?default 浼氬彇 + /// ShellConfig::default() 鐨?2, 鏃ч厤缃枃浠跺氨姘歌繙涓嶈縼绉讳簡銆? #[serde(default)] + pub cfg_version: u8, +} + +impl Default for ShellConfig { + fn default() -> Self { + Self { + snap_enabled: true, + window: WindowCfg::default(), + dock: DockCfg::default(), + window_width: Some(WindowCfg::default().width), + cfg_version: 2, + } + } +} + +/// 杩佺Щ鍓嶇殑绐楀彛瀹藉害 (鏃у彛寰?, 渚?load 浣跨敤 +impl WindowCfg { + /// 搴旂敤閿佸畾姣斾緥: 瀹藉害澶瑰彇鍒板悎娉曡寖鍥? 楂樺害鐢卞搴︽帹瀵?(蹇界暐瀛樼洏楂樺害) + pub(crate) fn normalize(&mut self) { + self.width = self.width.clamp(WIDTH_MIN, WIDTH_MAX); + self.height = height_for_width(self.width); + } +} + +impl ShellConfig { + pub fn load(dir: &Path) -> ShellConfig { + let path = dir.join(FILE_NAME); + let mut cfg = match std::fs::read_to_string(&path) { + Ok(text) => match serde_json::from_str::(&text) { + Ok(cfg) => cfg, + Err(_) => ShellConfig::default(), // 鍐欏潖 JSON 鈫?榛樿鍊?(W-CFG-03) + }, + Err(_) => ShellConfig::default(), + }; + // 一次性迁移 + if cfg.cfg_version < 1 { + // v0 (405 鍙e緞) 鈫?v1: 鏁翠綋缂╁皬 30% + cfg.window.width = (cfg.window.width * 0.7).max(216.0); + cfg.window.height = (cfg.window.height * 0.7).max(384.0); + cfg.cfg_version = 1; + } + if cfg.cfg_version < 2 { + // v1 (288 口径) -> v2: 放大 12% (323 口径), 引入单值宽度配置 + cfg.window.width = (cfg.window.width * 1.12).max(WIDTH_MIN); + cfg.window.height = height_for_width(cfg.window.width); + cfg.cfg_version = 2; + } + // 鍗曞€煎搴︿紭鍏? 楂樺害涓€寰嬫寜閿佸畾姣斾緥鎺ㄥ (蹇界暐瀛樼洏楂樺害) + if let Some(w) = cfg.window_width { + cfg.window.width = w; + } + cfg.window.normalize(); + cfg.window_width = Some(cfg.window.width); + cfg.save(dir); + cfg + } + + pub fn save(&self, dir: &Path) { + let path = dir.join(FILE_NAME); + let tmp = dir.join(format!("{FILE_NAME}.tmp")); + let text = match serde_json::to_string_pretty(self) { + Ok(t) => t, + Err(_) => return, + }; + if std::fs::write(&tmp, text).is_ok() { + // Windows 上 rename 不能覆盖已存在文件, 先移除 + let _ = std::fs::remove_file(&path); + let _ = std::fs::rename(&tmp, &path); + } + // 鍐欏け璐ヤ繚鎸侀潤榛?(W-CFG-04): 杩愯涓殑澶栧3涓嶅彈褰卞搷 + } +} diff --git a/src-tauri/src/shell/mod.rs b/src-tauri/src/shell/mod.rs new file mode 100644 index 0000000..9fc3736 --- /dev/null +++ b/src-tauri/src/shell/mod.rs @@ -0,0 +1,960 @@ +//! Windows 外壳 (需求文档 §3): 托盘常驻 / 开机自启动 / 四边吸附悬浮球 / 主题跟随 +//! +//! 仅在 `desktop + windows` 下编译 (lib.rs cfg 门控); Android 构建不含本模块。 +//! 状态机要点: +//! - 收起判定在「松开鼠标」后静默 150ms 进行 (W-SNP-01, 评审决策 #1); +//! - 悬浮球 hover 停留 ≥150ms 或单击即恢复 (W-SNP-04/05, 决策 #2); +//! - 悬浮球可沿边拖动、拖到其他边换边、拖离边缘 ≥32px 拖出主窗口 (W-SNP-12~14); +//! - 无边框全屏之上保持显示, 独占全屏自动避让 (W-SNP-15/16); +//! - 托盘与悬浮球深浅色跟随系统 (W-THE)。 + +mod config; +mod win; + +use config::{DockCfg, Edge, ShellConfig}; +use std::path::PathBuf; +use std::sync::Mutex; +use std::time::{Duration, Instant}; +use tauri::menu::{CheckMenuItem, Menu, MenuEvent, MenuItem}; +use tauri::tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent}; +use tauri::{AppHandle, Manager, PhysicalPosition, PhysicalSize, WebviewUrl, WebviewWindowBuilder, Wry}; + +const MAIN: &str = "main"; +const DOCK: &str = "dock"; +const TRAY_ID: &str = "iboard-tray"; + +/// 悬浮球尺寸 (逻辑像素, 附录 A): 垂直边 = 28×56, 水平边 = 56×28 +const HANDLE_SHORT: f64 = 28.0; +const HANDLE_LONG: f64 = 56.0; +/// 吸附触发阈值 (W-SNP-01) +const SNAP_PX: f64 = 8.0; +/// 解除吸附阈值 (W-SNP-06/14) +const UNDOCK_PX: f64 = 32.0; +/// 碰触恢复延时 (W-SNP-04) +const RESTORE_DELAY: Duration = Duration::from_millis(150); +/// 吸附态展开后, 鼠标移开窗口多久自动收起 (auto-hide) +const AUTOHIDE_DELAY: Duration = Duration::from_millis(400); +/// 移动静默判定窗口 (松手判定, 决策 #1) +const MOVE_QUIET: Duration = Duration::from_millis(150); +/// 程序性移动后的吸附抑制 (避免 set_position 触发立即收起) +const MOVE_SUPPRESS: Duration = Duration::from_millis(400); +/// 尺寸比例锁容差 (逻辑像素) +const RATIO_TOL: f64 = 2.0; + +type CheckItem = CheckMenuItem; + +struct Shared { + data_dir: PathBuf, + cfg: ShellConfig, + /// 主窗口处于吸附态 (含贴边可见的“已恢复”状态) + docked: bool, + /// 悬浮球当前可见 (true = 收起态) + dock_visible: bool, + /// 因独占全屏而隐藏 (W-SNP-16) + fs_hidden: bool, + /// 悬浮球拖动中 (JS pointer 事件驱动) + dragging: bool, + hover_since: Option, + last_main_move: Option, + /// 最近一次移动的 (最近边, 距边缘距离), 供解除吸附的静默判定 + last_move_eval: Option<(Edge, f64)>, + /// 是否已离开边缘条带 (拖离过程中置位; 只有 armed 才允许再次触碰收起, + /// 否则恢复到贴边位置后的第一次移动事件会立即误收) + edge_armed: bool, + /// 上一次移动事件时的窗口矩形 (越线判定用) + last_main_rect: Option, + /// 吸附态展开后, 光标移出窗口的起始时刻 (auto-hide 计时) + mouse_outside_since: Option, + /// 展开后光标是否进过窗口 (悬浮球唤回=true; 托盘唤回时光标在远处=false, + /// 未武装则永不自动收起, 否则托盘唤回会立刻缩回去) + mouse_inside_since_restore: bool, + ignore_until: Option, + theme_dark: bool, + menu_autostart: Option, + menu_snap: Option, + /// 主窗口在吸附态下的恢复位置 (贴边, 物理像素) + docked_rect: Option<(PhysicalPosition, PhysicalSize)>, +} + +type State = Mutex; + +fn state<'a>(app: &'a AppHandle) -> Option<&'a State> { + app.try_state::().map(|m| m.inner()) +} + +// ============================================================================ +// 生命周期 +// ============================================================================ + +pub fn setup(app: &mut tauri::App) -> Result<(), Box> { + let silent = std::env::args().any(|a| a == "--autostart"); // W-AUT-04 静默启动 + let data_dir = app.path().app_data_dir()?; + let _ = std::fs::create_dir_all(&data_dir); + let cfg = ShellConfig::load(&data_dir); + + let main = app.get_webview_window(MAIN).expect("main window missing"); + apply_saved_window(&main, &cfg); + + // 内容缩放跟随窗口宽度: 布局视口始终等于 405 设计宽, 窗口变大/变小只是整体等比缩放. + // 仅主窗口 —— 悬浮球窗口自绘尺寸不缩放; Android 端不经过本模块, 不受影响。 + let _ = main.set_zoom(cfg.window.width / config::DESIGN_WIDTH); + + // 悬浮球窗口 (W-SNP-02): 透明 / 置顶 / 无任务栏条目, 初始隐藏 + WebviewWindowBuilder::new(app, DOCK, WebviewUrl::App("dock.html".into())) + .title("iBoard Dock") + .decorations(false) + .transparent(true) + .shadow(false) + .resizable(false) + .always_on_top(true) + .skip_taskbar(true) + .focused(false) + .visible(false) + .build()?; + + let dark = win::system_prefers_dark(); + let (menu_autostart, menu_snap) = build_tray(app, &cfg, dark)?; + + let state = Mutex::new(Shared { + data_dir, + cfg, + docked: false, + dock_visible: false, + fs_hidden: false, + dragging: false, + hover_since: None, + last_main_move: None, + last_move_eval: None, + edge_armed: true, + last_main_rect: None, + mouse_outside_since: None, + mouse_inside_since_restore: false, + ignore_until: None, + theme_dark: dark, + menu_autostart: Some(menu_autostart), + menu_snap: Some(menu_snap), + docked_rect: None, + }); + app.manage(state); + + let handle = app.handle().clone(); + std::thread::spawn(move || checker_loop(handle)); + + if !silent { + let _ = main.show(); + let _ = main.set_focus(); + } + Ok(()) +} + +fn build_tray( + app: &tauri::App, + cfg: &ShellConfig, + dark: bool, +) -> Result<(CheckItem, CheckItem), Box> { + use tauri_plugin_autostart::ManagerExt; + let autostart_on = app.autolaunch().is_enabled().unwrap_or(false); // W-AUT-03 真实状态 + + let show = MenuItem::with_id(app, "show", "显示主窗口", true, None::<&str>)?; + let autostart = CheckMenuItem::with_id(app, "autostart", "开机启动", true, autostart_on, None::<&str>)?; + let snap = CheckMenuItem::with_id(app, "snap", "边缘吸附", true, cfg.snap_enabled, None::<&str>)?; + let quit = MenuItem::with_id(app, "quit", "退出", true, None::<&str>)?; + let menu = Menu::with_items(app, &[&show, &autostart, &snap, &quit])?; + + TrayIconBuilder::with_id(TRAY_ID) + .menu(&menu) + .show_menu_on_left_click(false) // 左键留给唤回 (W-TRY-03), 右键出菜单 (W-TRY-05) + .icon(tray_icon_image(dark)?) + .tooltip("iBoard") + .on_menu_event(on_menu_event) + .on_tray_icon_event(on_tray_event) + .build(app)?; + Ok((autostart, snap)) +} + +fn checker_loop(app: AppHandle) { + let mut tick: u64 = 0; + loop { + std::thread::sleep(Duration::from_millis(80)); + tick += 1; + let now = Instant::now(); + let action = { + let Some(st) = state(&app) else { continue }; + let mut s = st.lock().expect("shell state poisoned"); + decide(&mut s, now) + }; + match action { + Action::Restore => restore_main(&app), + Action::Undock => undock(&app, None), + Action::None => {} + } + autohide_check(&app); + if tick % 6 == 0 { + fullscreen_check(&app); // ~480ms + } + if tick % 12 == 0 { + theme_check(&app); // ~1s + } + } +} + +enum Action { + None, + Restore, + Undock, +} + +fn decide(s: &mut Shared, now: Instant) -> Action { + // 1) 移动静默判定仅用于「解除吸附」(W-SNP-05/06); 收起改为触碰即收起 + // (见 record_main_move, 修订决策 #1) + if let Some(t) = s.last_main_move { + if now.duration_since(t) >= MOVE_QUIET && s.ignore_until.map_or(true, |u| now >= u) { + s.last_main_move = None; + if s.cfg.snap_enabled { + if let Some((_edge, dist)) = s.last_move_eval { + if s.docked && !s.dock_visible && s.edge_armed && dist >= UNDOCK_PX { + return Action::Undock; // 拖离 → 解除吸附 (W-SNP-05) + } + } + } + } + } + // 2) 悬浮球碰触延时恢复 (W-SNP-04) + if s.dock_visible && !s.dragging { + if let Some(t0) = s.hover_since { + if now.duration_since(t0) >= RESTORE_DELAY { + s.hover_since = None; + return Action::Restore; + } + } + } + Action::None +} + +// ============================================================================ +// 事件入口 (lib.rs 转发) +// ============================================================================ + +pub fn on_window_event(window: &tauri::Window, event: &tauri::WindowEvent) { + if window.label() != MAIN { + return; + } + match event { + WindowEvent::CloseRequested { api, .. } => { + // W-TRY-02: 关闭到托盘, 进程不退出 + api.prevent_close(); + save_window_cfg(window.app_handle()); + let _ = window.hide(); + } + WindowEvent::Resized(size) => ratio_lock(window, *size), + WindowEvent::Moved(pos) => record_main_move(window, *pos), + _ => {} + } +} + +use tauri::WindowEvent; + +fn record_main_move(window: &tauri::Window, pos: PhysicalPosition) { + let app = window.app_handle(); + let Some(st) = state(app) else { return }; + // 程序性移动 (恢复/解除吸附的 set_position) 期间不记录, + // 否则抑制期一过会把"恢复到贴边位置"误判成用户再次贴边 (W-SNP-04) + if st + .lock() + .expect("shell state poisoned") + .ignore_until + .map_or(false, |u| Instant::now() < u) + { + return; + } + let Some(wa) = window + .hwnd() + .ok() + .map(|h| win::workarea_for_hwnd(h.0)) + .flatten() + else { + return; + }; + let Ok(size) = window.outer_size() else { return }; + let rect = rect_of(pos, size); + let (near_edge, dist) = nearest_edge(&rect, &wa); + let prev_rect = st.lock().expect("shell state poisoned").last_main_rect; + let touching = edge_touching(prev_rect.as_ref(), &rect, &wa); + + let do_collapse = { + let mut s = st.lock().expect("shell state poisoned"); + // 触碰即收起 (修订决策 #1): 拖动中窗口边缘一进入边缘条带就收起, + // 不做静默等待 —— 天然免疫 Win11 Aero Snap 抢跑与不可见边框过冲。 + // 「入带 + 越线」双条件: 停泊在边缘以外 (如压住任务栏区) 的窗口不受影响。 + match touching { + Some(edge) => { + let go = s.cfg.snap_enabled && !s.dock_visible && s.edge_armed; + if go { + s.edge_armed = false; + s.last_main_move = None; + s.last_main_rect = None; + } + go.then_some(edge) + } + None => { + s.edge_armed = true; // 离开边缘条带 → 重新武装 + s.last_main_move = Some(Instant::now()); + s.last_move_eval = Some((near_edge, dist)); + s.last_main_rect = Some(rect); + None + } + } + }; + if let Some(edge) = do_collapse { + collapse(app, edge); + } +} + +/// 9:16 比例锁 (W-WIN-02/03): 宽度为驱动, 高度 = 宽 × 16/9, 上限 = 可工作区高 × 95% +fn ratio_lock(window: &tauri::Window, actual: PhysicalSize) { + if window.is_minimized().unwrap_or(true) || actual.width == 0 || actual.height == 0 { + return; + } + let Ok(scale) = window.scale_factor() else { return }; + let wa_h: i32 = window + .hwnd() + .ok() + .and_then(|h| win::workarea_for_hwnd(h.0)) + .map(|wa| wa.height()) + .or_else(|| { + window + .current_monitor() + .ok() + .flatten() + .map(|m| m.size().height as i32) + }) + .unwrap_or(1080); + let max_h = (wa_h as f64 * 0.95) as u32; + let min_w = (216.0 * scale).round() as u32; + let mut w = actual.width; + let mut h = w * 16 / 9; + if h > max_h { + h = max_h; + w = h * 9 / 16; + } + if w < min_w { + w = min_w; + h = w * 16 / 9; + if h > max_h { + h = max_h; + w = h * 9 / 16; + } + } + let tol = (RATIO_TOL * scale).ceil() as i64; + if (actual.width as i64 - w as i64).abs() > tol || (actual.height as i64 - h as i64).abs() > tol { + let _ = window.set_size(PhysicalSize::new(w, h)); + } +} + +// ============================================================================ +// 吸附 / 恢复 / 解除 +// ============================================================================ + +/// 收起 (W-SNP-01/02): 主窗口贴边隐藏, 悬浮球出现在边缘。 +/// edge 由 record_main_move 的触碰判定给出, 不在此重判。 +fn collapse(app: &AppHandle, edge: Edge) { + let Some(main) = app.get_webview_window(MAIN) else { return }; + let Ok(hwnd) = main.hwnd() else { return }; + let Some(wa) = win::workarea_for_hwnd(hwnd.0) else { return }; + let Ok(scale) = main.scale_factor() else { return }; + let (Ok(pos), Ok(size)) = (main.outer_position(), main.outer_size()) else { return }; + let rect = rect_of(pos, size); + let docked_pos = flush_pos(&rect, edge, &wa); + let offset = clamp_offset( + along_center(&rect, edge), + edge, + &wa, + HANDLE_LONG, + scale, + ); + { + let Some(st) = state(app) else { return }; + let mut s = st.lock().expect("shell state poisoned"); + s.docked = true; + s.mouse_outside_since = None; + s.cfg.dock = DockCfg { edge, offset }; + s.docked_rect = Some((docked_pos, size)); + let cfg = s.cfg.clone(); + let dir = s.data_dir.clone(); + drop(s); + cfg.save(&dir); + } + let _ = main.set_position(PhysicalPosition::new(docked_pos.x, docked_pos.y)); + let _ = main.hide(); + place_handle(app, edge, offset, &wa, scale); +} + +/// 悬浮球定位 + 显示 (W-SNP-02/03) +fn place_handle(app: &AppHandle, edge: Edge, offset: i32, wa: &win::WorkArea, scale: f64) { + let Some(dock) = app.get_webview_window(DOCK) else { return }; + let (lw, lh) = match edge { + Edge::Left | Edge::Right => (HANDLE_SHORT, HANDLE_LONG), + Edge::Top | Edge::Bottom => (HANDLE_LONG, HANDLE_SHORT), + }; + let w = (lw * scale).round() as i32; + let h = (lh * scale).round() as i32; + let (x, y) = match edge { + Edge::Left => (wa.left, wa.clamp_y(offset - h / 2, h)), + Edge::Right => (wa.right - w, wa.clamp_y(offset - h / 2, h)), + Edge::Top => (wa.clamp_x(offset - w / 2, w), wa.top), + Edge::Bottom => (wa.clamp_x(offset - w / 2, w), wa.bottom - h), + }; + let dark = state(app) + .map(|s| s.lock().expect("shell state poisoned").theme_dark) + .unwrap_or(false); + let _ = dock.set_size(PhysicalSize::new(w as u32, h as u32)); + let _ = dock.set_position(PhysicalPosition::new(x, y)); + let _ = dock.eval(&format!( + "window.__SCALE = {scale}; window.applyDock('{}', '{}')", + edge.css(), + if dark { "dark" } else { "light" } + )); + let _ = dock.show(); + if let Some(st) = state(app) { + st.lock().expect("shell state poisoned").dock_visible = true; + } +} + +/// 唤回主窗口 (W-SNP-04/05, W-EX-01): 恢复到吸附位置, 悬浮球消失 +fn restore_main(app: &AppHandle) { + let Some(st) = state(app) else { return }; + let docked_rect = { + let mut s = st.lock().expect("shell state poisoned"); + if !s.docked { + return; + } + s.dock_visible = false; + s.hover_since = None; + s.edge_armed = false; // 恢复位置贴边, 需先拖离才允许再次触碰收起 + s.last_main_rect = None; + s.mouse_outside_since = None; + // auto-hide 武装: 恢复时光标是否已在窗口区域内 + // (悬浮球唤回 = 在; 托盘/单实例唤回 = 光标在远处, 不武装, 否则立刻缩回) + s.mouse_inside_since_restore = win::cursor_pos().map_or(false, |(cx, cy)| { + s.docked_rect.map_or(false, |(p, sz)| { + cx >= p.x + && cx <= p.x + sz.width as i32 + && cy >= p.y + && cy <= p.y + sz.height as i32 + }) + }); + s.ignore_until = Some(Instant::now() + MOVE_SUPPRESS); + s.docked_rect + }; + let Some((pos, _size)) = docked_rect else { return }; + let Some(main) = app.get_webview_window(MAIN) else { return }; + let Some(dock) = app.get_webview_window(DOCK) else { return }; + let _ = dock.hide(); + if let Ok(hwnd) = main.hwnd() { + if let Some(wa) = win::workarea_for_hwnd(hwnd.0) { + if let Ok(size) = main.outer_size() { + let x = wa.clamp_x(pos.x, size.width as i32); + let y = wa.clamp_y(pos.y, size.height as i32); + let _ = main.set_position(PhysicalPosition::new(x, y)); + } + } + } + let _ = main.unminimize(); + let _ = main.show(); + let _ = main.set_focus(); +} + +/// 解除吸附 (W-SNP-05/14): drop = 拖出时的释放点 (悬浮球中心, 物理像素) +fn undock(app: &AppHandle, drop: Option<(i32, i32)>) { + let Some(st) = state(app) else { return }; + { + let mut s = st.lock().expect("shell state poisoned"); + s.docked = false; + s.dock_visible = false; + s.hover_since = None; + s.edge_armed = true; // 自由窗口, 触碰边缘可再次收起 + s.last_main_rect = None; + s.ignore_until = Some(Instant::now() + MOVE_SUPPRESS); + } + if let Some(dock) = app.get_webview_window(DOCK) { + let _ = dock.hide(); + } + let Some(main) = app.get_webview_window(MAIN) else { return }; + if let Some((cx, cy)) = drop { + // 主窗口以释放点为中心, 完整夹取进可工作区 (W-SNP-14) + let Ok(size) = main.outer_size() else { return }; + if let Ok(hwnd) = main.hwnd() { + if let Some(wa) = win::workarea_for_hwnd(hwnd.0) { + let x = wa.clamp_x(cx - size.width as i32 / 2, size.width as i32); + let y = wa.clamp_y(cy - size.height as i32 / 2, size.height as i32); + let _ = main.set_position(PhysicalPosition::new(x, y)); + } + } + let _ = main.show(); + let _ = main.set_focus(); + } +} + +// ============================================================================ +// 托盘 / 菜单 / 退出 +// ============================================================================ + +fn on_menu_event(app: &AppHandle, event: MenuEvent) { + match event.id().as_ref() { + "show" => activate_primary(app), + "quit" => quit(app), + "autostart" => toggle_autostart(app), + "snap" => toggle_snap(app), + _ => {} + } +} + +fn on_tray_event(tray: &tauri::tray::TrayIcon, event: TrayIconEvent) { + match event { + // 单击与双击均唤回主窗口, 幂等 (W-TRY-03/04) + TrayIconEvent::Click { button: MouseButton::Left, button_state: MouseButtonState::Up, .. } => { + activate_primary(tray.app_handle()); + } + TrayIconEvent::DoubleClick { button: MouseButton::Left, .. } => { + activate_primary(tray.app_handle()); + } + _ => {} + } +} + +/// 唤回入口统一处理: 收起态 → 恢复到吸附位置 (W-EX-01); 否则前置主窗口 +pub fn activate_primary(app: &AppHandle) { + let docked = state(app) + .map(|s| s.lock().expect("shell state poisoned").docked) + .unwrap_or(false); + if docked { + restore_main(app); + return; + } + if let Some(main) = app.get_webview_window(MAIN) { + let _ = main.unminimize(); + let _ = main.show(); + let _ = main.set_focus(); + } +} + +fn toggle_autostart(app: &AppHandle) { + use tauri_plugin_autostart::ManagerExt; + let on = app.autolaunch().is_enabled().unwrap_or(false); + let result = if on { + app.autolaunch().disable() + } else { + app.autolaunch().enable() + }; + // 写入失败时如实回显 (W-EX-06), 不静默假成功 + let new_on = if on { false } else { result.is_ok() }; + if let Some(st) = state(app) { + let s = st.lock().expect("shell state poisoned"); + if let Some(item) = &s.menu_autostart { + let _ = item.set_checked(new_on); + } + } +} + +fn toggle_snap(app: &AppHandle) { + let Some(st) = state(app) else { return }; + let (on, cfg, dir) = { + let mut s = st.lock().expect("shell state poisoned"); + s.cfg.snap_enabled = !s.cfg.snap_enabled; + if let Some(item) = &s.menu_snap { + let _ = item.set_checked(s.cfg.snap_enabled); + } + (s.cfg.snap_enabled, s.cfg.clone(), s.data_dir.clone()) + }; + let _ = on; + cfg.save(&dir); +} + +/// 唯一正常退出入口 (W-TRY-06 / W-EX-02): 先收 UI, 再保存配置, 最后退出 +pub fn quit(app: &AppHandle) { + if let Some(dock) = app.get_webview_window(DOCK) { + let _ = dock.hide(); + } + if let Some(main) = app.get_webview_window(MAIN) { + save_window_cfg(app); + let _ = main.hide(); + } + if let Some(st) = state(app) { + let s = st.lock().expect("shell state poisoned"); + s.cfg.save(&s.data_dir); + } + let _ = app.remove_tray_by_id(TRAY_ID); + app.exit(0); +} + +// ============================================================================ +// 悬浮球 IPC (dock.html → Rust) +// ============================================================================ + +pub fn dock_hover_start(app: &AppHandle) { + if let Some(st) = state(app) { + st.lock().expect("shell state poisoned").hover_since = Some(Instant::now()); + } +} + +pub fn dock_hover_end(app: &AppHandle) { + if let Some(st) = state(app) { + st.lock().expect("shell state poisoned").hover_since = None; + } +} + +/// 单击/触屏点按 → 立即恢复 (W-SNP-05) +pub fn dock_click(app: &AppHandle) { + let docked = state(app) + .map(|s| s.lock().expect("shell state poisoned").docked) + .unwrap_or(false); + if docked { + restore_main(app); + } +} + +pub fn dock_drag_start(app: &AppHandle) { + if let Some(st) = state(app) { + let mut s = st.lock().expect("shell state poisoned"); + s.dragging = true; + s.hover_since = None; // 拖动取消未决的 hover 恢复 + } +} + +pub fn dock_drag_move(app: &AppHandle, dx: i32, dy: i32) { + let Some(dock) = app.get_webview_window(DOCK) else { return }; + if let Ok(pos) = dock.outer_position() { + let _ = dock.set_position(PhysicalPosition::new(pos.x + dx, pos.y + dy)); + } +} + +/// 拖动结束: ≤8px 停靠该边 (含换边 W-SNP-13); 8~32px 吸附到最近边; ≥32px 拖出恢复 (W-SNP-14) +pub fn dock_drag_end(app: &AppHandle) { + { + let Some(st) = state(app) else { return }; + st.lock().expect("shell state poisoned").dragging = false; + } + let Some(dock) = app.get_webview_window(DOCK) else { return }; + let (Ok(pos), Ok(size)) = (dock.outer_position(), dock.outer_size()) else { return }; + let Ok(hwnd) = dock.hwnd() else { return }; + let Some(wa) = win::workarea_for_hwnd(hwnd.0) else { return }; + let Ok(scale) = dock.scale_factor() else { return }; + let rect = rect_of(pos, size); + let (edge, dist) = nearest_edge(&rect, &wa); + if dist >= UNDOCK_PX { + let center = (rect.left + rect.width() / 2, rect.top + rect.height() / 2); + undock(app, Some(center)); + return; + } + // 停靠 (含 8~32px 死区: 吸附到最近边, 悬浮球不悬空) + let offset = clamp_offset(along_center(&rect, edge), edge, &wa, HANDLE_LONG, scale); + { + let Some(st) = state(app) else { return }; + let mut s = st.lock().expect("shell state poisoned"); + s.docked = true; + s.mouse_outside_since = None; + s.cfg.dock = DockCfg { edge, offset }; + // 主窗口恢复位置改为新边的贴边矩形 (W-SNP-13: 下次恢复出现在新边缘) + let main_size = s + .docked_rect + .map(|(_, sz)| sz) + .or_else(|| app.get_webview_window(MAIN).and_then(|m| m.outer_size().ok())); + if let Some(msize) = main_size { + let (x, y) = main_flush_from_offset(edge, offset, msize, &wa); + s.docked_rect = Some((PhysicalPosition::new(x, y), msize)); + } + let cfg = s.cfg.clone(); + let dir = s.data_dir.clone(); + drop(s); + cfg.save(&dir); + } + place_handle(app, edge, offset, &wa, scale); +} + +// ============================================================================ +// 全屏避让 / 主题跟随 +// ============================================================================ + +/// 独占全屏 → 隐藏悬浮球; 退出 → 原位恢复 (W-SNP-16)。无边框全屏不受影响 (W-SNP-15)。 +fn fullscreen_check(app: &AppHandle) { + let exclusive = win::is_exclusive_fullscreen(); + let Some(st) = state(app) else { return }; + let (transition, was_visible) = { + let mut s = st.lock().expect("shell state poisoned"); + let mut t = None; + if exclusive && s.dock_visible && !s.fs_hidden { + s.fs_hidden = true; + t = Some(false); + } else if !exclusive && s.fs_hidden { + s.fs_hidden = false; + t = Some(true); + } + (t, s.dock_visible) + }; + match transition { + Some(false) => { + if let Some(d) = app.get_webview_window(DOCK) { + let _ = d.hide(); + } + } + Some(true) => { + if was_visible { + if let Some(d) = app.get_webview_window(DOCK) { + let _ = d.show(); + } + } + } + None => {} + } +} + +/// 吸附态已展开 (悬浮球唤回) 时, 光标移开窗口 → 自动收起 (auto-hide 停靠交互)。 +/// 仅当光标在展开后进过窗口才武装 —— 托盘/单实例唤回时光标在远处, 不缩回。 +fn autohide_check(app: &AppHandle) { + let now = Instant::now(); + let armed = { + let Some(st) = state(app) else { return }; + let s = st.lock().expect("shell state poisoned"); + if !s.docked || s.dock_visible || s.dragging { + return; + } + if s.ignore_until.map_or(false, |u| now < u) { + return; + } + // 窗口正在移动 (拖拽中) 时不判定, 避免拖拽途中误收 + if s.last_main_move.map_or(false, |t| now.duration_since(t) < MOVE_QUIET * 2) { + return; + } + s.mouse_inside_since_restore + }; + if !armed { + return; + } + let Some(main) = app.get_webview_window(MAIN) else { return }; + let (Ok(pos), Ok(size)) = (main.outer_position(), main.outer_size()) else { return }; + let Some((cx, cy)) = win::cursor_pos() else { return }; + let inside = cx >= pos.x + && cx <= pos.x + size.width as i32 + && cy >= pos.y + && cy <= pos.y + size.height as i32; + let outside_since = { + let Some(st) = state(app) else { return }; + let mut s = st.lock().expect("shell state poisoned"); + if inside { + s.mouse_outside_since = None; + None + } else { + Some(*s.mouse_outside_since.get_or_insert(now)) + } + }; + if let Some(t) = outside_since { + if now.duration_since(t) >= AUTOHIDE_DELAY { + let edge = { + let Some(st) = state(app) else { return }; + st.lock().expect("shell state poisoned").cfg.dock.edge + }; + collapse(app, edge); + } + } +} + +/// 深浅色跟随系统 (W-THE): 托盘图标 + 悬浮球外观 +fn theme_check(app: &AppHandle) { + let dark = win::system_prefers_dark(); + let changed = { + let Some(st) = state(app) else { return }; + let mut s = st.lock().expect("shell state poisoned"); + if s.theme_dark == dark { + false + } else { + s.theme_dark = dark; + true + } + }; + if !changed { + return; + } + if let Ok(icon) = tray_icon_image(dark) { + if let Some(tray) = app.tray_by_id(TRAY_ID) { + let _ = tray.set_icon(Some(icon)); + } + } + if let Some(d) = app.get_webview_window(DOCK) { + let _ = d.eval(&format!("window.applyTheme('{}')", if dark { "dark" } else { "light" })); + } +} + +// ============================================================================ +// 配置持久化 +// ============================================================================ + +/// 启动时应用记忆的窗口尺寸/位置 (W-WIN-07) +/// 尺寸只取宽度, 高度按 405:720 锁定比例推导 (见 config::height_for_width) +fn apply_saved_window(main: &tauri::WebviewWindow, cfg: &ShellConfig) { + let Ok(scale) = main.scale_factor() else { return }; + let w = cfg.window.width.clamp(config::WIDTH_MIN, config::WIDTH_MAX); + let h = config::height_for_width(w); + let _ = main.set_size(tauri::LogicalSize::new(w, h)); + if let (Some(x), Some(y)) = (cfg.window.x, cfg.window.y) { + let pw = (w * scale).round() as i32; + let ph = (h * scale).round() as i32; + if let Some(wa) = win::workarea_for_point(x + pw / 2, y + ph / 2) { + let nx = wa.clamp_x(x, pw); + let ny = wa.clamp_y(y, ph); + let _ = main.set_position(PhysicalPosition::new(nx, ny)); + } + // 无效位置 → 保持配置默认居中 (W-WIN-07) + } +} + +/// 关闭/退出时保存窗口尺寸与位置 (W-WIN-07) +fn save_window_cfg(app: &AppHandle) { + let Some(main) = app.get_webview_window(MAIN) else { return }; + let Some(st) = state(app) else { return }; + let Ok(scale) = main.scale_factor() else { return }; + let (Ok(size), Ok(pos)) = (main.outer_size(), main.outer_position()) else { return }; + let cfg = { + let mut s = st.lock().expect("shell state poisoned"); + // 只记宽度; 高度按锁定比例推导, 保证下次启动比例不变 + s.cfg.window.width = size.width as f64 / scale; + s.cfg.window.normalize(); + s.cfg.window_width = Some(s.cfg.window.width); + s.cfg.window.x = Some(pos.x); + s.cfg.window.y = Some(pos.y); + s.cfg.clone() + }; + let dir = st.lock().expect("shell state poisoned").data_dir.clone(); + cfg.save(&dir); +} + +// ============================================================================ +// 几何辅助 +// ============================================================================ + +#[derive(Clone, Copy)] +struct Rect { + left: i32, + top: i32, + right: i32, + bottom: i32, +} + +impl Rect { + fn width(&self) -> i32 { + self.right - self.left + } + fn height(&self) -> i32 { + self.bottom - self.top + } +} + +fn rect_of(pos: PhysicalPosition, size: PhysicalSize) -> Rect { + Rect { + left: pos.x, + top: pos.y, + right: pos.x + size.width as i32, + bottom: pos.y + size.height as i32, + } +} + +/// 最近边与距离 (窗口边缘 ↔ 可工作区边缘) +fn nearest_edge(rect: &Rect, wa: &win::WorkArea) -> (Edge, f64) { + let candidates = [ + (Edge::Left, (rect.left - wa.left).abs()), + (Edge::Right, (wa.right - rect.right).abs()), + (Edge::Top, (rect.top - wa.top).abs()), + (Edge::Bottom, (wa.bottom - rect.bottom).abs()), + ]; + let (edge, dist) = candidates + .into_iter() + .min_by_key(|(_, d)| *d) + .unwrap_or((Edge::Left, i32::MAX)); + (edge, dist as f64) +} + +/// 触碰判定 (W-SNP-01, 修订决策 #1): +/// ① 入带 —— 当前窗口边缘落在边缘条带 [edge, edge+SNAP] 内; +/// ② 越线 —— 上一样本在带外, 当前样本已到线或越过线 (快速拖动跨过条带的采样间隙)。 +/// 对不可见边框 (视觉贴边时 rect 已越界 7~9px) 与过冲免疫; +/// 停泊在边缘以外 (如窗口压住任务栏区, rect.bottom > wa.bottom) 不算触碰。 +fn edge_touching(prev: Option<&Rect>, cur: &Rect, wa: &win::WorkArea) -> Option { + let s = SNAP_PX as i32; + let in_band = |a: i32, lo: i32, hi: i32| a >= lo && a <= hi; + let crossed = |p: i32, c: i32, line: i32, outward: bool| { + if outward { + // Bottom: 带在 [line-8, line], "带外"指 p < line-8 + p < line - s && c >= line - s + } else { + // Left/Right/Top: 带在 [line, line+8], "带外"指 p > line+8 + p > line + s && c <= line + s + } + }; + let hit = + |p: Option, c: i32, lo: i32, hi: i32, line: i32, outward: bool| match p { + Some(p) => in_band(c, lo, hi) || crossed(p, c, line, outward), + None => in_band(c, lo, hi), + }; + if hit(prev.map(|r| r.left), cur.left, wa.left, wa.left + s, wa.left, false) { + Some(Edge::Left) + } else if hit(prev.map(|r| r.right), cur.right, wa.right - s, wa.right, wa.right, true) { + Some(Edge::Right) + } else if hit(prev.map(|r| r.top), cur.top, wa.top, wa.top + s, wa.top, false) { + Some(Edge::Top) + } else if hit(prev.map(|r| r.bottom), cur.bottom, wa.bottom - s, wa.bottom, wa.bottom, true) { + Some(Edge::Bottom) + } else { + None + } +} + +/// 贴边位置: 保持沿边坐标, 垂直于边的坐标贴到边缘 +fn flush_pos(rect: &Rect, edge: Edge, wa: &win::WorkArea) -> PhysicalPosition { + match edge { + Edge::Left => PhysicalPosition::new(wa.left, wa.clamp_y(rect.top, rect.height())), + Edge::Right => PhysicalPosition::new(wa.right - rect.width(), wa.clamp_y(rect.top, rect.height())), + Edge::Top => PhysicalPosition::new(wa.clamp_x(rect.left, rect.width()), wa.top), + Edge::Bottom => PhysicalPosition::new(wa.clamp_x(rect.left, rect.width()), wa.bottom - rect.height()), + } +} + +/// 主窗口在给定边/沿边偏移下的贴边位置 +fn main_flush_from_offset( + edge: Edge, + offset: i32, + size: PhysicalSize, + wa: &win::WorkArea, +) -> (i32, i32) { + let w = size.width as i32; + let h = size.height as i32; + match edge { + Edge::Left => (wa.left, wa.clamp_y(offset - h / 2, h)), + Edge::Right => (wa.right - w, wa.clamp_y(offset - h / 2, h)), + Edge::Top => (wa.clamp_x(offset - w / 2, w), wa.top), + Edge::Bottom => (wa.clamp_x(offset - w / 2, w), wa.bottom - h), + } +} + +/// 沿边中心 (Left/Right → 垂直中心; Top/Bottom → 水平中心) +fn along_center(rect: &Rect, edge: Edge) -> i32 { + match edge { + Edge::Left | Edge::Right => rect.top + rect.height() / 2, + Edge::Top | Edge::Bottom => rect.left + rect.width() / 2, + } +} + +/// 悬浮球沿边位置夹取 (完整可见, W-SNP-02) +fn clamp_offset(offset: i32, edge: Edge, wa: &win::WorkArea, handle_long: f64, scale: f64) -> i32 { + let half = (handle_long * scale / 2.0).round() as i32; + match edge { + Edge::Left | Edge::Right => offset.clamp(wa.top + half, wa.bottom - half), + Edge::Top | Edge::Bottom => offset.clamp(wa.left + half, wa.right - half), + } +} + +fn tray_icon_image(dark: bool) -> tauri::Result> { + if dark { + tauri::image::Image::from_bytes(include_bytes!("../../icons/tray-dark.png")) + } else { + tauri::image::Image::from_bytes(include_bytes!("../../icons/tray-light.png")) + } +} diff --git a/src-tauri/src/shell/win.rs b/src-tauri/src/shell/win.rs new file mode 100644 index 0000000..1bc1506 --- /dev/null +++ b/src-tauri/src/shell/win.rs @@ -0,0 +1,117 @@ +//! Win32 辅助: 可工作区 / 独占全屏检测 / 系统深浅色 (W-SNP、W-THE) +#![cfg(windows)] + +use windows_sys::Win32::{ + Foundation::{HWND, POINT, RECT}, + Graphics::Gdi::{ + GetMonitorInfoW, MonitorFromPoint, MonitorFromWindow, MONITORINFO, MONITOR_DEFAULTTONEAREST, + }, + System::Registry::{RegGetValueW, HKEY_CURRENT_USER, RRF_RT_REG_DWORD}, + UI::Shell::{SHQueryUserNotificationState, QUNS_RUNNING_D3D_FULL_SCREEN}, + UI::WindowsAndMessaging::GetCursorPos, +}; + +/// 当前光标位置 (物理像素) +pub fn cursor_pos() -> Option<(i32, i32)> { + let mut pt = POINT { x: 0, y: 0 }; + unsafe { + if GetCursorPos(&mut pt) == 0 { + return None; + } + } + Some((pt.x, pt.y)) +} + +/// 显示器可工作区 (物理像素, 已扣除任务栏, W-EX-05) +#[derive(Debug, Clone, Copy)] +pub struct WorkArea { + pub left: i32, + pub top: i32, + pub right: i32, + pub bottom: i32, +} + +impl WorkArea { + pub fn height(&self) -> i32 { + self.bottom - self.top + } + pub fn clamp_x(&self, x: i32, w: i32) -> i32 { + x.clamp(self.left, (self.right - w).max(self.left)) + } + pub fn clamp_y(&self, y: i32, h: i32) -> i32 { + y.clamp(self.top, (self.bottom - h).max(self.top)) + } +} + +fn utf16(s: &str) -> Vec { + s.encode_utf16().chain(std::iter::once(0)).collect() +} + +/// 窗口所在显示器的可工作区 (hwnd: tauri `hwnd().0`, 即裸指针) +pub fn workarea_for_hwnd(hwnd: *mut std::ffi::c_void) -> Option { + unsafe { + let hmon = MonitorFromWindow(hwnd as HWND, MONITOR_DEFAULTTONEAREST); + if hmon.is_null() { + return None; + } + let mut info: MONITORINFO = std::mem::zeroed(); + info.cbSize = std::mem::size_of::() as u32; + if GetMonitorInfoW(hmon, &mut info) == 0 { + return None; + } + let RECT { left, top, right, bottom } = info.rcWork; + Some(WorkArea { left, top, right, bottom }) + } +} + +/// 前台是否为独占全屏 (D3D FSE, W-SNP-16)。 +/// 无边框全屏 / 全屏优化不在此列 (悬浮球保持可见, W-SNP-15)。 +pub fn is_exclusive_fullscreen() -> bool { + unsafe { + let mut state: i32 = 0; + if SHQueryUserNotificationState(&mut state) < 0 { + return false; // 判定失败 → 默认非全屏 (W-EX-11) + } + state == QUNS_RUNNING_D3D_FULL_SCREEN + } +} + +/// 系统「应用模式」是否为深色 (W-THE-01, AppsUseLightTheme == 0) +pub fn system_prefers_dark() -> bool { + unsafe { + let subkey = utf16("Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"); + let value = utf16("AppsUseLightTheme"); + let mut val: u32 = 1; // 缺省按浅色 + let mut size = std::mem::size_of::() as u32; + let status = RegGetValueW( + HKEY_CURRENT_USER, + subkey.as_ptr(), + value.as_ptr(), + RRF_RT_REG_DWORD, + std::ptr::null_mut(), + (&mut val as *mut u32).cast(), + &mut size, + ); + if status != 0 { + return false; // 读不到按浅色 (W-EX-11 口径) + } + val == 0 + } +} + +/// 物理坐标所在显示器的可工作区 (启动位置校验, W-WIN-07) +pub fn workarea_for_point(x: i32, y: i32) -> Option { + unsafe { + let hmon = MonitorFromPoint(POINT { x, y }, MONITOR_DEFAULTTONEAREST); + if hmon.is_null() { + return None; + } + let mut info: MONITORINFO = std::mem::zeroed(); + info.cbSize = std::mem::size_of::() as u32; + if GetMonitorInfoW(hmon, &mut info) == 0 { + return None; + } + let RECT { left, top, right, bottom } = info.rcWork; + Some(WorkArea { left, top, right, bottom }) + } +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 7b82045..33d518a 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,36 +1,38 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "iBoard", - "version": "0.2.0", + "version": "0.2.1", "identifier": "com.iboard.app", "build": { "beforeDevCommand": "npm run dev", - "beforeBuildCommand": "npm run build", + "beforeBuildCommand": "npm run build:shell", "devUrl": "http://localhost:5173", "frontendDist": "../dist" }, "plugins": { "hotswap": { - "endpoint": "http://bh.vps.honor3.com:3001/api/ota/check/{{current_sequence}}", + "endpoint": "https://iboard.honor3.com/api/ota/check/{{current_sequence}}", "pubkey": "RWQQ4/wfHjJiC/O6NmA7eIQYUNRpCsz5wLLsLqJXgHmsUraAavUWx0HA", "require_https": false, "headers": {} } }, "app": { + "withGlobalTauri": true, "windows": [ { "title": "iBoard", - "width": 420, - "height": 820, - "minWidth": 360, - "minHeight": 640, + "width": 323, + "height": 574, + "minWidth": 242, + "minHeight": 430, "resizable": true, + "visible": false, "fullscreen": false } ], "security": { - "csp": "default-src 'self' ipc: http://ipc.localhost; img-src 'self' data: blob: asset: http://asset.localhost; connect-src 'self' ipc: http://ipc.localhost http://bh.vps.honor3.com:3001 https://bh.vps.honor3.com:3001; style-src 'self' 'unsafe-inline'; script-src 'self'" + "csp": "default-src 'self' ipc: http://ipc.localhost; img-src 'self' data: blob: asset: http://asset.localhost; connect-src 'self' ipc: http://ipc.localhost https://iboard.honor3.com http://bh.vps.honor3.com:3001 https://bh.vps.honor3.com:3001; style-src 'self' 'unsafe-inline'; script-src 'self'" } }, "bundle": { @@ -43,6 +45,13 @@ "icons/icon.icns", "icons/icon.ico" ], + "windows": { + "nsis": { + "installMode": "currentUser", + "languages": ["SimpChinese", "English"], + "displayLanguageSelector": false + } + }, "android": { "minSdkVersion": 24 } diff --git a/src/main.jsx b/src/main.jsx index 8f87dfd..5905f44 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -21,6 +21,16 @@ initOta() function calibrateSafeTop() { const root = document.documentElement + // 校准只对 Android 有意义 (状态栏/刘海让位)。桌面 (Windows WebView2 / 桌面浏览器) + // 没有状态栏: env() 本来就是 0; 而「screen.height - visualViewport.height」在桌面 + // 竖屏窗口下会把标题栏+边框高度 (~99px) 误判成状态栏, 让标题栏下多出一条大空隙 + // (2026-10-26 Windows 外壳实测)。非 Android 一律 0。 + const isAndroid = /android/i.test(navigator.userAgent) + if (!isAndroid) { + root.style.setProperty('--safe-top', '0px') + return + } + // env() 的真实值必须用一个临时元素测量, 不能直接读 --safe-top —— // 该变量是 max(env(...), 0px) 这样的表达式, parseFloat 会得到 NaN. const probe = document.createElement('div') @@ -37,7 +47,7 @@ function calibrateSafeTop() { const viewH = window.visualViewport?.height || window.innerHeight || 0 const screenW = window.screen?.width || 0 const viewW = window.visualViewport?.width || window.innerWidth || 0 - // 只在"纵向且高度差合理"时采用, 避免横屏/桌面窗口误判 + // 只在"纵向且高度差合理"时采用, 避免横屏误判 const isPortrait = viewW <= viewH const diff = screenH - viewH const measured = isPortrait && diff > 0 && diff < 120 ? diff : 0 @@ -45,7 +55,7 @@ function calibrateSafeTop() { // 取 env() 与实测值的较大者; 两者都失效时给 24px 保底 // (多数 Android 状态栏在 24~28px, 宁可多一点也不能压字) let top = Math.max(envTop, measured) - if (top < 4) top = 24 // env 与实测都没拿到 → 用保守兜底, 保证不遮挡 + if (top < 4) top = 24 root.style.setProperty('--safe-top', top + 'px') }