fix(app): project icon color flash on load
This commit is contained in:
@@ -119,6 +119,22 @@ function createGlobalSync() {
|
|||||||
if (!owner) throw new Error("GlobalSync must be created within owner")
|
if (!owner) throw new Error("GlobalSync must be created within owner")
|
||||||
const vcsCache = new Map<string, VcsCache>()
|
const vcsCache = new Map<string, VcsCache>()
|
||||||
const metaCache = new Map<string, MetaCache>()
|
const metaCache = new Map<string, MetaCache>()
|
||||||
|
|
||||||
|
const [projectCache, setProjectCache, , projectCacheReady] = persisted(
|
||||||
|
Persist.global("globalSync.project", ["globalSync.project.v1"]),
|
||||||
|
createStore({ value: [] as Project[] }),
|
||||||
|
)
|
||||||
|
|
||||||
|
const sanitizeProject = (project: Project) => {
|
||||||
|
if (!project.icon?.url) return project
|
||||||
|
return {
|
||||||
|
...project,
|
||||||
|
icon: {
|
||||||
|
...project.icon,
|
||||||
|
url: undefined,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
const [globalStore, setGlobalStore] = createStore<{
|
const [globalStore, setGlobalStore] = createStore<{
|
||||||
ready: boolean
|
ready: boolean
|
||||||
error?: InitError
|
error?: InitError
|
||||||
@@ -131,7 +147,7 @@ function createGlobalSync() {
|
|||||||
}>({
|
}>({
|
||||||
ready: false,
|
ready: false,
|
||||||
path: { state: "", config: "", worktree: "", directory: "", home: "" },
|
path: { state: "", config: "", worktree: "", directory: "", home: "" },
|
||||||
project: [],
|
project: projectCache.value,
|
||||||
provider: { all: [], connected: [], default: {} },
|
provider: { all: [], connected: [], default: {} },
|
||||||
provider_auth: {},
|
provider_auth: {},
|
||||||
config: {},
|
config: {},
|
||||||
@@ -139,6 +155,20 @@ function createGlobalSync() {
|
|||||||
})
|
})
|
||||||
let bootstrapQueue: string[] = []
|
let bootstrapQueue: string[] = []
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (!projectCacheReady()) return
|
||||||
|
if (globalStore.project.length !== 0) return
|
||||||
|
const cached = projectCache.value
|
||||||
|
if (cached.length === 0) return
|
||||||
|
setGlobalStore("project", cached)
|
||||||
|
})
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (!projectCacheReady()) return
|
||||||
|
if (globalStore.project.length === 0 && projectCache.value.length !== 0) return
|
||||||
|
setProjectCache("value", globalStore.project.map(sanitizeProject))
|
||||||
|
})
|
||||||
|
|
||||||
createEffect(async () => {
|
createEffect(async () => {
|
||||||
if (globalStore.reload !== "complete") return
|
if (globalStore.reload !== "complete") return
|
||||||
if (bootstrapQueue.length) {
|
if (bootstrapQueue.length) {
|
||||||
@@ -178,7 +208,7 @@ function createGlobalSync() {
|
|||||||
metaCache.set(directory, { store: meta[0], setStore: meta[1], ready: meta[3] })
|
metaCache.set(directory, { store: meta[0], setStore: meta[1], ready: meta[3] })
|
||||||
|
|
||||||
const init = () => {
|
const init = () => {
|
||||||
children[directory] = createStore<State>({
|
const child = createStore<State>({
|
||||||
project: "",
|
project: "",
|
||||||
projectMeta: meta[0].value,
|
projectMeta: meta[0].value,
|
||||||
provider: { all: [], connected: [], default: {} },
|
provider: { all: [], connected: [], default: {} },
|
||||||
@@ -201,6 +231,12 @@ function createGlobalSync() {
|
|||||||
message: {},
|
message: {},
|
||||||
part: {},
|
part: {},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
children[directory] = child
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
child[1]("projectMeta", meta[0].value)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
runWithOwner(owner, init)
|
runWithOwner(owner, init)
|
||||||
@@ -300,12 +336,7 @@ function createGlobalSync() {
|
|||||||
setStore("vcs", (value) => value ?? cached)
|
setStore("vcs", (value) => value ?? cached)
|
||||||
})
|
})
|
||||||
|
|
||||||
createEffect(() => {
|
// projectMeta is synced from persisted storage in ensureChild.
|
||||||
if (!meta.ready()) return
|
|
||||||
const cached = meta.store.value
|
|
||||||
if (!cached) return
|
|
||||||
setStore("projectMeta", (value) => value ?? cached)
|
|
||||||
})
|
|
||||||
|
|
||||||
const blockingRequests = {
|
const blockingRequests = {
|
||||||
project: () => sdk.project.current().then((x) => setStore("project", x.data!.id)),
|
project: () => sdk.project.current().then((x) => setStore("project", x.data!.id)),
|
||||||
|
|||||||
@@ -223,6 +223,13 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
|
|||||||
? 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)
|
||||||
|
|
||||||
|
const local = childStore.projectMeta
|
||||||
|
const localOverride =
|
||||||
|
local?.name !== undefined ||
|
||||||
|
local?.commands?.start !== undefined ||
|
||||||
|
local?.icon?.override !== undefined ||
|
||||||
|
local?.icon?.color !== undefined
|
||||||
|
|
||||||
const base = {
|
const base = {
|
||||||
...(metadata ?? {}),
|
...(metadata ?? {}),
|
||||||
...project,
|
...project,
|
||||||
@@ -233,11 +240,12 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if (projectID !== "global") return base
|
const isGlobal = projectID === "global" || (metadata?.id === undefined && localOverride)
|
||||||
|
if (!isGlobal) return base
|
||||||
|
|
||||||
const local = childStore.projectMeta
|
|
||||||
return {
|
return {
|
||||||
...base,
|
...base,
|
||||||
|
id: base.id ?? "global",
|
||||||
name: local?.name,
|
name: local?.name,
|
||||||
commands: local?.commands,
|
commands: local?.commands,
|
||||||
icon: {
|
icon: {
|
||||||
@@ -306,10 +314,12 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
|
|||||||
|
|
||||||
for (const project of projects) {
|
for (const project of projects) {
|
||||||
if (project.icon?.color) continue
|
if (project.icon?.color) continue
|
||||||
if (colors[project.worktree]) continue
|
const existing = colors[project.worktree]
|
||||||
const color = pickAvailableColor(used)
|
const color = existing ?? pickAvailableColor(used)
|
||||||
used.add(color)
|
if (!existing) {
|
||||||
setColors(project.worktree, color)
|
used.add(color)
|
||||||
|
setColors(project.worktree, color)
|
||||||
|
}
|
||||||
if (!project.id) continue
|
if (!project.id) continue
|
||||||
if (project.id === "global") {
|
if (project.id === "global") {
|
||||||
globalSync.project.meta(project.worktree, { icon: { color } })
|
globalSync.project.meta(project.worktree, { icon: { color } })
|
||||||
|
|||||||
Reference in New Issue
Block a user