Skip to content

Commit

Permalink
feat: add extensionsInstallDir var to +layout.ts, exposed to all pages
Browse files Browse the repository at this point in the history
All pages won't need to get the path asynchronously, it's kind of like a global constant
  • Loading branch information
HuakunShen committed Nov 4, 2024
1 parent 54b7cc5 commit f64e562
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 19 deletions.
18 changes: 16 additions & 2 deletions apps/desktop/src/lib/components/main/CommandPalette.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ passing everything through props will be very complicated and hard to maintain.
<script lang="ts">
import { systemCommands } from "@/cmds/system"
import { devStoreExts, installedStoreExts } from "@/stores"
import { getActiveElementNodeName } from "@/utils/dom"
import type { ExtPackageJsonExtra } from "@kksh/api/models"
import { isExtPathInDev } from "@kksh/extension/utils"
import { Command } from "@kksh/svelte5"
Expand Down Expand Up @@ -35,23 +36,36 @@ passing everything through props will be very complicated and hard to maintain.
appState: Writable<AppState>
builtinCmds: BuiltinCmd[]
} = $props()
function onKeyDown(event: KeyboardEvent) {
if (event.key === "Escape") {
if (getActiveElementNodeName() === "INPUT") {
;(event.target as HTMLInputElement).value = ""
if ((event.target as HTMLInputElement | undefined)?.id === "main-command-input") {
$appState.searchTerm = ""
}
}
}
}
</script>

<svelte:window on:keydown={onKeyDown} />
<Command.Root
class={cn("rounded-lg border shadow-md", className)}
bind:value={$appState.highlightedCmd}
loop
>
<CustomCommandInput
autofocus
id="main-command-input"
placeholder="Type a command or search..."
bind:value={$appState.searchTerm}
/>
<Command.List class="max-h-screen grow">
<Command.Empty data-tauri-drag-region>No results found.</Command.Empty>
<BuiltinCmds {builtinCmds} />
<SystemCmds {systemCommands} />
{#if $appConfig.extensionPath && $devStoreExts.length > 0}
{#if $appConfig.extensionsInstallDir && $devStoreExts.length > 0}
<ExtCmdsGroup
extensions={$devStoreExts}
heading="Dev Extensions"
Expand All @@ -60,7 +74,7 @@ passing everything through props will be very complicated and hard to maintain.
hmr={$appConfig.hmr}
/>
{/if}
{#if $appConfig.extensionPath && $installedStoreExts.length > 0}
{#if $appConfig.extensionsInstallDir && $installedStoreExts.length > 0}
<ExtCmdsGroup
extensions={$installedStoreExts}
heading="Extensions"
Expand Down
9 changes: 3 additions & 6 deletions apps/desktop/src/lib/stores/appConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const defaultAppConfig: AppConfig = {
launchAtLogin: true,
showInTray: true,
devExtensionPath: null,
extensionPath: undefined,
extensionsInstallDir: undefined,
hmr: false,
hideOnBlur: true,
extensionAutoUpgrade: true,
Expand All @@ -40,20 +40,17 @@ function createAppConfig(): Writable<AppConfig> & AppConfigAPI {

async function init() {
debug("Initializing app config")
const appDataDir = await path.appDataDir()
// const appConfigPath = await path.join(appDataDir, "appConfig.json")
// debug(`appConfigPath: ${appConfigPath}`)
const persistStore = await load("kk-config.json", { autoSave: true })
const loadedConfig = await persistStore.get("config")
const parseRes = v.safeParse(PersistedAppConfig, loadedConfig)
if (parseRes.success) {
console.log("Parse Persisted App Config Success", parseRes.output)
const extensionPath = await path.join(appDataDir, "extensions")
const extensionsInstallDir = await getExtensionsFolder()
update((config) => ({
...config,
...parseRes.output,
isInitialized: true,
extensionPath,
extensionsInstallDir,
platform: os.platform()
}))
} else {
Expand Down
8 changes: 4 additions & 4 deletions apps/desktop/src/lib/stores/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function createExtensionsStore(): Writable<ExtPackageJsonExtra[]> & {
}

function getExtensionsFromStore() {
const extContainerPath = get(appConfig).extensionPath
const extContainerPath = get(appConfig).extensionsInstallDir
if (!extContainerPath) return []
return get(extensions).filter((ext) => !extAPI.isExtPathInDev(extContainerPath, ext.extPath))
}
Expand Down Expand Up @@ -83,7 +83,7 @@ function createExtensionsStore(): Writable<ExtPackageJsonExtra[]> & {
identifier: string,
tarballUrl: string
): Promise<ExtPackageJsonExtra> {
const extsDir = get(appConfig).extensionPath
const extsDir = get(appConfig).extensionsInstallDir
if (!extsDir) throw new Error("Extension path not set")
return uninstallStoreExtensionByIdentifier(identifier).then(() =>
installFromTarballUrl(tarballUrl, extsDir)
Expand All @@ -109,15 +109,15 @@ export const extensions = createExtensionsStore()
export const installedStoreExts: Readable<ExtPackageJsonExtra[]> = derived(
extensions,
($extensionsStore) => {
const extContainerPath = get(appConfig).extensionPath
const extContainerPath = get(appConfig).extensionsInstallDir
if (!extContainerPath) return []
return $extensionsStore.filter((ext) => !extAPI.isExtPathInDev(extContainerPath, ext.extPath))
}
)
export const devStoreExts: Readable<ExtPackageJsonExtra[]> = derived(
extensions,
($extensionsStore) => {
const extContainerPath = get(appConfig).extensionPath
const extContainerPath = get(appConfig).extensionsInstallDir
if (!extContainerPath) return []
return $extensionsStore.filter((ext) => extAPI.isExtPathInDev(extContainerPath, ext.extPath))
}
Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src/lib/utils/dom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function getActiveElementNodeName(): string | undefined {
return document.activeElement?.nodeName
}
7 changes: 7 additions & 0 deletions apps/desktop/src/routes/+layout.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { getExtensionsFolder } from "@/constants"
import type { LayoutLoad } from "./$types"

// Tauri doesn't have a Node.js server to do proper SSR
// so we will use adapter-static to prerender the app (SSG)
// See: https://v2.tauri.app/start/frontend/sveltekit/ for more info
export const prerender = true
export const ssr = false

export const load: LayoutLoad = async () => {
return { extsInstallDir: await getExtensionsFolder() }
}
1 change: 0 additions & 1 deletion apps/desktop/src/routes/extension/store/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
</script>

<svelte:window on:keydown={goBackOnEscapeClearSearchTerm} />

{#snippet leftSlot()}
<Button
variant="outline"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
onMount(() => {
showBtn = {
install: !installedExt,
install: !$installedExt,
upgrade: isUpgradable,
uninstall: !!installedExt
uninstall: !!$installedExt
}
})
Expand Down Expand Up @@ -140,7 +140,6 @@
</script>

<svelte:window on:keydown={handleKeydown} />

<Button
variant="outline"
size="icon"
Expand Down
2 changes: 1 addition & 1 deletion packages/types/src/appConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ export type PersistedAppConfig = v.InferOutput<typeof PersistedAppConfig>

export type AppConfig = PersistedAppConfig & {
isInitialized: boolean
extensionPath?: string
extensionsInstallDir?: string
platform: Platform
}
4 changes: 2 additions & 2 deletions packages/ui/src/components/extension/StoreExtDetail.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@
data-flip-id={`${Constants.CLASSNAMES.EXT_LOGO}-${ext.identifier}`}
/>
</span>
<div>
<span class="flex items-center">
<div class="w-full">
<span class="flex items-center w-full" use:autoAnimate>
<strong class="ext-name text-xl">{manifest?.name}</strong>
{#if isInstalled}
<CircleCheckBigIcon class="ml-2 inline text-green-400" />
Expand Down

0 comments on commit f64e562

Please sign in to comment.