mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-14 00:01:03 +00:00
fix(native): the widgets show the trip the dashboard features
With several trips running at once, the widgets took whichever came first on the device, so an old test trip spanning today pushed out the journey under way, and the today widget counted its days. The dashboard's choice moves to utils/heroTrip.ts (running first, earliest start, else the next to come) and the widgets ask the same function, so the home screen always shows the trip the app opens on.
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { heroTrip, sortTripsByRelevance } from './heroTrip';
|
||||
|
||||
const trip = (id: number, start_date: string | null, end_date: string | null) => ({ id, start_date, end_date });
|
||||
|
||||
describe('heroTrip', () => {
|
||||
const today = '2026-11-06';
|
||||
const trips = [
|
||||
trip(1, '2026-01-01', '2026-01-05'),
|
||||
trip(2, '2026-12-01', '2026-12-05'),
|
||||
trip(3, '2026-11-04', '2026-11-12'),
|
||||
trip(4, '2026-10-20', '2026-11-18'),
|
||||
trip(5, null, null),
|
||||
];
|
||||
|
||||
it('orders running trips first, then the ones coming up, then the rest, latest first', () => {
|
||||
expect(sortTripsByRelevance(trips, today).map((t) => t.id)).toEqual([4, 3, 2, 1, 5]);
|
||||
});
|
||||
|
||||
it('features the running trip that started first, else the next to come', () => {
|
||||
expect(heroTrip(sortTripsByRelevance(trips, today), today)?.id).toBe(4);
|
||||
expect(heroTrip(sortTripsByRelevance([trips[0], trips[1]], today), today)?.id).toBe(2);
|
||||
expect(heroTrip(sortTripsByRelevance([trips[0], trips[4]], today), today)).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Which trip the dashboard features, in one place: the dashboard's hero and
|
||||
* the iOS widgets (native/widgets.ts) both ask here, so the trip on the home
|
||||
* screen is always the one the app opens on.
|
||||
*/
|
||||
interface DatedTrip {
|
||||
start_date?: string | null;
|
||||
end_date?: string | null;
|
||||
}
|
||||
|
||||
/** 0 running, 1 coming up, 2 past or undated. */
|
||||
function rank(trip: DatedTrip, today: string): number {
|
||||
if (trip.start_date && trip.end_date && trip.start_date <= today && trip.end_date >= today) return 0;
|
||||
if (trip.start_date && trip.start_date >= today) return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/** Running trips first, then the ones coming up, both soonest first; the rest latest first. */
|
||||
export function sortTripsByRelevance<T extends DatedTrip>(trips: T[], today: string): T[] {
|
||||
return [...trips].sort((a, b) => {
|
||||
const ra = rank(a, today);
|
||||
const rb = rank(b, today);
|
||||
if (ra !== rb) return ra - rb;
|
||||
const ad = a.start_date || '';
|
||||
const bd = b.start_date || '';
|
||||
if (ra <= 1) return ad.localeCompare(bd);
|
||||
return bd.localeCompare(ad);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The trip the hero features on its own merit: the first running one in that
|
||||
* order, else the first coming up; null when every trip is past or undated.
|
||||
*/
|
||||
export function heroTrip<T extends DatedTrip>(sorted: T[], today: string): T | null {
|
||||
return sorted.find((t) => rank(t, today) === 0) || sorted.find((t) => rank(t, today) === 1) || null;
|
||||
}
|
||||
Reference in New Issue
Block a user