fix: apply game order to dailies and routines

Account creation order leaked into daily rows and routine groups even when the reader had arranged their games. Apply the shared display rule while preserving each game's server and task order.
This commit is contained in:
Lucas Winther committed 2026-11-02 03:35:32 +01:00
1 parent 2056630f67
commit dd5d374422
8 files changed
+74 -8

No files matched your search

+3 -3
View File
@@ -52,7 +52,7 @@ import {
import { metaFor } from "../shared/games.ts";
import { readGoal } from "../shared/goal.ts";
import { isDaily, resolveDaily } from "../shared/daily.ts";
import { orderGames } from "./state/gameOrder.ts";
import { orderGameItems, orderGames } from "./state/gameOrder.ts";
import { advanceFocus } from "./state/lens.ts";
import { restorePrefsValue } from "./state/usePrefs.ts";
import { readableAmounts } from "./state/useAmounts.ts";
@@ -532,12 +532,12 @@ function ReaderContent({
setSettingsPage(next);
setPage("settings");
};
const accounts = Object.values(state.accounts).filter(
const accounts = orderGameItems(Object.values(state.accounts).filter(
(a) =>
!a.retiredAt &&
!prefs.hiddenGames.includes(a.game) &&
(a.intent.events || Object.values(a.routines).some((r) => r.followed)),
);
), prefs.gameOrder, (game) => meta(game).name);
const ordered = orderGames(
[...new Set(accounts.map((a) => a.game))],
prefs.gameOrder,
@@ -1,4 +1,5 @@
import { useGameMeta } from "../../state/gameMeta.tsx";
import { orderGameItems } from "../../state/gameOrder.ts";
import { serverSuffix } from "../../state/reader/servers.ts";
import type { CSSProperties } from "react";
import { useEffect, useRef, useState } from "react";
@@ -193,6 +194,11 @@ export function DailyPanel({
now: number;
}) {
const meta = useGameMeta();
rows = orderGameItems(
rows,
Array.isArray(state.prefs.gameOrder) ? state.prefs.gameOrder as string[] : undefined,
(game) => meta(game).name,
);
const total = rows.length;
const done = rows.filter((r) =>
doneToday(r, readerDayKey(now, r.clock)),
@@ -2,6 +2,7 @@ import { routinePeriod } from "./TimelinePage.tsx";
import { manyServers, serverSuffix } from "../../state/reader/servers.ts";
import { formatRemaining } from "../../../shared/time.ts";
import { useGameMeta } from "../../state/gameMeta.tsx";
import { orderGameItems } from "../../state/gameOrder.ts";
import type { CSSProperties } from "react";
import { RoutineHistory } from "./RoutineHistory.tsx";
import { useState } from "react";
@@ -120,14 +121,15 @@ export function RoutinesPage({
setEditing(task);
setDrawer(pane);
};
const accounts = Object.values(state.accounts).filter(
const accounts = orderGameItems(Object.values(state.accounts).filter(
(a) =>
!a.retiredAt &&
!(
Array.isArray(state.prefs.hiddenGames) &&
state.prefs.hiddenGames.includes(a.game)
),
);
), Array.isArray(state.prefs.gameOrder) ? state.prefs.gameOrder as string[] : undefined,
(game) => meta(game).name);
const save = async (draft: TaskDraft, placement: CreatePlacement) => {
const at = new Date().toISOString(),
id = editing ? editing.id : mintTaskId();
+10
View File
@@ -64,6 +64,16 @@ export function orderGames(
return [...placed, ...alphabetical(lanes.filter((id) => !seen.has(id)))];
}
/** Apply the same display order to accounts or tasks, keeping ties stable. */
export function orderGameItems<T extends { game: LaneId }>(
items: readonly T[],
stored: readonly LaneId[] | undefined,
nameOf: (id: LaneId) => string,
): T[] {
const games = orderGames([...new Set(items.map((item) => item.game))], stored, nameOf);
return [...items].sort((a, b) => games.indexOf(a.game) - games.indexOf(b.game));
}
/**
* Move one entry, shifting the rest.
*