Skip to content
Source
Sign inSign up
Open History to see the last commit

SnoozePresetsSettings.logic.ts

40 lines1.5 KB

1import type { SnoozePresetSetting } from "@t3tools/contracts/settings";
2import { resolveSnoozePreset } from "@t3tools/client-runtime/state/thread-settled";
3import * as Equal from "effect/Equal";
4​
5/**
6 * Reads a server value against the editor's writes still in flight. Matching one acknowledges
7 * it and every earlier write; anything else came from elsewhere and replaces the draft.
8 */
9export function reconcileSnoozeDraft<T>(
10 pending: ReadonlyArray<T>,
11 saved: T,
12): { readonly adopt: true } | { readonly adopt: false; readonly pending: ReadonlyArray<T> } {
13 const acknowledged = pending.findIndex((snapshot) => Equal.equals(snapshot, saved));
14 return acknowledged === -1
15 ? { adopt: true }
16 : { adopt: false, pending: pending.slice(acknowledged + 1) };
18​
19/**
20 * Orders editor rows the way the menu lists them: soonest wake first, with options that
21 * have no wake right now (a passed "Today") last. Ties keep their current order.
22 */
23export function sortSnoozeRows<K>(
24 presets: ReadonlyArray<SnoozePresetSetting>,
25 keys: ReadonlyArray<K>,
26 now: Date,
27): { readonly presets: ReadonlyArray<SnoozePresetSetting>; readonly keys: ReadonlyArray<K> } {
28 const order = presets
29 .map((preset, index) => ({
30 index,
31 wake: resolveSnoozePreset(preset, now)?.snoozedUntil ?? null,
32 }))
33 .toSorted((a, b) =>
34 a.wake === b.wake ? 0 : a.wake === null ? 1 : b.wake === null ? -1 : a.wake < b.wake ? -1 : 1,
35 );
36 return {
37 presets: order.map(({ index }) => presets[index]!),
38 keys: order.map(({ index }) => keys[index]!),
39 };