chore: cleanup
This commit is contained in:
@@ -112,21 +112,35 @@ export function SessionHeader() {
|
|||||||
|
|
||||||
const [exists, setExists] = createStore<Partial<Record<OpenApp, boolean>>>({ finder: true })
|
const [exists, setExists] = createStore<Partial<Record<OpenApp, boolean>>>({ finder: true })
|
||||||
|
|
||||||
|
const apps = createMemo(() => {
|
||||||
|
if (os() === "macos") return MAC_APPS
|
||||||
|
if (os() === "windows") return WINDOWS_APPS
|
||||||
|
return LINUX_APPS
|
||||||
|
})
|
||||||
|
|
||||||
|
const fileManager = createMemo(() => {
|
||||||
|
if (os() === "macos") return { label: "Finder", icon: "finder" as const }
|
||||||
|
if (os() === "windows") return { label: "File Explorer", icon: "file-explorer" as const }
|
||||||
|
return { label: "File Manager", icon: "finder" as const }
|
||||||
|
})
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (platform.platform !== "desktop") return
|
if (platform.platform !== "desktop") return
|
||||||
if (!platform.checkAppExists) return
|
if (!platform.checkAppExists) return
|
||||||
|
|
||||||
const list = os()
|
const list = apps()
|
||||||
const apps = list === "macos" ? MAC_APPS : list === "windows" ? WINDOWS_APPS : list === "linux" ? LINUX_APPS : []
|
|
||||||
if (apps.length === 0) return
|
setExists(Object.fromEntries(list.map((app) => [app.id, undefined])) as Partial<Record<OpenApp, boolean>>)
|
||||||
|
|
||||||
void Promise.all(
|
void Promise.all(
|
||||||
apps.map((app) =>
|
list.map((app) =>
|
||||||
Promise.resolve(platform.checkAppExists?.(app.openWith)).then((value) => {
|
Promise.resolve(platform.checkAppExists?.(app.openWith))
|
||||||
const ok = Boolean(value)
|
.then((value) => Boolean(value))
|
||||||
console.debug(`[session-header] App "${app.label}" (${app.openWith}): ${ok ? "exists" : "does not exist"}`)
|
.catch(() => false)
|
||||||
return [app.id, ok] as const
|
.then((ok) => {
|
||||||
}),
|
console.debug(`[session-header] App "${app.label}" (${app.openWith}): ${ok ? "exists" : "does not exist"}`)
|
||||||
|
return [app.id, ok] as const
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
).then((entries) => {
|
).then((entries) => {
|
||||||
setExists(Object.fromEntries(entries) as Partial<Record<OpenApp, boolean>>)
|
setExists(Object.fromEntries(entries) as Partial<Record<OpenApp, boolean>>)
|
||||||
@@ -134,23 +148,23 @@ export function SessionHeader() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const options = createMemo(() => {
|
const options = createMemo(() => {
|
||||||
if (os() === "macos") {
|
|
||||||
return [{ id: "finder", label: "Finder", icon: "finder" }, ...MAC_APPS.filter((app) => exists[app.id])] as const
|
|
||||||
}
|
|
||||||
|
|
||||||
if (os() === "windows") {
|
|
||||||
return [
|
|
||||||
{ id: "finder", label: "File Explorer", icon: "file-explorer" },
|
|
||||||
...WINDOWS_APPS.filter((app) => exists[app.id]),
|
|
||||||
] as const
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{ id: "finder", label: "File Manager", icon: "finder" },
|
{ id: "finder", label: fileManager().label, icon: fileManager().icon },
|
||||||
...LINUX_APPS.filter((app) => exists[app.id]),
|
...apps().filter((app) => exists[app.id]),
|
||||||
] as const
|
] as const
|
||||||
})
|
})
|
||||||
|
|
||||||
|
type OpenIcon = OpenApp | "file-explorer"
|
||||||
|
const base = new Set<OpenIcon>(["finder", "vscode", "cursor", "zed"])
|
||||||
|
const size = (id: OpenIcon) => (base.has(id) ? "size-4" : "size-[19px]")
|
||||||
|
|
||||||
|
const checksReady = createMemo(() => {
|
||||||
|
if (platform.platform !== "desktop") return true
|
||||||
|
if (!platform.checkAppExists) return true
|
||||||
|
const list = apps()
|
||||||
|
return list.every((app) => exists[app.id] !== undefined)
|
||||||
|
})
|
||||||
|
|
||||||
const [prefs, setPrefs] = persisted(Persist.global("open.app"), createStore({ app: "finder" as OpenApp }))
|
const [prefs, setPrefs] = persisted(Persist.global("open.app"), createStore({ app: "finder" as OpenApp }))
|
||||||
|
|
||||||
const canOpen = createMemo(() => platform.platform === "desktop" && !!platform.openPath && server.isLocal())
|
const canOpen = createMemo(() => platform.platform === "desktop" && !!platform.openPath && server.isLocal())
|
||||||
@@ -158,6 +172,7 @@ export function SessionHeader() {
|
|||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
if (platform.platform !== "desktop") return
|
if (platform.platform !== "desktop") return
|
||||||
|
if (!checksReady()) return
|
||||||
const value = prefs.app
|
const value = prefs.app
|
||||||
if (options().some((o) => o.id === value)) return
|
if (options().some((o) => o.id === value)) return
|
||||||
setPrefs("app", options()[0]?.id ?? "finder")
|
setPrefs("app", options()[0]?.id ?? "finder")
|
||||||
@@ -334,11 +349,13 @@ export function SessionHeader() {
|
|||||||
onClick={() => openDir(current().id)}
|
onClick={() => openDir(current().id)}
|
||||||
aria-label={language.t("session.header.open.ariaLabel", { app: current().label })}
|
aria-label={language.t("session.header.open.ariaLabel", { app: current().label })}
|
||||||
>
|
>
|
||||||
<AppIcon id={current().icon} class="size-4" />
|
<div class="flex size-5 shrink-0 items-center justify-center">
|
||||||
|
<AppIcon id={current().icon} class="size-4" />
|
||||||
|
</div>
|
||||||
<span class="text-12-regular text-text-strong">Open</span>
|
<span class="text-12-regular text-text-strong">Open</span>
|
||||||
</Button>
|
</Button>
|
||||||
<div class="self-stretch w-px bg-border-base/70" />
|
<div class="self-stretch w-px bg-border-base/70" />
|
||||||
<DropdownMenu>
|
<DropdownMenu gutter={6} placement="bottom-end">
|
||||||
<DropdownMenu.Trigger
|
<DropdownMenu.Trigger
|
||||||
as={IconButton}
|
as={IconButton}
|
||||||
icon="chevron-down"
|
icon="chevron-down"
|
||||||
@@ -347,7 +364,7 @@ export function SessionHeader() {
|
|||||||
aria-label={language.t("session.header.open.menu")}
|
aria-label={language.t("session.header.open.menu")}
|
||||||
/>
|
/>
|
||||||
<DropdownMenu.Portal>
|
<DropdownMenu.Portal>
|
||||||
<DropdownMenu.Content placement="bottom-end" gutter={6}>
|
<DropdownMenu.Content>
|
||||||
<DropdownMenu.Group>
|
<DropdownMenu.Group>
|
||||||
<DropdownMenu.GroupLabel>{language.t("session.header.openIn")}</DropdownMenu.GroupLabel>
|
<DropdownMenu.GroupLabel>{language.t("session.header.openIn")}</DropdownMenu.GroupLabel>
|
||||||
<DropdownMenu.RadioGroup
|
<DropdownMenu.RadioGroup
|
||||||
@@ -359,7 +376,9 @@ export function SessionHeader() {
|
|||||||
>
|
>
|
||||||
{options().map((o) => (
|
{options().map((o) => (
|
||||||
<DropdownMenu.RadioItem value={o.id} onSelect={() => openDir(o.id)}>
|
<DropdownMenu.RadioItem value={o.id} onSelect={() => openDir(o.id)}>
|
||||||
<AppIcon id={o.icon} class="size-5" />
|
<div class="flex size-5 shrink-0 items-center justify-center">
|
||||||
|
<AppIcon id={o.icon} class={size(o.icon)} />
|
||||||
|
</div>
|
||||||
<DropdownMenu.ItemLabel>{o.label}</DropdownMenu.ItemLabel>
|
<DropdownMenu.ItemLabel>{o.label}</DropdownMenu.ItemLabel>
|
||||||
<DropdownMenu.ItemIndicator>
|
<DropdownMenu.ItemIndicator>
|
||||||
<Icon name="check-small" size="small" class="text-icon-weak" />
|
<Icon name="check-small" size="small" class="text-icon-weak" />
|
||||||
@@ -370,7 +389,9 @@ export function SessionHeader() {
|
|||||||
</DropdownMenu.Group>
|
</DropdownMenu.Group>
|
||||||
<DropdownMenu.Separator />
|
<DropdownMenu.Separator />
|
||||||
<DropdownMenu.Item onSelect={copyPath}>
|
<DropdownMenu.Item onSelect={copyPath}>
|
||||||
<Icon name="copy" size="small" class="text-icon-weak" />
|
<div class="flex size-5 shrink-0 items-center justify-center">
|
||||||
|
<Icon name="copy" size="small" class="text-icon-weak" />
|
||||||
|
</div>
|
||||||
<DropdownMenu.ItemLabel>
|
<DropdownMenu.ItemLabel>
|
||||||
{language.t("session.header.open.copyPath")}
|
{language.t("session.header.open.copyPath")}
|
||||||
</DropdownMenu.ItemLabel>
|
</DropdownMenu.ItemLabel>
|
||||||
|
|||||||
Reference in New Issue
Block a user