Merge the file-icon theme shell from #594 (feat/file-icon-theme)

Brings in the theme plumbing around #531's API — the `fileIconTheme` pref
thread, the settings row, the 20 dictionaries' keys and the theme loader's
test — so the working tree is a complete, green starting point before the
colored implementation is replaced.

Conflicts (three; resolved by taking this line's side where it had moved on):

- src/client/service.ts: the import block keeps `baseName, extOf` (the
  `isNarrowWidth` import the theme branch needed belongs to its own
  fresh-session seeding, which main has since rewritten) and the feature-list
  doc comment keeps main's "v0.19.0 REMOVED 'floatWindows'" note while
  adopting the sharper `fileIcons` wording (matched by exts / names /
  folderNames).
- tests/plugin-shape.spec.ts and tests/prefs.spec.ts: main DELETED the store
  seeding tests these files used to hold and rewrote the schema assertions
  (the `SIDEBAR_PREFS_DEFAULTS` destructuring), so this line's side wins —
  the theme branch's re-added blocks describe behaviour main no longer has.

Next commit removes `fileIconTheme` again along with the 563-entry dataset and
its lazy chunk: DSH 0.1.5-rc.2 exports the official `FileTypeIcon` artwork, so
the plugin renders the host's icons instead of shipping its own color table.
This commit is contained in:
Menghuan1918
2026-09-11 15:14:47 +08:00
42 changed files with 1464 additions and 72 deletions
+16
View File
@@ -24,6 +24,7 @@ import { registerBottomToggle } from './sidebar/bottom-toggle.tsx'
import { createNativeSurface } from './native/surface.ts'
import { registerLinkInterception } from './link-intercept.ts'
import { registerImeGuard } from './ime-guard.ts'
import { createFileIconThemeLoader } from './file-icon-theme.ts'
import { registerSettingsNavIcon } from './settings-nav-icon.ts'
import { loadBootDecision } from './prefs.ts'
import { SideCardSection } from './SideCardSection.tsx'
@@ -188,6 +189,21 @@ export function apply(ctx: Context): void {
() => registerBuiltins(ctx, service, { terminalTitle: () => terminalTitle }),
'dsh-better-sidebar: register built-in tabs and viewers',
)
// Optional colored file-icon theme: the `fileIconTheme` pref decides whether
// the lazy `file-icons` chunk is fetched and its dataset registered through
// `registerFileIcon`. The loader reacts to prefs writes and is disposed with
// the fiber (HMR-safe); 'builtin' (the default) keeps the startup path free
// of icon data.
ctx.effect(() => {
const loader = createFileIconThemeLoader(service)
const sync = (): void => { loader.set(sidebarStore.getPrefs().fileIconTheme) }
sync()
const unsubscribe = service.subscribeState(sync)
return () => {
unsubscribe()
loader.dispose()
}
}, 'dsh-better-sidebar: colored file-icon theme')
// A failure anywhere in the client lifecycle must never take the app down
// silently: log with the plugin prefix and pin a visible diagnostic strip
// to the page so a blank panel is never the only symptom. This strip is