66 lines
1.8 KiB
TypeScript
66 lines
1.8 KiB
TypeScript
import type { TravelTimeEntry } from '../hooks/useTravelTime';
|
|
|
|
function mergeTimeRanges(
|
|
current: [number, number] | null,
|
|
next: [number, number] | null
|
|
): [number, number] | null {
|
|
if (!current) return next;
|
|
if (!next) return current;
|
|
return [Math.max(current[0], next[0]), Math.min(current[1], next[1])];
|
|
}
|
|
|
|
export function dedupeTravelTimeEntries(entries: TravelTimeEntry[]): TravelTimeEntry[] {
|
|
const result: TravelTimeEntry[] = [];
|
|
const indexByKey = new Map<string, number>();
|
|
|
|
for (const entry of entries) {
|
|
if (!entry.slug) {
|
|
result.push(entry);
|
|
continue;
|
|
}
|
|
|
|
const key = `${entry.mode}:${entry.slug}`;
|
|
const existingIndex = indexByKey.get(key);
|
|
if (existingIndex == null) {
|
|
indexByKey.set(key, result.length);
|
|
result.push({ ...entry });
|
|
continue;
|
|
}
|
|
|
|
const existing = result[existingIndex];
|
|
result[existingIndex] = {
|
|
...existing,
|
|
label: existing.label || entry.label,
|
|
timeRange: mergeTimeRanges(existing.timeRange, entry.timeRange),
|
|
useBest: existing.useBest || entry.useBest,
|
|
};
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
export function buildTravelParam(
|
|
entries: TravelTimeEntry[],
|
|
excludeFieldKey?: string,
|
|
includeUnboundedExcludedRange = false
|
|
): string {
|
|
const segments: string[] = [];
|
|
|
|
for (const entry of dedupeTravelTimeEntries(entries)) {
|
|
if (!entry.slug) continue;
|
|
|
|
let segment = `${entry.mode}:${entry.slug}`;
|
|
if (entry.useBest) segment += ':best';
|
|
|
|
const isExcluded = excludeFieldKey === `tt_${entry.mode}_${entry.slug}`;
|
|
if (isExcluded && includeUnboundedExcludedRange) {
|
|
segment += ':0:1440';
|
|
} else if (!isExcluded && entry.timeRange) {
|
|
segment += `:${entry.timeRange[0]}:${entry.timeRange[1]}`;
|
|
}
|
|
|
|
segments.push(segment);
|
|
}
|
|
|
|
return segments.join('|');
|
|
}
|