diff --git a/packages/desktop/src/context/global-sync.tsx b/packages/desktop/src/context/global-sync.tsx index 62de028f5..890801611 100644 --- a/packages/desktop/src/context/global-sync.tsx +++ b/packages/desktop/src/context/global-sync.tsx @@ -31,13 +31,20 @@ const PASTEL_COLORS = [ "#C1E1C1", // pastel mint ] -function randomPastelColor() { - return PASTEL_COLORS[Math.floor(Math.random() * PASTEL_COLORS.length)] +function pickAvailableColor(usedColors: Set) { + const available = PASTEL_COLORS.filter((c) => !usedColors.has(c)) + if (available.length === 0) return PASTEL_COLORS[Math.floor(Math.random() * PASTEL_COLORS.length)] + return available[Math.floor(Math.random() * available.length)] } -async function ensureProjectColor(project: Project, sdk: ReturnType): Promise { +async function ensureProjectColor( + project: Project, + sdk: ReturnType, + usedColors: Set, +): Promise { if (project.icon?.color) return project - const color = randomPastelColor() + const color = pickAvailableColor(usedColors) + usedColors.add(color) const updated = { ...project, icon: { ...project.icon, color } } sdk.client.project.update({ projectID: project.id, icon: { color } }) return updated @@ -117,7 +124,8 @@ export const { use: useGlobalSync, provider: GlobalSyncProvider } = createSimple if (directory === "global") { switch (event.type) { case "project.updated": { - ensureProjectColor(event.properties, sdk).then((project) => { + const usedColors = new Set(globalStore.projects.map((p) => p.icon?.color).filter(Boolean) as string[]) + ensureProjectColor(event.properties, sdk, usedColors).then((project) => { const result = Binary.search(globalStore.projects, project.id, (s) => s.id) if (result.found) { setGlobalStore("projects", result.index, reconcile(project)) @@ -209,7 +217,8 @@ export const { use: useGlobalSync, provider: GlobalSyncProvider } = createSimple Promise.all([ sdk.client.project.list().then(async (x) => { const filtered = x.data!.filter((p) => !p.worktree.includes("opencode-test") && p.vcs) - const projects = await Promise.all(filtered.map((p) => ensureProjectColor(p, sdk))) + const usedColors = new Set(filtered.map((p) => p.icon?.color).filter(Boolean) as string[]) + const projects = await Promise.all(filtered.map((p) => ensureProjectColor(p, sdk, usedColors))) setGlobalStore( "projects", projects.sort((a, b) => a.id.localeCompare(b.id)),