mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 07:40:59 +00:00
80c04df4fc
Packing items, tasks and expenses swipe sideways to their actions, as in Mail or Reminders: done or open one way, delete and edit the other, the first one run by a full swipe. They are second ways to what each row already offers; an expense still asks before it goes. A long press on a trip card lifts it and opens its menu with the card's own actions. Plain confirmations in MConfirmSheet now also ask through the system where the app can. Lists, the atlas and a journey show grey placeholders in their shape while loading instead of a spinner in an empty screen (MSkeleton); buttons keep theirs. A picture still loading fades in once it is there; one from the cache shows at once. In the iOS app the page bounces at its ends again, except on screens with pull-to-refresh, whose pull it would race; Android keeps its stretch off. On iOS a long press on the app icon offers "New trip" and the trip coming up by its name, set by the UI in its language (TrekShell.setQuickActions, feature quickActions), and a tap opens it, also from a cold start. The app's own CSS moves out of index.css into native/nativeApp.css, which had outgrown its size budget.
67 lines
2.6 KiB
TypeScript
67 lines
2.6 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import type { Trip } from '../types';
|
|
import { hasNativeFeature } from './capabilities';
|
|
import { isNativeApp } from './platform';
|
|
import { openPushTarget } from './push';
|
|
import { publishQuickActions, quickActionsFor, startQuickActions } from './quickActions';
|
|
import { TrekShell } from './trekShell';
|
|
|
|
vi.mock('./capabilities', () => ({ hasNativeFeature: vi.fn() }));
|
|
vi.mock('./platform', () => ({ isNativeApp: vi.fn() }));
|
|
vi.mock('./push', () => ({ openPushTarget: vi.fn() }));
|
|
vi.mock('./reportFailure', () => ({ reportNativeFailure: vi.fn() }));
|
|
vi.mock('./trekShell', () => ({
|
|
TrekShell: { setQuickActions: vi.fn(async () => {}), takeQuickAction: vi.fn(), addListener: vi.fn() },
|
|
}));
|
|
|
|
const t = ((key: string) =>
|
|
({ 'dashboard.newTrip': 'New Trip', 'dashboard.nextTrip': 'Next trip', 'native.widget.today': 'Today' })[key] ??
|
|
key) as never;
|
|
const trip = (start: string, end: string) =>
|
|
({ id: 7, title: 'Lisbon', start_date: start, end_date: end }) as unknown as Trip;
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
vi.mocked(isNativeApp).mockReturnValue(true);
|
|
vi.mocked(hasNativeFeature).mockReturnValue(true);
|
|
});
|
|
|
|
describe('quickActionsFor', () => {
|
|
it('offers "New trip" alone without a trip', () => {
|
|
expect(quickActionsFor(null, '2026-11-09', t)).toEqual([
|
|
{ type: 'newTrip', title: 'New Trip', icon: 'add', path: '/dashboard?create=1' },
|
|
]);
|
|
});
|
|
|
|
it('adds the trip coming up by its name', () => {
|
|
expect(quickActionsFor(trip('2026-12-01', '2026-12-05'), '2026-11-09', t)[1]).toEqual({
|
|
type: 'trip',
|
|
title: 'Lisbon',
|
|
subtitle: 'Next trip',
|
|
icon: 'trip',
|
|
path: '/trips/7',
|
|
});
|
|
});
|
|
|
|
it('calls a trip that runs today "Today"', () => {
|
|
expect(quickActionsFor(trip('2026-11-08', '2026-11-10'), '2026-11-09', t)[1]?.subtitle).toBe('Today');
|
|
});
|
|
});
|
|
|
|
describe('the binary', () => {
|
|
it('gets the actions only where it has the feature', async () => {
|
|
await publishQuickActions([]);
|
|
expect(TrekShell.setQuickActions).toHaveBeenCalledWith({ items: [] });
|
|
vi.mocked(hasNativeFeature).mockReturnValue(false);
|
|
await publishQuickActions([]);
|
|
expect(TrekShell.setQuickActions).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('opens the action the app was launched with, and listens for the next ones', async () => {
|
|
vi.mocked(TrekShell.takeQuickAction).mockResolvedValue({ path: '/trips/7' });
|
|
await startQuickActions();
|
|
expect(openPushTarget).toHaveBeenCalledWith('/trips/7');
|
|
expect(TrekShell.addListener).toHaveBeenCalledWith('quickAction', expect.any(Function));
|
|
});
|
|
});
|