diff --git a/bun.lockb b/bun.lockb index 53f8db2..fe07be3 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..057a9c7 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1273 @@ +{ + "name": "handy-app", + "version": "0.3.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "handy-app", + "version": "0.3.1", + "dependencies": { + "@tailwindcss/vite": "^4.0.2", + "@tauri-apps/api": "^2.6.0", + "@tauri-apps/plugin-autostart": "~2", + "@tauri-apps/plugin-clipboard-manager": "~2", + "@tauri-apps/plugin-fs": "^2.4.1", + "@tauri-apps/plugin-global-shortcut": "~2", + "@tauri-apps/plugin-opener": "^2", + "@tauri-apps/plugin-os": "~2", + "@tauri-apps/plugin-process": "~2", + "@tauri-apps/plugin-store": "~2", + "@tauri-apps/plugin-stronghold": "~2", + "@tauri-apps/plugin-updater": "~2", + "@tauri-apps/plugin-upload": "~2", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "tailwindcss": "^4.0.2", + "tauri-plugin-macos-permissions-api": "^2.0.4", + "zod": "^3.24.4" + }, + "devDependencies": { + "@tauri-apps/cli": "^2", + "@types/node": "^24.0.6", + "@types/react": "^18.3.1", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.4", + "typescript": "~5.6.2", + "vite": "^6.0.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.5", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.7", + "@babel/parser": "^7.26.7", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.26.7", + "@babel/types": "^7.26.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.5", + "@babel/types": "^7.26.5", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.26.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.5", + "@babel/parser": "^7.26.7", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.32.1", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@tailwindcss/node": { + "version": "4.0.2", + "license": "MIT", + "dependencies": { + "enhanced-resolve": "^5.18.0", + "jiti": "^2.4.2", + "tailwindcss": "4.0.2" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.0.2", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.0.2", + "@tailwindcss/oxide-darwin-arm64": "4.0.2", + "@tailwindcss/oxide-darwin-x64": "4.0.2", + "@tailwindcss/oxide-freebsd-x64": "4.0.2", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.2", + "@tailwindcss/oxide-linux-arm64-gnu": "4.0.2", + "@tailwindcss/oxide-linux-arm64-musl": "4.0.2", + "@tailwindcss/oxide-linux-x64-gnu": "4.0.2", + "@tailwindcss/oxide-linux-x64-musl": "4.0.2", + "@tailwindcss/oxide-win32-arm64-msvc": "4.0.2", + "@tailwindcss/oxide-win32-x64-msvc": "4.0.2" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.0.2", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.0.2", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "^4.0.2", + "@tailwindcss/oxide": "^4.0.2", + "lightningcss": "^1.29.1", + "tailwindcss": "4.0.2" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6" + } + }, + "node_modules/@tauri-apps/api": { + "version": "2.6.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/cli": { + "version": "2.2.7", + "dev": true, + "license": "Apache-2.0 OR MIT", + "bin": { + "tauri": "tauri.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "2.2.7", + "@tauri-apps/cli-darwin-x64": "2.2.7", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.2.7", + "@tauri-apps/cli-linux-arm64-gnu": "2.2.7", + "@tauri-apps/cli-linux-arm64-musl": "2.2.7", + "@tauri-apps/cli-linux-x64-gnu": "2.2.7", + "@tauri-apps/cli-linux-x64-musl": "2.2.7", + "@tauri-apps/cli-win32-arm64-msvc": "2.2.7", + "@tauri-apps/cli-win32-ia32-msvc": "2.2.7", + "@tauri-apps/cli-win32-x64-msvc": "2.2.7" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "2.2.7", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/plugin-autostart": { + "version": "2.2.0", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, + "node_modules/@tauri-apps/plugin-autostart/node_modules/@tauri-apps/api": { + "version": "2.2.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/plugin-clipboard-manager": { + "version": "2.2.1", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, + "node_modules/@tauri-apps/plugin-clipboard-manager/node_modules/@tauri-apps/api": { + "version": "2.2.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/plugin-fs": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.4.1.tgz", + "integrity": "sha512-vJlKZVGF3UAFGoIEVT6Oq5L4HGDCD78WmA4uhzitToqYiBKWAvZR61M6zAyQzHqLs0ADemkE4RSy/5sCmZm6ZQ==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.6.0" + } + }, + "node_modules/@tauri-apps/plugin-global-shortcut": { + "version": "2.2.0", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, + "node_modules/@tauri-apps/plugin-global-shortcut/node_modules/@tauri-apps/api": { + "version": "2.2.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/plugin-opener": { + "version": "2.2.5", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, + "node_modules/@tauri-apps/plugin-opener/node_modules/@tauri-apps/api": { + "version": "2.2.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/plugin-os": { + "version": "2.2.1", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, + "node_modules/@tauri-apps/plugin-os/node_modules/@tauri-apps/api": { + "version": "2.2.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/plugin-process": { + "version": "2.3.0", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.6.0" + } + }, + "node_modules/@tauri-apps/plugin-store": { + "version": "2.2.0", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, + "node_modules/@tauri-apps/plugin-store/node_modules/@tauri-apps/api": { + "version": "2.2.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/plugin-stronghold": { + "version": "2.2.0", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, + "node_modules/@tauri-apps/plugin-stronghold/node_modules/@tauri-apps/api": { + "version": "2.2.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/plugin-updater": { + "version": "2.9.0", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.6.0" + } + }, + "node_modules/@tauri-apps/plugin-updater/node_modules/@tauri-apps/api": { + "version": "2.6.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/plugin-upload": { + "version": "2.2.1", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.0.0" + } + }, + "node_modules/@tauri-apps/plugin-upload/node_modules/@tauri-apps/api": { + "version": "2.2.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.0.10", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.14", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.18", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.5", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.24.4", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001696", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "license": "Apache-2.0", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.90", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esbuild": { + "version": "0.24.2", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.4.2", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lightningcss": { + "version": "1.29.1", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.29.1", + "lightningcss-darwin-x64": "1.29.1", + "lightningcss-freebsd-x64": "1.29.1", + "lightningcss-linux-arm-gnueabihf": "1.29.1", + "lightningcss-linux-arm64-gnu": "1.29.1", + "lightningcss-linux-arm64-musl": "1.29.1", + "lightningcss-linux-x64-gnu": "1.29.1", + "lightningcss-linux-x64-musl": "1.29.1", + "lightningcss-win32-arm64-msvc": "1.29.1", + "lightningcss-win32-x64-msvc": "1.29.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.29.1", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.1", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "18.3.1", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.32.1", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.32.1", + "@rollup/rollup-android-arm64": "4.32.1", + "@rollup/rollup-darwin-arm64": "4.32.1", + "@rollup/rollup-darwin-x64": "4.32.1", + "@rollup/rollup-freebsd-arm64": "4.32.1", + "@rollup/rollup-freebsd-x64": "4.32.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.32.1", + "@rollup/rollup-linux-arm-musleabihf": "4.32.1", + "@rollup/rollup-linux-arm64-gnu": "4.32.1", + "@rollup/rollup-linux-arm64-musl": "4.32.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.32.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.32.1", + "@rollup/rollup-linux-riscv64-gnu": "4.32.1", + "@rollup/rollup-linux-s390x-gnu": "4.32.1", + "@rollup/rollup-linux-x64-gnu": "4.32.1", + "@rollup/rollup-linux-x64-musl": "4.32.1", + "@rollup/rollup-win32-arm64-msvc": "4.32.1", + "@rollup/rollup-win32-ia32-msvc": "4.32.1", + "@rollup/rollup-win32-x64-msvc": "4.32.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tailwindcss": { + "version": "4.0.2", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tauri-plugin-macos-permissions-api": { + "version": "2.0.4", + "license": "MIT", + "dependencies": { + "@tauri-apps/api": ">=2.0.0-beta.6" + } + }, + "node_modules/tauri-plugin-macos-permissions-api/node_modules/@tauri-apps/api": { + "version": "2.2.0", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "devOptional": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.1.2", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "6.0.11", + "license": "MIT", + "dependencies": { + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/zod": { + "version": "3.24.4", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json index 2c43f39..461d1c8 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@tauri-apps/api": "^2.6.0", "@tauri-apps/plugin-autostart": "~2", "@tauri-apps/plugin-clipboard-manager": "~2", + "@tauri-apps/plugin-fs": "~2", "@tauri-apps/plugin-global-shortcut": "~2", "@tauri-apps/plugin-opener": "^2", "@tauri-apps/plugin-os": "~2", diff --git a/public/icon/recording.png b/public/icon/recording.png new file mode 100644 index 0000000..8839e84 Binary files /dev/null and b/public/icon/recording.png differ diff --git a/public/icon/transcribing.png b/public/icon/transcribing.png new file mode 100644 index 0000000..bb6fb25 Binary files /dev/null and b/public/icon/transcribing.png differ diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 2ca528c..d268f1f 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2024,6 +2024,7 @@ dependencies = [ "tauri-build", "tauri-plugin-autostart", "tauri-plugin-clipboard-manager", + "tauri-plugin-fs", "tauri-plugin-global-shortcut", "tauri-plugin-macos-permissions", "tauri-plugin-opener", @@ -5450,6 +5451,28 @@ dependencies = [ "thiserror 2.0.11", ] +[[package]] +name = "tauri-plugin-fs" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6ef84ee2f2094ce093e55106d90d763ba343fad57566992962e8f76d113f99" +dependencies = [ + "anyhow", + "dunce", + "glob", + "percent-encoding", + "schemars", + "serde", + "serde_json", + "serde_repr", + "tauri", + "tauri-plugin", + "tauri-utils", + "thiserror 2.0.11", + "toml", + "url", +] + [[package]] name = "tauri-plugin-global-shortcut" version = "2.2.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index cbc444b..6407516 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -51,6 +51,7 @@ tauri-plugin-process = "2" rodio = { git = "https://github.com/cjpais/rodio.git" } reqwest = { version = "0.11", features = ["json", "stream"] } futures-util = "0.3" +tauri-plugin-fs = "2" [dependencies.ort-sys] version = "=2.0.0-rc.9" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 93c56db..84593ed 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -13,6 +13,8 @@ "global-shortcut:allow-register", "global-shortcut:allow-unregister", "global-shortcut:allow-unregister-all", - "macos-permissions:default" + "macos-permissions:default", + "fs:read-files", + "fs:allow-resource-read-recursive" ] } diff --git a/src-tauri/gen/apple/PrivacyInfo.xcprivacy b/src-tauri/gen/apple/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..7caf423 --- /dev/null +++ b/src-tauri/gen/apple/PrivacyInfo.xcprivacy @@ -0,0 +1,17 @@ + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + + diff --git a/src-tauri/src/actions.rs b/src-tauri/src/actions.rs index f8a657f..53b2a08 100644 --- a/src-tauri/src/actions.rs +++ b/src-tauri/src/actions.rs @@ -5,6 +5,8 @@ use crate::utils; use crate::utils::change_tray_icon; use crate::utils::play_recording_start_sound; use crate::utils::play_recording_stop_sound; +use crate::utils::show_recording_overlay; +use crate::utils::show_transcribing_overlay; use crate::utils::TrayIconState; use log::debug; use once_cell::sync::Lazy; @@ -30,6 +32,7 @@ impl ShortcutAction for TranscribeAction { let binding_id = binding_id.to_string(); change_tray_icon(app, TrayIconState::Recording); + show_recording_overlay(app); let rm = app.state::>(); @@ -78,6 +81,7 @@ impl ShortcutAction for TranscribeAction { let tm = Arc::clone(&app.state::>()); change_tray_icon(app, TrayIconState::Transcribing); + show_transcribing_overlay(app); // Play audio feedback for recording stop play_recording_stop_sound(app); @@ -119,23 +123,29 @@ impl ShortcutAction for TranscribeAction { ), Err(e) => eprintln!("Failed to paste transcription: {}", e), } + // Hide the overlay after transcription is complete + utils::hide_recording_overlay(&ah_clone); change_tray_icon(&ah_clone, TrayIconState::Idle); }) .unwrap_or_else(|e| { eprintln!("Failed to run paste on main thread: {:?}", e); + utils::hide_recording_overlay(&ah); change_tray_icon(&ah, TrayIconState::Idle); }); } else { + utils::hide_recording_overlay(&ah); change_tray_icon(&ah, TrayIconState::Idle); } } Err(err) => { debug!("Global Shortcut Transcription error: {}", err); + utils::hide_recording_overlay(&ah); change_tray_icon(&ah, TrayIconState::Idle); - }, + } } } else { debug!("No samples retrieved from recording stop"); + utils::hide_recording_overlay(&ah); change_tray_icon(&ah, TrayIconState::Idle); } }); diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 11e4d7e..682f112 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -60,6 +60,7 @@ pub fn run() { env_logger::init(); tauri::Builder::default() + .plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_process::init()) .plugin(tauri_plugin_updater::Builder::new().build()) .plugin(tauri_plugin_os::init()) @@ -154,6 +155,9 @@ pub fn run() { app.manage(model_manager.clone()); app.manage(transcription_manager.clone()); + // Create the recording overlay window (hidden by default) + utils::create_recording_overlay(&app.handle()); + shortcut::init_shortcuts(app); Ok(()) diff --git a/src-tauri/src/managers/audio.rs b/src-tauri/src/managers/audio.rs index 9476f72..e5c8994 100644 --- a/src-tauri/src/managers/audio.rs +++ b/src-tauri/src/managers/audio.rs @@ -3,7 +3,7 @@ use crate::settings::get_settings; use log::{debug, info}; use std::sync::{Arc, Mutex}; use std::time::Instant; -use tauri::{App, LogicalSize, Manager, WebviewWindowBuilder}; +use tauri::{App, Manager}; const WHISPER_SAMPLE_RATE: usize = 16000; @@ -195,7 +195,6 @@ impl AudioRecordingManager { binding_id: binding_id.to_string(), }; debug!("Recording started for binding {binding_id}"); - self.show_overlay(); return true; } } @@ -240,9 +239,6 @@ impl AudioRecordingManager { *self.is_recording.lock().unwrap() = false; - // Hide the overlay - self.hide_overlay(); - // In on-demand mode turn the mic off again if matches!(*self.mode.lock().unwrap(), MicrophoneMode::OnDemand) { self.stop_microphone_stream(); @@ -262,58 +258,4 @@ impl AudioRecordingManager { _ => None, } } - - /* ---------- overlay window -------------------------------------------- */ - - fn show_overlay(&self) { - if let Some(overlay_window) = self.app_handle.get_webview_window("recording_overlay") { - let _ = overlay_window.show(); - } else { - // Get screen dimensions for positioning - if let Ok(monitors) = self.app_handle.primary_monitor() { - if let Some(monitor) = monitors { - let size = monitor.size(); - let scale = monitor.scale_factor(); - let screen_width = (size.width as f64 / scale) as i32; - let screen_height = (size.height as f64 / scale) as i32; - - // Position at bottom center, 30px from bottom - let x = (screen_width - 150) / 2; - let y = screen_height - 30 - 30; - - match WebviewWindowBuilder::new( - &self.app_handle, - "recording_overlay", - tauri::WebviewUrl::App("src/overlay/index.html".into()), - ) - .title("Recording") - .position(x as f64, y as f64) - .resizable(false) - .maximizable(false) - .minimizable(false) - .closable(false) - .decorations(false) - .always_on_top(true) - .skip_taskbar(true) - .transparent(true) - .focused(false) - .build() - { - Ok(_window) => { - debug!("Recording overlay window created successfully"); - } - Err(e) => { - debug!("Failed to create recording overlay window: {}", e); - } - } - } - } - } - } - - fn hide_overlay(&self) { - if let Some(overlay_window) = self.app_handle.get_webview_window("recording_overlay") { - let _ = overlay_window.hide(); - } - } } diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs index 54bf605..0d3d421 100644 --- a/src-tauri/src/utils.rs +++ b/src-tauri/src/utils.rs @@ -6,14 +6,14 @@ use enigo::Keyboard; use enigo::Settings; use cpal::traits::{DeviceTrait, HostTrait}; +use log::debug; use rodio::OutputStreamBuilder; use std::fs::File; use std::io::BufReader; use std::thread; use tauri::image::Image; use tauri::tray::TrayIcon; -use tauri::AppHandle; -use tauri::Manager; +use tauri::{AppHandle, Emitter, Manager, WebviewWindowBuilder}; use tauri_plugin_clipboard_manager::ClipboardExt; fn send_paste() -> Result<(), String> { @@ -194,3 +194,83 @@ fn play_audio_file( Ok(()) } + +/* ──────────────────────────────────────────────────────────────── */ +/* OVERLAY MANAGEMENT */ +/* ──────────────────────────────────────────────────────────────── */ + +/// Creates the recording overlay window and keeps it hidden by default +pub fn create_recording_overlay(app_handle: &AppHandle) { + // Get screen dimensions for positioning + if let Ok(monitors) = app_handle.primary_monitor() { + if let Some(monitor) = monitors { + let size = monitor.size(); + let scale = monitor.scale_factor(); + let screen_width = (size.width as f64 / scale) as i32; + let screen_height = (size.height as f64 / scale) as i32; + + // Position at bottom center, 30px from bottom + let x = (screen_width - 150) / 2; + let y = screen_height - 30 - 30; + + match WebviewWindowBuilder::new( + app_handle, + "recording_overlay", + tauri::WebviewUrl::App("src/overlay/index.html".into()), + ) + .title("Recording") + .position(x as f64, y as f64) + .resizable(false) + .maximizable(false) + .minimizable(false) + .closable(false) + .decorations(false) + .always_on_top(true) + .skip_taskbar(true) + .transparent(true) + .focused(false) + .visible(false) // Start hidden + .build() + { + Ok(_window) => { + debug!("Recording overlay window created successfully (hidden)"); + } + Err(e) => { + debug!("Failed to create recording overlay window: {}", e); + } + } + } + } +} + +/// Shows the recording overlay window with fade-in animation +pub fn show_recording_overlay(app_handle: &AppHandle) { + if let Some(overlay_window) = app_handle.get_webview_window("recording_overlay") { + let _ = overlay_window.show(); + // Emit event to trigger fade-in animation with recording state + let _ = overlay_window.emit("show-overlay", "recording"); + } +} + +/// Shows the transcribing overlay window +pub fn show_transcribing_overlay(app_handle: &AppHandle) { + if let Some(overlay_window) = app_handle.get_webview_window("recording_overlay") { + let _ = overlay_window.show(); + // Emit event to switch to transcribing state + let _ = overlay_window.emit("show-overlay", "transcribing"); + } +} + +/// Hides the recording overlay window with fade-out animation +pub fn hide_recording_overlay(app_handle: &AppHandle) { + if let Some(overlay_window) = app_handle.get_webview_window("recording_overlay") { + // Emit event to trigger fade-out animation + let _ = overlay_window.emit("hide-overlay", ()); + // Hide the window after a short delay to allow animation to complete + let window_clone = overlay_window.clone(); + std::thread::spawn(move || { + std::thread::sleep(std::time::Duration::from_millis(300)); + let _ = window_clone.hide(); + }); + } +} diff --git a/src/assets/fonts/ShortStack-Regular.ttf b/src/assets/fonts/ShortStack-Regular.ttf deleted file mode 100644 index 671a4d3..0000000 Binary files a/src/assets/fonts/ShortStack-Regular.ttf and /dev/null differ diff --git a/src/assets/react.svg b/src/assets/react.svg deleted file mode 100644 index 6c87de9..0000000 --- a/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/overlay/RecordingOverlay.css b/src/overlay/RecordingOverlay.css index cf4382a..5265fc8 100644 --- a/src/overlay/RecordingOverlay.css +++ b/src/overlay/RecordingOverlay.css @@ -1,13 +1,15 @@ .recording-overlay { - width: 128px; - height: 32px; + height: 40px; + width: min-content; display: flex; + gap: 12px; align-items: center; - justify-content: center; - background: rgba(0, 0, 0, 0.7); - border-radius: 8px; - backdrop-filter: blur(10px); - -webkit-backdrop-filter: blur(10px); + padding-left: 4px; + padding-right: 24px; + background: rgba(0, 0, 0, 0.6); + border-radius: 24px; + opacity: 0; + transition: opacity 300ms ease-out; } .bars-container { @@ -37,3 +39,26 @@ opacity: 1; } } + +.recording-overlay.fade-in { + opacity: 1; +} + +.transcribing-text { + color: #faa2ca; + font-size: 14px; + font-weight: 600; + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + animation: transcribing-pulse 1.5s infinite ease-in-out; +} + +@keyframes transcribing-pulse { + 0%, + 100% { + opacity: 0.6; + } + 50% { + opacity: 1; + } +} diff --git a/src/overlay/RecordingOverlay.tsx b/src/overlay/RecordingOverlay.tsx index b4b3663..479977a 100644 --- a/src/overlay/RecordingOverlay.tsx +++ b/src/overlay/RecordingOverlay.tsx @@ -1,28 +1,67 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import "./RecordingOverlay.css"; -import { resolveResource } from "@tauri-apps/api/path"; +import { listen } from "@tauri-apps/api/event"; + +type OverlayState = "recording" | "transcribing"; const RecordingOverlay: React.FC = () => { + const [isVisible, setIsVisible] = useState(false); + const [state, setState] = useState("recording"); + useEffect(() => { - resolveResource("tray_idle.png").then((r) => { - console.log("res", r); - }); + const setupEventListeners = async () => { + // Listen for show-overlay event from Rust + const unlistenShow = await listen("show-overlay", (event) => { + const overlayState = event.payload as OverlayState; + setState(overlayState); + setIsVisible(true); + }); + + // Listen for hide-overlay event from Rust + const unlistenHide = await listen("hide-overlay", () => { + setIsVisible(false); + }); + + // Cleanup function + return () => { + unlistenShow(); + unlistenHide(); + }; + }; + + setupEventListeners(); }, []); + const getIconPath = () => { + return state === "recording" + ? "/icon/recording.png" + : "/icon/transcribing.png"; + }; + + const getIconAlt = () => { + return state === "recording" ? "Recording Icon" : "Transcribing Icon"; + }; + return ( -
-
- {Array.from({ length: 8 }, (_, i) => ( -
- ))} -
+
+ {getIconAlt()} + {state === "recording" && ( +
+ {Array.from({ length: 8 }, (_, i) => ( +
+ ))} +
+ )} + {state === "transcribing" && ( +
Transcribing...
+ )}
); };