From 2c99f231f7719d3a47eb736c6f90faf8c0b09c0c Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Tue, 5 Nov 2024 06:04:34 -0500 Subject: [PATCH] [feat] troubleshooters (#15) * feat: add extension loading troubleshooter * feat: add extension permission inspector * feat: add extension window map troubleshooter (WIP) * fix: unregister extension when window is closed --- apps/desktop/package.json | 3 +- apps/desktop/src/lib/cmds/builtin.ts | 71 +++++----- apps/desktop/src/lib/cmds/ext.ts | 5 + .../lib/components/main/CommandPalette.svelte | 4 +- apps/desktop/src/lib/stores/winExtMap.ts | 15 +- apps/desktop/src/lib/utils/tauri-events.ts | 57 ++++++++ .../permission-inspector/+page.svelte | 100 ++++++++++++++ .../settings/set-dev-ext-path/+page.svelte | 2 +- .../extension-loading/+page.svelte | 129 ++++++++++++++++++ .../extension-window/+page.svelte | 111 +++++++++++++++ packages/api/src/commands/extension.ts | 1 - .../extension/PermissionInspector.svelte | 1 - .../extension/StoreExtDetail.svelte | 2 +- pnpm-lock.yaml | 3 + 14 files changed, 456 insertions(+), 48 deletions(-) create mode 100644 apps/desktop/src/lib/utils/tauri-events.ts create mode 100644 apps/desktop/src/routes/extension/permission-inspector/+page.svelte create mode 100644 apps/desktop/src/routes/troubleshooters/extension-loading/+page.svelte create mode 100644 apps/desktop/src/routes/troubleshooters/extension-window/+page.svelte diff --git a/apps/desktop/package.json b/apps/desktop/package.json index ff6075a..dd4b409 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -30,7 +30,8 @@ "semver": "^7.6.3", "svelte-radix": "^2.0.1", "svelte-sonner": "^0.3.28", - "sveltekit-superforms": "^2.20.0" + "sveltekit-superforms": "^2.20.0", + "uuid": "^11.0.2" }, "devDependencies": { "@kksh/types": "workspace:*", diff --git a/apps/desktop/src/lib/cmds/builtin.ts b/apps/desktop/src/lib/cmds/builtin.ts index 9c9033c..8d81220 100644 --- a/apps/desktop/src/lib/cmds/builtin.ts +++ b/apps/desktop/src/lib/cmds/builtin.ts @@ -2,10 +2,12 @@ import { appConfig, appState } from "@/stores" import { checkUpdateAndInstall } from "@/utils/updater" import type { BuiltinCmd } from "@kksh/ui/types" import { getVersion } from "@tauri-apps/api/app" +import { WebviewWindow } from "@tauri-apps/api/webviewWindow" import { exit } from "@tauri-apps/plugin-process" import { dev } from "$app/environment" import { goto } from "$app/navigation" import { toast } from "svelte-sonner" +import { v4 as uuidv4 } from "uuid" export const builtinCmds: BuiltinCmd[] = [ { @@ -79,42 +81,39 @@ export const builtinCmds: BuiltinCmd[] = [ goto("/settings/set-dev-ext-path") } }, - // { - // name: "Extension Window Troubleshooter", - // iconifyIcon: "material-symbols:window-outline", - // description: "", - // function: async () => { - // const appStateStore = useAppStateStore() - // appStateStore.setSearchTermSync("") - // // goto("/window-troubleshooter") - // const winLabel = `main:window-troubleshooter-${uuidv4()}` - // console.log(winLabel) - // new WebviewWindow(winLabel, { - // url: "/window-troubleshooter", - // title: "Window Troubleshooter" - // }) - // } - // }, - // { - // name: "Extension Permission Inspector", - // iconifyIcon: "hugeicons:inspect-code", - // description: "", - // function: async () => { - // const appStateStore = useAppStateStore() - // appStateStore.setSearchTermSync("") - // goto("/ext-permission-inspector") - // } - // }, - // { - // name: "Extension Loading Troubleshooter", - // iconifyIcon: "material-symbols:troubleshoot", - // description: "", - // function: async () => { - // const appStateStore = useAppStateStore() - // appStateStore.setSearchTermSync("") - // goto("/extension-load-troubleshooter") - // } - // }, + { + name: "Extension Window Troubleshooter", + iconifyIcon: "material-symbols:window-outline", + description: "", + function: async () => { + appState.clearSearchTerm() + // goto("/window-troubleshooter") + const winLabel = `main:extension-window-troubleshooter-${uuidv4()}` + console.log(winLabel) + new WebviewWindow(winLabel, { + url: "/troubleshooters/extension-window", + title: "Extension Window Troubleshooter" + }) + } + }, + { + name: "Extension Permission Inspector", + iconifyIcon: "hugeicons:inspect-code", + description: "", + function: async () => { + appState.clearSearchTerm() + goto("/extension/permission-inspector") + } + }, + { + name: "Extension Loading Troubleshooter", + iconifyIcon: "material-symbols:troubleshoot", + description: "", + function: async () => { + appState.clearSearchTerm() + goto("/troubleshooters/extension-loading") + } + }, // { // name: "Create Quicklink", // iconifyIcon: "material-symbols:link", diff --git a/apps/desktop/src/lib/cmds/ext.ts b/apps/desktop/src/lib/cmds/ext.ts index 68fb4b6..f8ad67f 100644 --- a/apps/desktop/src/lib/cmds/ext.ts +++ b/apps/desktop/src/lib/cmds/ext.ts @@ -1,3 +1,4 @@ +import { appState } from "@/stores" import { winExtMap } from "@/stores/winExtMap" import { trimSlash } from "@/utils/url" import { constructExtensionSupportDir } from "@kksh/api" @@ -48,6 +49,9 @@ export async function onCustomUiCmdSelect( }) console.log("Launch new window, ", winLabel) const window = launchNewExtWindow(winLabel, url2, cmd.window) + window.onCloseRequested(async (event) => { + await winExtMap.unregisterExtensionFromWindow(winLabel) + }) } else { console.log("Launch main window") return winExtMap @@ -58,4 +62,5 @@ export async function onCustomUiCmdSelect( }) .then(() => goto(url2)) } + appState.clearSearchTerm() } diff --git a/apps/desktop/src/lib/components/main/CommandPalette.svelte b/apps/desktop/src/lib/components/main/CommandPalette.svelte index b7f97ae..2ae6ff1 100644 --- a/apps/desktop/src/lib/components/main/CommandPalette.svelte +++ b/apps/desktop/src/lib/components/main/CommandPalette.svelte @@ -63,8 +63,6 @@ passing everything through props will be very complicated and hard to maintain. /> No results found. - - {#if $appConfig.extensionsInstallDir && $devStoreExts.length > 0} {/if} + + diff --git a/apps/desktop/src/lib/stores/winExtMap.ts b/apps/desktop/src/lib/stores/winExtMap.ts index 7b5cd5f..62f67c7 100644 --- a/apps/desktop/src/lib/stores/winExtMap.ts +++ b/apps/desktop/src/lib/stores/winExtMap.ts @@ -58,11 +58,11 @@ function createWinExtMapStore(): Writable & API { await killProcesses(winExtMap[windowLabel].pids) delete winExtMap[windowLabel] } else { - winExtMap[windowLabel] = { - windowLabel, - extPath, - pids: [] - } + // winExtMap[windowLabel] = { + // windowLabel, + // extPath, + // pids: [] + // } } } const returnedWinLabel = await registerExtensionWindow({ @@ -70,6 +70,11 @@ function createWinExtMapStore(): Writable & API { windowLabel, dist }) + winExtMap[returnedWinLabel] = { + windowLabel: returnedWinLabel, + extPath, + pids: [] + } store.set(winExtMap) return returnedWinLabel }, diff --git a/apps/desktop/src/lib/utils/tauri-events.ts b/apps/desktop/src/lib/utils/tauri-events.ts new file mode 100644 index 0000000..1102342 --- /dev/null +++ b/apps/desktop/src/lib/utils/tauri-events.ts @@ -0,0 +1,57 @@ +import { DEEP_LINK_PATH_REFRESH_DEV_EXTENSION } from "@kksh/api" +import { + emit, + emitTo, + listen, + TauriEvent, + type Event, + type EventCallback, + type UnlistenFn +} from "@tauri-apps/api/event" + +export const FileDragDrop = "tauri://drag-drop" +export const FileDragEnter = "tauri://drag-enter" +export const FileDragLeave = "tauri://drag-leave" +export const FileDragOver = "tauri://drag-over" +export const NewClipboardItemAddedEvent = "new_clipboard_item_added" +export const RefreshConfigEvent = "kunkun://refresh-config" +export const RefreshExtEvent = "kunkun://refresh-extensions" +export function listenToFileDrop(cb: EventCallback<{ paths: string[] }>) { + return listen<{ paths: string[] }>(FileDragDrop, cb) +} + +export function listenToWindowBlur(cb: EventCallback) { + return listen(TauriEvent.WINDOW_BLUR, cb) +} + +export function listenToWindowFocus(cb: EventCallback) { + return listen(TauriEvent.WINDOW_FOCUS, cb) +} + +export function listenToNewClipboardItem(cb: EventCallback) { + return listen(NewClipboardItemAddedEvent, cb) +} + +export function emitRefreshConfig() { + return emit(RefreshConfigEvent) +} + +export function listenToRefreshConfig(cb: EventCallback) { + return listen(RefreshConfigEvent, cb) +} + +export function emitRefreshExt() { + return emitTo("main", RefreshExtEvent) +} + +export function listenToRefreshExt(cb: EventCallback) { + return listen(RefreshExtEvent, cb) +} + +export function emitRefreshDevExt() { + return emit(DEEP_LINK_PATH_REFRESH_DEV_EXTENSION) +} + +export function listenToRefreshDevExt(cb: EventCallback) { + return listen(DEEP_LINK_PATH_REFRESH_DEV_EXTENSION, cb) +} diff --git a/apps/desktop/src/routes/extension/permission-inspector/+page.svelte b/apps/desktop/src/routes/extension/permission-inspector/+page.svelte new file mode 100644 index 0000000..2294407 --- /dev/null +++ b/apps/desktop/src/routes/extension/permission-inspector/+page.svelte @@ -0,0 +1,100 @@ + + + + +
+ +

Extension Permission Inspector

+ +
+ {#each pkgJsons as pkgJson} + + + {pkgJson.kunkun.name} + {pkgJson.kunkun.shortDescription} + + + + + +

+ Identifier: {pkgJson.kunkun.identifier} +

+

+ Extension Path: {pkgJson.extPath} +

+
+
+ {/each} +
+
+ + diff --git a/apps/desktop/src/routes/settings/set-dev-ext-path/+page.svelte b/apps/desktop/src/routes/settings/set-dev-ext-path/+page.svelte index 867100e..290feb1 100644 --- a/apps/desktop/src/routes/settings/set-dev-ext-path/+page.svelte +++ b/apps/desktop/src/routes/settings/set-dev-ext-path/+page.svelte @@ -6,7 +6,7 @@ import { ArrowLeftIcon } from "lucide-svelte" - + diff --git a/apps/desktop/src/routes/troubleshooters/extension-loading/+page.svelte b/apps/desktop/src/routes/troubleshooters/extension-loading/+page.svelte new file mode 100644 index 0000000..df4901d --- /dev/null +++ b/apps/desktop/src/routes/troubleshooters/extension-loading/+page.svelte @@ -0,0 +1,129 @@ + + + + +
+
+

Extension Loading Troubleshooter

+ + + + + Error Details + + {errorMsg} + + + + A list of your extensions. + + + Identifier + Path + Error + + + + {#each sortedResults as row} + +
{row.identifier}
+ + + + + + +
+ {/each} +
+
+
+ + diff --git a/apps/desktop/src/routes/troubleshooters/extension-window/+page.svelte b/apps/desktop/src/routes/troubleshooters/extension-window/+page.svelte new file mode 100644 index 0000000..08c0044 --- /dev/null +++ b/apps/desktop/src/routes/troubleshooters/extension-window/+page.svelte @@ -0,0 +1,111 @@ + + + + +
+
+
+ + +
+ + + Refreshed {refreshCount} times + +
+ + {#each Object.entries(winLabelMap) as [label, content]} +
  • + + Label: +
    {label}
    +
    +
      + {#each Object.entries(content) as [key, value]} +
    • + + {key}: +
      {value}
      +
      +
    • + {/each} +
    + +
  • + {/each} +
    +
    diff --git a/packages/api/src/commands/extension.ts b/packages/api/src/commands/extension.ts index d7b02d0..66481bb 100644 --- a/packages/api/src/commands/extension.ts +++ b/packages/api/src/commands/extension.ts @@ -26,7 +26,6 @@ export function registerExtensionWindow(options: { } export function unregisterExtensionWindow(label: string): Promise { - console.log("unregisterExtensionWindow", label) return invoke(generateJarvisPluginCommand("unregister_extension_window"), { label }) diff --git a/packages/ui/src/components/extension/PermissionInspector.svelte b/packages/ui/src/components/extension/PermissionInspector.svelte index d813696..3917046 100644 --- a/packages/ui/src/components/extension/PermissionInspector.svelte +++ b/packages/ui/src/components/extension/PermissionInspector.svelte @@ -20,7 +20,6 @@
    - + {manifest?.name} {#if isInstalled} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index db384ea..d948c68 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -165,6 +165,9 @@ importers: sveltekit-superforms: specifier: ^2.20.0 version: 2.20.0(@sveltejs/kit@2.7.4(@sveltejs/vite-plugin-svelte@4.0.0(svelte@5.1.9)(vite@5.4.10(@types/node@22.8.7)(terser@5.36.0)))(svelte@5.1.9)(vite@5.4.10(@types/node@22.8.7)(terser@5.36.0)))(@types/json-schema@7.0.15)(svelte@5.1.9)(typescript@5.6.3) + uuid: + specifier: ^11.0.2 + version: 11.0.2 devDependencies: '@kksh/types': specifier: workspace:*