fix: improve moments clustering
This commit is contained in:
84
apps/web/app/lib/moments.ts
Normal file
84
apps/web/app/lib/moments.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
export type MomentAsset = {
|
||||
id: string;
|
||||
capture_ts_utc: string;
|
||||
};
|
||||
|
||||
export type MomentCluster = {
|
||||
day: string;
|
||||
start: string;
|
||||
end: string;
|
||||
count: number;
|
||||
assets: MomentAsset[];
|
||||
};
|
||||
|
||||
const MOMENT_WINDOW_MINUTES = 30;
|
||||
const MOMENT_WINDOW_MS = MOMENT_WINDOW_MINUTES * 60 * 1000;
|
||||
|
||||
function dayKeyFromIso(iso: string) {
|
||||
const d = new Date(iso);
|
||||
const yyyy = d.getUTCFullYear();
|
||||
const mm = String(d.getUTCMonth() + 1).padStart(2, "0");
|
||||
const dd = String(d.getUTCDate()).padStart(2, "0");
|
||||
return `${yyyy}-${mm}-${dd}`;
|
||||
}
|
||||
|
||||
export function clusterMoments(input: MomentAsset[]): MomentCluster[] {
|
||||
const byDay = new Map<string, MomentAsset[]>();
|
||||
|
||||
for (const asset of input) {
|
||||
if (!asset.capture_ts_utc) continue;
|
||||
const key = dayKeyFromIso(asset.capture_ts_utc);
|
||||
const list = byDay.get(key);
|
||||
if (list) list.push(asset);
|
||||
else byDay.set(key, [asset]);
|
||||
}
|
||||
|
||||
const clusters: MomentCluster[] = [];
|
||||
|
||||
for (const [day, assets] of byDay) {
|
||||
const sorted = [...assets].sort((a, b) =>
|
||||
a.capture_ts_utc.localeCompare(b.capture_ts_utc),
|
||||
);
|
||||
|
||||
let current: MomentAsset[] = [];
|
||||
let lastTs: number | null = null;
|
||||
|
||||
for (const asset of sorted) {
|
||||
const ts = new Date(asset.capture_ts_utc).getTime();
|
||||
if (!Number.isFinite(ts)) continue;
|
||||
|
||||
if (lastTs === null || ts - lastTs <= MOMENT_WINDOW_MS) {
|
||||
current.push(asset);
|
||||
} else {
|
||||
const start = current[0]?.capture_ts_utc;
|
||||
const end = current[current.length - 1]?.capture_ts_utc;
|
||||
if (start && end) {
|
||||
clusters.push({
|
||||
day,
|
||||
start,
|
||||
end,
|
||||
count: current.length,
|
||||
assets: current,
|
||||
});
|
||||
}
|
||||
current = [asset];
|
||||
}
|
||||
|
||||
lastTs = ts;
|
||||
}
|
||||
|
||||
if (current.length) {
|
||||
const start = current[0].capture_ts_utc;
|
||||
const end = current[current.length - 1].capture_ts_utc;
|
||||
clusters.push({
|
||||
day,
|
||||
start,
|
||||
end,
|
||||
count: current.length,
|
||||
assets: current,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return clusters;
|
||||
}
|
||||
Reference in New Issue
Block a user