summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packages/app/src/components/dialog-edit-project.tsx1
-rw-r--r--packages/app/src/context/global-sync.tsx35
-rw-r--r--packages/app/src/context/layout.tsx10
3 files changed, 44 insertions, 2 deletions
diff --git a/packages/app/src/components/dialog-edit-project.tsx b/packages/app/src/components/dialog-edit-project.tsx
index a90cac169..9e2bddc6b 100644
--- a/packages/app/src/components/dialog-edit-project.tsx
+++ b/packages/app/src/components/dialog-edit-project.tsx
@@ -85,6 +85,7 @@ export function DialogEditProject(props: { project: LocalProject }) {
icon: { color: store.color, override: store.iconUrl },
commands: { start },
})
+ globalSync.project.icon(props.project.worktree, store.iconUrl || undefined)
setStore("saving", false)
dialog.close()
return
diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx
index b6d9b518f..5f0f3d76f 100644
--- a/packages/app/src/context/global-sync.tsx
+++ b/packages/app/src/context/global-sync.tsx
@@ -61,6 +61,7 @@ type State = {
command: Command[]
project: string
projectMeta: ProjectMeta | undefined
+ icon: string | undefined
provider: ProviderListResponse
config: Config
path: Path
@@ -107,6 +108,12 @@ type MetaCache = {
ready: Accessor<boolean>
}
+type IconCache = {
+ store: Store<{ value: string | undefined }>
+ setStore: SetStoreFunction<{ value: string | undefined }>
+ ready: Accessor<boolean>
+}
+
type ChildOptions = {
bootstrap?: boolean
}
@@ -119,6 +126,7 @@ function createGlobalSync() {
if (!owner) throw new Error("GlobalSync must be created within owner")
const vcsCache = new Map<string, VcsCache>()
const metaCache = new Map<string, MetaCache>()
+ const iconCache = new Map<string, IconCache>()
const [projectCache, setProjectCache, , projectCacheReady] = persisted(
Persist.global("globalSync.project", ["globalSync.project.v1"]),
@@ -126,12 +134,13 @@ function createGlobalSync() {
)
const sanitizeProject = (project: Project) => {
- if (!project.icon?.url) return project
+ if (!project.icon?.url && !project.icon?.override) return project
return {
...project,
icon: {
...project.icon,
url: undefined,
+ override: undefined,
},
}
}
@@ -207,10 +216,20 @@ function createGlobalSync() {
if (!meta) throw new Error("Failed to create persisted project metadata")
metaCache.set(directory, { store: meta[0], setStore: meta[1], ready: meta[3] })
+ const icon = runWithOwner(owner, () =>
+ persisted(
+ Persist.workspace(directory, "icon", ["icon.v1"]),
+ createStore({ value: undefined as string | undefined }),
+ ),
+ )
+ if (!icon) throw new Error("Failed to create persisted project icon")
+ iconCache.set(directory, { store: icon[0], setStore: icon[1], ready: icon[3] })
+
const init = () => {
const child = createStore<State>({
project: "",
projectMeta: meta[0].value,
+ icon: icon[0].value,
provider: { all: [], connected: [], default: {} },
config: {},
path: { state: "", config: "", worktree: "", directory: "", home: "" },
@@ -237,6 +256,10 @@ function createGlobalSync() {
createEffect(() => {
child[1]("projectMeta", meta[0].value)
})
+
+ createEffect(() => {
+ child[1]("icon", icon[0].value)
+ })
}
runWithOwner(owner, init)
@@ -811,6 +834,15 @@ function createGlobalSync() {
setStore("projectMeta", next)
}
+ function projectIcon(directory: string, value: string | undefined) {
+ const [store, setStore] = ensureChild(directory)
+ const cached = iconCache.get(directory)
+ if (!cached) return
+ if (store.icon === value) return
+ cached.setStore("value", value)
+ setStore("icon", value)
+ }
+
return {
data: globalStore,
set: setGlobalStore,
@@ -833,6 +865,7 @@ function createGlobalSync() {
project: {
loadSessions,
meta: projectMeta,
+ icon: projectIcon,
},
}
}
diff --git a/packages/app/src/context/layout.tsx b/packages/app/src/context/layout.tsx
index 9db03b25f..444a36d65 100644
--- a/packages/app/src/context/layout.tsx
+++ b/packages/app/src/context/layout.tsx
@@ -235,7 +235,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
...project,
icon: {
url: metadata?.icon?.url,
- override: metadata?.icon?.override,
+ override: metadata?.icon?.override ?? childStore.icon,
color: metadata?.icon?.color,
},
}
@@ -306,6 +306,14 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
const projects = enriched()
if (projects.length === 0) return
+ if (globalSync.ready) {
+ for (const project of projects) {
+ if (!project.id) continue
+ if (project.id === "global") continue
+ globalSync.project.icon(project.worktree, project.icon?.override)
+ }
+ }
+
const used = new Set<string>()
for (const project of projects) {
const color = project.icon?.color ?? colors[project.worktree]