Skip to content

Shared color scope: reuse type/track colors across datasets#1796

Open
mattdawkins wants to merge 1 commit into
mainfrom
feat/persistent-user-type-colors
Open

Shared color scope: reuse type/track colors across datasets#1796
mattdawkins wants to merge 1 commit into
mainfrom
feat/persistent-user-type-colors

Conversation

@mattdawkins

Copy link
Copy Markdown
Member

Summary

Type/track/group color and style overrides were stored only in the metadata of the dataset they were set on (customTypeStyling / customGroupStyling). The same class could therefore render a different color in every sequence, and a color a user picked never followed them to the next dataset.

This adds a Type color scope user setting (User Settings dialog) with two modes:

  • Shared across all data (default) — one set of color/style overrides is reused across every dataset.
    • Desktop (no user accounts): stored once per data directory in global_style_settings.json, shared across all sequences.
    • Web: scoped to the current user/browser via localStorage, consistent with how the web client already persists user preferences (clientSettings).
    • On dataset open, the shared styles overlay the dataset's own styling (shared wins on conflicts); any style the user edits is mirrored back to the shared store; and colors that ride in with a dataset seed the shared store (without overwriting existing shared choices) so imported colors propagate to future sequences.
  • Per dataset — the original behavior; colors are saved only with the dataset they were set on.

The default is shared, so out of the box a color set once is reused everywhere. Choosing Per dataset reproduces today's exact behavior (the shared paths become no-ops).

Changes

  • dive-common/store/settings.ts — new typeSettings.colorScope: 'shared' | 'dataset' (default 'shared'; hydrates onto existing stored settings).
  • dive-common/components/UserSettingsDialog.vue — a "Type color scope" select.
  • src/StyleManager.ts — optional onStyleEdit hook, fired on updateTypeStyle (genuine edits only, not on dataset load).
  • dive-common/components/Viewer.vue — loads/overlays/seeds the shared store on dataset open and persists edits (debounced).
  • dive-common/apispec.ts — new GlobalStyleSettings type and optional loadGlobalStyleSettings / saveGlobalStyleSettings Api methods.
  • Desktop: backend/native/globalStyles.ts (file read/write under settings.dataPath, degrades to empty on missing/corrupt), IPC handlers, and frontend api wrappers.
  • Web: localStorage-backed implementation in web-girder/api/dataset.service.ts, wired into provideApi.

Test plan

  • vitest run platform/desktop/backend/native/globalStyles.spec.ts → 6 passed (round-trip, missing dir, corrupt file, normalization).
  • vitest run src/StyleManager.spec.ts → passed (optional hook is additive).
  • eslint on all changed files → clean.
  • electron-vite build (desktop backend + renderer) and vite build (web) → both succeed.

Notes

  • Web persistence is per-user-per-browser (localStorage), not cross-device — there is no per-user server settings blob today, and adding one would need a new Girder route. This keeps the change client-only; a server-backed per-user store can be a follow-up.
  • Group styling is included alongside type styling for completeness.

Type/track/group color and style overrides were saved only with the
dataset they were set on, so the same class could render a different
color in every sequence. Add a "Type color scope" user setting with two
modes:

- shared (default): one set of color/style overrides is reused across
  every dataset. On desktop it is stored once per data directory
  (global_style_settings.json) and shared across all sequences; on web
  it is scoped to the current user/browser (localStorage). When a
  dataset opens, the shared styles overlay the dataset's own styling
  (shared wins on conflicts), any color the user edits is mirrored back
  to the shared store, and colors imported with a dataset seed the
  shared store so they propagate to future sequences.
- dataset: the original behavior, colors are saved only with their
  dataset.

Wiring: StyleManager gains an onStyleEdit hook fired on user edits;
Viewer overlays/seeds/persists the shared store; a new optional
loadGlobalStyleSettings/saveGlobalStyleSettings pair on the Api is
implemented by both the desktop backend (file under the data dir) and
the web client (localStorage). Backend read/write is unit tested.
@mattdawkins
mattdawkins requested a review from BryonLewis July 23, 2026 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant