Fix: ext window loading (#82)

* fix: extension new window loading with localStorage

* fix: extension loading in new window

* upgrade: @kksh/svelte5

* refactor: update SideBar import to Sidebar across desktop app

* fix: safely remove test directories with existsSync check

* feat: add open preference command with platform-specific shortcut

* chore: clean up vite config trailing comma

* fix: iframe custom ext loading

* fix: fix template extension loading

* feat: add progress bar to extension form and list views

* feat: add optional description to form view template
This commit is contained in:
Huakun Shen 2025-01-28 09:44:46 -05:00 committed by GitHub
parent c93ebd895e
commit 0bb59e4f66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 31 additions and 4 deletions

View File

@ -35,14 +35,21 @@ export async function createExtSupportDir(extPath: string) {
} }
} }
function setTemplateExtParams(extPath: string, cmdName: string) {
localStorage.setItem(
"kunkun-template-ext-params",
JSON.stringify({ extPath, cmdName } satisfies KunkunTemplateExtParams)
)
}
export async function onTemplateUiCmdSelect( export async function onTemplateUiCmdSelect(
ext: ExtPackageJsonExtra, ext: ExtPackageJsonExtra,
cmd: TemplateUiCmd, cmd: TemplateUiCmd,
{ isDev, hmr }: { isDev: boolean; hmr: boolean } { isDev, hmr }: { isDev: boolean; hmr: boolean }
) { ) {
await createExtSupportDir(ext.extPath) await createExtSupportDir(ext.extPath)
// console.log("onTemplateUiCmdSelect", ext, cmd, isDev, hmr)
const url = `/app/extension/ui-worker?extPath=${encodeURIComponent(ext.extPath)}&cmdName=${encodeURIComponent(cmd.name)}` const url = `/app/extension/ui-worker?extPath=${encodeURIComponent(ext.extPath)}&cmdName=${encodeURIComponent(cmd.name)}`
setTemplateExtParams(ext.extPath, cmd.name)
if (cmd.window) { if (cmd.window) {
const winLabel = await winExtMap.registerExtensionWithWindow({ extPath: ext.extPath }) const winLabel = await winExtMap.registerExtensionWithWindow({ extPath: ext.extPath })
localStorage.setItem( localStorage.setItem(
@ -101,6 +108,13 @@ export async function onHeadlessCmdSelect(
await workerAPI.load() await workerAPI.load()
} }
function setIframeExtParams(extPath: string, url: string) {
localStorage.setItem(
"kunkun-iframe-ext-params",
JSON.stringify({ url, extPath } satisfies KunkunIframeExtParams)
)
}
export async function onCustomUiCmdSelect( export async function onCustomUiCmdSelect(
ext: ExtPackageJsonExtra, ext: ExtPackageJsonExtra,
cmd: CustomUiCmd, cmd: CustomUiCmd,
@ -119,6 +133,8 @@ export async function onCustomUiCmdSelect(
} }
let url2 = `/app/extension/ui-iframe?url=${encodeURIComponent(url)}&extPath=${encodeURIComponent(ext.extPath)}` let url2 = `/app/extension/ui-iframe?url=${encodeURIComponent(url)}&extPath=${encodeURIComponent(ext.extPath)}`
// url2 = `/dev?url=${encodeURIComponent(url)}&extPath=${encodeURIComponent(ext.extPath)}` // url2 = `/dev?url=${encodeURIComponent(url)}&extPath=${encodeURIComponent(ext.extPath)}`
setIframeExtParams(ext.extPath, url)
if (cmd.window) { if (cmd.window) {
const winLabel = await winExtMap.registerExtensionWithWindow({ const winLabel = await winExtMap.registerExtensionWithWindow({
extPath: ext.extPath, extPath: ext.extPath,
@ -128,6 +144,7 @@ export async function onCustomUiCmdSelect(
const addr = await spawnExtensionFileServer(winLabel) const addr = await spawnExtensionFileServer(winLabel)
const newUrl = `http://${addr}` const newUrl = `http://${addr}`
url2 = `/app/extension/ui-iframe?url=${encodeURIComponent(newUrl)}&extPath=${encodeURIComponent(ext.extPath)}` url2 = `/app/extension/ui-iframe?url=${encodeURIComponent(newUrl)}&extPath=${encodeURIComponent(ext.extPath)}`
setIframeExtParams(ext.extPath, newUrl)
} }
localStorage.setItem( localStorage.setItem(
"kunkun-iframe-ext-params", "kunkun-iframe-ext-params",
@ -149,6 +166,7 @@ export async function onCustomUiCmdSelect(
console.log("Extension file server address: ", addr) console.log("Extension file server address: ", addr)
const newUrl = `http://${addr}` const newUrl = `http://${addr}`
url2 = `/app/extension/ui-iframe?url=${encodeURIComponent(newUrl)}&extPath=${encodeURIComponent(ext.extPath)}` url2 = `/app/extension/ui-iframe?url=${encodeURIComponent(newUrl)}&extPath=${encodeURIComponent(ext.extPath)}`
setIframeExtParams(ext.extPath, newUrl)
} }
goto(i18n.resolveRoute(url2)) goto(i18n.resolveRoute(url2))
} }

View File

@ -361,6 +361,7 @@
{:else if loaded && formViewContent !== undefined} {:else if loaded && formViewContent !== undefined}
<Templates.FormView <Templates.FormView
{formViewContent} {formViewContent}
{pbar}
onGoBack={goBack} onGoBack={goBack}
onSubmit={(formData: Record<string, string | number | boolean>) => { onSubmit={(formData: Record<string, string | number | boolean>) => {
console.log("formData", formData) console.log("formData", formData)

View File

@ -20,7 +20,7 @@ export const load: PageLoad = async ({ url }) => {
toast.error("Invalid extension path or url") toast.error("Invalid extension path or url")
return svError(404, "Invalid extension path or url") return svError(404, "Invalid extension path or url")
} }
localStorage.removeItem("kunkun-template-ext-params")
const parsed = v.safeParse(KunkunTemplateExtParams, JSON.parse(rawKunkunTemplateExtParams)) const parsed = v.safeParse(KunkunTemplateExtParams, JSON.parse(rawKunkunTemplateExtParams))
if (!parsed.success) { if (!parsed.success) {
toast.error("Fail to parse extension params from local storage", { toast.error("Fail to parse extension params from local storage", {

View File

@ -1,25 +1,33 @@
<script lang="ts"> <script lang="ts">
import { FormNodeNameEnum, FormSchema } from "@kksh/api/models" import { FormNodeNameEnum, FormSchema } from "@kksh/api/models"
import { Button } from "@kksh/svelte5" import { Button, Progress } from "@kksh/svelte5"
import { ArrowLeftIcon } from "lucide-svelte" import { ArrowLeftIcon } from "lucide-svelte"
import Form from "./form.svelte" import Form from "./form.svelte"
let { let {
formViewContent, formViewContent,
pbar,
onGoBack, onGoBack,
onSubmit onSubmit
}: { }: {
formViewContent: FormSchema.Form formViewContent: FormSchema.Form
pbar: number | null
onGoBack: () => void onGoBack: () => void
onSubmit?: (formData: Record<string, string | number | boolean>) => void onSubmit?: (formData: Record<string, string | number | boolean>) => void
} = $props() } = $props()
</script> </script>
{#if pbar && pbar > 0}
<Progress value={Math.min(pbar, 100)} class="absolute top-0 h-0.5 rounded-none" />
{/if}
<div data-tauri-drag-region class="h-12 w-full"></div> <div data-tauri-drag-region class="h-12 w-full"></div>
<Button class="fixed left-2 top-2" size="icon" variant="outline" onclick={onGoBack}> <Button class="fixed left-2 top-2" size="icon" variant="outline" onclick={onGoBack}>
<ArrowLeftIcon /> <ArrowLeftIcon />
</Button> </Button>
<main class="container flex flex-col gap-2 pb-4"> <main class="container flex flex-col gap-2 pb-4">
<h1 class="text-2xl font-bold">{formViewContent.title}</h1> <h1 class="text-2xl font-bold">{formViewContent.title}</h1>
{#if formViewContent.description}
<p>{formViewContent.description}</p>
{/if}
<Form {formViewContent} {onSubmit} /> <Form {formViewContent} {onSubmit} />
</main> </main>

View File

@ -131,7 +131,7 @@
{/snippet} {/snippet}
</CustomCommandInput> </CustomCommandInput>
{#if pbar} {#if pbar}
<Progress value={50} class="h-0.4 rounded-none" /> <Progress value={pbar} class="h-0.5 rounded-none" />
{/if} {/if}
<Resizable.PaneGroup direction="horizontal"> <Resizable.PaneGroup direction="horizontal">