From 204cda1cf66265e3988f425368f48f7f8e1b8090 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 00:17:53 +0530 Subject: [PATCH 01/34] feat: set Excalidraw default theme to dark Co-authored-by: CommandCodeBot --- bun.lock | 1 + src/packages/excalidraw/excalidraw-app/useHandleAppTheme.ts | 4 ++-- src/pages/motion-board/App.tsx | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bun.lock b/bun.lock index 1cb3669..6a85356 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "penio", diff --git a/src/packages/excalidraw/excalidraw-app/useHandleAppTheme.ts b/src/packages/excalidraw/excalidraw-app/useHandleAppTheme.ts index e319611..dd00db8 100644 --- a/src/packages/excalidraw/excalidraw-app/useHandleAppTheme.ts +++ b/src/packages/excalidraw/excalidraw-app/useHandleAppTheme.ts @@ -14,10 +14,10 @@ export const useHandleAppTheme = () => { (localStorage.getItem(STORAGE_KEYS.LOCAL_STORAGE_THEME) as | Theme | "system" - | null) || THEME.LIGHT + | null) || THEME.DARK ); }); - const [editorTheme, setEditorTheme] = useState(THEME.LIGHT); + const [editorTheme, setEditorTheme] = useState(THEME.DARK); useEffect(() => { const mediaQuery = getDarkThemeMediaQuery(); diff --git a/src/pages/motion-board/App.tsx b/src/pages/motion-board/App.tsx index 6f51cad..5654a5a 100644 --- a/src/pages/motion-board/App.tsx +++ b/src/pages/motion-board/App.tsx @@ -30,7 +30,7 @@ import "@excalidraw/excalidraw/fonts/fonts.css"; import { getCurrentWindow } from "@tauri-apps/api/window"; import { clickRippleAnimate, clickFirework, clickSpiral, clickCircleStroke, clickRectStroke } from "./animation/mouse"; import { type } from '@tauri-apps/plugin-os'; -import { Excalidraw } from "@excalidraw/excalidraw"; +import { Excalidraw, THEME } from "@excalidraw/excalidraw"; import { useMouseSettings } from "../../hooks/useMouseSettings"; import { useKeyboardSettings } from "../../hooks/useKeyboardSettings"; import { useDrawingSettings } from "../../hooks/useDrawingSettings"; @@ -471,6 +471,7 @@ function App() { }} /> { { excalidrawAPIRef.current = api; }} From 1c85c9ca0b9f17275ff584db7f03063c5bcb2ac3 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 01:15:35 +0530 Subject: [PATCH 02/34] feat: add app-level light/dark theme switching Co-authored-by: CommandCodeBot --- src/App.tsx | 4 ++- src/components/Settings.tsx | 33 +++++++++++++++--- src/i18n/locales/de-DE.json | 4 +++ src/i18n/locales/en-US.json | 4 +++ src/i18n/locales/es-ES.json | 4 +++ src/i18n/locales/fr-FR.json | 4 +++ src/i18n/locales/ja-JP.json | 4 +++ src/i18n/locales/ko-KR.json | 4 +++ src/i18n/locales/zh-CN.json | 4 +++ src/i18n/locales/zh-TW.json | 4 +++ src/main.tsx | 62 +++++++++++++++++++++++++++++----- src/pages/motion-board/App.tsx | 2 +- src/store/settings.ts | 8 +++++ src/theme.ts | 33 ++++++++++++------ 14 files changed, 148 insertions(+), 26 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index d55380b..6d0732b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -27,6 +27,7 @@ import "./App.css"; import Tabs from "@mui/material/Tabs"; import Tab from "@mui/material/Tab"; import Box from "@mui/material/Box"; +import { useTheme } from "@mui/material/styles"; import { useTranslation } from 'react-i18next'; import i18n from './i18n'; import { initLocale } from './i18n'; @@ -53,12 +54,13 @@ interface TabPanelProps { function TabPanel(props: TabPanelProps) { const { children, value, index, ...other } = props; + const theme = useTheme(); return (
{t('keyboard.title')} - + {t('mouse.title')} - + @@ -1265,7 +1265,7 @@ function 绘图设置页面() { {t('drawing.title')} - + ('auto'); const [hasAccessibilityPermission, setHasAccessibilityPermission] = useState(false); const [hasInputMonitoringPermission, setHasInputMonitoringPermission] = useState(false); const { notify } = useSnackbar(); @@ -1323,6 +1324,9 @@ function 通用设置页面() { const isEnabled = await AutoStart.isEnabled(); setEnableAutoStart(isEnabled); + const settings = await getSettings(); + setAppTheme(settings.theme ?? 'auto'); + // 检查 macOS 权限 if (isMac()) { try { @@ -1359,6 +1363,11 @@ function 通用设置页面() { } } + const handleThemeChange = async (value: 'light' | 'dark' | 'auto') => { + setAppTheme(value); + await updateSettings({ theme: value }); + }; + // 请求辅助功能权限 const handleRequestAccessibilityPermission = async () => { try { @@ -1393,7 +1402,7 @@ function 通用设置页面() { }}>{t('general.permissionTitle')} {t('general.title')} - + + handleThemeChange(e.target.value as 'light' | 'dark' | 'auto')} + > + {t('general.themeLight')} + {t('general.themeDark')} + {t('general.themeAuto')} + + } + /> - +function resolveTheme(setting: string | undefined): 'light' | 'dark' { + if (setting === 'dark') return 'dark'; + if (setting === 'light') return 'light'; + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; +} + +function ThemedApp() { + const [mode, setMode] = useState<'light' | 'dark'>(() => resolveTheme(undefined)); + + useEffect(() => { + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + let currentSetting: string | undefined; + + getSettings().then(s => { + currentSetting = s.theme; + setMode(resolveTheme(s.theme)); + }); + + const handleMedia = () => { + if (!currentSetting || currentSetting === 'auto') { + setMode(mediaQuery.matches ? 'dark' : 'light'); + } + }; + mediaQuery.addEventListener('change', handleMedia); + + let unlisten: (() => void) | undefined; + listen<{ theme: string }>('theme-updated', (event) => { + currentSetting = event.payload.theme; + setMode(resolveTheme(event.payload.theme)); + }).then(fn => { unlisten = fn; }); + + return () => { + mediaQuery.removeEventListener('change', handleMedia); + unlisten?.(); + }; + }, []); + + return ( + + ); +} + +ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( + + , ); diff --git a/src/pages/motion-board/App.tsx b/src/pages/motion-board/App.tsx index 5654a5a..9b1625a 100644 --- a/src/pages/motion-board/App.tsx +++ b/src/pages/motion-board/App.tsx @@ -90,7 +90,7 @@ function App() { useEffect(() => { const setupListener = async () => { const appWindow = getCurrentWindow(); - + const unlisten = await appWindow.listen<{ language: string }>('language-updated', (event) => { console.log('Received language-updated event:', event.payload.language); const newLanguage = event.payload.language; diff --git a/src/store/settings.ts b/src/store/settings.ts index 5822435..81489ae 100644 --- a/src/store/settings.ts +++ b/src/store/settings.ts @@ -165,6 +165,14 @@ export const updateSettings = async (newSettings: Partial) => { } } + if (newSettings.theme !== undefined) { + try { + await emit('theme-updated', { theme: updatedSettings.theme }); + } catch (error) { + console.error('Failed to emit theme-updated event:', error); + } + } + const { register, unregister } = useShortcut(); if (newSettings.drawing) { try { diff --git a/src/theme.ts b/src/theme.ts index e565f7a..81e4b3e 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -15,7 +15,7 @@ declare module '@mui/material/styles' { 800?: string; 900?: string; } - + interface SimplePaletteColorOptions { 50?: string; 100?: string; @@ -30,19 +30,32 @@ declare module '@mui/material/styles' { } } -const theme = createTheme({ +const successPalette = { + main: '#2e7d32', + light: '#4caf50', + dark: '#1b5e20', + contrastText: '#fff', + ...green, +}; + +export const lightTheme = createTheme({ + typography: { + fontFamily: '"Fira Code", "Noto Sans SC", "Noto Sans TC", "Noto Sans", sans-serif', + }, + palette: { + mode: 'light', + success: successPalette, + }, +}); + +export const darkTheme = createTheme({ typography: { fontFamily: '"Fira Code", "Noto Sans SC", "Noto Sans TC", "Noto Sans", sans-serif', }, palette: { - success: { - main: '#2e7d32', // MUI 默认 success.main - light: '#4caf50', - dark: '#1b5e20', - contrastText: '#fff', - ...green, // 注入 50-900 的色阶 - }, + mode: 'dark', + success: successPalette, }, }); -export default theme; +export default lightTheme; From 95a20a44a2a2e13c168e7c8b53d86ec538731c0f Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 02:18:09 +0530 Subject: [PATCH 03/34] feat: improve ShortcutField dark mode support Use theme-aware colors instead of hardcoded hex values for background, border, text, and hover states. Co-authored-by: CommandCodeBot --- bun.lock | 1 - src/components/ShortcutField.tsx | 20 +++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/bun.lock b/bun.lock index 6a85356..1cb3669 100644 --- a/bun.lock +++ b/bun.lock @@ -1,6 +1,5 @@ { "lockfileVersion": 1, - "configVersion": 0, "workspaces": { "": { "name": "penio", diff --git a/src/components/ShortcutField.tsx b/src/components/ShortcutField.tsx index 39c1bba..e87090c 100644 --- a/src/components/ShortcutField.tsx +++ b/src/components/ShortcutField.tsx @@ -23,7 +23,7 @@ */ import { useState, useEffect, useRef } from "react"; -import { Box, Typography, IconButton } from "@mui/material"; +import { Box, Typography, IconButton, useTheme } from "@mui/material"; import { KeyComboTag } from "@blueprintjs/core"; import "@blueprintjs/core/lib/css/blueprint.css"; import { platform } from '@tauri-apps/plugin-os'; @@ -38,6 +38,8 @@ interface ShortcutFieldProps { } export default function ShortcutField({ value, onChange, disable = false, minWidth = '10rem' }: ShortcutFieldProps) { + const theme = useTheme(); + const isDark = theme.palette.mode === 'dark'; const [isRecording, setIsRecording] = useState(false); const [currentCombo, setCurrentCombo] = useState(''); const [isHovered, setIsHovered] = useState(false); @@ -224,11 +226,15 @@ export default function ShortcutField({ value, onChange, disable = false, minWid display: 'flex', alignItems: 'center', gap: 2, - border: '1px solid #e0e0e0', + border: `1px solid ${theme.palette.divider}`, borderRadius: 1, padding: '0.5rem 0.75rem', minWidth, - backgroundColor: disable ? '#f5f5f5' : (isRecording ? '#e3f2fd' : '#fff'), + backgroundColor: disable + ? theme.palette.action.disabledBackground + : (isRecording + ? (isDark ? 'rgba(144, 202, 249, 0.16)' : '#e3f2fd') + : theme.palette.background.paper), cursor: disable ? 'not-allowed' : 'pointer', opacity: disable ? 0.7 : 1, }} @@ -249,7 +255,7 @@ export default function ShortcutField({ value, onChange, disable = false, minWid {index < array.length - 1 && ( - + + + )} ))} @@ -267,7 +273,7 @@ export default function ShortcutField({ value, onChange, disable = false, minWid {index < array.length - 1 && ( - + + + )} ))} @@ -288,11 +294,11 @@ export default function ShortcutField({ value, onChange, disable = false, minWid display: disable ? 'none' : 'flex', padding: '0.25rem', '&:hover': { - backgroundColor: 'rgba(0, 0, 0, 0.04)', + backgroundColor: 'action.hover', } }} > - + )} From c938c5063007428186cecce1c5ba2e76ba395d12 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 02:37:03 +0530 Subject: [PATCH 04/34] feat: add i18n for ShortcutField, ThemeProvider for motion-board, snackbar styling - ShortcutField now uses react-i18next for all display text - Added shortcut translation keys to all locale files - Motion-board page gets its own ThemeProvider with system theme support - Snackbar alerts use filled variant throughout Co-authored-by: CommandCodeBot --- src/components/ShortcutField.tsx | 14 +++++---- src/contexts/SnackbarContext.tsx | 2 +- src/i18n/locales/de-DE.json | 14 +++++++-- src/i18n/locales/en-US.json | 10 ++++-- src/i18n/locales/es-ES.json | 14 +++++++-- src/i18n/locales/fr-FR.json | 8 ++++- src/i18n/locales/ja-JP.json | 8 ++++- src/i18n/locales/ko-KR.json | 8 ++++- src/i18n/locales/zh-CN.json | 10 ++++-- src/i18n/locales/zh-TW.json | 20 +++++++++--- src/pages/motion-board/App.tsx | 3 +- src/pages/motion-board/main.tsx | 52 ++++++++++++++++++++++++++++++-- 12 files changed, 133 insertions(+), 30 deletions(-) diff --git a/src/components/ShortcutField.tsx b/src/components/ShortcutField.tsx index e87090c..11fb830 100644 --- a/src/components/ShortcutField.tsx +++ b/src/components/ShortcutField.tsx @@ -28,6 +28,7 @@ import { KeyComboTag } from "@blueprintjs/core"; import "@blueprintjs/core/lib/css/blueprint.css"; import { platform } from '@tauri-apps/plugin-os'; import { useSnackbar } from "../contexts/SnackbarContext"; +import { useTranslation } from 'react-i18next'; import ClearIcon from '@mui/icons-material/Clear'; interface ShortcutFieldProps { @@ -40,6 +41,7 @@ interface ShortcutFieldProps { export default function ShortcutField({ value, onChange, disable = false, minWidth = '10rem' }: ShortcutFieldProps) { const theme = useTheme(); const isDark = theme.palette.mode === 'dark'; + const { t } = useTranslation(); const [isRecording, setIsRecording] = useState(false); const [currentCombo, setCurrentCombo] = useState(''); const [isHovered, setIsHovered] = useState(false); @@ -65,13 +67,13 @@ export default function ShortcutField({ value, onChange, disable = false, minWid if (event.metaKey) { switch (os) { case 'windows': - notify('不支持使用 Win 键作为快捷键', 'warning'); + notify(t('shortcut.winKeyNotSupported'), 'warning'); return; case 'macos': keys.push('Command'); break; case 'linux': - notify('不支持使用 Meta 键作为快捷键', 'warning'); + notify(t('shortcut.metaKeyNotSupported'), 'warning'); break; } } @@ -167,13 +169,13 @@ export default function ShortcutField({ value, onChange, disable = false, minWid if (event.metaKey) { switch (os) { case 'windows': - notify('不支持使用 Win 键作为快捷键', 'warning'); + notify(t('shortcut.winKeyNotSupported'), 'warning'); return; case 'macos': keys.push('Command'); break; case 'linux': - notify('不支持使用 Meta 键作为快捷键', 'warning'); + notify(t('shortcut.metaKeyNotSupported'), 'warning'); break; } } @@ -262,7 +264,7 @@ export default function ShortcutField({ value, onChange, disable = false, minWid ) : ( - + )} @@ -281,7 +283,7 @@ export default function ShortcutField({ value, onChange, disable = false, minWid ) : ( - + ) diff --git a/src/contexts/SnackbarContext.tsx b/src/contexts/SnackbarContext.tsx index 20f2d6a..ee2f6ed 100644 --- a/src/contexts/SnackbarContext.tsx +++ b/src/contexts/SnackbarContext.tsx @@ -57,7 +57,7 @@ export const SnackbarProvider: React.FC<{ children: ReactNode }> = ({ children } onClose={handleClose} anchorOrigin={{ vertical: 'top', horizontal: 'right' }} > - + {message} diff --git a/src/i18n/locales/de-DE.json b/src/i18n/locales/de-DE.json index 990ab7c..48a8d02 100644 --- a/src/i18n/locales/de-DE.json +++ b/src/i18n/locales/de-DE.json @@ -155,9 +155,11 @@ "version": "Version {{version}}", "officialAccount": "Offizieller Account", "visitWebsite": "Website besuchen", - "contactUs": "Kontaktieren Sie uns", "copySystemInfo": "Systeminformationen", + "contactUs": "Kontaktieren Sie uns", + "copySystemInfo": "Systeminformationen", "copySuccess": "Systeminformationen in die Zwischenablage kopiert", - "copyFailed": "Kopieren fehlgeschlagen, bitte versuchen Sie es erneut", "copyright": "© {{year}} FioFio Studio. Alle Rechte vorbehalten." + "copyFailed": "Kopieren fehlgeschlagen, bitte versuchen Sie es erneut", + "copyright": "© {{year}} FioFio Studio. Alle Rechte vorbehalten." }, "tray": { "preferences": "Einstellungen", @@ -186,5 +188,11 @@ "leftClick": "LClick", "middleClick": "MClick", "rightClick": "RClick" + }, + "shortcut": { + "winKeyNotSupported": "Die Win-Taste kann nicht als Tastenkürzel verwendet werden", + "metaKeyNotSupported": "Die Meta-Taste kann nicht als Tastenkürzel verwendet werden", + "pressShortcut": "Tastenkürzel drücken", + "notSet": "Nicht gesetzt" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index ee538ce..6291ce8 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -51,8 +51,6 @@ "speedUpdated": "Speed updated", "primaryColorUpdated": "Primary color updated", "secondaryColorUpdated": "Secondary color updated", - "primaryColorUpdated": "Primary color updated", - "secondaryColorUpdated": "Secondary color updated", "saveFailed": "Failed to save settings", "loadFailed": "Failed to load settings", "vipOnly": "Click effect type is a VIP feature", @@ -190,5 +188,11 @@ "leftClick": "LClick", "middleClick": "MClick", "rightClick": "RClick" + }, + "shortcut": { + "winKeyNotSupported": "Win key is not supported as a shortcut key", + "metaKeyNotSupported": "Meta key is not supported as a shortcut key", + "pressShortcut": "Press shortcut", + "notSet": "Not set" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/es-ES.json b/src/i18n/locales/es-ES.json index 9b0d518..f880e0b 100644 --- a/src/i18n/locales/es-ES.json +++ b/src/i18n/locales/es-ES.json @@ -155,9 +155,11 @@ "version": "Versión {{version}}", "officialAccount": "Cuenta oficial", "visitWebsite": "Visitar sitio web", - "contactUs": "Contáctanos", "copySystemInfo": "Información del sistema", + "contactUs": "Contáctanos", + "copySystemInfo": "Información del sistema", "copySuccess": "Información del sistema copiada al portapapeles", - "copyFailed": "Error al copiar, inténtelo de nuevo", "copyright": "© {{year}} FioFio Studio. Todos los derechos reservados." + "copyFailed": "Error al copiar, inténtelo de nuevo", + "copyright": "© {{year}} FioFio Studio. Todos los derechos reservados." }, "tray": { "preferences": "Preferencias", @@ -186,5 +188,11 @@ "leftClick": "LClick", "middleClick": "MClick", "rightClick": "RClick" + }, + "shortcut": { + "winKeyNotSupported": "La tecla Win no se puede usar como atajo de teclado", + "metaKeyNotSupported": "La tecla Meta no se puede usar como atajo de teclado", + "pressShortcut": "Presione el atajo", + "notSet": "No establecido" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/fr-FR.json b/src/i18n/locales/fr-FR.json index 335f49d..6a8831f 100644 --- a/src/i18n/locales/fr-FR.json +++ b/src/i18n/locales/fr-FR.json @@ -188,5 +188,11 @@ "leftClick": "LClick", "middleClick": "MClick", "rightClick": "RClick" + }, + "shortcut": { + "winKeyNotSupported": "La touche Win ne peut pas être utilisée comme raccourci", + "metaKeyNotSupported": "La touche Meta ne peut pas être utilisée comme raccourci", + "pressShortcut": "Appuyez sur le raccourci", + "notSet": "Non défini" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/ja-JP.json b/src/i18n/locales/ja-JP.json index cac3286..40eaea3 100644 --- a/src/i18n/locales/ja-JP.json +++ b/src/i18n/locales/ja-JP.json @@ -188,5 +188,11 @@ "leftClick": "LClick", "middleClick": "MClick", "rightClick": "RClick" + }, + "shortcut": { + "winKeyNotSupported": "Winキーはショートカットキーとして使用できません", + "metaKeyNotSupported": "MetaキーはショートカットキーとSして使用できません", + "pressShortcut": "ショートカットを押してください", + "notSet": "未設定" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/ko-KR.json b/src/i18n/locales/ko-KR.json index d5f6d83..aa0df56 100644 --- a/src/i18n/locales/ko-KR.json +++ b/src/i18n/locales/ko-KR.json @@ -188,5 +188,11 @@ "leftClick": "LClick", "middleClick": "MClick", "rightClick": "RClick" + }, + "shortcut": { + "winKeyNotSupported": "Win 키는 단축키로 사용할 수 없습니다", + "metaKeyNotSupported": "Meta 키는 단축키로 사용할 수 없습니다", + "pressShortcut": "단축키를 누르세요", + "notSet": "설정 안됨" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 122f465..84fc9c4 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -51,8 +51,6 @@ "speedUpdated": "动画速度已更新", "primaryColorUpdated": "主颜色已更新", "secondaryColorUpdated": "副颜色已更新", - "primaryColorUpdated": "主颜色已更新", - "secondaryColorUpdated": "副颜色已更新", "saveFailed": "保存设置失败", "loadFailed": "加载设置失败", "vipOnly": "点击特效类型为会员专享功能", @@ -190,5 +188,11 @@ "leftClick": "鼠标左键", "middleClick": "鼠标中键", "rightClick": "鼠标右键" + }, + "shortcut": { + "winKeyNotSupported": "不支持使用 Win 键作为快捷键", + "metaKeyNotSupported": "不支持使用 Meta 键作为快捷键", + "pressShortcut": "按下快捷键", + "notSet": "未设置" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index ec30f40..9717156 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -155,9 +155,11 @@ "version": "版本 {{version}}", "officialAccount": "官方公眾號", "visitWebsite": "造訪官網", - "contactUs": "聯絡我們", "copySystemInfo": "軟體資訊", + "contactUs": "聯絡我們", + "copySystemInfo": "軟體資訊", "copySuccess": "軟體資訊已複製到剪貼簿", - "copyFailed": "複製失敗,請重試", "copyright": "© {{year}} 飛鷗工作室. All rights reserved." + "copyFailed": "複製失敗,請重試", + "copyright": "© {{year}} 飛鷗工作室. All rights reserved." }, "tray": { "preferences": "偏好設定", @@ -165,7 +167,8 @@ "website": "GitHub", "version": "版本 {{version}}", "restart": "重新啟動應用程式", - "quit": "結束" }, + "quit": "結束" + }, "keys": { "kp0": "小鍵盤0", "kp1": "小鍵盤1", @@ -184,5 +187,12 @@ "kpPlus": "小鍵盤+", "leftClick": "鼠標左鍵", "middleClick": "鼠標中鍵", - "rightClick": "鼠標右鍵" } -} + "rightClick": "鼠標右鍵" + }, + "shortcut": { + "winKeyNotSupported": "不支援使用 Win 鍵作為快捷鍵", + "metaKeyNotSupported": "不支援使用 Meta 鍵作為快捷鍵", + "pressShortcut": "按下快捷鍵", + "notSet": "未設置" + } +} \ No newline at end of file diff --git a/src/pages/motion-board/App.tsx b/src/pages/motion-board/App.tsx index 9b1625a..1d79266 100644 --- a/src/pages/motion-board/App.tsx +++ b/src/pages/motion-board/App.tsx @@ -138,7 +138,7 @@ function App() { setIgnoreCursorEvents(newState); if (newState == false) { - setSnackbar({ open: true, message: '进入绘制模式' }); + setSnackbar({ open: true, message: i18n.t('drawing.messages.enterDrawMode') }); setKeyboardPanel(prev => ({ ...prev, modifierKeys: [], keys: [] })); await appWindow.setFocusable(true) await appWindow.setIgnoreCursorEvents(newState); @@ -406,6 +406,7 @@ function App() { setSnackbar({ open: false, message: '' })} severity="info" + variant="filled" > {snackbar.message} diff --git a/src/pages/motion-board/main.tsx b/src/pages/motion-board/main.tsx index 5aebd06..338147f 100644 --- a/src/pages/motion-board/main.tsx +++ b/src/pages/motion-board/main.tsx @@ -22,17 +22,65 @@ * SOFTWARE. */ -import React from "react"; +import React, { useState, useEffect } from "react"; import ReactDOM from "react-dom/client"; import App from "./App"; +import { ThemeProvider } from '@mui/material/styles'; +import { lightTheme, darkTheme } from '../../theme'; +import { getSettings } from '../../store/settings'; +import { listen } from '@tauri-apps/api/event'; import '@fontsource/fira-code/index.css'; import '@fontsource/noto-sans/index.css'; import '@fontsource/noto-sans-sc/index.css'; import '@fontsource/noto-sans-tc/index.css'; +function resolveTheme(setting: string | undefined): 'light' | 'dark' { + if (setting === 'dark') return 'dark'; + if (setting === 'light') return 'light'; + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; +} + +function ThemedApp() { + const [mode, setMode] = useState<'light' | 'dark'>(() => resolveTheme(undefined)); + + useEffect(() => { + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + let currentSetting: string | undefined; + + getSettings().then(s => { + currentSetting = s.theme; + setMode(resolveTheme(s.theme)); + }); + + const handleMedia = () => { + if (!currentSetting || currentSetting === 'auto') { + setMode(mediaQuery.matches ? 'dark' : 'light'); + } + }; + mediaQuery.addEventListener('change', handleMedia); + + let unlisten: (() => void) | undefined; + listen<{ theme: string }>('theme-updated', (event) => { + currentSetting = event.payload.theme; + setMode(resolveTheme(event.payload.theme)); + }).then(fn => { unlisten = fn; }); + + return () => { + mediaQuery.removeEventListener('change', handleMedia); + unlisten?.(); + }; + }, []); + + return ( + + + + ); +} + ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( - + , ); From f1257141987ce77e4b3a772d00af80da243e357c Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 02:49:55 +0530 Subject: [PATCH 05/34] feat: lazy-show main window after theme loads, init locale in motion-board - Main window starts hidden to prevent flash of wrong theme - Window shown once theme setting is resolved from store - Motion-board initializes locale on mount Co-authored-by: CommandCodeBot --- src/main.tsx | 2 ++ src/pages/motion-board/App.tsx | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main.tsx b/src/main.tsx index 7be2fdb..a1121ef 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -25,6 +25,7 @@ import React, { useState, useEffect } from "react"; import ReactDOM from "react-dom/client"; import App from "./App.tsx"; +import { getCurrentWindow } from "@tauri-apps/api/window"; import { ThemeProvider } from '@mui/material/styles'; import CssBaseline from '@mui/material/CssBaseline'; import { lightTheme, darkTheme } from './theme'; @@ -54,6 +55,7 @@ function ThemedApp() { getSettings().then(s => { currentSetting = s.theme; setMode(resolveTheme(s.theme)); + getCurrentWindow().show(); }); const handleMedia = () => { diff --git a/src/pages/motion-board/App.tsx b/src/pages/motion-board/App.tsx index 1d79266..149d59f 100644 --- a/src/pages/motion-board/App.tsx +++ b/src/pages/motion-board/App.tsx @@ -36,7 +36,7 @@ import { useKeyboardSettings } from "../../hooks/useKeyboardSettings"; import { useDrawingSettings } from "../../hooks/useDrawingSettings"; import { KeyLabel, MODIFIER_KEY_LIST, IGNORE_KEY_LIST, MOUSE_CLICK_KEYS } from "../../types/ModifierKey"; import { Alert, Snackbar, Zoom } from "@mui/material"; -import i18n from "../../i18n"; +import i18n, { initLocale } from "../../i18n"; function App() { // 从 store 加载鼠标设置 @@ -109,6 +109,15 @@ function App() { }; }, []); + useEffect(() => { + initLocale().then(language => { + if (language !== i18n.language) { + i18n.changeLanguage(language); + setLocale(language); + } + }); + }, []); + // 组件挂载时初始化窗口设置 useEffect(() => { // 设置窗口焦点和忽略鼠标事件 From 5b358bc54d96fafb3d5e08060b4a9b0afa23e21c Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 02:50:14 +0530 Subject: [PATCH 06/34] feat: hide main window on startup to prevent theme flash Window starts with visible: false so theme can be resolved before the user sees anything. Co-authored-by: CommandCodeBot --- src-tauri/tauri.conf.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 6b89a44..1cb23de 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -19,7 +19,8 @@ "width": 880, "height": 720, "decorations": true, - "shadow": true + "shadow": true, + "visible": false } ], "security": { From 388c05a321be217c798477f4ab8feb6bd0368ad7 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 02:59:44 +0530 Subject: [PATCH 07/34] feat: update default keyboard settings to disable echo --- src-tauri/src/tray.rs | 4 ++-- src/store/settings.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src-tauri/src/tray.rs b/src-tauri/src/tray.rs index 968d7fa..02f84cc 100644 --- a/src-tauri/src/tray.rs +++ b/src-tauri/src/tray.rs @@ -25,7 +25,7 @@ use tauri::{ tray::TrayIconBuilder, App, AppHandle, Manager, }; -use tauri_plugin_shell::ShellExt; +use tauri_plugin_opener::OpenerExt; /// 创建系统托盘图标 #[allow(dead_code)] @@ -123,7 +123,7 @@ fn handle_menu_event(app: &AppHandle, event: tauri::menu::MenuEvent) { } } "website" => { - let _ = app.shell().open("https://www.fiofio.cn", None); + let _ = app.opener().open_url("https://www.fiofio.cn", None::<&str>); } "restart" => { app.restart(); diff --git a/src/store/settings.ts b/src/store/settings.ts index 81489ae..b9411e2 100644 --- a/src/store/settings.ts +++ b/src/store/settings.ts @@ -96,8 +96,8 @@ const defaultSettings: AppSettings = { apertureScale: 1.0, }, keyboard: { - enableKeyboardEcho: true, - enableClickEcho: true, + enableKeyboardEcho: false, + enableClickEcho: false, preview: false, scale: 1.0, fgColor: 'rgba(190,255,255,1.0)', From ec06636a8b3cb278413a4f3e0f049f9e4fa708bd Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 03:02:45 +0530 Subject: [PATCH 08/34] feat: reduce default stroke width for elements from 2 to 1 --- src/packages/excalidraw/packages/excalidraw/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/excalidraw/packages/excalidraw/constants.ts b/src/packages/excalidraw/packages/excalidraw/constants.ts index 616ced1..bc69288 100644 --- a/src/packages/excalidraw/packages/excalidraw/constants.ts +++ b/src/packages/excalidraw/packages/excalidraw/constants.ts @@ -391,7 +391,7 @@ export const DEFAULT_ELEMENT_PROPS: { strokeColor: COLOR_PALETTE.black, backgroundColor: COLOR_PALETTE.transparent, fillStyle: "solid", - strokeWidth: 2, + strokeWidth: 1, strokeStyle: "solid", roughness: ROUGHNESS.artist, opacity: 100, From 6936aa83157259c8435897a5d52da34c4acce2eb Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 03:17:21 +0530 Subject: [PATCH 09/34] feat: add confirm clear annotation setting and related translations --- src/components/Settings.tsx | 25 +++++++++++++++++++ src/i18n/locales/de-DE.json | 1 + src/i18n/locales/en-US.json | 1 + src/i18n/locales/es-ES.json | 1 + src/i18n/locales/fr-FR.json | 1 + src/i18n/locales/ja-JP.json | 1 + src/i18n/locales/ko-KR.json | 1 + src/i18n/locales/zh-CN.json | 1 + src/i18n/locales/zh-TW.json | 1 + .../components/ActiveConfirmDialog.tsx | 13 ++++++++++ src/pages/motion-board/App.tsx | 4 +++ src/store/settings.ts | 2 ++ 12 files changed, 52 insertions(+) diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index a189095..421a2fd 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -1206,6 +1206,7 @@ function 绘图设置页面() { const { t } = useTranslation(); const [toggleShortcut, setToggleShortcut] = useState(''); const [toolbarShortcut, setToolbarShortcut] = useState(''); + const [confirmClearAnnotation, setConfirmClearAnnotation] = useState(false); const { notify } = useSnackbar(); // 加载设置 @@ -1215,6 +1216,7 @@ function 绘图设置页面() { const settings = await getSettings(); setToggleShortcut(settings.drawing?.toggleShortcut); setToolbarShortcut(settings.drawing?.toolbarShortcut); + setConfirmClearAnnotation(settings.drawing?.confirmClearAnnotation ?? true); } catch (error) { console.error('加载绘图设置失败:', error); notify(t('drawing.messages.loadFailed'), 'error'); @@ -1261,6 +1263,21 @@ function 绘图设置页面() { } }; + const handleConfirmClearChange = async (checked: boolean) => { + setConfirmClearAnnotation(checked); + try { + const currentSettings = await getSettings(); + await updateSettings({ + drawing: { + ...currentSettings.drawing, + confirmClearAnnotation: checked, + } + }); + } catch (error) { + console.error('保存设置失败:', error); + } + }; + return ( {t('drawing.title')} @@ -1293,6 +1310,14 @@ function 绘图设置页面() { /> } /> + handleConfirmClearChange(e.target.checked)} + /> + } /> { ); const actionManager = useExcalidrawActionManager(); + useEffect(() => { + if (activeConfirmDialog === "clearCanvas") { + if ((window as any).__penio_confirmClearAnnotation === false) { + actionManager.executeAction(actionClearCanvas); + setActiveConfirmDialog(null); + } + } + }, [activeConfirmDialog]); + if (!activeConfirmDialog) { return null; } if (activeConfirmDialog === "clearCanvas") { + if ((window as any).__penio_confirmClearAnnotation === false) { + return null; + } return ( { diff --git a/src/pages/motion-board/App.tsx b/src/pages/motion-board/App.tsx index 149d59f..d2dfa17 100644 --- a/src/pages/motion-board/App.tsx +++ b/src/pages/motion-board/App.tsx @@ -45,6 +45,10 @@ function App() { const { keyboardSettings, } = useKeyboardSettings(); const { drawingSettings, } = useDrawingSettings(); + useEffect(() => { + (window as any).__penio_confirmClearAnnotation = drawingSettings.confirmClearAnnotation ?? true; + }, [drawingSettings]); + // 存储鼠标穿透状态 const [ignoreCursorEvents, setIgnoreCursorEvents] = useState(true); diff --git a/src/store/settings.ts b/src/store/settings.ts index b9411e2..225fc82 100644 --- a/src/store/settings.ts +++ b/src/store/settings.ts @@ -63,6 +63,7 @@ export interface KeyboardSettings { export interface DrawingSettings { toggleShortcut: string; toolbarShortcut: string; + confirmClearAnnotation?: boolean; } // 应用设置接口 @@ -108,6 +109,7 @@ const defaultSettings: AppSettings = { drawing: { toggleShortcut: 'Alt+`', toolbarShortcut: 'Alt+H', + confirmClearAnnotation: true, }, }; From ab06a9ddfcc708b0237565c7d43639fb9c40a7ea Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 12:57:09 +0530 Subject: [PATCH 10/34] feat: add enable scroll and pan setting with translations --- src/components/Settings.tsx | 25 +++++++++++++++++++ src/i18n/locales/de-DE.json | 5 ++-- src/i18n/locales/en-US.json | 5 ++-- src/i18n/locales/es-ES.json | 5 ++-- src/i18n/locales/fr-FR.json | 5 ++-- src/i18n/locales/ja-JP.json | 5 ++-- src/i18n/locales/ko-KR.json | 5 ++-- src/i18n/locales/zh-CN.json | 5 ++-- src/i18n/locales/zh-TW.json | 5 ++-- src/main.tsx | 14 +++++++---- .../packages/excalidraw/components/App.tsx | 8 ++++-- src/pages/motion-board/App.tsx | 1 + src/store/settings.ts | 2 ++ 13 files changed, 67 insertions(+), 23 deletions(-) diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index 421a2fd..396999b 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -1207,6 +1207,7 @@ function 绘图设置页面() { const [toggleShortcut, setToggleShortcut] = useState(''); const [toolbarShortcut, setToolbarShortcut] = useState(''); const [confirmClearAnnotation, setConfirmClearAnnotation] = useState(false); + const [enableScrollAndPan, setEnableScrollAndPan] = useState(true); const { notify } = useSnackbar(); // 加载设置 @@ -1217,6 +1218,7 @@ function 绘图设置页面() { setToggleShortcut(settings.drawing?.toggleShortcut); setToolbarShortcut(settings.drawing?.toolbarShortcut); setConfirmClearAnnotation(settings.drawing?.confirmClearAnnotation ?? true); + setEnableScrollAndPan(settings.drawing?.enableScrollAndPan ?? true); } catch (error) { console.error('加载绘图设置失败:', error); notify(t('drawing.messages.loadFailed'), 'error'); @@ -1263,6 +1265,21 @@ function 绘图设置页面() { } }; + const handleEnableScrollAndPanChange = async (checked: boolean) => { + setEnableScrollAndPan(checked); + try { + const currentSettings = await getSettings(); + await updateSettings({ + drawing: { + ...currentSettings.drawing, + enableScrollAndPan: checked, + } + }); + } catch (error) { + console.error('保存设置失败:', error); + } + }; + const handleConfirmClearChange = async (checked: boolean) => { setConfirmClearAnnotation(checked); try { @@ -1318,6 +1335,14 @@ function 绘图设置页面() { onChange={(e) => handleConfirmClearChange(e.target.checked)} /> } /> + handleEnableScrollAndPanChange(e.target.checked)} + /> + } />
); } diff --git a/src/components/AboutPage.tsx b/src/components/AboutPage.tsx index 4e0e8f3..bfbc5c0 100644 --- a/src/components/AboutPage.tsx +++ b/src/components/AboutPage.tsx @@ -47,7 +47,7 @@ function 关于页面() { platformArch: "...", platformVersion: "...", }); - const githubUrl = "https://github.com/game1024/Penio"; + const githubUrl = "https://github.com/khatrihemang07/Penio"; useEffect(() => { getName().then(setAppName); diff --git a/src/hooks/useTray.ts b/src/hooks/useTray.ts index 49733e5..262cf1c 100644 --- a/src/hooks/useTray.ts +++ b/src/hooks/useTray.ts @@ -62,7 +62,7 @@ export function useTray() { id: 'website', text: t('tray.website'), action: async () => { - await open('https://github.com/game1024/Penio'); + await open('https://github.com/khatrihemang07/Penio'); } }, PredefinedMenuItem.new({ item: 'Separator' }), From be4a074bda44153205f45f6dafb88d40c89acc53 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 15:11:05 +0530 Subject: [PATCH 12/34] Remove English README and add Chinese README; update links and titles in other language READMEs; modify Tauri configuration for window title; adjust App component for conditional rendering; update visitor badge paths and GitHub links to new repository. --- README.md | 198 ++++++++++++++++----------------- README_CN.md | 216 ++++++++++++++++++++++++++++++++++++ README_DE.md | 39 ++++--- README_EN.md | 223 -------------------------------------- README_FR.md | 39 ++++--- README_JA.md | 39 ++++--- README_KO.md | 39 ++++--- src-tauri/tauri.conf.json | 2 +- src/App.tsx | 10 +- 9 files changed, 396 insertions(+), 409 deletions(-) create mode 100644 README_CN.md delete mode 100644 README_EN.md diff --git a/README.md b/README.md index ed0412e..9f368eb 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,6 @@

- -Gemini_Generated_Image_n3p4rln3p4rln3p4 - -

-

- 简体中文 | English | 日本語 | 한국어 | Français | Deutsch + 简体中文 | English | 日本語 | 한국어 | Français | Deutsch

@@ -15,42 +10,42 @@

Penio

- 更酷、更炫、更灵动 + Cooler, Flashier, More Dynamic

- 一款强大的屏幕标注和演示工具,让你的演示、教学、录屏更加生动有趣 + A powerful screen annotation and presentation tool that makes your demos, teaching, and screen recordings more vivid and engaging

- +
- - GitHub Stars + + GitHub Stars - GitHub Forks + GitHub Forks - - Github Issues + + Github Issues
- - Downloads + + Downloads - - Version + + Version - + Platform
- - 提交活跃度 + + Commit Activity @@ -63,11 +58,11 @@ --- -## 📦 安装 +## 📦 Installation -### 下载安装包 +### Download Installer -前往 [Releases](https://github.com/game1024/Penio/releases) 页面下载适合你操作系统的安装包: +Visit the [Releases](https://github.com/khatrihemang07/Penio/releases) page to download the installer for your operating system: - **Windows**: @@ -76,151 +71,150 @@ - **macOS**: - - Apple Silicon (M1/M2/M3等): `Penio_x.x.x_aarch64.dmg` - - Intel 芯片: `Penio_x.x.x_x64.dmg` + - Apple Silicon (M1/M2/M3, etc.): `Penio_x.x.x_aarch64.dmg` + - Intel chips: `Penio_x.x.x_x64.dmg` - **Linux**: - - ARM 芯片: `Penio_x.x.x_aarch64.deb` / `Penio_x.x.x_aarch64.AppImage` / `Penio_x.x.x_aarch64.rpm` - - x64 芯片: `Penio_x.x.x_amd64.deb` / `Penio_x.x.x_amd64.AppImage` / `Penio_x.x.x_amd64.rpm` + - ARM chips: `Penio_x.x.x_aarch64.deb` / `Penio_x.x.x_aarch64.AppImage` / `Penio_x.x.x_aarch64.rpm` + - x64 chips: `Penio_x.x.x_amd64.deb` / `Penio_x.x.x_amd64.AppImage` / `Penio_x.x.x_amd64.rpm` --- -## 🚀 使用 +## 🚀 Usage -### 基本操作 +### Basic Operations -1. **启动应用**:应用会最小化到系统托盘 -2. **打开设置**:点击托盘图标 → 设置 -3. **启用功能**: - - 在"鼠标"标签页启用点击特效 - - 在"键盘"标签页启用键盘回显 - - 在"绘图"标签页配置快捷键 -4. **开始使用**:按下快捷键即可在屏幕上绘图 +1. **Launch App**: The app minimizes to the system tray +2. **Open Settings**: Click tray icon → Settings +3. **Enable Features**: + - Enable click effects in the "Mouse" tab + - Enable keyboard echo in the "Keyboard" tab + - Configure shortcuts in the "Drawing" tab +4. **Start Using**: Press the shortcut to start drawing on screen --- -## ✨ 功能特性 +## ✨ Features -### 🎨 屏幕绘图 +### 🎨 Screen Drawing -在屏幕上自由绘制,支持多种绘图工具,让你的演示更加直观。 +Draw freely on your screen with various drawing tools to make your presentations more intuitive. -#### 压感画笔 -支持压感的画笔工具,线条粗细随力度变化 +#### Pressure-Sensitive Brush +A pressure-sensitive brush tool where line thickness varies with applied force -#### 渐隐画笔 -笔迹自动渐隐消失,适合临时标注 +#### Fade-Out Brush +Strokes automatically fade away, perfect for temporary annotations -#### 矩形工具 -快速绘制矩形框,突出重点区域 +#### Rectangle Tool +Quickly draw rectangular frames to highlight key areas -#### 椭圆工具 -绘制圆形和椭圆,标注关键内容 +#### Ellipse Tool +Draw circles and ellipses to mark important content -### 🖱️ 鼠标点击特效 +### 🖱️ Mouse Click Effects -为鼠标点击添加炫酷的视觉效果,让观众清楚看到你的操作。 +Add cool visual effects to mouse clicks so viewers can clearly see your actions. -#### 水波纹 +#### Ripple -#### 烟花 +#### Firework -#### 螺旋 +#### Spiral -#### 圆形描边 +#### Circle Stroke -#### 方形描边 +#### Rectangle Stroke -### ⌨️ 键盘回显 +### ⌨️ Keyboard Echo -实时显示你按下的按键,让教学演示更加清晰。 +Display pressed keys in real-time for clearer teaching demonstrations. -### 🌍 多语言支持 +### 🌍 Multi-Language Support -支持中文(简体/繁体)、英语、日语、韩语、法语、德语、西班牙语等多种语言。 +Supports Chinese (Simplified/Traditional), English, Japanese, Korean, French, German, Spanish, and more. -### 🎯 其他特性 +### 🎯 Other Features -- ✅ **跨平台支持**:支持 Windows、macOS、Linux -- ✅ **透明窗口**:绘图时不遮挡屏幕内容 -- ✅ **快捷键操作**:自定义快捷键,快速切换功能 -- ✅ **自定义样式**:调整颜色、大小、速度等参数 -- ✅ **开机自启**:可设置开机自动启动 -- ✅ **系统托盘**:最小化到系统托盘,随时调用 +- ✅ **Cross-Platform**: Supports Windows, macOS, Linux +- ✅ **Transparent Window**: Drawing doesn't obstruct screen content +- ✅ **Keyboard Shortcuts**: Customizable shortcuts for quick feature toggling +- ✅ **Customizable Styles**: Adjust colors, sizes, speeds, and other parameters +- ✅ **Auto-Start**: Optional auto-start on system boot +- ✅ **System Tray**: Minimize to system tray for easy access --- -## 🛠️ 开发 - +## 🛠️ Development -### 开发环境要求 +### Development Requirements - Node.js >= 18 - Bun >= 1.0 - Rust >= 1.70 -- 操作系统特定要求: +- OS-specific requirements: - **Windows**: WebView2 - **macOS**: Xcode Command Line Tools - **Linux**: webkit2gtk, libgtk-3-dev -### 项目结构 +### Project Structure ``` penio/ -├── src/ # 前端源码 -│ ├── components/ # React 组件 -│ ├── hooks/ # 自定义 Hooks -│ ├── i18n/ # 国际化 -│ ├── pages/ # 页面 -│ ├── store/ # 状态管理 -│ └── utils/ # 工具函数 -├── src-tauri/ # Tauri 后端 -│ ├── src/ # Rust 源码 -│ ├── icons/ # 应用图标 -│ └── capabilities/ # 权限配置 -├── docs/ # 文档和演示视频 -└── public/ # 静态资源 +├── src/ # Frontend source code +│ ├── components/ # React components +│ ├── hooks/ # Custom Hooks +│ ├── i18n/ # Internationalization +│ ├── pages/ # Pages +│ ├── store/ # State management +│ └── utils/ # Utilities +├── src-tauri/ # Tauri backend +│ ├── src/ # Rust source code +│ ├── icons/ # App icons +│ └── capabilities/ # Permission configs +├── docs/ # Documentation and demo videos +└── public/ # Static assets ``` -## 📄 许可证 +## 📄 License -本项目采用 [MIT License](LICENSE) 开源协议。 +This project is licensed under the [MIT License](LICENSE). --- -## 🙏 致谢 +## 🙏 Acknowledgments -- [Tauri](https://tauri.app/) - 强大的桌面应用框架 -- [Excalidraw](https://excalidraw.com/) - 优秀的手绘风格绘图工具 -- [Mo.js](https://mojs.github.io/) - 灵活的动画库 -- [Material-UI](https://mui.com/) - React UI 组件库 -- [rdev](https://github.com/Narsil/rdev) - Rust 事件监听 +- [Tauri](https://tauri.app/) - Powerful desktop application framework +- [Excalidraw](https://excalidraw.com/) - Excellent hand-drawn style drawing tool +- [Mo.js](https://mojs.github.io/) - Flexible animation library +- [Material-UI](https://mui.com/) - React UI component library +- [rdev](https://github.com/Narsil/rdev) - Rust event listening -## 🎁 请我杯咖啡 -如果觉得这个项目对你有帮助,请给个 ⭐️ Star 支持一下! +## 🎁 Support the Project +If this project helps you, please give it a ⭐️ Star! -|名称|介绍|备注| -|-|-|-| -|365VPN|我用过最稳定的,不限流的全系统VPN|[体验地址](https://ref.365tz87989.com/?r=RWQVZD)| +You can also support the development via [GitHub Sponsors](https://github.com/sponsors/khatrihemang07). --- -## 📮 联系方式 +## 📮 Contact -- **官网**: https://github.com/game1024 -- **BiliBili**: [@game1024](https://space.bilibili.com/426988409) -- **GitHub Issues**: [报告问题](https://github.com/game1024/Penio/issues) +- **Website**: https://github.com/khatrihemang07 +- **GitHub Issues**: [Report Issues](https://github.com/khatrihemang07/Penio/issues) --- -[![Star History Chart](https://api.star-history.com/svg?repos=game1024/Penio&type=date&legend=top-left)](https://www.star-history.com/#game1024/Penio&type=date&legend=top-left) +[![Star History Chart](https://api.star-history.com/svg?repos=khatrihemang07/Penio&type=date&legend=top-left)](https://www.star-history.com/#khatrihemang07/Penio&type=date&legend=top-left) +left) +svg?repos=khatrihemang07/Penio&type=date&legend=top-left)](https://www.star-history.com/#khatrihemang07/Penio&type=date&legend=top-left) +left) diff --git a/README_CN.md b/README_CN.md new file mode 100644 index 0000000..c222fe8 --- /dev/null +++ b/README_CN.md @@ -0,0 +1,216 @@ +

+ 简体中文 | English | 日本語 | 한국어 | Français | Deutsch +

+ +

+ Penio Logo +

+ +

Penio

+ +

+ 更酷、更炫、更灵动 +

+ +

+ 一款强大的屏幕标注和演示工具,让你的演示、教学、录屏更加生动有趣 +

+ +

+ + +
+ + + GitHub Stars + + + GitHub Forks + + + Github Issues + +
+ + + Downloads + + + Version + + + Platform + +
+ + + 提交活跃度 + + + +
+ + + Penio - A screen drawing application to add mouse click effects  | Product Hunt + +

+ +--- + +## 📦 安装 + +### 下载安装包 + +前往 [Releases](https://github.com/khatrihemang07/Penio/releases) 页面下载适合你操作系统的安装包: + +- **Windows**: + + + + + +- **macOS**: + - Apple Silicon (M1/M2/M3等): `Penio_x.x.x_aarch64.dmg` + - Intel 芯片: `Penio_x.x.x_x64.dmg` +- **Linux**: + - ARM 芯片: `Penio_x.x.x_aarch64.deb` / `Penio_x.x.x_aarch64.AppImage` / `Penio_x.x.x_aarch64.rpm` + - x64 芯片: `Penio_x.x.x_amd64.deb` / `Penio_x.x.x_amd64.AppImage` / `Penio_x.x.x_amd64.rpm` + +--- + +## 🚀 使用 + +### 基本操作 + +1. **启动应用**:应用会最小化到系统托盘 +2. **打开设置**:点击托盘图标 → 设置 +3. **启用功能**: + - 在"鼠标"标签页启用点击特效 + - 在"键盘"标签页启用键盘回显 + - 在"绘图"标签页配置快捷键 +4. **开始使用**:按下快捷键即可在屏幕上绘图 + +--- + +## ✨ 功能特性 + +### 🎨 屏幕绘图 + +在屏幕上自由绘制,支持多种绘图工具,让你的演示更加直观。 + +#### 压感画笔 +支持压感的画笔工具,线条粗细随力度变化 + + + +#### 渐隐画笔 +笔迹自动渐隐消失,适合临时标注 + + +#### 矩形工具 +快速绘制矩形框,突出重点区域 + + +#### 椭圆工具 +绘制圆形和椭圆,标注关键内容 + + +### 🖱️ 鼠标点击特效 + +为鼠标点击添加炫酷的视觉效果,让观众清楚看到你的操作。 + +#### 水波纹 + + +#### 烟花 + + +#### 螺旋 + + +#### 圆形描边 + + +#### 方形描边 + + +### ⌨️ 键盘回显 + +实时显示你按下的按键,让教学演示更加清晰。 + + +### 🌍 多语言支持 + +支持中文(简体/繁体)、英语、日语、韩语、法语、德语、西班牙语等多种语言。 + +### 🎯 其他特性 + +- ✅ **跨平台支持**:支持 Windows、macOS、Linux +- ✅ **透明窗口**:绘图时不遮挡屏幕内容 +- ✅ **快捷键操作**:自定义快捷键,快速切换功能 +- ✅ **自定义样式**:调整颜色、大小、速度等参数 +- ✅ **开机自启**:可设置开机自动启动 +- ✅ **系统托盘**:最小化到系统托盘,随时调用 + +--- + +## 🛠️ 开发 + + +### 开发环境要求 + +- Node.js >= 18 +- Bun >= 1.0 +- Rust >= 1.70 +- 操作系统特定要求: + - **Windows**: WebView2 + - **macOS**: Xcode Command Line Tools + - **Linux**: webkit2gtk, libgtk-3-dev + +### 项目结构 + +``` +penio/ +├── src/ # 前端源码 +│ ├── components/ # React 组件 +│ ├── hooks/ # 自定义 Hooks +│ ├── i18n/ # 国际化 +│ ├── pages/ # 页面 +│ ├── store/ # 状态管理 +│ └── utils/ # 工具函数 +├── src-tauri/ # Tauri 后端 +│ ├── src/ # Rust 源码 +│ ├── icons/ # 应用图标 +│ └── capabilities/ # 权限配置 +├── docs/ # 文档和演示视频 +└── public/ # 静态资源 +``` + +## 📄 许可证 + +本项目采用 [MIT License](LICENSE) 开源协议。 + +--- + +## 🙏 致谢 + +- [Tauri](https://tauri.app/) - 强大的桌面应用框架 +- [Excalidraw](https://excalidraw.com/) - 优秀的手绘风格绘图工具 +- [Mo.js](https://mojs.github.io/) - 灵活的动画库 +- [Material-UI](https://mui.com/) - React UI 组件库 +- [rdev](https://github.com/Narsil/rdev) - Rust 事件监听 + +## 🎁 请我杯咖啡 +如果觉得这个项目对你有帮助,请给个 ⭐️ Star 支持一下! + + +--- + +## 📮 联系方式 + +- **官网**: https://github.com/khatrihemang07 +- **GitHub Issues**: [报告问题](https://github.com/khatrihemang07/Penio/issues) + +--- + +[![Star History Chart](https://api.star-history.com/svg?repos=khatrihemang07/Penio&type=date&legend=top-left)](https://www.star-history.com/#khatrihemang07/Penio&type=date&legend=top-left) diff --git a/README_DE.md b/README_DE.md index 0f14010..1b60d47 100644 --- a/README_DE.md +++ b/README_DE.md @@ -1,5 +1,5 @@

- 简体中文 | English | 日本語 | 한국어 | Français | Deutsch + 简体中文 | English | 日本語 | 한국어 | Français | Deutsch

@@ -18,33 +18,33 @@

- +
- - GitHub Stars + + GitHub Stars - GitHub Forks + GitHub Forks - - Github Issues + + Github Issues
- - Downloads + + Downloads - - Version + + Version - + Platform
- - Commit-Aktivität + + Commit-Aktivität @@ -61,7 +61,7 @@ ### Installationsprogramm herunterladen -Besuchen Sie die [Releases](https://github.com/game1024/Penio/releases)-Seite, um das Installationsprogramm für Ihr Betriebssystem herunterzuladen: +Besuchen Sie die [Releases](https://github.com/khatrihemang07/Penio/releases)-Seite, um das Installationsprogramm für Ihr Betriebssystem herunterzuladen: - **Windows**: @@ -202,16 +202,15 @@ Dieses Projekt ist unter der [MIT-Lizenz](LICENSE) lizenziert. ## 🎁 Projekt unterstützen Wenn Ihnen dieses Projekt hilft, geben Sie ihm bitte einen ⭐️ Star! -Sie können die Entwicklung auch über [GitHub Sponsors](https://github.com/sponsors/game1024) unterstützen. +Sie können die Entwicklung auch über [GitHub Sponsors](https://github.com/sponsors/khatrihemang07) unterstützen. --- ## 📮 Kontakt -- **Webseite**: https://github.com/game1024 -- **BiliBili**: [@game1024](https://space.bilibili.com/426988409) -- **GitHub Issues**: [Problem melden](https://github.com/game1024/Penio/issues) +- **Webseite**: https://github.com/khatrihemang07 +- **GitHub Issues**: [Problem melden](https://github.com/khatrihemang07/Penio/issues) --- -[![Star History Chart](https://api.star-history.com/svg?repos=game1024/Penio&type=date&legend=top-left)](https://www.star-history.com/#game1024/Penio&type=date&legend=top-left) \ No newline at end of file +[![Star History Chart](https://api.star-history.com/svg?repos=khatrihemang07/Penio&type=date&legend=top-left)](https://www.star-history.com/#khatrihemang07/Penio&type=date&legend=top-left) \ No newline at end of file diff --git a/README_EN.md b/README_EN.md deleted file mode 100644 index f0859df..0000000 --- a/README_EN.md +++ /dev/null @@ -1,223 +0,0 @@ -

- -Gemini_Generated_Image_n3p4rln3p4rln3p4 - -

- -

- 简体中文 | English | 日本語 | 한국어 | Français | Deutsch -

- -

- Penio Logo -

- -

Penio

- -

- Cooler, Flashier, More Dynamic -

- -

- A powerful screen annotation and presentation tool that makes your demos, teaching, and screen recordings more vivid and engaging -

- -

- - -
- - - GitHub Stars - - - GitHub Forks - - - Github Issues - -
- - - Downloads - - - Version - - - Platform - -
- - - Commit Activity - - - -
- - - Penio - A screen drawing application to add mouse click effects  | Product Hunt - -

- ---- - -## 📦 Installation - -### Download Installer - -Visit the [Releases](https://github.com/game1024/Penio/releases) page to download the installer for your operating system: - -- **Windows**: - - - - - -- **macOS**: - - Apple Silicon (M1/M2/M3, etc.): `Penio_x.x.x_aarch64.dmg` - - Intel chips: `Penio_x.x.x_x64.dmg` -- **Linux**: - - ARM chips: `Penio_x.x.x_aarch64.deb` / `Penio_x.x.x_aarch64.AppImage` / `Penio_x.x.x_aarch64.rpm` - - x64 chips: `Penio_x.x.x_amd64.deb` / `Penio_x.x.x_amd64.AppImage` / `Penio_x.x.x_amd64.rpm` - ---- - -## 🚀 Usage - -### Basic Operations - -1. **Launch App**: The app minimizes to the system tray -2. **Open Settings**: Click tray icon → Settings -3. **Enable Features**: - - Enable click effects in the "Mouse" tab - - Enable keyboard echo in the "Keyboard" tab - - Configure shortcuts in the "Drawing" tab -4. **Start Using**: Press the shortcut to start drawing on screen - ---- - -## ✨ Features - -### 🎨 Screen Drawing - -Draw freely on your screen with various drawing tools to make your presentations more intuitive. - -#### Pressure-Sensitive Brush -A pressure-sensitive brush tool where line thickness varies with applied force - - - -#### Fade-Out Brush -Strokes automatically fade away, perfect for temporary annotations - - -#### Rectangle Tool -Quickly draw rectangular frames to highlight key areas - - -#### Ellipse Tool -Draw circles and ellipses to mark important content - - -### 🖱️ Mouse Click Effects - -Add cool visual effects to mouse clicks so viewers can clearly see your actions. - -#### Ripple - - -#### Firework - - -#### Spiral - - -#### Circle Stroke - - -#### Rectangle Stroke - - -### ⌨️ Keyboard Echo - -Display pressed keys in real-time for clearer teaching demonstrations. - - -### 🌍 Multi-Language Support - -Supports Chinese (Simplified/Traditional), English, Japanese, Korean, French, German, Spanish, and more. - -### 🎯 Other Features - -- ✅ **Cross-Platform**: Supports Windows, macOS, Linux -- ✅ **Transparent Window**: Drawing doesn't obstruct screen content -- ✅ **Keyboard Shortcuts**: Customizable shortcuts for quick feature toggling -- ✅ **Customizable Styles**: Adjust colors, sizes, speeds, and other parameters -- ✅ **Auto-Start**: Optional auto-start on system boot -- ✅ **System Tray**: Minimize to system tray for easy access - ---- - -## 🛠️ Development - -### Development Requirements - -- Node.js >= 18 -- Bun >= 1.0 -- Rust >= 1.70 -- OS-specific requirements: - - **Windows**: WebView2 - - **macOS**: Xcode Command Line Tools - - **Linux**: webkit2gtk, libgtk-3-dev - -### Project Structure - -``` -penio/ -├── src/ # Frontend source code -│ ├── components/ # React components -│ ├── hooks/ # Custom Hooks -│ ├── i18n/ # Internationalization -│ ├── pages/ # Pages -│ ├── store/ # State management -│ └── utils/ # Utilities -├── src-tauri/ # Tauri backend -│ ├── src/ # Rust source code -│ ├── icons/ # App icons -│ └── capabilities/ # Permission configs -├── docs/ # Documentation and demo videos -└── public/ # Static assets -``` - -## 📄 License - -This project is licensed under the [MIT License](LICENSE). - ---- - -## 🙏 Acknowledgments - -- [Tauri](https://tauri.app/) - Powerful desktop application framework -- [Excalidraw](https://excalidraw.com/) - Excellent hand-drawn style drawing tool -- [Mo.js](https://mojs.github.io/) - Flexible animation library -- [Material-UI](https://mui.com/) - React UI component library -- [rdev](https://github.com/Narsil/rdev) - Rust event listening - -## 🎁 Support the Project -If this project helps you, please give it a ⭐️ Star! - -You can also support the development via [GitHub Sponsors](https://github.com/sponsors/game1024). - ---- - -## 📮 Contact - -- **Website**: https://github.com/game1024 -- **BiliBili**: [@game1024](https://space.bilibili.com/426988409) -- **GitHub Issues**: [Report Issues](https://github.com/game1024/Penio/issues) - ---- - -[![Star History Chart](https://api.star-history.com/svg?repos=game1024/Penio&type=date&legend=top-left)](https://www.star-history.com/#game1024/Penio&type=date&legend=top-left) diff --git a/README_FR.md b/README_FR.md index 74151e8..ddafc6f 100644 --- a/README_FR.md +++ b/README_FR.md @@ -1,5 +1,5 @@

- 简体中文 | English | 日本語 | 한국어 | Français | Deutsch + 简体中文 | English | 日本語 | 한국어 | Français | Deutsch

@@ -18,33 +18,33 @@

- +
- - GitHub Stars + + GitHub Stars - GitHub Forks + GitHub Forks - - Github Issues + + Github Issues
- - Downloads + + Downloads - - Version + + Version - + Platform
- - Activité des commits + + Activité des commits @@ -61,7 +61,7 @@ ### Télécharger l'installateur -Visitez la page [Releases](https://github.com/game1024/Penio/releases) pour télécharger l'installateur pour votre système d'exploitation : +Visitez la page [Releases](https://github.com/khatrihemang07/Penio/releases) pour télécharger l'installateur pour votre système d'exploitation : - **Windows** : @@ -202,16 +202,15 @@ Ce projet est sous licence [MIT License](LICENSE). ## 🎁 Soutenir le projet Si ce projet vous aide, donnez-lui une ⭐️ Star ! -Vous pouvez aussi soutenir le développement via [GitHub Sponsors](https://github.com/sponsors/game1024). +Vous pouvez aussi soutenir le développement via [GitHub Sponsors](https://github.com/sponsors/khatrihemang07). --- ## 📮 Contact -- **Site web** : https://github.com/game1024 -- **BiliBili** : [@game1024](https://space.bilibili.com/426988409) -- **GitHub Issues** : [Signaler un problème](https://github.com/game1024/Penio/issues) +- **Site web** : https://github.com/khatrihemang07 +- **GitHub Issues** : [Signaler un problème](https://github.com/khatrihemang07/Penio/issues) --- -[![Star History Chart](https://api.star-history.com/svg?repos=game1024/Penio&type=date&legend=top-left)](https://www.star-history.com/#game1024/Penio&type=date&legend=top-left) \ No newline at end of file +[![Star History Chart](https://api.star-history.com/svg?repos=khatrihemang07/Penio&type=date&legend=top-left)](https://www.star-history.com/#khatrihemang07/Penio&type=date&legend=top-left) \ No newline at end of file diff --git a/README_JA.md b/README_JA.md index fc4c25e..f26ce76 100644 --- a/README_JA.md +++ b/README_JA.md @@ -1,5 +1,5 @@

- 简体中文 | English | 日本語 | 한국어 | Français | Deutsch + 简体中文 | English | 日本語 | 한국어 | Français | Deutsch

@@ -18,33 +18,33 @@

- +
- - GitHub Stars + + GitHub Stars - GitHub Forks + GitHub Forks - - Github Issues + + Github Issues
- - Downloads + + Downloads - - Version + + Version - + Platform
- - コミット頻度 + + コミット頻度 @@ -61,7 +61,7 @@ ### インストーラーのダウンロード -[Releases](https://github.com/game1024/Penio/releases) ページからお使いのOSに合ったインストーラーをダウンロードしてください: +[Releases](https://github.com/khatrihemang07/Penio/releases) ページからお使いのOSに合ったインストーラーをダウンロードしてください: - **Windows**: @@ -202,16 +202,15 @@ penio/ ## 🎁 プロジェクトを支援する このプロジェクトが役立ったら、⭐️ Starをお願いします! -[GitHub Sponsors](https://github.com/sponsors/game1024) からも開発を支援できます。 +[GitHub Sponsors](https://github.com/sponsors/khatrihemang07) からも開発を支援できます。 --- ## 📮 お問い合わせ -- **ウェブサイト**: https://github.com/game1024 -- **BiliBili**: [@game1024](https://space.bilibili.com/426988409) -- **GitHub Issues**: [問題を報告](https://github.com/game1024/Penio/issues) +- **ウェブサイト**: https://github.com/khatrihemang07 +- **GitHub Issues**: [問題を報告](https://github.com/khatrihemang07/Penio/issues) --- -[![Star History Chart](https://api.star-history.com/svg?repos=game1024/Penio&type=date&legend=top-left)](https://www.star-history.com/#game1024/Penio&type=date&legend=top-left) \ No newline at end of file +[![Star History Chart](https://api.star-history.com/svg?repos=khatrihemang07/Penio&type=date&legend=top-left)](https://www.star-history.com/#khatrihemang07/Penio&type=date&legend=top-left) \ No newline at end of file diff --git a/README_KO.md b/README_KO.md index 134d778..d2086e0 100644 --- a/README_KO.md +++ b/README_KO.md @@ -1,5 +1,5 @@

- 简体中文 | English | 日本語 | 한국어 | Français | Deutsch + 简体中文 | English | 日本語 | 한국어 | Français | Deutsch

@@ -18,33 +18,33 @@

- +
- - GitHub Stars + + GitHub Stars - GitHub Forks + GitHub Forks - - Github Issues + + Github Issues
- - Downloads + + Downloads - - Version + + Version - + Platform
- - 커밋 활동 + + 커밋 활동 @@ -61,7 +61,7 @@ ### 설치 프로그램 다운로드 -[Releases](https://github.com/game1024/Penio/releases) 페이지에서 운영 체제에 맞는 설치 프로그램을 다운로드하세요: +[Releases](https://github.com/khatrihemang07/Penio/releases) 페이지에서 운영 체제에 맞는 설치 프로그램을 다운로드하세요: - **Windows**: @@ -202,16 +202,15 @@ penio/ ## 🎁 프로젝트 지원 이 프로젝트가 도움이 되셨다면 ⭐️ Star를 눌러주세요! -[GitHub Sponsors](https://github.com/sponsors/game1024)를 통해 개발을 지원할 수도 있습니다. +[GitHub Sponsors](https://github.com/sponsors/khatrihemang07)를 통해 개발을 지원할 수도 있습니다. --- ## 📮 연락처 -- **웹사이트**: https://github.com/game1024 -- **BiliBili**: [@game1024](https://space.bilibili.com/426988409) -- **GitHub Issues**: [문제 보고](https://github.com/game1024/Penio/issues) +- **웹사이트**: https://github.com/khatrihemang07 +- **GitHub Issues**: [문제 보고](https://github.com/khatrihemang07/Penio/issues) --- -[![Star History Chart](https://api.star-history.com/svg?repos=game1024/Penio&type=date&legend=top-left)](https://www.star-history.com/#game1024/Penio&type=date&legend=top-left) \ No newline at end of file +[![Star History Chart](https://api.star-history.com/svg?repos=khatrihemang07/Penio&type=date&legend=top-left)](https://www.star-history.com/#khatrihemang07/Penio&type=date&legend=top-left) \ No newline at end of file diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 1cb23de..51a5c2d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -13,7 +13,7 @@ "macOSPrivateApi": true, "windows": [ { - "title": "控制台", + "title": "Penio", "url": "/", "label": "console", "width": 880, diff --git a/src/App.tsx b/src/App.tsx index 3e65fa2..8331929 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -70,9 +70,11 @@ function TabPanel(props: TabPanelProps) { aria-labelledby={`vertical-tab-${index}`} {...other} > - - {children} - + {value === index && ( + + {children} + + )} ); } @@ -90,6 +92,7 @@ function App() { if (language !== i18n.language) { await i18n.changeLanguage(language); } + // await getCurrentWindow().setTitle(i18n.t('tray.preferences')); // 语言初始化完成后创建托盘 await createTray(); await initShortcut(); @@ -106,6 +109,7 @@ function App() { const unlisten = await appWindow.listen<{ language: string }>('language-updated', () => { updateTray(); + getCurrentWindow().setTitle(i18n.t('tray.preferences')); }); return unlisten; From b7c7c5c9ba1b4572ffb19077bcdd8d7d4cd71ab4 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 15:20:39 +0530 Subject: [PATCH 13/34] feat: add mounted prop to TabPanel for conditional rendering based on visited tabs --- src/App.tsx | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 8331929..baa4064 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -50,10 +50,11 @@ interface TabPanelProps { children?: React.ReactNode; index: number; value: number; + mounted: boolean; } function TabPanel(props: TabPanelProps) { - const { children, value, index, ...other } = props; + const { children, value, index, mounted, ...other } = props; const theme = useTheme(); return ( @@ -70,7 +71,7 @@ function TabPanel(props: TabPanelProps) { aria-labelledby={`vertical-tab-${index}`} {...other} > - {value === index && ( + {mounted && ( {children} @@ -165,6 +166,9 @@ function App() { } const [tabno, setTabno] = useState(initTab); + const [visitedTabs, setVisitedTabs] = useState>( + () => new Set([initTab()]) + ); // 监听标签切换,更新 URL useEffect(() => { @@ -179,7 +183,12 @@ function App() {

setTabno(newValue)} + onChange={(_, newValue) => { + setTabno(newValue); + setVisitedTabs(prev => + prev.has(newValue) ? prev : new Set([...prev, newValue]) + ); + }} orientation="vertical" sx={{ minWidth: '6rem' }}> } label={t('tabs.mouse')} /> @@ -189,19 +198,19 @@ function App() { } label={t('tabs.about')} /> - + <鼠标设置页面 /> - + <键盘设置页面 /> - + <绘图设置页面 /> - + <通用设置页面 /> - + <关于页面 />
From 01198aa3126098ddbeaa609cfd129d9c95b60082 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 15:24:22 +0530 Subject: [PATCH 14/34] chore: update version to 1.0.10 in package.json and tauri.conf.json --- package.json | 2 +- src-tauri/tauri.conf.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1e93aeb..6ab15ab 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "penio", "private": true, - "version": "0.1.0", + "version": "1.0.10", "type": "module", "workspaces": [ "src/packages/excalidraw/packages/excalidraw", diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 51a5c2d..0941f45 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Penio", - "version": "1.0.9", + "version": "1.0.10", "identifier": "com.fiofio.penio", "build": { "beforeDevCommand": "bun run dev", From 1fbc131d00e3f6eedc19a0e68288e68496059567 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 16:03:20 +0530 Subject: [PATCH 15/34] feat: adjust stroke width for freedraw tool and update default stroke width in constants --- .../packages/excalidraw/components/App.tsx | 13 +++++++++++++ .../excalidraw/packages/excalidraw/constants.ts | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/packages/excalidraw/packages/excalidraw/components/App.tsx b/src/packages/excalidraw/packages/excalidraw/components/App.tsx index 00d37fa..13281ab 100644 --- a/src/packages/excalidraw/packages/excalidraw/components/App.tsx +++ b/src/packages/excalidraw/packages/excalidraw/components/App.tsx @@ -2328,6 +2328,10 @@ class App extends React.Component { : scene.appState.activeTool, isLoading: false, toast: this.state.toast, + currentItemStrokeWidth: + scene.appState.activeTool.type === "freedraw" + ? 1 + : scene.appState.currentItemStrokeWidth, }; if (initialData?.scrollToContent) { scene.appState = { @@ -4727,6 +4731,13 @@ class App extends React.Component { this.store.shouldCaptureIncrement(); } + const toolSpecificResets: Partial = + nextActiveTool.type === "freedraw" + ? { currentItemStrokeWidth: 1 } + : prevState.activeTool.type === "freedraw" + ? { currentItemStrokeWidth: 2 } + : {}; + if (nextActiveTool.type !== "selection") { return { ...prevState, @@ -4736,12 +4747,14 @@ class App extends React.Component { editingGroupId: null, multiElement: null, ...commonResets, + ...toolSpecificResets, }; } return { ...prevState, activeTool: nextActiveTool, ...commonResets, + ...toolSpecificResets, }; }); }; diff --git a/src/packages/excalidraw/packages/excalidraw/constants.ts b/src/packages/excalidraw/packages/excalidraw/constants.ts index bc69288..616ced1 100644 --- a/src/packages/excalidraw/packages/excalidraw/constants.ts +++ b/src/packages/excalidraw/packages/excalidraw/constants.ts @@ -391,7 +391,7 @@ export const DEFAULT_ELEMENT_PROPS: { strokeColor: COLOR_PALETTE.black, backgroundColor: COLOR_PALETTE.transparent, fillStyle: "solid", - strokeWidth: 1, + strokeWidth: 2, strokeStyle: "solid", roughness: ROUGHNESS.artist, opacity: 100, From f203460940a0389ce01d8dccb65937ae5437bbe6 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 16:06:19 +0530 Subject: [PATCH 16/34] chore: update version to 1.0.11 in package.json and tauri.conf.json --- package.json | 2 +- src-tauri/tauri.conf.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6ab15ab..acc45e9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "penio", "private": true, - "version": "1.0.10", + "version": "1.0.11", "type": "module", "workspaces": [ "src/packages/excalidraw/packages/excalidraw", diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 0941f45..da31765 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Penio", - "version": "1.0.10", + "version": "1.0.11", "identifier": "com.fiofio.penio", "build": { "beforeDevCommand": "bun run dev", From f0418498b09163df33f32a6dc251d959a2e61eb8 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 16:19:11 +0530 Subject: [PATCH 17/34] Update configs and add entitlements.plist Co-authored-by: CommandCodeBot --- package.json | 2 +- src-tauri/entitlements.plist | 14 ++++++++++++++ src-tauri/tauri.conf.json | 4 ++-- 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src-tauri/entitlements.plist diff --git a/package.json b/package.json index acc45e9..83012c3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "penio", "private": true, - "version": "1.0.11", + "version": "1.0.12", "type": "module", "workspaces": [ "src/packages/excalidraw/packages/excalidraw", diff --git a/src-tauri/entitlements.plist b/src-tauri/entitlements.plist new file mode 100644 index 0000000..be8b716 --- /dev/null +++ b/src-tauri/entitlements.plist @@ -0,0 +1,14 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + com.apple.security.cs.allow-dyld-environment-variables + + + diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index da31765..de4c577 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Penio", - "version": "1.0.11", + "version": "1.0.12", "identifier": "com.fiofio.penio", "build": { "beforeDevCommand": "bun run dev", @@ -61,7 +61,7 @@ "exceptionDomain": null, "signingIdentity": null, "providerShortName": null, - "entitlements": null, + "entitlements": "entitlements.plist", "files": { "Resources/zh-Hans.lproj/InfoPlist.strings": "locale/zh-Hans.lproj/InfoPlist.strings", "Resources/en.lproj/InfoPlist.strings": "locale/en.lproj/InfoPlist.strings" From 6ae062c136d680b487843687bae55ba2ccb3ec75 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 16:24:09 +0530 Subject: [PATCH 18/34] chore: update version to 1.0.13 in tauri.conf.json and modify default mouse settings --- src-tauri/tauri.conf.json | 2 +- src/store/settings.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index de4c577..0143a19 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Penio", - "version": "1.0.12", + "version": "1.0.13", "identifier": "com.fiofio.penio", "build": { "beforeDevCommand": "bun run dev", diff --git a/src/store/settings.ts b/src/store/settings.ts index 4b19b19..8a62a77 100644 --- a/src/store/settings.ts +++ b/src/store/settings.ts @@ -88,11 +88,11 @@ const defaultSettings: AppSettings = { autoStart: false, minimizeToTray: true, mouse: { - enableClickEffect: true, + enableClickEffect: false, clickEffectType: 'ripple', scale: 1.0, speed: 1.0, - enableAperture: true, + enableAperture: false, apertureStyle: 'neon', enableApertureAnimation: true, apertureScale: 1.0, From 573c2d9f293b4cc6d7317b44f5daf428abc7c5f0 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 16:28:38 +0530 Subject: [PATCH 19/34] =?UTF-8?q?Remove=20Apple=20signing=20from=20CI=20?= =?UTF-8?q?=E2=80=94=20no=20Developer=20account?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: CommandCodeBot --- .github/workflows/build.yml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9338e90..1d946a6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,30 +46,6 @@ jobs: with: workspaces: './src-tauri -> target' - - name: Import Apple Developer Certificate - if: contains(matrix.platform, 'macos') - env: - APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} - run: | - echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12 - security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain - security default-keychain -s build.keychain - security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain - security set-keychain-settings -t 3600 -u build.keychain - security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign - security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain - security find-identity -v -p codesigning build.keychain - - - name: Verify Certificate - if: contains(matrix.platform, 'macos') - run: | - CERT_INFO=$(security find-identity -v -p codesigning build.keychain | grep "Developer ID Application") - CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}') - echo "CERT_ID=$CERT_ID" >> $GITHUB_ENV - echo "Certificate imported." - - name: Install dependencies (Ubuntu only) if: contains(matrix.platform, 'ubuntu-24.04') run: | @@ -91,12 +67,6 @@ jobs: uses: tauri-apps/tauri-action@v0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} - APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} - APPLE_SIGNING_IDENTITY: ${{ env.CERT_ID }} - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} - APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} with: tagName: v${{ steps.get_version.outputs.version }} releaseName: 'Penio v${{ steps.get_version.outputs.version }}' From 8c646eb7ddd93014a5097212b488511ea2627ce8 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 16:30:42 +0530 Subject: [PATCH 20/34] Restore signed build workflow and add unsigned variant Co-authored-by: CommandCodeBot --- .github/workflows/build-unsigned.yml | 75 ++++++++++++++++++++++++++++ .github/workflows/build.yml | 30 +++++++++++ 2 files changed, 105 insertions(+) create mode 100644 .github/workflows/build-unsigned.yml diff --git a/.github/workflows/build-unsigned.yml b/.github/workflows/build-unsigned.yml new file mode 100644 index 0000000..0a3060c --- /dev/null +++ b/.github/workflows/build-unsigned.yml @@ -0,0 +1,75 @@ +name: Build Tauri App (Unsigned) + +on: + workflow_dispatch: + +permissions: + contents: write + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - platform: 'macos-latest' + args: '--target x86_64-apple-darwin' + target: 'x86_64-apple-darwin' + - platform: 'macos-latest' + args: '--target aarch64-apple-darwin' + target: 'aarch64-apple-darwin' + - platform: 'windows-latest' + args: '' + - platform: 'ubuntu-24.04' + args: '' + - platform: 'ubuntu-24.04-arm' + args: '' + + runs-on: ${{ matrix.platform }} + + steps: + - uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v1 + with: + bun-version: latest + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target || '' }} + + - name: Rust cache + uses: swatinem/rust-cache@v2 + with: + workspaces: './src-tauri -> target' + + - name: Install dependencies (Ubuntu only) + if: contains(matrix.platform, 'ubuntu-24.04') + run: | + sudo apt-get update + sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libudev-dev xdg-utils + + - name: Install frontend dependencies + run: bun install + + - name: Get version from tauri.conf.json + id: get_version + shell: bash + run: | + VERSION=$(cat src-tauri/tauri.conf.json | grep -o '"version": *"[^"]*"' | head -1 | sed 's/"version": *"\(.*\)"/\1/') + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Version: $VERSION" + + - name: Build the app + uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tagName: v${{ steps.get_version.outputs.version }} + releaseName: 'Penio v${{ steps.get_version.outputs.version }} (Unsigned)' + releaseBody: 'Unsigned build. macOS users: right-click → Open to bypass Gatekeeper on first launch.' + releaseDraft: true + prerelease: false + args: ${{ matrix.args }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1d946a6..9338e90 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,6 +46,30 @@ jobs: with: workspaces: './src-tauri -> target' + - name: Import Apple Developer Certificate + if: contains(matrix.platform, 'macos') + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} + run: | + echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12 + security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain + security set-keychain-settings -t 3600 -u build.keychain + security import certificate.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain + security find-identity -v -p codesigning build.keychain + + - name: Verify Certificate + if: contains(matrix.platform, 'macos') + run: | + CERT_INFO=$(security find-identity -v -p codesigning build.keychain | grep "Developer ID Application") + CERT_ID=$(echo "$CERT_INFO" | awk -F'"' '{print $2}') + echo "CERT_ID=$CERT_ID" >> $GITHUB_ENV + echo "Certificate imported." + - name: Install dependencies (Ubuntu only) if: contains(matrix.platform, 'ubuntu-24.04') run: | @@ -67,6 +91,12 @@ jobs: uses: tauri-apps/tauri-action@v0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + APPLE_SIGNING_IDENTITY: ${{ env.CERT_ID }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} with: tagName: v${{ steps.get_version.outputs.version }} releaseName: 'Penio v${{ steps.get_version.outputs.version }}' From 4f2c3f2e69b3acc3abc3d18e0040761515c00e84 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 16:52:29 +0530 Subject: [PATCH 21/34] chore: update version to 1.0.14 and enhance release instructions for unsigned builds --- .github/workflows/build-unsigned.yml | 14 +++++++++++++- src-tauri/tauri.conf.json | 4 ++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-unsigned.yml b/.github/workflows/build-unsigned.yml index 0a3060c..5514e75 100644 --- a/.github/workflows/build-unsigned.yml +++ b/.github/workflows/build-unsigned.yml @@ -69,7 +69,19 @@ jobs: with: tagName: v${{ steps.get_version.outputs.version }} releaseName: 'Penio v${{ steps.get_version.outputs.version }} (Unsigned)' - releaseBody: 'Unsigned build. macOS users: right-click → Open to bypass Gatekeeper on first launch.' + releaseBody: | + ## Install Instructions + + **macOS** — The app is ad-hoc signed but not notarized. After dragging to Applications: + - Right-click the app → **Open** → click Open in the dialog, OR + - If you still see "damaged", run in Terminal: + ``` + sudo xattr -rd com.apple.quarantine /Applications/Penio.app + ``` + + **Windows** — If SmartScreen appears, click "More info" → "Run anyway". + + **Linux** — `.deb` for Debian/Ubuntu, `.rpm` for Fedora/RHEL, `.AppImage` runs without install. releaseDraft: true prerelease: false args: ${{ matrix.args }} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 0143a19..3949588 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Penio", - "version": "1.0.13", + "version": "1.0.14", "identifier": "com.fiofio.penio", "build": { "beforeDevCommand": "bun run dev", @@ -59,7 +59,7 @@ "minimumSystemVersion": "10.13", "frameworks": [], "exceptionDomain": null, - "signingIdentity": null, + "signingIdentity": "-", "providerShortName": null, "entitlements": "entitlements.plist", "files": { From 6fe403adb515fa3eb09cdd57f5bd7552cd3299a4 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 17:49:59 +0530 Subject: [PATCH 22/34] fix: prevent keyboard echo from persisting on one monitor after toggle off The useEffect cleanup was async fire-and-forget (unlistenPromise.then(...)), leaving stale key-press/key-release Tauri listeners alive during re-render. When echo was toggled off, the new effect cleared the keyboard panel, but a stale listener could fire in the gap and repopulate it. Timing differed per WebView window, causing one monitor to clear while the other hung onto stale key state. Replaced promise-based cleanup with synchronous listener tracking via a mutable array and cancellation flag. Co-authored-by: CommandCodeBot --- src/pages/motion-board/App.tsx | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/pages/motion-board/App.tsx b/src/pages/motion-board/App.tsx index fca8fde..f8b618d 100644 --- a/src/pages/motion-board/App.tsx +++ b/src/pages/motion-board/App.tsx @@ -152,7 +152,9 @@ function App() { setIgnoreCursorEvents(newState); if (newState == false) { - setSnackbar({ open: true, message: i18n.t('drawing.messages.enterDrawMode') }); + if (drawingSettings.showDrawingModeNotice ?? true) { + setSnackbar({ open: true, message: i18n.t('drawing.messages.enterDrawMode') }); + } setKeyboardPanel(prev => ({ ...prev, modifierKeys: [], keys: [] })); await appWindow.setFocusable(true) await appWindow.setIgnoreCursorEvents(newState); @@ -229,6 +231,9 @@ function App() { useEffect(() => { // 监听来自 Rust 的全局鼠标事件 + const unlisteners: (() => void)[] = []; + let cancelled = false; + const setupListener = async () => { const appWindow = getCurrentWindow(); @@ -236,6 +241,8 @@ function App() { console.log('refresh-monitors event received:', event); setKeyboardPanel(prev => ({ ...prev, modifierKeys: [], keys: [] })); }); + if (cancelled) { unlistenRefreshMonitors(); return; } + unlisteners.push(unlistenRefreshMonitors); // 监听鼠标点击事件 // 如果鼠标穿透关闭,不处理点击事件 @@ -301,10 +308,12 @@ function App() { console.error('Error handling mouse-click event:', error); } }); + if (cancelled) { unlistenMouseDown(); return; } + unlisteners.push(unlistenMouseDown); if (!keyboardSettings.enableKeyboardEcho) { setKeyboardPanel(prev => ({ ...prev, modifierKeys: [], keys: [] })); - return [unlistenMouseDown]; + return; } // 监听键盘按下事件 @@ -348,6 +357,8 @@ function App() { }); } }); + if (cancelled) { unlistenKeyPress(); return; } + unlisteners.push(unlistenKeyPress); // 监听键盘释放事件 const unlistenKeyRelease = await appWindow.listen<{ key: string }>('key-release', async (event) => { @@ -362,17 +373,15 @@ function App() { setKeyboardPanel(prev => ({ ...prev, keys: prev.keys.filter(k => k !== keyName) })); } }); - - return [unlistenRefreshMonitors, unlistenMouseDown, unlistenKeyPress, unlistenKeyRelease]; + if (cancelled) { unlistenKeyRelease(); return; } + unlisteners.push(unlistenKeyRelease); }; - const unlistenPromise = setupListener(); + setupListener(); - // 组件卸载时清理 return () => { - unlistenPromise.then(unlisteners => { - unlisteners.forEach(unlisten => unlisten()); - }); + cancelled = true; + unlisteners.forEach(fn => fn()); }; }, [ignoreCursorEvents, mouseSettings, keyboardSettings]); From 0912a15e6dcffb38d5fcffdc7e98ea08a1b868d8 Mon Sep 17 00:00:00 2001 From: Hemang Date: Sun, 31 May 2026 23:40:43 +0530 Subject: [PATCH 23/34] chore: update version to 1.0.15 and modify drawing settings interface --- src-tauri/tauri.conf.json | 2 +- src/components/Settings.tsx | 2 +- .../packages/excalidraw/components/LayerUI.tsx | 16 ---------------- src/pages/motion-board/App.tsx | 6 ------ src/store/settings.ts | 1 + 5 files changed, 3 insertions(+), 24 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 3949588..6518664 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Penio", - "version": "1.0.14", + "version": "1.0.15", "identifier": "com.fiofio.penio", "build": { "beforeDevCommand": "bun run dev", diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index 396999b..c38a39c 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -1217,7 +1217,7 @@ function 绘图设置页面() { const settings = await getSettings(); setToggleShortcut(settings.drawing?.toggleShortcut); setToolbarShortcut(settings.drawing?.toolbarShortcut); - setConfirmClearAnnotation(settings.drawing?.confirmClearAnnotation ?? true); + setConfirmClearAnnotation(settings.drawing?.confirmClearAnnotation ?? false); setEnableScrollAndPan(settings.drawing?.enableScrollAndPan ?? true); } catch (error) { console.error('加载绘图设置失败:', error); diff --git a/src/packages/excalidraw/packages/excalidraw/components/LayerUI.tsx b/src/packages/excalidraw/packages/excalidraw/components/LayerUI.tsx index 7ec1f62..002841a 100644 --- a/src/packages/excalidraw/packages/excalidraw/components/LayerUI.tsx +++ b/src/packages/excalidraw/packages/excalidraw/components/LayerUI.tsx @@ -145,22 +145,6 @@ const LayerUI = ({ const [toastMsg, setToastMsg] = React.useState(null); const toolbarVisible = appState.toolbarVisible; - // show toast when toolbar toggled - const prevVisibleRef = React.useRef(toolbarVisible); - React.useEffect(() => { - if (prevVisibleRef.current === toolbarVisible) return; - prevVisibleRef.current = toolbarVisible; - const isMac = /Mac|iPod|iPhone|iPad/.test(navigator.platform); - const key = isMac ? "⌘+H" : "Ctrl+H"; - setToastMsg( - toolbarVisible - ? `工具栏已显示 (${key} 切换)` - : `工具栏已隐藏 (${key} 恢复)`, - ); - const timer = setTimeout(() => setToastMsg(null), 2000); - return () => clearTimeout(timer); - }, [toolbarVisible]); - const TunnelsJotaiProvider = tunnels.tunnelsJotai.Provider; const [eyeDropperState, setEyeDropperState] = useAtom(activeEyeDropperAtom); diff --git a/src/pages/motion-board/App.tsx b/src/pages/motion-board/App.tsx index f8b618d..a150443 100644 --- a/src/pages/motion-board/App.tsx +++ b/src/pages/motion-board/App.tsx @@ -401,12 +401,6 @@ function App() { const currentState = api.getAppState(); const newVisible = !currentState.toolbarVisible; api.updateScene({ appState: { toolbarVisible: newVisible } }); - setSnackbar({ - open: true, - message: newVisible - ? i18n.t('drawing.messages.toolbarShown', { shortcut: drawingSettings.toolbarShortcut }) - : i18n.t('drawing.messages.toolbarHidden', { shortcut: drawingSettings.toolbarShortcut }), - }); }); return unlisten; }; diff --git a/src/store/settings.ts b/src/store/settings.ts index 8a62a77..8d9eba9 100644 --- a/src/store/settings.ts +++ b/src/store/settings.ts @@ -65,6 +65,7 @@ export interface DrawingSettings { toolbarShortcut: string; confirmClearAnnotation?: boolean; enableScrollAndPan?: boolean; + showDrawingModeNotice?: boolean; } // 应用设置接口 From 2abeb3ad56d13560e5255130457b32546266f1c8 Mon Sep 17 00:00:00 2001 From: Hemang Date: Mon, 1 Jun 2026 00:00:04 +0530 Subject: [PATCH 24/34] fix: use stable self-signed cert so TCC permissions persist across app updates Replaced ad-hoc signing ("-") with a persistent "Penio Dev" self-signed certificate. macOS TCC now keys Accessibility/Input Monitoring grants to the cert identity instead of the binary hash, so permissions survive DMG updates without requiring the user to remove and re-grant them. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/build-unsigned.yml | 13 ++++++++ scripts/setup-signing.sh | 45 ++++++++++++++++++++++++++++ src-tauri/tauri.conf.json | 2 +- 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100755 scripts/setup-signing.sh diff --git a/.github/workflows/build-unsigned.yml b/.github/workflows/build-unsigned.yml index 5514e75..e0778b2 100644 --- a/.github/workflows/build-unsigned.yml +++ b/.github/workflows/build-unsigned.yml @@ -51,6 +51,19 @@ jobs: sudo apt-get update sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libudev-dev xdg-utils + - name: Import self-signed signing cert (macOS only) + if: contains(matrix.platform, 'macos') + run: | + echo "${{ secrets.SELF_SIGNED_CERT_P12 }}" | base64 --decode > /tmp/penio-signing.p12 + security create-keychain -p "peniosigning" build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p "peniosigning" build.keychain + security set-keychain-settings -u build.keychain + security import /tmp/penio-signing.p12 -k build.keychain -P "peniosigning" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple: -s -k "peniosigning" build.keychain + security list-keychains -d user -s build.keychain + rm /tmp/penio-signing.p12 + - name: Install frontend dependencies run: bun install diff --git a/scripts/setup-signing.sh b/scripts/setup-signing.sh new file mode 100755 index 0000000..b5cf5ee --- /dev/null +++ b/scripts/setup-signing.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Run once on your dev machine. +# Creates a stable self-signed signing cert in a dedicated keychain so that +# macOS TCC (Accessibility / Input Monitoring) permissions survive app updates. +set -e + +CERT_NAME="Penio Dev" +KEYCHAIN="$HOME/Library/Keychains/penio-signing.keychain-db" +KEYCHAIN_PASS="peniosigning" + +# Remove any old keychain +security delete-keychain "$KEYCHAIN" 2>/dev/null || true + +# Create dedicated keychain +security create-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN" +security unlock-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN" +security set-keychain-settings -u "$KEYCHAIN" # disable auto-lock + +# Add to user keychain search list alongside login keychain +security list-keychains -d user -s "$HOME/Library/Keychains/login.keychain-db" "$KEYCHAIN" + +# Generate self-signed cert with code signing extension +openssl req -x509 -newkey rsa:2048 -keyout /tmp/penio-pk.pem -out /tmp/penio-cert.pem \ + -days 3650 -nodes -subj "/CN=$CERT_NAME" \ + -addext "keyUsage=critical,digitalSignature" \ + -addext "extendedKeyUsage=codeSigning" + +# Package as p12 and import into keychain +openssl pkcs12 -export -out /tmp/penio-signing.p12 \ + -inkey /tmp/penio-pk.pem -in /tmp/penio-cert.pem -passout pass:"$KEYCHAIN_PASS" + +security import /tmp/penio-signing.p12 -P "$KEYCHAIN_PASS" -T /usr/bin/codesign \ + -k "$KEYCHAIN" +security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASS" "$KEYCHAIN" + +# Cleanup +rm /tmp/penio-pk.pem /tmp/penio-cert.pem /tmp/penio-signing.p12 + +echo "" +echo "Done! '$CERT_NAME' installed in $KEYCHAIN" +echo "Tauri will now sign with this identity (signingIdentity: \"$CERT_NAME\" in tauri.conf.json)." +echo "" +echo "To add the cert to CI, re-run this script and then:" +echo " security export -k \"$KEYCHAIN\" -t identities -f pkcs12 -o /tmp/penio-signing.p12 -P \"$KEYCHAIN_PASS\"" +echo " base64 -i /tmp/penio-signing.p12 | gh secret set SELF_SIGNED_CERT_P12 -R " diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 6518664..a0b04f0 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -59,7 +59,7 @@ "minimumSystemVersion": "10.13", "frameworks": [], "exceptionDomain": null, - "signingIdentity": "-", + "signingIdentity": "Penio Dev", "providerShortName": null, "entitlements": "entitlements.plist", "files": { From cb04f2b80e5ad6b2025f80d0c1bdd734ce8720a6 Mon Sep 17 00:00:00 2001 From: Hemang Date: Mon, 1 Jun 2026 19:59:43 +0530 Subject: [PATCH 25/34] chore: update version to 1.0.16 Co-Authored-By: Claude Sonnet 4.6 --- package.json | 2 +- src-tauri/tauri.conf.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 83012c3..51b158b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "penio", "private": true, - "version": "1.0.12", + "version": "1.0.16", "type": "module", "workspaces": [ "src/packages/excalidraw/packages/excalidraw", diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index a0b04f0..f628ef0 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Penio", - "version": "1.0.15", + "version": "1.0.16", "identifier": "com.fiofio.penio", "build": { "beforeDevCommand": "bun run dev", From 9d28cbe77eb81ab344a7fa0d50e10f6c9290431e Mon Sep 17 00:00:00 2001 From: Hemang Date: Mon, 1 Jun 2026 20:00:20 +0530 Subject: [PATCH 26/34] fix: reset stroke width to 1 for freedraw when clearing canvas Co-Authored-By: Claude Sonnet 4.6 --- .../excalidraw/packages/excalidraw/actions/actionCanvas.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx b/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx index 6096927..52e0551 100644 --- a/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx +++ b/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx @@ -115,6 +115,7 @@ export const actionClearCanvas = register({ currentItemRoundness: appState.currentItemRoundness, stats: appState.stats, pasteDialog: appState.pasteDialog, + currentItemStrokeWidth: appState.activeTool.type === "freedraw" ? 1 : appState.currentItemStrokeWidth, activeTool: appState.activeTool.type === "image" ? { ...appState.activeTool, type: "selection" } From 93f28152178da692dc183adccaa2ff6b9b73c9ac Mon Sep 17 00:00:00 2001 From: Hemang Date: Tue, 2 Jun 2026 00:00:28 +0530 Subject: [PATCH 27/34] fix: preserve toolbarVisible state when clearing canvas Co-authored-by: CommandCodeBot --- .../excalidraw/packages/excalidraw/actions/actionCanvas.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx b/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx index 52e0551..f9bd985 100644 --- a/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx +++ b/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx @@ -116,6 +116,7 @@ export const actionClearCanvas = register({ stats: appState.stats, pasteDialog: appState.pasteDialog, currentItemStrokeWidth: appState.activeTool.type === "freedraw" ? 1 : appState.currentItemStrokeWidth, + toolbarVisible: appState.toolbarVisible, activeTool: appState.activeTool.type === "image" ? { ...appState.activeTool, type: "selection" } From ec8de578a923674cbcad0144ca73ce2a3d18eae2 Mon Sep 17 00:00:00 2001 From: Hemang Date: Tue, 2 Jun 2026 00:31:51 +0530 Subject: [PATCH 28/34] fix: pass theme prop to App component for dynamic theming --- src/pages/motion-board/App.tsx | 4 ++-- src/pages/motion-board/main.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/motion-board/App.tsx b/src/pages/motion-board/App.tsx index a150443..cd4be0d 100644 --- a/src/pages/motion-board/App.tsx +++ b/src/pages/motion-board/App.tsx @@ -38,7 +38,7 @@ import { KeyLabel, MODIFIER_KEY_LIST, IGNORE_KEY_LIST, MOUSE_CLICK_KEYS } from " import { Alert, Snackbar, Zoom } from "@mui/material"; import i18n, { initLocale } from "../../i18n"; -function App() { +function App({ theme }: { theme: 'light' | 'dark' }) { // 从 store 加载鼠标设置 const { mouseSettings, } = useMouseSettings(); @@ -489,7 +489,7 @@ function App() { }} /> { { excalidrawAPIRef.current = api; }} diff --git a/src/pages/motion-board/main.tsx b/src/pages/motion-board/main.tsx index 338147f..19b8a6c 100644 --- a/src/pages/motion-board/main.tsx +++ b/src/pages/motion-board/main.tsx @@ -74,7 +74,7 @@ function ThemedApp() { return ( - + ); } From 07c83405d1a74462e5c4a747b312308242f0faee Mon Sep 17 00:00:00 2001 From: Hemang Date: Tue, 23 Jun 2026 00:17:37 +0530 Subject: [PATCH 29/34] feat: add toggle-and-clear shortcut (Alt+`) and bump version to 1.0.17 Adds a new shortcut that simultaneously toggles drawing mode and clears the canvas. Reassigns the old toggle shortcut default from Alt+` to Alt+1 to make room. Co-Authored-By: Claude Sonnet 4.6 --- .npmrc | 2 ++ package.json | 2 +- src-tauri/tauri.conf.json | 2 +- src/components/Settings.tsx | 29 +++++++++++++++++++++++++++++ src/hooks/useShortcut.ts | 8 +++++++- src/i18n/locales/de-DE.json | 1 + src/i18n/locales/en-US.json | 1 + src/i18n/locales/es-ES.json | 1 + src/i18n/locales/fr-FR.json | 1 + src/i18n/locales/ja-JP.json | 1 + src/i18n/locales/ko-KR.json | 1 + src/i18n/locales/zh-CN.json | 1 + src/i18n/locales/zh-TW.json | 1 + src/pages/motion-board/App.tsx | 18 ++++++++++++++++++ src/store/settings.ts | 21 +++++++++++++++++++-- 15 files changed, 85 insertions(+), 5 deletions(-) create mode 100644 .npmrc diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..1b78f1c --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +save-exact=true +legacy-peer-deps=true diff --git a/package.json b/package.json index 51b158b..759e266 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "penio", "private": true, - "version": "1.0.16", + "version": "1.0.17", "type": "module", "workspaces": [ "src/packages/excalidraw/packages/excalidraw", diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index f628ef0..602d16b 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Penio", - "version": "1.0.16", + "version": "1.0.17", "identifier": "com.fiofio.penio", "build": { "beforeDevCommand": "bun run dev", diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index c38a39c..dba213a 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -1206,6 +1206,7 @@ function 绘图设置页面() { const { t } = useTranslation(); const [toggleShortcut, setToggleShortcut] = useState(''); const [toolbarShortcut, setToolbarShortcut] = useState(''); + const [toggleAndClearShortcut, setToggleAndClearShortcut] = useState(''); const [confirmClearAnnotation, setConfirmClearAnnotation] = useState(false); const [enableScrollAndPan, setEnableScrollAndPan] = useState(true); const { notify } = useSnackbar(); @@ -1217,6 +1218,7 @@ function 绘图设置页面() { const settings = await getSettings(); setToggleShortcut(settings.drawing?.toggleShortcut); setToolbarShortcut(settings.drawing?.toolbarShortcut); + setToggleAndClearShortcut(settings.drawing?.toggleAndClearShortcut); setConfirmClearAnnotation(settings.drawing?.confirmClearAnnotation ?? false); setEnableScrollAndPan(settings.drawing?.enableScrollAndPan ?? true); } catch (error) { @@ -1246,6 +1248,25 @@ function 绘图设置页面() { } }; + // 处理切换绘图模式并清空快捷键变化 + const handleToggleAndClearShortcutChange = async (shortcut: string) => { + setToggleAndClearShortcut(shortcut); + + try { + const currentSettings = await getSettings(); + await updateSettings({ + drawing: { + ...currentSettings.drawing, + toggleAndClearShortcut: shortcut, + } + }); + notify(t('drawing.messages.shortcutUpdated', { shortcut }), 'success'); + } catch (error) { + console.error('保存设置失败:', error); + notify(t('drawing.messages.saveFailed', { error: String(error) }), 'error'); + } + }; + // 处理工具栏快捷键变化 const handleToolbarShortcutChange = async (shortcut: string) => { setToolbarShortcut(shortcut); @@ -1309,6 +1330,14 @@ function 绘图设置页面() { onChange={handleShortcutChange} /> } /> + + } /> { await invoke('trigger_drawing_mode'); }); @@ -53,6 +53,12 @@ export function useShortcut() { await register(toolbarShortcut, async () => { await emit('toolbar-visibility-toggled'); }); + + const toggleAndClearShortcut = settings.drawing?.toggleAndClearShortcut || 'Alt+`'; + await register(toggleAndClearShortcut, async () => { + await emit('trigger-clear-canvas'); + await invoke('trigger_drawing_mode'); + }); } catch (error) { console.error('Failed to initialize shortcut:', error); } diff --git a/src/i18n/locales/de-DE.json b/src/i18n/locales/de-DE.json index 69a7d69..2d7d7f2 100644 --- a/src/i18n/locales/de-DE.json +++ b/src/i18n/locales/de-DE.json @@ -87,6 +87,7 @@ "drawing": { "title": "Zeicheneinstellungen", "toggleMode": "Zeichenmodus umschalten", + "toggleAndClearMode": "Zeichenmodus umschalten & leeren", "clearAnnotation": "Anmerkungen löschen", "confirmClearAnnotation": "Vor dem Löschen bestätigen", "shortcutHelp": "Tastenkürzel-Hilfe", diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 4df92ef..368f074 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -87,6 +87,7 @@ "drawing": { "title": "Drawing Settings", "toggleMode": "Toggle Drawing Mode", + "toggleAndClearMode": "Toggle Drawing Mode & Clear", "clearAnnotation": "Clear Annotation", "confirmClearAnnotation": "Confirm before clearing", "shortcutHelp": "Shortcut Help", diff --git a/src/i18n/locales/es-ES.json b/src/i18n/locales/es-ES.json index 6b5082b..7064a4e 100644 --- a/src/i18n/locales/es-ES.json +++ b/src/i18n/locales/es-ES.json @@ -87,6 +87,7 @@ "drawing": { "title": "Configuración de dibujo", "toggleMode": "Alternar modo de dibujo", + "toggleAndClearMode": "Alternar modo de dibujo y limpiar", "clearAnnotation": "Borrar anotaciones", "confirmClearAnnotation": "Confirmar antes de borrar", "shortcutHelp": "Ayuda de atajos", diff --git a/src/i18n/locales/fr-FR.json b/src/i18n/locales/fr-FR.json index 1b54561..f75ec4f 100644 --- a/src/i18n/locales/fr-FR.json +++ b/src/i18n/locales/fr-FR.json @@ -87,6 +87,7 @@ "drawing": { "title": "Paramètres de dessin", "toggleMode": "Basculer le mode dessin", + "toggleAndClearMode": "Basculer le mode dessin et effacer", "clearAnnotation": "Effacer les annotations", "confirmClearAnnotation": "Confirmer avant d'effacer", "shortcutHelp": "Aide des raccourcis", diff --git a/src/i18n/locales/ja-JP.json b/src/i18n/locales/ja-JP.json index 6b0bb6c..081da59 100644 --- a/src/i18n/locales/ja-JP.json +++ b/src/i18n/locales/ja-JP.json @@ -87,6 +87,7 @@ "drawing": { "title": "描画設定", "toggleMode": "描画モード切替", + "toggleAndClearMode": "描画モード切替&クリア", "clearAnnotation": "注釈をクリア", "confirmClearAnnotation": "クリア前に確認", "shortcutHelp": "ショートカットヘルプ", diff --git a/src/i18n/locales/ko-KR.json b/src/i18n/locales/ko-KR.json index cce6653..be9f0c8 100644 --- a/src/i18n/locales/ko-KR.json +++ b/src/i18n/locales/ko-KR.json @@ -87,6 +87,7 @@ "drawing": { "title": "그리기 설정", "toggleMode": "그리기 모드 전환", + "toggleAndClearMode": "그리기 모드 전환 및 지우기", "clearAnnotation": "주석 지우기", "confirmClearAnnotation": "지우기 전 확인", "shortcutHelp": "단축키 도움말", diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 761ba99..df05d6a 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -87,6 +87,7 @@ "drawing": { "title": "绘图设置", "toggleMode": "切换绘图模式", + "toggleAndClearMode": "切换绘图模式并清空", "clearAnnotation": "清空标注", "confirmClearAnnotation": "清除前确认", "shortcutHelp": "快捷键帮助", diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index 6abf432..0973b94 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -87,6 +87,7 @@ "drawing": { "title": "繪圖設定", "toggleMode": "切換繪圖模式", + "toggleAndClearMode": "切換繪圖模式並清空", "clearAnnotation": "清空標註", "confirmClearAnnotation": "清除前確認", "shortcutHelp": "快速鍵說明", diff --git a/src/pages/motion-board/App.tsx b/src/pages/motion-board/App.tsx index cd4be0d..ef6e126 100644 --- a/src/pages/motion-board/App.tsx +++ b/src/pages/motion-board/App.tsx @@ -391,6 +391,24 @@ function App({ theme }: { theme: 'light' | 'dark' }) { const ignoreCursorEventsRef = useRef(ignoreCursorEvents); ignoreCursorEventsRef.current = ignoreCursorEvents; + // 监听 Alt+` 触发的清除画布事件 + useEffect(() => { + const setupListener = async () => { + const appWindow = getCurrentWindow(); + const unlisten = await appWindow.listen('trigger-clear-canvas', () => { + excalidrawAPIRef.current?.updateScene({ + elements: [], + appState: { currentItemStrokeWidth: 1 }, + }); + }); + return unlisten; + }; + const unlistenPromise = setupListener(); + return () => { + unlistenPromise.then(unlisten => unlisten()); + }; + }, []); + // 监听全局快捷键触发的工具栏可见性切换事件 useEffect(() => { const setupListener = async () => { diff --git a/src/store/settings.ts b/src/store/settings.ts index 8d9eba9..06567e2 100644 --- a/src/store/settings.ts +++ b/src/store/settings.ts @@ -63,6 +63,7 @@ export interface KeyboardSettings { export interface DrawingSettings { toggleShortcut: string; toolbarShortcut: string; + toggleAndClearShortcut: string; confirmClearAnnotation?: boolean; enableScrollAndPan?: boolean; showDrawingModeNotice?: boolean; @@ -109,8 +110,9 @@ const defaultSettings: AppSettings = { offsetY: 0, }, drawing: { - toggleShortcut: 'Alt+`', + toggleShortcut: 'Alt+1', toolbarShortcut: 'Alt+H', + toggleAndClearShortcut: 'Alt+`', confirmClearAnnotation: true, enableScrollAndPan: true, }, @@ -133,7 +135,11 @@ export const getSettings = async (): Promise => { ...settings, mouse: { ...defaultSettings.mouse, ...settings?.mouse }, keyboard: { ...defaultSettings.keyboard, ...settings?.keyboard }, - drawing: {...defaultSettings.drawing, ...settings?.drawing }, + drawing: { + ...defaultSettings.drawing, + ...settings?.drawing, + ...(settings?.drawing?.toggleShortcut === 'Alt+`' ? { toggleShortcut: 'Alt+1' } : {}), + }, }; }; @@ -202,6 +208,17 @@ export const updateSettings = async (newSettings: Partial) => { await emit('toolbar-visibility-toggled'); }) } + + // 切换绘图模式并自动清除画布快捷键 + if (currentSettings.drawing.toggleAndClearShortcut) { + await unregister(currentSettings.drawing.toggleAndClearShortcut); + } + if (updatedSettings.drawing.toggleAndClearShortcut && updatedSettings.drawing.toggleAndClearShortcut != "") { + await register(updatedSettings.drawing.toggleAndClearShortcut, async () => { + await emit('trigger-clear-canvas'); + await invoke('trigger_drawing_mode'); + }) + } } catch (error: any) { throw error; } From 2b05afa199e924cc4c4409f5ade21a5ee39ff9a9 Mon Sep 17 00:00:00 2001 From: Hemang Date: Tue, 23 Jun 2026 00:20:04 +0530 Subject: [PATCH 30/34] fix: resolve TS error in useDrawingSettings and update tauri Rust crate to 2.11.x Co-Authored-By: Claude Sonnet 4.6 --- src-tauri/Cargo.lock | 599 ++++++++++++++++++++++---------- src-tauri/Cargo.toml | 2 +- src/hooks/useDrawingSettings.ts | 3 +- 3 files changed, 417 insertions(+), 187 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 078ead2..55ea394 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -236,6 +236,21 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitflags" version = "1.3.2" @@ -281,7 +296,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ - "objc2 0.6.3", + "objc2 0.6.4", ] [[package]] @@ -710,6 +725,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cssparser" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dae61cf9c0abb83bd659dab65b7e4e38d8236824c85f0f804f173567bda257d2" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "phf 0.13.1", + "smallvec", +] + [[package]] name = "cssparser-macros" version = "0.6.1" @@ -722,14 +750,20 @@ dependencies = [ [[package]] name = "ctor" -version = "0.2.9" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98" dependencies = [ - "quote", - "syn 2.0.108", + "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" + [[package]] name = "ctrlc" version = "3.5.1" @@ -782,6 +816,17 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376" +[[package]] +name = "dbus" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b942602992bb7acfd1f51c49811c58a610ef9181b6e66f3e519d79b540a3bf73" +dependencies = [ + "libc", + "libdbus-sys", + "windows-sys 0.61.2", +] + [[package]] name = "deranged" version = "0.5.5" @@ -805,6 +850,27 @@ dependencies = [ "syn 2.0.108", ] +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.108", +] + [[package]] name = "digest" version = "0.10.7" @@ -871,7 +937,7 @@ dependencies = [ "bitflags 2.10.0", "block2 0.6.2", "libc", - "objc2 0.6.3", + "objc2 0.6.4", ] [[package]] @@ -917,6 +983,21 @@ dependencies = [ "litrs", ] +[[package]] +name = "dom_query" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89" +dependencies = [ + "bit-set", + "cssparser 0.36.0", + "foldhash", + "html5ever 0.38.0", + "precomputed-hash", + "selectors 0.36.1", + "tendril 0.5.0", +] + [[package]] name = "dpi" version = "0.1.2" @@ -941,6 +1022,21 @@ 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" @@ -1000,7 +1096,7 @@ dependencies = [ "libc", "log", "nom", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit", "objc2-foundation 0.3.2", "windows 0.61.3", @@ -1125,6 +1221,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.5.0" @@ -1515,7 +1617,7 @@ checksum = "b9247516746aa8e53411a0db9b62b0e24efbcf6a76e0ba73e5a91b512ddabed7" dependencies = [ "crossbeam-channel", "keyboard-types", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit", "once_cell", "serde", @@ -1651,10 +1753,20 @@ checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" dependencies = [ "log", "mac", - "markup5ever", + "markup5ever 0.14.1", "match_token", ] +[[package]] +name = "html5ever" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1054432bae2f14e0061e33d23402fbaa67a921d319d56adc6bcf887ddad1cbc2" +dependencies = [ + "log", + "markup5ever 0.38.0", +] + [[package]] name = "http" version = "1.3.1" @@ -1772,7 +1884,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.2", + "windows-core 0.61.2", ] [[package]] @@ -1786,9 +1898,9 @@ dependencies = [ [[package]] name = "ico" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" +checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" dependencies = [ "byteorder", "png 0.17.16", @@ -1953,16 +2065,6 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" -[[package]] -name = "iri-string" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is-docker" version = "0.2.0" @@ -2035,11 +2137,12 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.82" +version = "0.3.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" dependencies = [ - "once_cell", + "cfg-if", + "futures-util", "wasm-bindgen", ] @@ -2082,10 +2185,10 @@ version = "0.8.8-speedreader" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" dependencies = [ - "cssparser", - "html5ever", + "cssparser 0.29.6", + "html5ever 0.29.1", "indexmap 2.12.0", - "selectors", + "selectors 0.24.0", ] [[package]] @@ -2124,6 +2227,15 @@ version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +[[package]] +name = "libdbus-sys" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043" +dependencies = [ + "pkg-config", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2228,9 +2340,20 @@ dependencies = [ "log", "phf 0.11.3", "phf_codegen 0.11.3", - "string_cache", - "string_cache_codegen", - "tendril", + "string_cache 0.8.9", + "string_cache_codegen 0.5.4", + "tendril 0.4.3", +] + +[[package]] +name = "markup5ever" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8983d30f2915feeaaab2d6babdd6bc7e9ed1a00b66b5e6d74df19aa9c0e91862" +dependencies = [ + "log", + "tendril 0.5.0", + "web_atoms", ] [[package]] @@ -2313,23 +2436,23 @@ dependencies = [ [[package]] name = "muda" -version = "0.17.1" +version = "0.19.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a" +checksum = "1dd04e60bc0b07438a6771710ee1698f98f6ebbc7f89b61264af1563b8aeb878" dependencies = [ "crossbeam-channel", "dpi", "gtk", "keyboard-types", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.2", "once_cell", - "png 0.17.16", + "png 0.18.0", "serde", "thiserror 2.0.17", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2347,12 +2470,6 @@ 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" @@ -2460,9 +2577,9 @@ dependencies = [ [[package]] name = "objc2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" dependencies = [ "objc2-encode", "objc2-exception-helper", @@ -2476,17 +2593,9 @@ checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ "bitflags 2.10.0", "block2 0.6.2", - "libc", - "objc2 0.6.3", - "objc2-cloud-kit", - "objc2-core-data", + "objc2 0.6.4", "objc2-core-foundation", - "objc2-core-graphics", - "objc2-core-image", - "objc2-core-text", - "objc2-core-video", "objc2-foundation 0.3.2", - "objc2-quartz-core 0.3.2", ] [[package]] @@ -2496,7 +2605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-foundation 0.3.2", ] @@ -2506,8 +2615,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-foundation 0.3.2", ] @@ -2521,7 +2629,7 @@ dependencies = [ "block2 0.6.2", "dispatch2", "libc", - "objc2 0.6.3", + "objc2 0.6.4", ] [[package]] @@ -2534,7 +2642,7 @@ dependencies = [ "block2 0.6.2", "dispatch2", "libc", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-core-foundation", "objc2-io-surface", "objc2-metal 0.3.2", @@ -2546,33 +2654,30 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" dependencies = [ - "objc2 0.6.3", + "objc2 0.6.4", "objc2-foundation 0.3.2", ] [[package]] -name = "objc2-core-text" +name = "objc2-core-location" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009" dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-core-foundation", - "objc2-core-graphics", + "objc2 0.6.4", + "objc2-foundation 0.3.2", ] [[package]] -name = "objc2-core-video" +name = "objc2-core-text" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-core-foundation", "objc2-core-graphics", - "objc2-io-surface", ] [[package]] @@ -2611,7 +2716,7 @@ dependencies = [ "bitflags 2.10.0", "block2 0.6.2", "libc", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-core-foundation", ] @@ -2622,17 +2727,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-javascript-core" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a1e6550c4caed348956ce3370c9ffeca70bb1dbed4fa96112e7c6170e074586" -dependencies = [ - "objc2 0.6.3", + "objc2 0.6.4", "objc2-core-foundation", ] @@ -2655,7 +2750,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0125f776a10d00af4152d74616409f0d4a2053a6f57fa5b7d6aa2854ac04794" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-foundation 0.3.2", ] @@ -2679,30 +2774,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", + "objc2 0.6.4", + "objc2-core-foundation", "objc2-foundation 0.3.2", ] [[package]] -name = "objc2-security" +name = "objc2-ui-kit" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ "bitflags 2.10.0", - "objc2 0.6.3", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-cloud-kit", + "objc2-core-data", "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image", + "objc2-core-location", + "objc2-core-text", + "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", + "objc2-user-notifications", ] [[package]] -name = "objc2-ui-kit" +name = "objc2-user-notifications" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" dependencies = [ - "bitflags 2.10.0", - "objc2 0.6.3", - "objc2-core-foundation", + "objc2 0.6.4", "objc2-foundation 0.3.2", ] @@ -2714,12 +2818,10 @@ checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" dependencies = [ "bitflags 2.10.0", "block2 0.6.2", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.2", - "objc2-javascript-core", - "objc2-security", ] [[package]] @@ -2898,10 +3000,20 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ - "phf_macros 0.11.3", "phf_shared 0.11.3", ] +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros 0.13.1", + "phf_shared 0.13.1", + "serde", +] + [[package]] name = "phf_codegen" version = "0.8.0" @@ -2922,6 +3034,16 @@ dependencies = [ "phf_shared 0.11.3", ] +[[package]] +name = "phf_codegen" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" +dependencies = [ + "phf_generator 0.13.1", + "phf_shared 0.13.1", +] + [[package]] name = "phf_generator" version = "0.8.0" @@ -2952,6 +3074,16 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared 0.13.1", +] + [[package]] name = "phf_macros" version = "0.10.0" @@ -2968,12 +3100,12 @@ dependencies = [ [[package]] name = "phf_macros" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", + "phf_generator 0.13.1", + "phf_shared 0.13.1", "proc-macro2", "quote", "syn 2.0.108", @@ -3006,6 +3138,15 @@ dependencies = [ "siphasher 1.0.1", ] +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher 1.0.1", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -3416,7 +3557,7 @@ dependencies = [ "dispatch", "lazy_static", "libc", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-core-foundation", "objc2-core-graphics", "objc2-foundation 0.3.2", @@ -3516,7 +3657,6 @@ dependencies = [ "cookie_store", "encoding_rs", "futures-core", - "futures-util", "h2", "http", "http-body", @@ -3538,6 +3678,39 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "reqwest" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "sync_wrapper", + "tokio", "tokio-util", "tower", "tower-http", @@ -3547,7 +3720,6 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", ] [[package]] @@ -3712,14 +3884,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" dependencies = [ "bitflags 1.3.2", - "cssparser", - "derive_more", + "cssparser 0.29.6", + "derive_more 0.99.20", "fxhash", "log", "phf 0.8.0", "phf_codegen 0.8.0", "precomputed-hash", - "servo_arc", + "servo_arc 0.2.0", + "smallvec", +] + +[[package]] +name = "selectors" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" +dependencies = [ + "bitflags 2.10.0", + "cssparser 0.36.0", + "derive_more 2.1.1", + "log", + "new_debug_unreachable", + "phf 0.13.1", + "phf_codegen 0.13.1", + "precomputed-hash", + "rustc-hash", + "servo_arc 0.4.3", "smallvec", ] @@ -3903,6 +4094,15 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "servo_arc" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170fb83ab34de17dc69aa7c67482b22218ddb85da56546f9bd6b929e32a05930" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "sha2" version = "0.10.9" @@ -4074,6 +4274,18 @@ dependencies = [ "serde", ] +[[package]] +name = "string_cache" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.13.1", + "precomputed-hash", +] + [[package]] name = "string_cache_codegen" version = "0.5.4" @@ -4086,6 +4298,18 @@ dependencies = [ "quote", ] +[[package]] +name = "string_cache_codegen" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" +dependencies = [ + "phf_generator 0.13.1", + "phf_shared 0.13.1", + "proc-macro2", + "quote", +] + [[package]] name = "strsim" version = "0.11.1" @@ -4196,35 +4420,35 @@ dependencies = [ [[package]] name = "tao" -version = "0.34.5" +version = "0.35.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a753bdc39c07b192151523a3f77cd0394aa75413802c883a0f6f6a0e5ee2e7" +checksum = "d1c93047acf68669466a34690ac58cca7010bd1b201e1ec86f1fd0a75d3dd4a9" dependencies = [ "bitflags 2.10.0", "block2 0.6.2", "core-foundation 0.10.1", - "core-graphics 0.24.0", + "core-graphics 0.25.0", "crossbeam-channel", - "dispatch", + "dbus", + "dispatch2", "dlopen2", "dpi", "gdkwayland-sys", "gdkx11-sys", "gtk", "jni", - "lazy_static", "libc", "log", "ndk", - "ndk-context", "ndk-sys", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit", "objc2-foundation 0.3.2", + "objc2-ui-kit", "once_cell", "parking_lot", + "percent-encoding", "raw-window-handle", - "scopeguard", "tao-macros", "unicode-segmentation", "url", @@ -4253,9 +4477,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.9.2" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bceb52453e507c505b330afe3398510e87f428ea42b6e76ecb6bd63b15965b5" +checksum = "c2616f96cb644bf2c5c456d9de4d5d5100e592d7424c74d8b55c5cb96e359e93" dependencies = [ "anyhow", "bytes", @@ -4274,7 +4498,7 @@ dependencies = [ "log", "mime", "muda", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit", "objc2-foundation 0.3.2", "objc2-ui-kit", @@ -4282,7 +4506,7 @@ dependencies = [ "percent-encoding", "plist", "raw-window-handle", - "reqwest", + "reqwest 0.13.4", "serde", "serde_json", "serde_repr", @@ -4305,9 +4529,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.5.1" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a924b6c50fe83193f0f8b14072afa7c25b7a72752a2a73d9549b463f5fe91a38" +checksum = "bc9ce40b16101cb6ea63d3e221567affd1c3a9205f95d7bc574941a10636b632" dependencies = [ "anyhow", "cargo_toml", @@ -4321,15 +4545,14 @@ dependencies = [ "serde_json", "tauri-utils", "tauri-winres", - "toml 0.9.8", "walkdir", ] [[package]] name = "tauri-codegen" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c1fe64c74cc40f90848281a90058a6db931eb400b60205840e09801ee30f190" +checksum = "08279169ff42f8fc45a1dbc9dcae888893ba95288142e5880c59b93a26d2cfc5" dependencies = [ "base64 0.22.1", "brotli", @@ -4354,9 +4577,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "260c5d2eb036b76206b9fca20b7be3614cfd21046c5396f7959e0e64a4b07f2f" +checksum = "e8b394794f399a421811d06966343e7933fcae92d59f5180b9388d1174497a45" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -4445,7 +4668,7 @@ dependencies = [ "data-url", "http", "regex", - "reqwest", + "reqwest 0.12.24", "schemars 0.8.22", "serde", "serde_json", @@ -4465,7 +4688,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5607e0707d37d7b20e287cf0ce396d1efebe7b833b8e9cbd2ea4257091d9c604" dependencies = [ "macos-accessibility-client", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-foundation 0.3.2", "serde", "tauri", @@ -4577,16 +4800,16 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.9.1" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9368f09358496f2229313fccb37682ad116b7f46fa76981efe116994a0628926" +checksum = "b0b4bc95aed361b0019067d189a1174a603d460d0f6c72606512d59fc9c12ec8" dependencies = [ "cookie", "dpi", "gtk", "http", "jni", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-ui-kit", "objc2-web-kit", "raw-window-handle", @@ -4602,17 +4825,16 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.9.1" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "929f5df216f5c02a9e894554401bcdab6eec3e39ec6a4a7731c7067fc8688a93" +checksum = "fe41e015bf8fc4d6477ff4926a0ef769dc64ff34c7b0038b6f7cacae892acb5c" dependencies = [ "gtk", "http", "jni", "log", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit", - "objc2-foundation 0.3.2", "once_cell", "percent-encoding", "raw-window-handle", @@ -4629,24 +4851,26 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.8.0" +version = "2.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6b8bbe426abdbf52d050e52ed693130dbd68375b9ad82a3fb17efb4c8d85673" +checksum = "3e176a18e67764923c4f1ce66f25ae4abe5f688384d5eb1a0fa6c77f3d90f887" dependencies = [ "anyhow", "brotli", "cargo_metadata", "ctor", + "dom_query", "dunce", "glob", - "html5ever", + "html5ever 0.29.1", "http", "infer", "json-patch", "kuchikiki", "log", "memchr", - "phf 0.11.3", + "phf 0.13.1", + "plist", "proc-macro2", "quote", "regex", @@ -4699,6 +4923,16 @@ dependencies = [ "utf-8", ] +[[package]] +name = "tendril" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4790fc369d5a530f4b544b094e31388b9b3a37c0f4652ade4505945f5660d24" +dependencies = [ + "new_debug_unreachable", + "utf-8", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -4957,20 +5191,20 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "bitflags 2.10.0", "bytes", "futures-util", "http", "http-body", - "iri-string", "pin-project-lite", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -5018,24 +5252,24 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.21.2" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d5572781bee8e3f994d7467084e1b1fd7a93ce66bd480f8156ba89dee55a2b" +checksum = "65ba1e5f6b9ef9fd87e21b9c6f351554dbd717960089168fcfdef854686961dc" dependencies = [ "crossbeam-channel", "dirs 6.0.0", "libappindicator", "muda", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-core-graphics", "objc2-foundation 0.3.2", "once_cell", - "png 0.17.16", + "png 0.18.0", "serde", "thiserror 2.0.17", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -5248,9 +5482,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.105" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" dependencies = [ "cfg-if", "once_cell", @@ -5261,22 +5495,19 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.55" +version = "0.4.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" +checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280" dependencies = [ - "cfg-if", "js-sys", - "once_cell", "wasm-bindgen", - "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.105" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5284,9 +5515,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.105" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" dependencies = [ "bumpalo", "proc-macro2", @@ -5297,18 +5528,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.105" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-streams" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" dependencies = [ "futures-util", "js-sys", @@ -5319,9 +5550,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.82" +version = "0.3.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d" dependencies = [ "js-sys", "wasm-bindgen", @@ -5337,11 +5568,23 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web_atoms" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "075474b12bcb3d2e3d4546580e9de478eeeead668a1761e2a8860c836b7ef297" +dependencies = [ + "phf 0.13.1", + "phf_codegen 0.13.1", + "string_cache 0.9.0", + "string_cache_codegen 0.6.1", +] + [[package]] name = "webkit2gtk" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793" dependencies = [ "bitflags 1.3.2", "cairo-rs", @@ -5363,9 +5606,9 @@ dependencies = [ [[package]] name = "webkit2gtk-sys" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5" dependencies = [ "bitflags 1.3.2", "cairo-sys-rs", @@ -5463,7 +5706,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" dependencies = [ - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.2", @@ -5530,19 +5773,6 @@ dependencies = [ "windows-strings 0.4.2", ] -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - [[package]] name = "windows-future" version = "0.2.1" @@ -5997,27 +6227,26 @@ checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "wry" -version = "0.53.5" +version = "0.55.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728b7d4c8ec8d81cab295e0b5b8a4c263c0d41a785fb8f8c4df284e5411140a2" +checksum = "186f9871daa55fd9c016578b810d149de58367113db7fb72b462d2323ce19514" dependencies = [ "base64 0.22.1", "block2 0.6.2", "cookie", "crossbeam-channel", "dirs 6.0.0", + "dom_query", "dpi", "dunce", "gdkx11", "gtk", - "html5ever", "http", "javascriptcore-rs", "jni", - "kuchikiki", "libc", "ndk", - "objc2 0.6.3", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.2", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index dbe01bc..0821214 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -18,7 +18,7 @@ crate-type = ["staticlib", "cdylib", "rlib"] tauri-build = { version = "2", features = [] } [dependencies] -tauri = { version = "2", features = ["macos-private-api", "tray-icon", "image-png", "image-ico"] } +tauri = { version = "~2.11", features = ["macos-private-api", "tray-icon", "image-png", "image-ico"] } tauri-plugin-opener = "2" tauri-plugin-os = "2" tauri-plugin-global-shortcut = "2" diff --git a/src/hooks/useDrawingSettings.ts b/src/hooks/useDrawingSettings.ts index e7c6718..687e3c7 100644 --- a/src/hooks/useDrawingSettings.ts +++ b/src/hooks/useDrawingSettings.ts @@ -32,8 +32,9 @@ import { listen } from '@tauri-apps/api/event'; */ export function useDrawingSettings() { const [drawingSettings, setDrawingSettings] = useState({ - toggleShortcut: 'Alt+`', + toggleShortcut: 'Alt+1', toolbarShortcut: 'Alt+H', + toggleAndClearShortcut: 'Alt+`', }); const [loading, setLoading] = useState(true); From 68bdf043113a364d5b140d0a02bacc1111ce8d0c Mon Sep 17 00:00:00 2001 From: Hemang Date: Sat, 27 Jun 2026 14:56:45 +0530 Subject: [PATCH 31/34] feat: set freedraw default stroke width to 0.7 (near-hairline) and bump version to 1.0.18 Co-Authored-By: Claude Sonnet 4.6 --- package.json | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- src/components/Settings.tsx | 123 ++++++++++++++++++ src/hooks/useShortcut.ts | 4 +- src/i18n/locales/de-DE.json | 7 +- src/i18n/locales/en-US.json | 7 +- src/i18n/locales/es-ES.json | 7 +- src/i18n/locales/fr-FR.json | 7 +- src/i18n/locales/ja-JP.json | 7 +- src/i18n/locales/ko-KR.json | 7 +- src/i18n/locales/zh-CN.json | 7 +- src/i18n/locales/zh-TW.json | 7 +- .../excalidraw/actions/actionCanvas.tsx | 2 +- .../excalidraw/actions/actionProperties.tsx | 7 + .../packages/excalidraw/components/App.tsx | 4 +- .../packages/excalidraw/components/icons.tsx | 11 ++ .../packages/excalidraw/constants.ts | 1 + .../packages/excalidraw/locales/ar-SA.json | 5 +- .../packages/excalidraw/locales/az-AZ.json | 5 +- .../packages/excalidraw/locales/bg-BG.json | 5 +- .../packages/excalidraw/locales/bn-BD.json | 5 +- .../packages/excalidraw/locales/ca-ES.json | 5 +- .../packages/excalidraw/locales/cs-CZ.json | 5 +- .../packages/excalidraw/locales/da-DK.json | 5 +- .../packages/excalidraw/locales/de-DE.json | 5 +- .../packages/excalidraw/locales/el-GR.json | 5 +- .../packages/excalidraw/locales/en.json | 5 +- .../packages/excalidraw/locales/es-ES.json | 5 +- .../packages/excalidraw/locales/eu-ES.json | 5 +- .../packages/excalidraw/locales/fa-IR.json | 5 +- .../packages/excalidraw/locales/fi-FI.json | 5 +- .../packages/excalidraw/locales/fr-FR.json | 5 +- .../packages/excalidraw/locales/gl-ES.json | 5 +- .../packages/excalidraw/locales/he-IL.json | 5 +- .../packages/excalidraw/locales/hi-IN.json | 5 +- .../packages/excalidraw/locales/hu-HU.json | 5 +- .../packages/excalidraw/locales/id-ID.json | 5 +- .../packages/excalidraw/locales/it-IT.json | 5 +- .../packages/excalidraw/locales/ja-JP.json | 5 +- .../packages/excalidraw/locales/kaa.json | 5 +- .../packages/excalidraw/locales/kab-KAB.json | 5 +- .../packages/excalidraw/locales/kk-KZ.json | 5 +- .../packages/excalidraw/locales/km-KH.json | 5 +- .../packages/excalidraw/locales/ko-KR.json | 5 +- .../packages/excalidraw/locales/ku-TR.json | 5 +- .../packages/excalidraw/locales/lt-LT.json | 5 +- .../packages/excalidraw/locales/lv-LV.json | 5 +- .../packages/excalidraw/locales/mr-IN.json | 5 +- .../packages/excalidraw/locales/my-MM.json | 5 +- .../packages/excalidraw/locales/nb-NO.json | 5 +- .../packages/excalidraw/locales/nl-NL.json | 5 +- .../packages/excalidraw/locales/nn-NO.json | 5 +- .../packages/excalidraw/locales/oc-FR.json | 5 +- .../packages/excalidraw/locales/pa-IN.json | 5 +- .../excalidraw/locales/percentages.json | 2 +- .../packages/excalidraw/locales/pl-PL.json | 5 +- .../packages/excalidraw/locales/pt-BR.json | 5 +- .../packages/excalidraw/locales/pt-PT.json | 5 +- .../packages/excalidraw/locales/ro-RO.json | 5 +- .../packages/excalidraw/locales/ru-RU.json | 5 +- .../packages/excalidraw/locales/si-LK.json | 5 +- .../packages/excalidraw/locales/sk-SK.json | 5 +- .../packages/excalidraw/locales/sl-SI.json | 5 +- .../packages/excalidraw/locales/sv-SE.json | 5 +- .../packages/excalidraw/locales/ta-IN.json | 5 +- .../packages/excalidraw/locales/th-TH.json | 5 +- .../packages/excalidraw/locales/tr-TR.json | 5 +- .../packages/excalidraw/locales/uk-UA.json | 5 +- .../packages/excalidraw/locales/vi-VN.json | 5 +- .../packages/excalidraw/locales/zh-CN.json | 5 +- .../packages/excalidraw/locales/zh-HK.json | 5 +- .../packages/excalidraw/locales/zh-TW.json | 5 +- .../excalidraw/renderer/renderElement.ts | 6 +- src/pages/motion-board/App.tsx | 5 +- src/store/settings.ts | 12 +- 76 files changed, 369 insertions(+), 140 deletions(-) diff --git a/package.json b/package.json index 759e266..4b12939 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "penio", "private": true, - "version": "1.0.17", + "version": "1.0.18", "type": "module", "workspaces": [ "src/packages/excalidraw/packages/excalidraw", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 0821214..600c7a2 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "penio" -version = "1.0.9" +version = "1.0.10" description = "A Tauri App" authors = ["game1024"] edition = "2021" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 602d16b..8711ff3 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "Penio", - "version": "1.0.17", + "version": "1.0.18", "identifier": "com.fiofio.penio", "build": { "beforeDevCommand": "bun run dev", diff --git a/src/components/Settings.tsx b/src/components/Settings.tsx index dba213a..61984b2 100644 --- a/src/components/Settings.tsx +++ b/src/components/Settings.tsx @@ -1209,6 +1209,9 @@ function 绘图设置页面() { const [toggleAndClearShortcut, setToggleAndClearShortcut] = useState(''); const [confirmClearAnnotation, setConfirmClearAnnotation] = useState(false); const [enableScrollAndPan, setEnableScrollAndPan] = useState(true); + const [penPressureSensitivity, setPenPressureSensitivity] = useState(0.6); + const [penSmoothing, setPenSmoothing] = useState(0.5); + const [penStreamline, setPenStreamline] = useState(0.5); const { notify } = useSnackbar(); // 加载设置 @@ -1221,6 +1224,9 @@ function 绘图设置页面() { setToggleAndClearShortcut(settings.drawing?.toggleAndClearShortcut); setConfirmClearAnnotation(settings.drawing?.confirmClearAnnotation ?? false); setEnableScrollAndPan(settings.drawing?.enableScrollAndPan ?? true); + setPenPressureSensitivity(settings.drawing?.penPressureSensitivity ?? 0.6); + setPenSmoothing(settings.drawing?.penSmoothing ?? 0.5); + setPenStreamline(settings.drawing?.penStreamline ?? 0.5); } catch (error) { console.error('加载绘图设置失败:', error); notify(t('drawing.messages.loadFailed'), 'error'); @@ -1316,6 +1322,45 @@ function 绘图设置页面() { } }; + const handlePenPressureSensitivityChange = async (value: number) => { + const clamped = Math.max(0, Math.min(1, value)); + setPenPressureSensitivity(clamped); + try { + const currentSettings = await getSettings(); + await updateSettings({ + drawing: { ...currentSettings.drawing, penPressureSensitivity: clamped } + }); + } catch (error) { + console.error('保存设置失败:', error); + } + }; + + const handlePenSmoothingChange = async (value: number) => { + const clamped = Math.max(0, Math.min(1, value)); + setPenSmoothing(clamped); + try { + const currentSettings = await getSettings(); + await updateSettings({ + drawing: { ...currentSettings.drawing, penSmoothing: clamped } + }); + } catch (error) { + console.error('保存设置失败:', error); + } + }; + + const handlePenStreamlineChange = async (value: number) => { + const clamped = Math.max(0, Math.min(1, value)); + setPenStreamline(clamped); + try { + const currentSettings = await getSettings(); + await updateSettings({ + drawing: { ...currentSettings.drawing, penStreamline: clamped } + }); + } catch (error) { + console.error('保存设置失败:', error); + } + }; + return ( {t('drawing.title')} @@ -1381,6 +1426,84 @@ function 绘图设置页面() { disable={true} /> } /> + + handlePenPressureSensitivityChange(value as number)} + min={0} + max={1} + step={0.1} + valueLabelDisplay="auto" + sx={{ width: '9.375rem', mr: 2 }} + /> + { + const value = Number(e.target.value); + if (!isNaN(value)) handlePenPressureSensitivityChange(value); + }} + type="number" + size="small" + sx={{ width: 'max-content' }} + inputProps={{ min: 0, max: 1, step: 0.1 }} + /> + + } /> + + handlePenSmoothingChange(value as number)} + min={0} + max={1} + step={0.1} + valueLabelDisplay="auto" + sx={{ width: '9.375rem', mr: 2 }} + /> + { + const value = Number(e.target.value); + if (!isNaN(value)) handlePenSmoothingChange(value); + }} + type="number" + size="small" + sx={{ width: 'max-content' }} + inputProps={{ min: 0, max: 1, step: 0.1 }} + /> + + } /> + + handlePenStreamlineChange(value as number)} + min={0} + max={1} + step={0.1} + valueLabelDisplay="auto" + sx={{ width: '9.375rem', mr: 2 }} + /> + { + const value = Number(e.target.value); + if (!isNaN(value)) handlePenStreamlineChange(value); + }} + type="number" + size="small" + sx={{ width: 'max-content' }} + inputProps={{ min: 0, max: 1, step: 0.1 }} + /> + + } /> diff --git a/src/hooks/useShortcut.ts b/src/hooks/useShortcut.ts index 5845c85..0b75c10 100644 --- a/src/hooks/useShortcut.ts +++ b/src/hooks/useShortcut.ts @@ -44,7 +44,7 @@ export function useShortcut() { try { const settings = await getSettings(); - const toggleShortcut = settings.drawing?.toggleShortcut || 'Alt+1'; + const toggleShortcut = settings.drawing?.toggleShortcut || 'Alt+`'; await register(toggleShortcut, async () => { await invoke('trigger_drawing_mode'); }); @@ -54,7 +54,7 @@ export function useShortcut() { await emit('toolbar-visibility-toggled'); }); - const toggleAndClearShortcut = settings.drawing?.toggleAndClearShortcut || 'Alt+`'; + const toggleAndClearShortcut = settings.drawing?.toggleAndClearShortcut || 'Alt+1'; await register(toggleAndClearShortcut, async () => { await emit('trigger-clear-canvas'); await invoke('trigger_drawing_mode'); diff --git a/src/i18n/locales/de-DE.json b/src/i18n/locales/de-DE.json index 2d7d7f2..bb8a026 100644 --- a/src/i18n/locales/de-DE.json +++ b/src/i18n/locales/de-DE.json @@ -101,7 +101,10 @@ "toolbarShown": "Symbolleiste angezeigt ({{shortcut}} umschalten)", "toolbarHidden": "Symbolleiste ausgeblendet ({{shortcut}} wiederherstellen)" }, - "enableScrollAndPan": "Mausscrollen und Canvas-Schwenken aktivieren" + "enableScrollAndPan": "Mausscrollen und Canvas-Schwenken aktivieren", + "penPressureSensitivity": "Stiftdruckempfindlichkeit", + "penSmoothing": "Strich-Glättung", + "penStreamline": "Strich-Stabilisierung" }, "general": { "title": "Systemeinstellungen", @@ -198,4 +201,4 @@ "pressShortcut": "Tastenkürzel drücken", "notSet": "Nicht gesetzt" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 368f074..87c480a 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -101,7 +101,10 @@ "toolbarShown": "Toolbar shown ({{shortcut}} toggle)", "toolbarHidden": "Toolbar hidden ({{shortcut}} restore)" }, - "enableScrollAndPan": "Enable mouse scroll and canvas pan" + "enableScrollAndPan": "Enable mouse scroll and canvas pan", + "penPressureSensitivity": "Pen Pressure Sensitivity", + "penSmoothing": "Stroke Smoothing", + "penStreamline": "Stroke Stabilization" }, "general": { "title": "System Settings", @@ -198,4 +201,4 @@ "pressShortcut": "Press shortcut", "notSet": "Not set" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/es-ES.json b/src/i18n/locales/es-ES.json index 7064a4e..6d66592 100644 --- a/src/i18n/locales/es-ES.json +++ b/src/i18n/locales/es-ES.json @@ -101,7 +101,10 @@ "toolbarShown": "Barra de herramientas mostrada ({{shortcut}} alternar)", "toolbarHidden": "Barra de herramientas oculta ({{shortcut}} restaurar)" }, - "enableScrollAndPan": "Habilitar desplazamiento del ratón y paneo del lienzo" + "enableScrollAndPan": "Habilitar desplazamiento del ratón y paneo del lienzo", + "penPressureSensitivity": "Sensibilidad a la presión del lápiz", + "penSmoothing": "Suavizado del trazo", + "penStreamline": "Estabilización del trazo" }, "general": { "title": "Configuración del sistema", @@ -198,4 +201,4 @@ "pressShortcut": "Presione el atajo", "notSet": "No establecido" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/fr-FR.json b/src/i18n/locales/fr-FR.json index f75ec4f..fc59eb4 100644 --- a/src/i18n/locales/fr-FR.json +++ b/src/i18n/locales/fr-FR.json @@ -101,7 +101,10 @@ "toolbarShown": "Barre d'outils affichée ({{shortcut}} bascule)", "toolbarHidden": "Barre d'outils masquée ({{shortcut}} restaurer)" }, - "enableScrollAndPan": "Activer le défilement souris et le panoramique" + "enableScrollAndPan": "Activer le défilement souris et le panoramique", + "penPressureSensitivity": "Sensibilité à la pression du stylet", + "penSmoothing": "Lissage du trait", + "penStreamline": "Stabilisation du trait" }, "general": { "title": "Paramètres système", @@ -198,4 +201,4 @@ "pressShortcut": "Appuyez sur le raccourci", "notSet": "Non défini" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/ja-JP.json b/src/i18n/locales/ja-JP.json index 081da59..bb72331 100644 --- a/src/i18n/locales/ja-JP.json +++ b/src/i18n/locales/ja-JP.json @@ -101,7 +101,10 @@ "toolbarShown": "ツールバーを表示しました ({{shortcut}} 切替)", "toolbarHidden": "ツールバーを非表示にしました ({{shortcut}} 復元)" }, - "enableScrollAndPan": "マウススクロールとキャンバスパンを有効にする" + "enableScrollAndPan": "マウススクロールとキャンバスパンを有効にする", + "penPressureSensitivity": "ペン圧力感度", + "penSmoothing": "ストローク平滑化", + "penStreamline": "ストローク安定化" }, "general": { "title": "システム設定", @@ -198,4 +201,4 @@ "pressShortcut": "ショートカットを押してください", "notSet": "未設定" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/ko-KR.json b/src/i18n/locales/ko-KR.json index be9f0c8..e883274 100644 --- a/src/i18n/locales/ko-KR.json +++ b/src/i18n/locales/ko-KR.json @@ -101,7 +101,10 @@ "toolbarShown": "툴바 표시됨 ({{shortcut}} 전환)", "toolbarHidden": "툴바 숨김 ({{shortcut}} 복원)" }, - "enableScrollAndPan": "마우스 스크롤 및 캔버스 패닝 활성화" + "enableScrollAndPan": "마우스 스크롤 및 캔버스 패닝 활성화", + "penPressureSensitivity": "펜 압력 감도", + "penSmoothing": "획 부드럽기", + "penStreamline": "획 안정화" }, "general": { "title": "시스템 설정", @@ -198,4 +201,4 @@ "pressShortcut": "단축키를 누르세요", "notSet": "설정 안됨" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index df05d6a..0cdda6d 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -101,7 +101,10 @@ "toolbarShown": "工具栏已显示 ({{shortcut}} 切换)", "toolbarHidden": "工具栏已隐藏 ({{shortcut}} 恢复)" }, - "enableScrollAndPan": "启用鼠标滚动和画布平移" + "enableScrollAndPan": "启用鼠标滚动和画布平移", + "penPressureSensitivity": "钢笔压力灵敏度", + "penSmoothing": "笔画平滑度", + "penStreamline": "笔画稳定度" }, "general": { "title": "系统设置", @@ -198,4 +201,4 @@ "pressShortcut": "按下快捷键", "notSet": "未设置" } -} +} \ No newline at end of file diff --git a/src/i18n/locales/zh-TW.json b/src/i18n/locales/zh-TW.json index 0973b94..1630b54 100644 --- a/src/i18n/locales/zh-TW.json +++ b/src/i18n/locales/zh-TW.json @@ -101,7 +101,10 @@ "toolbarShown": "工具列已顯示 ({{shortcut}} 切換)", "toolbarHidden": "工具列已隱藏 ({{shortcut}} 恢復)" }, - "enableScrollAndPan": "啟用滑鼠滾動和畫布平移" + "enableScrollAndPan": "啟用滑鼠滾動和畫布平移", + "penPressureSensitivity": "鋼筆壓力靈敏度", + "penSmoothing": "筆畫平滑度", + "penStreamline": "筆畫穩定度" }, "general": { "title": "系統設定", @@ -198,4 +201,4 @@ "pressShortcut": "按下快捷鍵", "notSet": "未設置" } -} +} \ No newline at end of file diff --git a/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx b/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx index f9bd985..5aa653a 100644 --- a/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx +++ b/src/packages/excalidraw/packages/excalidraw/actions/actionCanvas.tsx @@ -115,7 +115,7 @@ export const actionClearCanvas = register({ currentItemRoundness: appState.currentItemRoundness, stats: appState.stats, pasteDialog: appState.pasteDialog, - currentItemStrokeWidth: appState.activeTool.type === "freedraw" ? 1 : appState.currentItemStrokeWidth, + currentItemStrokeWidth: appState.activeTool.type === "freedraw" ? 0.7 : appState.currentItemStrokeWidth, toolbarVisible: appState.toolbarVisible, activeTool: appState.activeTool.type === "image" diff --git a/src/packages/excalidraw/packages/excalidraw/actions/actionProperties.tsx b/src/packages/excalidraw/packages/excalidraw/actions/actionProperties.tsx index 0c2ad3b..5924cb2 100644 --- a/src/packages/excalidraw/packages/excalidraw/actions/actionProperties.tsx +++ b/src/packages/excalidraw/packages/excalidraw/actions/actionProperties.tsx @@ -32,6 +32,7 @@ import { SloppinessArchitectIcon, SloppinessArtistIcon, SloppinessCartoonistIcon, + StrokeWidthHairlineIcon, StrokeWidthBaseIcon, StrokeWidthBoldIcon, StrokeWidthExtraBoldIcon, @@ -475,6 +476,12 @@ export const actionChangeStrokeWidth = register({ { toast: this.state.toast, currentItemStrokeWidth: scene.appState.activeTool.type === "freedraw" - ? 1 + ? 0.7 : scene.appState.currentItemStrokeWidth, }; if (initialData?.scrollToContent) { @@ -4733,7 +4733,7 @@ class App extends React.Component { const toolSpecificResets: Partial = nextActiveTool.type === "freedraw" - ? { currentItemStrokeWidth: 1 } + ? { currentItemStrokeWidth: 0.7 } : prevState.activeTool.type === "freedraw" ? { currentItemStrokeWidth: 2 } : {}; diff --git a/src/packages/excalidraw/packages/excalidraw/components/icons.tsx b/src/packages/excalidraw/packages/excalidraw/components/icons.tsx index 073d7a9..fe20d40 100644 --- a/src/packages/excalidraw/packages/excalidraw/components/icons.tsx +++ b/src/packages/excalidraw/packages/excalidraw/components/icons.tsx @@ -1074,6 +1074,17 @@ export const FillSolidIcon = createIcon( { ...modifiedTablerIconProps, fill: "currentColor" }, ); +export const StrokeWidthHairlineIcon = createIcon( + , + modifiedTablerIconProps, +); + export const StrokeWidthBaseIcon = createIcon( <> Math.sin((t * Math.PI) / 2), // https://easings.net/#easeOutSine last: !!element.lastCommittedPoint, // LastCommittedPoint is added on pointerup }; diff --git a/src/pages/motion-board/App.tsx b/src/pages/motion-board/App.tsx index ef6e126..fa6f356 100644 --- a/src/pages/motion-board/App.tsx +++ b/src/pages/motion-board/App.tsx @@ -48,6 +48,9 @@ function App({ theme }: { theme: 'light' | 'dark' }) { useEffect(() => { (window as any).__penio_confirmClearAnnotation = drawingSettings.confirmClearAnnotation ?? true; (window as any).__penio_enableScrollAndPan = drawingSettings.enableScrollAndPan ?? true; + (window as any).__penio_penPressureSensitivity = drawingSettings.penPressureSensitivity ?? 0.6; + (window as any).__penio_penSmoothing = drawingSettings.penSmoothing ?? 0.5; + (window as any).__penio_penStreamline = drawingSettings.penStreamline ?? 0.5; }, [drawingSettings]); // 存储鼠标穿透状态 @@ -398,7 +401,7 @@ function App({ theme }: { theme: 'light' | 'dark' }) { const unlisten = await appWindow.listen('trigger-clear-canvas', () => { excalidrawAPIRef.current?.updateScene({ elements: [], - appState: { currentItemStrokeWidth: 1 }, + appState: {}, }); }); return unlisten; diff --git a/src/store/settings.ts b/src/store/settings.ts index 06567e2..a943549 100644 --- a/src/store/settings.ts +++ b/src/store/settings.ts @@ -67,6 +67,9 @@ export interface DrawingSettings { confirmClearAnnotation?: boolean; enableScrollAndPan?: boolean; showDrawingModeNotice?: boolean; + penPressureSensitivity?: number; + penSmoothing?: number; + penStreamline?: number; } // 应用设置接口 @@ -110,11 +113,14 @@ const defaultSettings: AppSettings = { offsetY: 0, }, drawing: { - toggleShortcut: 'Alt+1', + toggleShortcut: 'Alt+`', toolbarShortcut: 'Alt+H', - toggleAndClearShortcut: 'Alt+`', + toggleAndClearShortcut: 'Alt+1', confirmClearAnnotation: true, enableScrollAndPan: true, + penPressureSensitivity: 0.6, + penSmoothing: 0.5, + penStreamline: 0.5, }, }; @@ -138,7 +144,7 @@ export const getSettings = async (): Promise => { drawing: { ...defaultSettings.drawing, ...settings?.drawing, - ...(settings?.drawing?.toggleShortcut === 'Alt+`' ? { toggleShortcut: 'Alt+1' } : {}), + ...(settings?.drawing?.toggleShortcut === 'Alt+1' ? { toggleShortcut: 'Alt+`' } : {}), }, }; }; From 00df4cb35da33a1a6f3d9b6e2662c763b24d4ddc Mon Sep 17 00:00:00 2001 From: Hemang Date: Sat, 27 Jun 2026 15:14:00 +0530 Subject: [PATCH 32/34] fix: update STROKE_WIDTH.hairline constant from 0.5 to 0.7 to match freedraw default Co-Authored-By: Claude Sonnet 4.6 --- src/packages/excalidraw/packages/excalidraw/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/packages/excalidraw/packages/excalidraw/constants.ts b/src/packages/excalidraw/packages/excalidraw/constants.ts index 8254d78..ba49f02 100644 --- a/src/packages/excalidraw/packages/excalidraw/constants.ts +++ b/src/packages/excalidraw/packages/excalidraw/constants.ts @@ -373,7 +373,7 @@ export const ROUGHNESS = { } as const; export const STROKE_WIDTH = { - hairline: 0.5, + hairline: 0.7, thin: 1, bold: 2, extraBold: 4, From e56afa10335c50dc02b8af9772dd76d9c63d3b0d Mon Sep 17 00:00:00 2001 From: Hemang Date: Sat, 27 Jun 2026 15:17:21 +0530 Subject: [PATCH 33/34] chore: update Cargo.lock Co-Authored-By: Claude Sonnet 4.6 --- src-tauri/Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 55ea394..80620a3 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2942,7 +2942,7 @@ checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "penio" -version = "1.0.9" +version = "1.0.10" dependencies = [ "cocoa", "ctrlc", From 07b1088928c871df0a6c782f8631ba08badf40ad Mon Sep 17 00:00:00 2001 From: Hemang Date: Sat, 27 Jun 2026 15:19:12 +0530 Subject: [PATCH 34/34] fix: pin @tauri-apps/api to ~2.11 to match tauri Rust crate v2.11.x Co-Authored-By: Claude Sonnet 4.6 --- bun.lock | 25 +++++++++++++++++++++++-- package.json | 2 +- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/bun.lock b/bun.lock index 1cb3669..ca25f4b 100644 --- a/bun.lock +++ b/bun.lock @@ -1,5 +1,6 @@ { "lockfileVersion": 1, + "configVersion": 0, "workspaces": { "": { "name": "penio", @@ -14,7 +15,7 @@ "@mojs/core": "^1.7.1", "@mui/icons-material": "^7.3.6", "@mui/material": "^7.3.6", - "@tauri-apps/api": "^2", + "@tauri-apps/api": "~2.11", "@tauri-apps/plugin-autostart": "~2", "@tauri-apps/plugin-cli": "~2", "@tauri-apps/plugin-global-shortcut": "^2.3.1", @@ -485,7 +486,7 @@ "@size-limit/webpack": ["@size-limit/webpack@9.0.0", "", { "dependencies": { "nanoid": "^3.3.6", "webpack": "^5.88.2" }, "peerDependencies": { "size-limit": "9.0.0" } }, "sha512-0YwdvmBj9rS4bXE/PY9vSdc5lCiQXmT0794EsG7yvlDMWyrWa/dsgcRok/w0MoZstfuLaS6lv03VI5UJRFU/lg=="], - "@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + "@tauri-apps/api": ["@tauri-apps/api@2.11.1", "", {}, "sha512-M2FPuYND2m+wh5hfW9ZpSdxMPdEJovPBWwoHJmwUpysTYNHaOkVFN419m/K0LIgjb/7KU2vBgsUepJWugQCvAA=="], "@tauri-apps/cli": ["@tauri-apps/cli@2.9.2", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.9.2", "@tauri-apps/cli-darwin-x64": "2.9.2", "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.2", "@tauri-apps/cli-linux-arm64-gnu": "2.9.2", "@tauri-apps/cli-linux-arm64-musl": "2.9.2", "@tauri-apps/cli-linux-riscv64-gnu": "2.9.2", "@tauri-apps/cli-linux-x64-gnu": "2.9.2", "@tauri-apps/cli-linux-x64-musl": "2.9.2", "@tauri-apps/cli-win32-arm64-msvc": "2.9.2", "@tauri-apps/cli-win32-ia32-msvc": "2.9.2", "@tauri-apps/cli-win32-x64-msvc": "2.9.2" }, "bin": { "tauri": "tauri.js" } }, "sha512-aGzdVgxQW6WQ7e5nydPZ/30u8HvltHjO3Ytzf1wOxX1N5Yj2TsjKWRb/AWJlB95Huml3k3c/b6s0ijAvlSo9xw=="], @@ -1771,6 +1772,24 @@ "@size-limit/webpack/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "@tauri-apps/plugin-autostart/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + + "@tauri-apps/plugin-cli/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + + "@tauri-apps/plugin-global-shortcut/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + + "@tauri-apps/plugin-http/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + + "@tauri-apps/plugin-opener/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + + "@tauri-apps/plugin-os/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + + "@tauri-apps/plugin-process/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + + "@tauri-apps/plugin-shell/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + + "@tauri-apps/plugin-store/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + "@testing-library/jest-dom/aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], "@testing-library/jest-dom/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="], @@ -1875,6 +1894,8 @@ "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "tauri-plugin-macos-permissions-api/@tauri-apps/api": ["@tauri-apps/api@2.9.0", "", {}, "sha512-qD5tMjh7utwBk9/5PrTA/aGr3i5QaJ/Mlt7p8NilQ45WgbifUNPyKWsA63iQ8YfQq6R8ajMapU+/Q8nMcPRLNw=="], + "upper-case/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "upper-case-first/tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], diff --git a/package.json b/package.json index 4b12939..c949ad7 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "@mojs/core": "^1.7.1", "@mui/icons-material": "^7.3.6", "@mui/material": "^7.3.6", - "@tauri-apps/api": "^2", + "@tauri-apps/api": "~2.11", "@tauri-apps/plugin-autostart": "~2", "@tauri-apps/plugin-cli": "~2", "@tauri-apps/plugin-global-shortcut": "^2.3.1",