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

143 lines
4.0 KiB
Svelte

<script lang="ts">
import { cn } from "@/utils"
import { goBackOrCloseOnEscape } from "@/utils/key"
import { setTransparentTitlebar } from "@kksh/api/commands"
import { Button } from "@kksh/svelte5"
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"
import { ArrowBigUpIcon, ChevronUpIcon, CommandIcon, OptionIcon } from "lucide-svelte"
import * as userInput from "tauri-plugin-user-input-api"
import { type InputEvent } from "tauri-plugin-user-input-api"
let { data } = $props()
const SymbolMap = {
Alt: "⎇",
AltGr: "⌥",
Backspace: "⌫",
CapsLock: "⇪",
ControlLeft: "⌃",
ControlRight: "⌃",
Delete: "⌦",
DownArrow: "↓",
End: "↘",
Escape: "⎋",
Home: "↖",
LeftArrow: "←",
MetaLeft: "⌘",
MetaRight: "⌘",
PageDown: "⇟",
PageUp: "⇞",
Return: "↩",
RightArrow: "→",
ShiftLeft: "⇧",
ShiftRight: "⇧",
Space: "␣",
Tab: "⇥",
UpArrow: "↑",
PrintScreen: "PrtSc",
ScrollLock: "ScrLk",
Pause: "⎉",
BackQuote: "`",
Minus: "-",
Equal: "=",
LeftBracket: "[",
RightBracket: "]",
SemiColon: ";",
Quote: "'",
BackSlash: "\\",
IntlBackslash: "\\",
Comma: ",",
Dot: ".",
Slash: "/",
Insert: ""
}
const MAX_QUEUE_SIZE = 20
let keys = $state<string[]>([])
let modifiers = $state({
shift: false,
ctrl: false,
alt: false,
meta: false
})
function handleKeyPress(evt: InputEvent) {
if (!evt.key) return
if (SymbolMap[evt.key as keyof typeof SymbolMap]) {
keys = [...keys, SymbolMap[evt.key as keyof typeof SymbolMap]]
}
if (evt.key.startsWith("Shift")) {
modifiers = { ...modifiers, shift: true }
} else if (evt.key.startsWith("Control")) {
modifiers = { ...modifiers, ctrl: true }
} else if (evt.key.startsWith("Alt")) {
modifiers = { ...modifiers, alt: true }
} else if (evt.key.startsWith("Meta")) {
modifiers = { ...modifiers, meta: true }
} else if (evt.key.startsWith("Key") || evt.key.startsWith("Num")) {
keys = [...keys, evt.key.slice(3)]
} else if (evt.key === "Space") {
keys = [...keys, "\u1680"]
} else if (evt.key.startsWith("F")) {
keys = [...keys, evt.key]
}
keys = keys.slice(-MAX_QUEUE_SIZE)
}
$inspect(keys)
function handleKeyRelease(evt: InputEvent) {
if (!evt.key) return
if (evt.key.startsWith("Shift")) {
modifiers = { ...modifiers, shift: false }
} else if (evt.key.startsWith("Control")) {
modifiers = { ...modifiers, ctrl: false }
} else if (evt.key.startsWith("Alt")) {
modifiers = { ...modifiers, alt: false }
} else if (evt.key.startsWith("Meta")) {
modifiers = { ...modifiers, meta: false }
}
}
$effect(() => {
data.win?.show().then(() => data.win?.setFocus())
userInput.setEventTypes([userInput.EventTypeEnum.KeyPress, userInput.EventTypeEnum.KeyRelease])
userInput.startListening((evt: InputEvent) => {
switch (evt.eventType) {
case userInput.EventTypeEnum.KeyPress:
handleKeyPress(evt)
break
case userInput.EventTypeEnum.KeyRelease:
handleKeyRelease(evt)
break
default:
break
}
})
return () => {
userInput.stopListening()
}
})
</script>
<svelte:window on:keydown={goBackOrCloseOnEscape} />
<div class="absolute h-screen w-screen" data-tauri-drag-region></div>
<main class="flex h-screen w-screen flex-col overflow-hidden p-1">
<div class="flex grow items-center px-2">
<div class="flex w-full justify-end overflow-x-hidden text-3xl font-bold tracking-[0.5rem]">
{#each keys as key, idx}
<span class={cn({ "text-white/[0.7]": idx !== keys.length - 1 })}>{key}</span>
{/each}
</div>
</div>
<!-- <pre>{keys}</pre> -->
<div class="flex justify-center space-x-2">
<Button variant={modifiers.shift ? "default" : "outline"} size="icon"><ArrowBigUpIcon /></Button
>
<Button variant={modifiers.ctrl ? "default" : "outline"} size="icon"><ChevronUpIcon /></Button>
<Button variant={modifiers.meta ? "default" : "outline"} size="icon"><CommandIcon /></Button>
<Button variant={modifiers.alt ? "default" : "outline"} size="icon"><OptionIcon /></Button>
</div>
</main>