mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 15:51:00 +00:00
fix(native): show the travel day's Live Activity from three hours before its first stop
The Live Activity started with the first sync of a travel day and stayed on the lock screen all day, so a day whose first stop is an evening flight held it from the early morning on. It now appears three hours before the day's first timed stop and stays until the day is done; liveDayDue() decides.
This commit is contained in:
@@ -20,6 +20,7 @@ import { widgetCover, widgetWeather } from '../../native/widgetMedia';
|
||||
import { atlasSummary, collabSummary, packingDetail, type WidgetAtlas } from '../../native/widgetOnline';
|
||||
import {
|
||||
buildSnapshot,
|
||||
liveDayDue,
|
||||
pickTrip,
|
||||
publishWidgets,
|
||||
todayOf,
|
||||
@@ -207,9 +208,10 @@ export default function NativeWidgetsSync(): null {
|
||||
});
|
||||
}
|
||||
if (cancelled) return;
|
||||
const live = main.day
|
||||
? tripDayState(main.day, now.getHours() * 60 + now.getMinutes(), t('native.widget.dayDone'))
|
||||
: null;
|
||||
// The Live Activity from three hours before the day's first timed stop, not all day long.
|
||||
const minutes = now.getHours() * 60 + now.getMinutes();
|
||||
const live =
|
||||
main.day && liveDayDue(main.day, minutes) ? tripDayState(main.day, minutes, t('native.widget.dayDone')) : null;
|
||||
await publishWidgets(main.snapshot, live, choices);
|
||||
await publishToWatch(hero, main, today);
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ vi.mock('./trekShell', () => ({
|
||||
import { TrekShell } from './trekShell';
|
||||
import {
|
||||
buildSnapshot,
|
||||
liveDayDue,
|
||||
pickTrip,
|
||||
publishWidgets,
|
||||
todayOf,
|
||||
@@ -151,6 +152,40 @@ describe('todayOf and tripDayState', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('liveDayDue', () => {
|
||||
const evening = {
|
||||
tripTitle: 'T',
|
||||
path: '/trips/1',
|
||||
dayLabel: 'D',
|
||||
stops: [
|
||||
{ name: 'Walk', time: null, minutes: null },
|
||||
{ name: 'Uber to the airport', time: '18:00', minutes: 18 * 60 },
|
||||
{ name: 'Flight', time: '21:00', minutes: 21 * 60 },
|
||||
],
|
||||
};
|
||||
|
||||
it('keeps the lock screen free until three hours before the first timed stop', () => {
|
||||
expect(liveDayDue(evening, 6 * 60 + 32)).toBe(false);
|
||||
expect(liveDayDue(evening, 14 * 60 + 59)).toBe(false);
|
||||
expect(liveDayDue(evening, 15 * 60)).toBe(true);
|
||||
});
|
||||
|
||||
it('stays on through the day once it has started, until the day is done', () => {
|
||||
expect(liveDayDue(evening, 19 * 60)).toBe(true);
|
||||
expect(liveDayDue(evening, 23 * 60 + 30)).toBe(true);
|
||||
});
|
||||
|
||||
it('starts from the earliest timed stop, wherever it stands in the list', () => {
|
||||
const early = { ...evening, stops: [...evening.stops, { name: 'Breakfast', time: '08:00', minutes: 8 * 60 }] };
|
||||
expect(liveDayDue(early, 5 * 60)).toBe(true);
|
||||
expect(liveDayDue(early, 4 * 60 + 59)).toBe(false);
|
||||
});
|
||||
|
||||
it('has nothing to show on a day without times', () => {
|
||||
expect(liveDayDue({ ...evening, stops: [{ name: 'Walk', time: null, minutes: null }] }, 12 * 60)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('publishWidgets', () => {
|
||||
it('writes the snapshot without the internal minutes and ends the activity on a day without times', async () => {
|
||||
const snapshot = buildSnapshot(
|
||||
|
||||
@@ -357,6 +357,23 @@ export function tripDayState(day: TripDay, nowMinutes: number, allDone: string):
|
||||
};
|
||||
}
|
||||
|
||||
/** How long before the day's first timed stop its Live Activity appears. */
|
||||
export const LIVE_LEAD_MINUTES = 3 * 60;
|
||||
|
||||
/**
|
||||
* Whether the travel day's Live Activity belongs on the lock screen now: from
|
||||
* three hours before the first stop with a time, then until the day is done. A
|
||||
* day whose first stop is an evening flight does not hold the lock screen from
|
||||
* the morning on.
|
||||
*/
|
||||
export function liveDayDue(day: TripDay, nowMinutes: number): boolean {
|
||||
const first = day.stops.reduce<number | null>(
|
||||
(min, s) => (s.minutes != null && (min === null || s.minutes < min) ? s.minutes : min),
|
||||
null
|
||||
);
|
||||
return first !== null && nowMinutes >= first - LIVE_LEAD_MINUTES;
|
||||
}
|
||||
|
||||
/** A trip a widget can be set to in Edit Widget, and its snapshot. */
|
||||
export interface TripWidgetSnapshot {
|
||||
id: number;
|
||||
|
||||
Reference in New Issue
Block a user