Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions resources/js/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ import {
pageReadAt,
} from '@/lib/realtime';
import { registerServiceWorker } from '@/lib/service-worker';
import { trackStarredCommitsHistory } from '@/lib/starred-commits-history';
import { browserClock, clockOf, setReaderClock } from '@/lib/utils';
import { trackVisualViewport } from '@/lib/visual-viewport';
import '../css/app.css';

trackCurrentPage();
trackStarredCommitsHistory();
trackCommitPhotoPage();
trackVisualViewport();
trackAnalyticsEvents();
Expand Down
26 changes: 26 additions & 0 deletions resources/js/lib/starred-commits-history.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { router } from '@inertiajs/react';

type PhotoBackground = { backgroundUrl?: string };

/** Starring or unstarring elsewhere can leave the cached starred list stale. */
export function trackStarredCommitsHistory(): VoidFunction {
return router.on('navigate', ({ detail: { type, page } }) => {
if (type !== 'history' || page.component !== 'starred/index') {
return;
}

const photo = page.props.photo as PhotoBackground | undefined;

queueMicrotask(() => {
// Drop old-cursor pagination requests before resetting the feed.
router.cancelAll({ async: true, prefetch: false, sync: false });
router.visit(photo?.backgroundUrl ?? page.url, {
only: ['commits'],
reset: ['commits'],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
preserveState: true,
preserveScroll: false,
preserveUrl: photo?.backgroundUrl !== undefined,
});
});
});
}
87 changes: 87 additions & 0 deletions tests/Unit/StarredCommitsHistory.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import assert from 'node:assert/strict';
import { test, vi } from 'vite-plus/test';

type NavigationType = 'initial' | 'visit' | 'history';
type Navigation = {
detail: {
type: NavigationType;
page: { component: string; url: string; props: { photo?: { backgroundUrl: string } } };
};
};

const visit = vi.fn();
const cancelAll = vi.fn();
let navigate: ((event: Navigation) => void) | undefined;

vi.doMock('@inertiajs/react', () => ({
router: {
on: (event: string, listener: (event: Navigation) => void) => {
assert.equal(event, 'navigate');
navigate = listener;

return () => {
navigate = undefined;
};
},
visit,
cancelAll,
},
}));

const { trackStarredCommitsHistory } = await import(
'../../resources/js/lib/starred-commits-history'
);

test('refreshes starred commits after history listeners have completed', async () => {
visit.mockClear();
cancelAll.mockClear();
const stop = trackStarredCommitsHistory();
const go = (
type: NavigationType,
component: string,
photo?: { backgroundUrl: string },
url = '/starred',
) =>
navigate?.({ detail: { type, page: { component, url, props: { photo } } } });

go('initial', 'starred/index');
go('visit', 'starred/index');
go('history', 'log/show');
assert.equal(visit.mock.calls.length, 0);

go('history', 'starred/index');
assert.equal(visit.mock.calls.length, 0);
await Promise.resolve();
assert.equal(visit.mock.calls.length, 1);
assert.equal(cancelAll.mock.calls.length, 1);
assert.deepEqual(cancelAll.mock.calls[0][0], {
async: true,
prefetch: false,
sync: false,
});
assert.equal(visit.mock.calls[0][0], '/starred');
assert.deepEqual(visit.mock.calls[0][1], {
only: ['commits'],
reset: ['commits'],
preserveState: true,
preserveScroll: false,
preserveUrl: false,
});

go('history', 'starred/index', { backgroundUrl: '/starred' }, '/post/photo/1');
assert.equal(visit.mock.calls.length, 1);
await Promise.resolve();
assert.equal(cancelAll.mock.calls.length, 2);
assert.equal(visit.mock.calls[1][0], '/starred');
assert.deepEqual(visit.mock.calls[1][1], {
only: ['commits'],
reset: ['commits'],
preserveState: true,
preserveScroll: false,
preserveUrl: true,
});

stop();
go('history', 'starred/index');
assert.equal(visit.mock.calls.length, 2);
});