fix(app): no more favicons
This commit is contained in:
@@ -22,7 +22,7 @@ export function DialogEditProject(props: { project: LocalProject }) {
|
|||||||
const [store, setStore] = createStore({
|
const [store, setStore] = createStore({
|
||||||
name: defaultName(),
|
name: defaultName(),
|
||||||
color: props.project.icon?.color || "pink",
|
color: props.project.icon?.color || "pink",
|
||||||
iconUrl: props.project.icon?.url || "",
|
iconUrl: props.project.icon?.override || "",
|
||||||
saving: false,
|
saving: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ export function DialogEditProject(props: { project: LocalProject }) {
|
|||||||
await globalSDK.client.project.update({
|
await globalSDK.client.project.update({
|
||||||
projectID: props.project.id,
|
projectID: props.project.id,
|
||||||
name,
|
name,
|
||||||
icon: { color: store.color, url: store.iconUrl },
|
icon: { color: store.color, override: store.iconUrl },
|
||||||
})
|
})
|
||||||
setStore("saving", false)
|
setStore("saving", false)
|
||||||
dialog.close()
|
dialog.close()
|
||||||
|
|||||||
@@ -208,10 +208,10 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const usedColors = new Set<AvatarColorKey>()
|
const [colors, setColors] = createStore<Record<string, AvatarColorKey>>({})
|
||||||
|
|
||||||
function pickAvailableColor(): AvatarColorKey {
|
function pickAvailableColor(used: Set<string>): AvatarColorKey {
|
||||||
const available = AVATAR_COLOR_KEYS.filter((c) => !usedColors.has(c))
|
const available = AVATAR_COLOR_KEYS.filter((c) => !used.has(c))
|
||||||
if (available.length === 0) return AVATAR_COLOR_KEYS[Math.floor(Math.random() * AVATAR_COLOR_KEYS.length)]
|
if (available.length === 0) return AVATAR_COLOR_KEYS[Math.floor(Math.random() * AVATAR_COLOR_KEYS.length)]
|
||||||
return available[Math.floor(Math.random() * available.length)]
|
return available[Math.floor(Math.random() * available.length)]
|
||||||
}
|
}
|
||||||
@@ -222,24 +222,15 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
|
|||||||
const metadata = projectID
|
const metadata = projectID
|
||||||
? globalSync.data.project.find((x) => x.id === projectID)
|
? globalSync.data.project.find((x) => x.id === projectID)
|
||||||
: globalSync.data.project.find((x) => x.worktree === project.worktree)
|
: globalSync.data.project.find((x) => x.worktree === project.worktree)
|
||||||
return [
|
return {
|
||||||
{
|
...(metadata ?? {}),
|
||||||
...(metadata ?? {}),
|
...project,
|
||||||
...project,
|
icon: {
|
||||||
icon: { url: metadata?.icon?.url, color: metadata?.icon?.color },
|
url: metadata?.icon?.url,
|
||||||
|
override: metadata?.icon?.override,
|
||||||
|
color: metadata?.icon?.color,
|
||||||
},
|
},
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
function colorize(project: LocalProject) {
|
|
||||||
if (project.icon?.color) return project
|
|
||||||
const color = pickAvailableColor()
|
|
||||||
usedColors.add(color)
|
|
||||||
project.icon = { ...project.icon, color }
|
|
||||||
if (project.id) {
|
|
||||||
globalSdk.client.project.update({ projectID: project.id, icon: { color } })
|
|
||||||
}
|
}
|
||||||
return project
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const roots = createMemo(() => {
|
const roots = createMemo(() => {
|
||||||
@@ -277,8 +268,37 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const enriched = createMemo(() => server.projects.list().flatMap(enrich))
|
const enriched = createMemo(() => server.projects.list().map(enrich))
|
||||||
const list = createMemo(() => enriched().flatMap(colorize))
|
const list = createMemo(() => {
|
||||||
|
const projects = enriched()
|
||||||
|
return projects.map((project) => {
|
||||||
|
const color = project.icon?.color ?? colors[project.worktree]
|
||||||
|
if (!color) return project
|
||||||
|
const icon = project.icon ? { ...project.icon, color } : { color }
|
||||||
|
return { ...project, icon }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
const projects = enriched()
|
||||||
|
if (projects.length === 0) return
|
||||||
|
|
||||||
|
const used = new Set<string>()
|
||||||
|
for (const project of projects) {
|
||||||
|
const color = project.icon?.color ?? colors[project.worktree]
|
||||||
|
if (color) used.add(color)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const project of projects) {
|
||||||
|
if (project.icon?.color) continue
|
||||||
|
if (colors[project.worktree]) continue
|
||||||
|
const color = pickAvailableColor(used)
|
||||||
|
used.add(color)
|
||||||
|
setColors(project.worktree, color)
|
||||||
|
if (!project.id) continue
|
||||||
|
void globalSdk.client.project.update({ projectID: project.id, icon: { color } })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
Promise.all(
|
Promise.all(
|
||||||
|
|||||||
@@ -1284,7 +1284,7 @@ export default function Layout(props: ParentProps) {
|
|||||||
<div class="size-full rounded overflow-clip">
|
<div class="size-full rounded overflow-clip">
|
||||||
<Avatar
|
<Avatar
|
||||||
fallback={name()}
|
fallback={name()}
|
||||||
src={props.project.id === opencode ? "https://opencode.ai/favicon-v2.svg" : props.project.icon?.url}
|
src={props.project.id === opencode ? "https://opencode.ai/favicon-v2.svg" : props.project.icon?.override}
|
||||||
{...getAvatarColors(props.project.icon?.color)}
|
{...getAvatarColors(props.project.icon?.color)}
|
||||||
class="size-full rounded"
|
class="size-full rounded"
|
||||||
style={
|
style={
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export namespace Project {
|
|||||||
icon: z
|
icon: z
|
||||||
.object({
|
.object({
|
||||||
url: z.string().optional(),
|
url: z.string().optional(),
|
||||||
|
override: z.string().optional(),
|
||||||
color: z.string().optional(),
|
color: z.string().optional(),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
@@ -190,6 +191,7 @@ export namespace Project {
|
|||||||
if (!existing.sandboxes) existing.sandboxes = []
|
if (!existing.sandboxes) existing.sandboxes = []
|
||||||
|
|
||||||
if (Flag.OPENCODE_EXPERIMENTAL_ICON_DISCOVERY) discover(existing)
|
if (Flag.OPENCODE_EXPERIMENTAL_ICON_DISCOVERY) discover(existing)
|
||||||
|
|
||||||
const result: Info = {
|
const result: Info = {
|
||||||
...existing,
|
...existing,
|
||||||
worktree,
|
worktree,
|
||||||
@@ -213,6 +215,7 @@ export namespace Project {
|
|||||||
|
|
||||||
export async function discover(input: Info) {
|
export async function discover(input: Info) {
|
||||||
if (input.vcs !== "git") return
|
if (input.vcs !== "git") return
|
||||||
|
if (input.icon?.override) return
|
||||||
if (input.icon?.url) return
|
if (input.icon?.url) return
|
||||||
const glob = new Bun.Glob("**/{favicon}.{ico,png,svg,jpg,jpeg,webp}")
|
const glob = new Bun.Glob("**/{favicon}.{ico,png,svg,jpg,jpeg,webp}")
|
||||||
const matches = await Array.fromAsync(
|
const matches = await Array.fromAsync(
|
||||||
@@ -293,6 +296,7 @@ export namespace Project {
|
|||||||
...draft.icon,
|
...draft.icon,
|
||||||
}
|
}
|
||||||
if (input.icon.url !== undefined) draft.icon.url = input.icon.url
|
if (input.icon.url !== undefined) draft.icon.url = input.icon.url
|
||||||
|
if (input.icon.override !== undefined) draft.icon.override = input.icon.override || undefined
|
||||||
if (input.icon.color !== undefined) draft.icon.color = input.icon.color
|
if (input.icon.color !== undefined) draft.icon.color = input.icon.color
|
||||||
}
|
}
|
||||||
draft.time.updated = Date.now()
|
draft.time.updated = Date.now()
|
||||||
|
|||||||
@@ -302,6 +302,7 @@ export class Project extends HeyApiClient {
|
|||||||
name?: string
|
name?: string
|
||||||
icon?: {
|
icon?: {
|
||||||
url?: string
|
url?: string
|
||||||
|
override?: string
|
||||||
color?: string
|
color?: string
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export type Project = {
|
|||||||
name?: string
|
name?: string
|
||||||
icon?: {
|
icon?: {
|
||||||
url?: string
|
url?: string
|
||||||
|
override?: string
|
||||||
color?: string
|
color?: string
|
||||||
}
|
}
|
||||||
time: {
|
time: {
|
||||||
@@ -2229,6 +2230,7 @@ export type ProjectUpdateData = {
|
|||||||
name?: string
|
name?: string
|
||||||
icon?: {
|
icon?: {
|
||||||
url?: string
|
url?: string
|
||||||
|
override?: string
|
||||||
color?: string
|
color?: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user