feat(comparisonStore): replace displayStore with comparisonStore that has only the logic related to ComparisonSlider

This commit is contained in:
Ilia Mashkov
2026-02-02 11:58:50 +03:00
parent d43c873dc9
commit 70f57283a8
4 changed files with 150 additions and 63 deletions

View File

@@ -1 +0,0 @@
export { displayedFontsStore } from './store';

View File

@@ -1,61 +0,0 @@
import {
type UnifiedFont,
selectedFontsStore,
} from '$entities/Font';
/**
* Store for displayed font samples
* - Handles shown text
* - Stores selected fonts for display
*/
export class DisplayedFontsStore {
#sampleText = $state('The quick brown fox jumps over the lazy dog');
#displayedFonts = $derived.by(() => {
return selectedFontsStore.all;
});
#fontA = $state<UnifiedFont | undefined>(undefined);
#fontB = $state<UnifiedFont | undefined>(undefined);
#hasAnySelectedFonts = $derived(this.#displayedFonts.length > 0);
get fonts() {
return this.#displayedFonts;
}
get fontA() {
return this.#fontA ?? this.#displayedFonts[0];
}
set fontA(font: UnifiedFont | undefined) {
this.#fontA = font;
}
get fontB() {
return this.#fontB ?? this.#displayedFonts[1];
}
set fontB(font: UnifiedFont | undefined) {
this.#fontB = font;
}
get text() {
return this.#sampleText;
}
set text(text: string) {
this.#sampleText = text;
}
get hasAnyFonts() {
return this.#hasAnySelectedFonts;
}
getById(id: string): UnifiedFont | undefined {
return selectedFontsStore.getById(id);
}
}
export const displayedFontsStore = new DisplayedFontsStore();

View File

@@ -1 +0,0 @@
export { displayedFontsStore } from './displayedFontsStore.svelte';

View File

@@ -0,0 +1,150 @@
import {
type UnifiedFont,
fetchFontsByIds,
unifiedFontStore,
} from '$entities/Font';
import { createPersistentStore } from '$shared/lib';
/**
* Storage schema for comparison state
*/
interface ComparisonState {
fontAId: string | null;
fontBId: string | null;
}
// Persistent storage for selected comparison fonts
const storage = createPersistentStore<ComparisonState>('glyphdiff:comparison', {
fontAId: null,
fontBId: null,
});
/**
* Store for managing font comparison state
* - Persists selection to localStorage
* - Handles font fetching on initialization
* - Manages sample text
*/
class ComparisonStore {
#fontA = $state<UnifiedFont | undefined>();
#fontB = $state<UnifiedFont | undefined>();
#sampleText = $state('The quick brown fox jumps over the lazy dog');
#isRestoring = $state(true);
constructor() {
this.restoreFromStorage();
// Reactively set defaults if we aren't restoring and have no selection
$effect.root(() => {
$effect(() => {
// Wait until we are done checking storage
if (this.#isRestoring) {
return;
}
// If we already have a selection, do nothing
if (this.#fontA && this.#fontB) {
return;
}
// Check if fonts are available to set as defaults
const fonts = unifiedFontStore.fonts;
if (fonts.length >= 2) {
// Only set if we really have nothing (fallback)
if (!this.#fontA) this.#fontA = fonts[0];
if (!this.#fontB) this.#fontB = fonts[fonts.length - 1];
// Sync defaults to storage so they persist if the user leaves
this.updateStorage();
}
});
});
}
/**
* Restore state from persistent storage
*/
async restoreFromStorage() {
this.#isRestoring = true;
const { fontAId, fontBId } = storage.value;
if (fontAId && fontBId) {
try {
// Batch fetch the saved fonts
const fonts = await fetchFontsByIds([fontAId, fontBId]);
const loadedFontA = fonts.find((f: UnifiedFont) => f.id === fontAId);
const loadedFontB = fonts.find((f: UnifiedFont) => f.id === fontBId);
if (loadedFontA && loadedFontB) {
this.#fontA = loadedFontA;
this.#fontB = loadedFontB;
}
} catch (error) {
console.warn('[ComparisonStore] Failed to restore fonts:', error);
}
}
// Mark restoration as complete (whether success or fail)
this.#isRestoring = false;
}
/**
* Update storage with current state
*/
private updateStorage() {
// Don't save if we are currently restoring (avoid race)
if (this.#isRestoring) return;
storage.value = {
fontAId: this.#fontA?.id ?? null,
fontBId: this.#fontB?.id ?? null,
};
}
// --- Getters & Setters ---
get fontA() {
return this.#fontA;
}
set fontA(font: UnifiedFont | undefined) {
this.#fontA = font;
this.updateStorage();
}
get fontB() {
return this.#fontB;
}
set fontB(font: UnifiedFont | undefined) {
this.#fontB = font;
this.updateStorage();
}
get text() {
return this.#sampleText;
}
set text(value: string) {
this.#sampleText = value;
}
/**
* Check if both fonts are selected
*/
get isReady() {
return !!this.#fontA && !!this.#fontB;
}
/**
* Public initializer (optional, as constructor starts it)
* Kept for compatibility if manual re-init is needed
*/
initialize() {
if (!this.#isRestoring && !this.#fontA && !this.#fontB) {
this.restoreFromStorage();
}
}
}
export const comparisonStore = new ComparisonStore();