diff options
| author | Brendan Allan <[email protected]> | 2026-04-22 13:36:20 +0800 |
|---|---|---|
| committer | Aiden Cline <[email protected]> | 2026-04-23 00:25:36 -0400 |
| commit | 06066dbb7bd05a99526f7b6a5eaa499d1cf47f78 (patch) | |
| tree | 29104113de3152f8c5b99130e1b8a081bcb5bb3a | |
| parent | 69b8ea0d66ce9a57e4692278853fb67cc163a67b (diff) | |
| download | opencode-06066dbb7bd05a99526f7b6a5eaa499d1cf47f78.tar.gz opencode-06066dbb7bd05a99526f7b6a5eaa499d1cf47f78.zip | |
fix(app): improve icon override handling in project edit dialog (#23768)
| -rw-r--r-- | packages/app/src/components/dialog-edit-project.tsx | 36 | ||||
| -rw-r--r-- | packages/app/src/context/layout.tsx | 2 | ||||
| -rw-r--r-- | packages/app/src/pages/layout/sidebar-items.tsx | 4 |
3 files changed, 23 insertions, 19 deletions
diff --git a/packages/app/src/components/dialog-edit-project.tsx b/packages/app/src/components/dialog-edit-project.tsx index ea5d70065..621d56646 100644 --- a/packages/app/src/components/dialog-edit-project.tsx +++ b/packages/app/src/components/dialog-edit-project.tsx @@ -26,8 +26,8 @@ export function DialogEditProject(props: { project: LocalProject }) { const [store, setStore] = createStore({ name: defaultName(), - color: props.project.icon?.color || "pink", - iconUrl: props.project.icon?.override || "", + color: props.project.icon?.color, + iconOverride: props.project.icon?.override, startup: props.project.commands?.start ?? "", dragOver: false, iconHover: false, @@ -39,7 +39,7 @@ export function DialogEditProject(props: { project: LocalProject }) { if (!file.type.startsWith("image/")) return const reader = new FileReader() reader.onload = (e) => { - setStore("iconUrl", e.target?.result as string) + setStore("iconOverride", e.target?.result as string) setStore("iconHover", false) } reader.readAsDataURL(file) @@ -68,7 +68,7 @@ export function DialogEditProject(props: { project: LocalProject }) { } function clearIcon() { - setStore("iconUrl", "") + setStore("iconOverride", "") } const saveMutation = useMutation(() => ({ @@ -81,17 +81,17 @@ export function DialogEditProject(props: { project: LocalProject }) { projectID: props.project.id, directory: props.project.worktree, name, - icon: { color: store.color, override: store.iconUrl }, + icon: { color: store.color || "", override: store.iconOverride || "" }, commands: { start }, }) - globalSync.project.icon(props.project.worktree, store.iconUrl || undefined) + globalSync.project.icon(props.project.worktree, store.iconOverride || undefined) dialog.close() return } globalSync.project.meta(props.project.worktree, { name, - icon: { color: store.color, override: store.iconUrl || undefined }, + icon: { color: store.color || undefined, override: store.iconOverride || undefined }, commands: { start: start || undefined }, }) dialog.close() @@ -130,13 +130,13 @@ export function DialogEditProject(props: { project: LocalProject }) { classList={{ "border-text-interactive-base bg-surface-info-base/20": store.dragOver, "border-border-base hover:border-border-strong": !store.dragOver, - "overflow-hidden": !!store.iconUrl, + "overflow-hidden": !!store.iconOverride, }} onDrop={handleDrop} onDragOver={handleDragOver} onDragLeave={handleDragLeave} onClick={() => { - if (store.iconUrl && store.iconHover) { + if (store.iconOverride && store.iconHover) { clearIcon() } else { iconInput?.click() @@ -144,7 +144,7 @@ export function DialogEditProject(props: { project: LocalProject }) { }} > <Show - when={store.iconUrl} + when={store.iconOverride || (!store.color && props.project.icon?.url)} fallback={ <div class="size-full flex items-center justify-center"> <Avatar @@ -156,7 +156,7 @@ export function DialogEditProject(props: { project: LocalProject }) { } > <img - src={store.iconUrl} + src={store.iconOverride || props.project.icon?.url} alt={language.t("dialog.project.edit.icon.alt")} class="size-full object-cover" /> @@ -165,8 +165,8 @@ export function DialogEditProject(props: { project: LocalProject }) { <div class="absolute inset-0 size-16 bg-surface-raised-stronger-non-alpha/90 rounded-[6px] z-10 pointer-events-none flex items-center justify-center transition-opacity" classList={{ - "opacity-100": store.iconHover && !store.iconUrl, - "opacity-0": !(store.iconHover && !store.iconUrl), + "opacity-100": store.iconHover && !store.iconOverride, + "opacity-0": !(store.iconHover && !store.iconOverride), }} > <Icon name="cloud-upload" size="large" class="text-icon-on-interactive-base drop-shadow-sm" /> @@ -174,8 +174,8 @@ export function DialogEditProject(props: { project: LocalProject }) { <div class="absolute inset-0 size-16 bg-surface-raised-stronger-non-alpha/90 rounded-[6px] z-10 pointer-events-none flex items-center justify-center transition-opacity" classList={{ - "opacity-100": store.iconHover && !!store.iconUrl, - "opacity-0": !(store.iconHover && !!store.iconUrl), + "opacity-100": store.iconHover && !!store.iconOverride, + "opacity-0": !(store.iconHover && !!store.iconOverride), }} > <Icon name="trash" size="large" class="text-icon-on-interactive-base drop-shadow-sm" /> @@ -198,7 +198,7 @@ export function DialogEditProject(props: { project: LocalProject }) { </div> </div> - <Show when={!store.iconUrl}> + <Show when={!store.iconOverride}> <div class="flex flex-col gap-2"> <label class="text-12-medium text-text-weak">{language.t("dialog.project.edit.color")}</label> <div class="flex gap-1.5"> @@ -215,7 +215,9 @@ export function DialogEditProject(props: { project: LocalProject }) { "bg-transparent border border-transparent hover:bg-surface-base-hover hover:border-border-weak-base": store.color !== color, }} - onClick={() => setStore("color", color)} + onClick={() => { + setStore("color", store.color === color ? undefined : color) + }} > <Avatar fallback={store.name || defaultName()} diff --git a/packages/app/src/context/layout.tsx b/packages/app/src/context/layout.tsx index 74ea28531..90e357bd3 100644 --- a/packages/app/src/context/layout.tsx +++ b/packages/app/src/context/layout.tsx @@ -516,7 +516,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext( } for (const project of projects) { - if (project.icon?.color) continue + if (project.icon?.color || project.icon.url) continue const worktree = project.worktree const existing = colors[worktree] const color = existing ?? pickAvailableColor(used) diff --git a/packages/app/src/pages/layout/sidebar-items.tsx b/packages/app/src/pages/layout/sidebar-items.tsx index 45db5b548..88d50db3e 100644 --- a/packages/app/src/pages/layout/sidebar-items.tsx +++ b/packages/app/src/pages/layout/sidebar-items.tsx @@ -45,7 +45,9 @@ export const ProjectIcon = (props: { project: LocalProject; class?: string; noti src={ props.project.id === OPENCODE_PROJECT_ID ? "https://opencode.ai/favicon.svg" - : props.project.icon?.override || props.project.icon?.url + : props.project.icon?.color + ? undefined + : props.project.icon?.override || props.project.icon?.url } {...getAvatarColors(props.project.icon?.color)} class="size-full rounded" |
