Skip to content

Commit 16154fb

Browse files
committed
refactor: remove unused iconThemeVersionAtom and streamline icon theme handling
1 parent 9fcde73 commit 16154fb

3 files changed

Lines changed: 54 additions & 43 deletions

File tree

packages/ui/lib/atoms.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { atom } from "jotai";
44
export const themesReadyAtom = atom(false);
55

66
export const systemThemeAtom = atom<SystemThemeKind>("dark");
7-
export const iconThemeVersionAtom = atom(0);
87

98
export const panelsVisibleAtom = atom(true);
109
export const terminalFocusRequestKeyAtom = atom(0);

packages/ui/lib/features/file-icons/iconResolver.ts

Lines changed: 52 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
1-
/**
2-
* Unified Icon Resolver
3-
*
4-
* Provides a single interface for resolving file/folder icons through
5-
* a theme adapter, regardless of whether the active theme comes from
6-
* FSS metadata or a VS Code icon theme JSON.
7-
*/
8-
9-
import { iconThemeVersionAtom } from "@/atoms";
101
import { useBridge } from "@/features/bridge/useBridge";
112
import { atom, useAtomValue, useSetAtom } from "jotai";
12-
import { useCallback, useMemo } from "react";
3+
import { useCallback } from "react";
134
import {
145
FssIconThemeAdapter,
156
NoneIconThemeAdapter,
@@ -23,58 +14,80 @@ import {
2314
import { DEFAULT_ICONS } from "./defaultIcons";
2415
import { useIconAssetStore } from "./iconCache";
2516

26-
const activeIconThemeAdapterAtom = atom<IconThemeAdapter>(new NoneIconThemeAdapter());
17+
type ActiveIconThemeState = {
18+
adapter: IconThemeAdapter;
19+
kind: "dark" | "light";
20+
type: IconThemeType;
21+
};
22+
23+
const activeIconThemeStateAtom = atom<ActiveIconThemeState>({
24+
adapter: new NoneIconThemeAdapter(),
25+
kind: "dark",
26+
type: "none",
27+
});
2728

2829
export function useSetIconTheme() {
2930
const bridge = useBridge();
30-
const fssTheme = useMemo(() => new FssIconThemeAdapter(), []);
31-
const vscodeTheme = useMemo(() => new VSCodeIconThemeAdapter(bridge), [bridge]);
32-
const noneTheme = useMemo(() => new NoneIconThemeAdapter(), []);
33-
const setActiveTheme = useSetAtom(activeIconThemeAdapterAtom);
34-
const bumpThemeVersion = useSetAtom(iconThemeVersionAtom);
31+
const setActiveThemeState = useSetAtom(activeIconThemeStateAtom);
3532

3633
return {
3734
setIconTheme: async (type: IconThemeType, path?: string): Promise<void> => {
38-
noneTheme.clear();
39-
fssTheme.clear();
40-
vscodeTheme.clear();
41-
4235
if (type === "vscode" && path) {
36+
const adapter = new VSCodeIconThemeAdapter(bridge);
4337
try {
44-
await vscodeTheme.load(path);
45-
setActiveTheme(vscodeTheme);
46-
bumpThemeVersion((v) => v + 1);
38+
await adapter.load(path);
39+
setActiveThemeState((current) => {
40+
current.adapter.clear();
41+
adapter.setThemeKind?.(current.kind);
42+
return {
43+
adapter,
44+
kind: current.kind,
45+
type: "vscode",
46+
};
47+
});
4748
} catch {
48-
setActiveTheme(noneTheme);
49-
bumpThemeVersion((v) => v + 1);
49+
setActiveThemeState((current) => {
50+
current.adapter.clear();
51+
return {
52+
adapter: new NoneIconThemeAdapter(),
53+
kind: current.kind,
54+
type: "none",
55+
};
56+
});
5057
}
5158
return;
5259
}
5360

54-
const nextTheme = type === "fss" ? fssTheme : noneTheme;
55-
setActiveTheme(nextTheme);
56-
bumpThemeVersion((v) => v + 1);
61+
setActiveThemeState((current) => {
62+
current.adapter.clear();
63+
const adapter: IconThemeAdapter = type === "fss" ? new FssIconThemeAdapter() : new NoneIconThemeAdapter();
64+
adapter.setThemeKind?.(current.kind);
65+
return {
66+
adapter,
67+
kind: current.kind,
68+
type,
69+
};
70+
});
5771
},
5872
};
5973
}
6074

6175
export function useSetIconThemeKind() {
62-
const activeTheme = useAtomValue(activeIconThemeAdapterAtom);
63-
const bumpThemeVersion = useSetAtom(iconThemeVersionAtom);
76+
const setActiveThemeState = useSetAtom(activeIconThemeStateAtom);
6477
return {
6578
setIconThemeKind: (kind: "dark" | "light"): void => {
66-
activeTheme.setThemeKind?.(kind);
67-
bumpThemeVersion((v) => v + 1);
79+
setActiveThemeState((current) => {
80+
current.adapter.setThemeKind?.(kind);
81+
return {
82+
...current,
83+
};
84+
});
6885
},
6986
};
7087
}
7188

7289
export function useIconThemeType(): IconThemeType {
73-
return useAtomValue(activeIconThemeAdapterAtom).kind;
74-
}
75-
76-
export function useIconThemeVersion(): number {
77-
return useAtomValue(iconThemeVersionAtom);
90+
return useAtomValue(activeIconThemeStateAtom).type;
7891
}
7992

8093
export interface ResolvedIcon {
@@ -90,7 +103,7 @@ export interface ResolvedIcon {
90103
* Returns either an image icon or a font icon plus fallback metadata.
91104
*/
92105
export function useResolveIcon() {
93-
const activeTheme = useAtomValue(activeIconThemeAdapterAtom);
106+
const { adapter: activeTheme } = useAtomValue(activeIconThemeStateAtom);
94107
const iconAssets = useIconAssetStore();
95108

96109
return useCallback(
@@ -143,7 +156,7 @@ export function useResolveIcon() {
143156
* Load any image assets and ensure any font families are ready.
144157
*/
145158
export function useLoadIconsForPaths() {
146-
const activeTheme = useAtomValue(activeIconThemeAdapterAtom);
159+
const { adapter: activeTheme } = useAtomValue(activeIconThemeStateAtom);
147160
const iconAssets = useIconAssetStore();
148161
return useCallback(
149162
async (icons: ResolvedThemeIcon[]): Promise<void> => {

packages/ui/lib/features/fss/fileStyleResolver.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { iconThemeVersionAtom, systemThemeAtom } from "@/atoms";
1+
import { systemThemeAtom } from "@/atoms";
22
import { useBridge } from "@/features/bridge/useBridge";
33
import { FileSystemObserver, useFileSystemWatchRegistry, type FileSystemChangeRecord } from "@/features/file-system/fs";
44
import type { FilePresentation } from "@/features/fss/types";
@@ -90,7 +90,6 @@ export function FileStyleResolverProvider({ path, pathKind = "directory", childr
9090
const watchRegistry = useFileSystemWatchRegistry();
9191
const extensionLayers = useExtensionFssLayers();
9292
const theme = useAtomValue(systemThemeAtom);
93-
const iconThemeVersion = useAtomValue(iconThemeVersionAtom);
9493
const resolveIcon = useResolveIcon();
9594
const resolverRef = useRef(createPanelResolver(theme));
9695
const currentDirPathRef = useRef("");
@@ -119,7 +118,7 @@ export function FileStyleResolverProvider({ path, pathKind = "directory", childr
119118

120119
useEffect(() => {
121120
void syncCurrentLayers();
122-
}, [syncCurrentLayers, iconThemeVersion]);
121+
}, [resolveIcon, syncCurrentLayers]);
123122

124123
useEffect(() => {
125124
const handleRecords = (records: FileSystemChangeRecord[]) => {

0 commit comments

Comments
 (0)