fix(settings): name descending size sort explicitly
The library sort setting used `size` for largest-first sorting while the ascending option used `sizeAsc`. That made the pair asymmetric and left the current settings model carrying a legacy-looking key. Rename the current descending key to `sizeDesc` in the type, menu, and sort logic. Stored `size` values are normalized to `sizeDesc` on read, so existing users keep the same largest-first behavior while new writes use the explicit key. Test Plan: - deno task build - RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= just build - git diff --check Refs: local review feedback
This commit is contained in:
@@ -5,7 +5,7 @@ import { GameSort } from '../../lib/types';
|
|||||||
|
|
||||||
const OPTIONS: ReadonlyArray<{ key: GameSort; label: string }> = [
|
const OPTIONS: ReadonlyArray<{ key: GameSort; label: string }> = [
|
||||||
{ key: 'az', label: 'Name (A–Z)' },
|
{ key: 'az', label: 'Name (A–Z)' },
|
||||||
{ key: 'size', label: 'Size (largest)' },
|
{ key: 'sizeDesc', label: 'Size (largest)' },
|
||||||
{ key: 'sizeAsc', label: 'Size (smallest)' },
|
{ key: 'sizeAsc', label: 'Size (smallest)' },
|
||||||
{ key: 'status', label: 'Status' },
|
{ key: 'status', label: 'Status' },
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ export interface UISettings {
|
|||||||
filter: GameFilter;
|
filter: GameFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StoredGameSort = GameSort | 'size';
|
||||||
|
type StoredUISettings = Partial<Omit<UISettings, 'sort'> & { sort: StoredGameSort }>;
|
||||||
|
|
||||||
export const ACCENT_OPTIONS = [
|
export const ACCENT_OPTIONS = [
|
||||||
{ value: '#3b82f6', label: 'Blue' },
|
{ value: '#3b82f6', label: 'Blue' },
|
||||||
{ value: '#22d3ee', label: 'Cyan' },
|
{ value: '#22d3ee', label: 'Cyan' },
|
||||||
@@ -53,15 +56,19 @@ export const DEFAULT_SETTINGS: UISettings = {
|
|||||||
filter: 'local',
|
filter: 'local',
|
||||||
};
|
};
|
||||||
|
|
||||||
const sanitize = (raw: Partial<UISettings> | undefined): UISettings => ({
|
const sanitize = (raw: StoredUISettings | undefined): UISettings => ({
|
||||||
accent: raw?.accent ?? DEFAULT_SETTINGS.accent,
|
accent: raw?.accent ?? DEFAULT_SETTINGS.accent,
|
||||||
bg: raw?.bg ?? DEFAULT_SETTINGS.bg,
|
bg: raw?.bg ?? DEFAULT_SETTINGS.bg,
|
||||||
density: raw?.density ?? DEFAULT_SETTINGS.density,
|
density: raw?.density ?? DEFAULT_SETTINGS.density,
|
||||||
aspect: raw?.aspect ?? DEFAULT_SETTINGS.aspect,
|
aspect: raw?.aspect ?? DEFAULT_SETTINGS.aspect,
|
||||||
sort: raw?.sort ?? DEFAULT_SETTINGS.sort,
|
sort: sanitizeSort(raw?.sort),
|
||||||
filter: raw?.filter ?? DEFAULT_SETTINGS.filter,
|
filter: raw?.filter ?? DEFAULT_SETTINGS.filter,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const sanitizeSort = (sort: StoredGameSort | undefined): GameSort => (
|
||||||
|
sort === 'size' ? 'sizeDesc' : sort ?? DEFAULT_SETTINGS.sort
|
||||||
|
);
|
||||||
|
|
||||||
export interface UseSettings {
|
export interface UseSettings {
|
||||||
settings: UISettings;
|
settings: UISettings;
|
||||||
set: <K extends keyof UISettings>(key: K, value: UISettings[K]) => void;
|
set: <K extends keyof UISettings>(key: K, value: UISettings[K]) => void;
|
||||||
@@ -82,7 +89,7 @@ export const useSettings = (): UseSettings => {
|
|||||||
const init = async () => {
|
const init = async () => {
|
||||||
try {
|
try {
|
||||||
const store = await load(SETTINGS_FILE, SETTINGS_FILE_OPTIONS);
|
const store = await load(SETTINGS_FILE, SETTINGS_FILE_OPTIONS);
|
||||||
const saved = await store.get<Partial<UISettings>>(UI_SETTINGS_KEY);
|
const saved = await store.get<StoredUISettings>(UI_SETTINGS_KEY);
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
setSettings(sanitize(saved ?? undefined));
|
setSettings(sanitize(saved ?? undefined));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ export const applyFilterAndSort = (
|
|||||||
switch (sort) {
|
switch (sort) {
|
||||||
case 'az':
|
case 'az':
|
||||||
return [...list].sort((a, b) => a.name.localeCompare(b.name));
|
return [...list].sort((a, b) => a.name.localeCompare(b.name));
|
||||||
case 'size':
|
case 'sizeDesc':
|
||||||
return [...list].sort((a, b) => b.size - a.size);
|
return [...list].sort((a, b) => b.size - a.size);
|
||||||
case 'sizeAsc':
|
case 'sizeAsc':
|
||||||
return [...list].sort((a, b) => a.size - b.size);
|
return [...list].sort((a, b) => a.size - b.size);
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ export interface GamesListPayload {
|
|||||||
export type GameFilter = 'all' | 'local' | 'installed';
|
export type GameFilter = 'all' | 'local' | 'installed';
|
||||||
|
|
||||||
/** Library sort order. */
|
/** Library sort order. */
|
||||||
export type GameSort = 'az' | 'size' | 'sizeAsc' | 'status';
|
export type GameSort = 'az' | 'sizeDesc' | 'sizeAsc' | 'status';
|
||||||
|
|
||||||
/** Visual state of a card. Derived from install/download flags. */
|
/** Visual state of a card. Derived from install/download flags. */
|
||||||
export type DerivedState = 'installed' | 'local' | 'none' | 'busy';
|
export type DerivedState = 'installed' | 'local' | 'none' | 'busy';
|
||||||
|
|||||||
Reference in New Issue
Block a user