Huakun 9cf06b1835
Feature: custom transition animation (#266)
* Add loading animation to general settings

* Update dependencies and integrate @tauri-store/svelte

- Added `bon` and `bon-macros` packages to Cargo.lock.
- Upgraded `tauri-plugin-svelte`, `tauri-store`, and related packages to their latest versions.
- Updated `@tauri-store/svelte` integration in the desktop app, including changes to app configuration and layout handling.
- Adjusted pnpm-lock.yaml to reflect updated package versions and added new dependencies.
- Introduced a new app configuration file for development.

* Enhance loading animation handling in FullScreenLoading component

- Integrated conditional rendering for loading animations based on app configuration.
- Updated default loading animation to "kunkun-dancing" in app configuration.
- Adjusted general settings to ensure proper type handling for language labels.
- Modified ui-iframe component to manage full-screen loading state more effectively.

* remove a mis-placed config file

* Refactor window handling to ensure focus after showing

- Updated various components to use promise chaining with `show()` and `setFocus()` for better window management.
- Introduced `data.win` in multiple places to streamline access to the current webview window.
- Enhanced splashscreen and app layout handling to improve user experience by ensuring the window is focused after being shown.

* Refactor window handling to improve safety and consistency

- Introduced optional chaining for `data.win` to prevent potential runtime errors when accessing window methods.
- Updated various components to ensure proper handling of window focus and visibility.
- Enhanced the layout and extension pages to utilize the current webview window more effectively, improving overall user experience.
2025-03-28 07:45:25 -04:00

113 lines
3.4 KiB
TypeScript

import { app } from "@tauri-apps/api"
import { getAllWindows, getCurrentWindow, type Window } from "@tauri-apps/api/window"
import { isRegistered, register, unregister } from "@tauri-apps/plugin-global-shortcut"
import { debug, info, warn } from "@tauri-apps/plugin-log"
import * as os from "@tauri-apps/plugin-os"
import * as userInput from "tauri-plugin-user-input-api"
import { sendNotificationWithPermission } from "./notification"
import { sleep } from "./time"
/**
* Tauri global shortcut doesn't accept 'Meta' Key. This function maps browser detected keys to Tauri-accepted keys.
* @param key
*/
export function mapKeyToTauriKey(key: string): string {
if (key === "Meta") {
return "Command"
}
return key
}
/**
* Registers a global hotkey for the application. If the hotkey is already registered, it will be unregistered first.
* When the hotkey is pressed, it toggles the visibility and focus of the main window.
* @param hotkeyStr - The hotkey string to register.
*/
export async function registerAppHotkey(hotkeyStr: string) {
if (await isRegistered(hotkeyStr)) {
warn(`Hotkey (${hotkeyStr}) already registered`)
await unregister(hotkeyStr)
}
info(`Registering hotkey: ${hotkeyStr}`)
return register(hotkeyStr, async (e) => {
if (e.state === "Released") {
const wins = await getAllWindows()
const mainWin = wins.find((w) => w.label === "main")
if (!mainWin) {
return sendNotificationWithPermission(
"No main window found",
"Please open main window first"
)
}
const isVisible = await mainWin.isVisible()
const isFocused = await mainWin.isFocused()
if (isVisible) {
if (isFocused) {
mainWin.hide()
} else {
mainWin.setFocus()
}
} else {
mainWin.show().then(() => mainWin.setFocus())
}
}
})
}
/**
* Updates the application's global hotkey. If an old hotkey is provided, it will be unregistered first.
* @param newHotkey - The new hotkey combination to register.
* @param oldHotkey - The old hotkey combination to unregister, if any.
*/
export async function updateAppHotkey(newHotkey: string[], oldHotkey?: string[] | null) {
if (oldHotkey) {
const hotkeyStr = oldHotkey.map(mapKeyToTauriKey).join("+")
if (await isRegistered(hotkeyStr)) {
await unregister(hotkeyStr)
}
}
const hotkeyStr = newHotkey.map(mapKeyToTauriKey).join("+")
return registerAppHotkey(hotkeyStr)
}
/**
* Simulates a key combination press and release.
* @param keys - The array of keys to press and release.
*/
export async function applyKeyComb(keys: userInput.Key[]) {
// await Promise.all(keys.map((key) => userInput.key("KeyPress", key)))
for (const key of keys) {
await userInput.key("KeyPress", key)
await sleep(100)
}
await sleep(150)
for (const key of keys) {
await userInput.key("KeyRelease", key)
await sleep(100)
}
}
/**
* Simulates a paste operation based on the operating system.
* On macOS, it uses Command+V. On Windows and Linux, it uses Shift+Insert.
*/
export async function paste() {
const _platform = os.platform()
if (_platform === "macos") {
return applyKeyComb(["MetaLeft", "KeyV"])
} else if (_platform === "windows" || _platform === "linux") {
return applyKeyComb(["ShiftLeft", "Insert"])
} else {
console.error("Unsupported platform: " + _platform)
}
}
export async function hideAndPaste(win?: Window) {
return app
.hide()
.then(() => sleep(60))
.then(() => (win ?? getCurrentWindow()).hide())
.then(() => sleep(60))
.then(() => paste())
}