fix(sync): keep view settings device-local and exclude them from sync (#4672)
This commit is contained in:
@@ -37,7 +37,6 @@ const h = vi.hoisted(() => {
|
||||
user: { id: 'u1' },
|
||||
syncConfigsMock: vi.fn(async () => {}),
|
||||
syncBooksMock: vi.fn(async () => {}),
|
||||
setConfigMock: vi.fn(),
|
||||
cfiCompareMock: vi.fn((_a: string, _b: string) => 0),
|
||||
view: { renderer: { getContents: () => [], primaryIndex: 0 }, goTo: vi.fn() },
|
||||
state: {
|
||||
@@ -67,7 +66,7 @@ vi.mock('@/hooks/useTranslation', () => ({
|
||||
vi.mock('@/store/bookDataStore', () => ({
|
||||
useBookDataStore: h.makeStore({
|
||||
getConfig: () => h.config,
|
||||
setConfig: h.setConfigMock,
|
||||
setConfig: vi.fn(),
|
||||
getBookData: () => ({ book: h.book }),
|
||||
}),
|
||||
}));
|
||||
@@ -142,7 +141,6 @@ beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
h.syncConfigsMock.mockClear();
|
||||
h.syncBooksMock.mockClear();
|
||||
h.setConfigMock.mockClear();
|
||||
h.view.goTo.mockClear();
|
||||
h.cfiCompareMock.mockReset();
|
||||
h.cfiCompareMock.mockReturnValue(0);
|
||||
@@ -247,11 +245,10 @@ describe('useProgressSync', () => {
|
||||
renderHook(() => useProgressSync('h1-view1'));
|
||||
await advance(0);
|
||||
|
||||
// Not navigated to, and not persisted into the local config (the local
|
||||
// 'cfi-loc' is kept instead of the malformed remote value).
|
||||
// The malformed remote location is discarded so it can't move the reader.
|
||||
// (Config is no longer merged from sync — only reading progress drives
|
||||
// navigation — so the local position is left untouched.)
|
||||
expect(h.view.goTo).not.toHaveBeenCalled();
|
||||
const persisted = h.setConfigMock.mock.calls.at(-1)?.[1] as { location?: string } | undefined;
|
||||
expect(persisted?.location).toBe('cfi-loc');
|
||||
});
|
||||
|
||||
test('navigates to a well-formed newer synced location', async () => {
|
||||
|
||||
@@ -27,7 +27,6 @@ export const useProgressSync = (bookKey: string) => {
|
||||
// to the WHOLE bookDataStore — saveConfig writes booksData on every
|
||||
// throttled save and would otherwise re-render the entire reader subtree.
|
||||
const getConfig = useBookDataStore((s) => s.getConfig);
|
||||
const setConfig = useBookDataStore((s) => s.setConfig);
|
||||
const getBookData = useBookDataStore((s) => s.getBookData);
|
||||
const getView = useReaderStore((s) => s.getView);
|
||||
const setHoveredBookKey = useReaderStore((s) => s.setHoveredBookKey);
|
||||
@@ -238,14 +237,8 @@ export const useProgressSync = (bookKey: string) => {
|
||||
remoteCFILocation = candidateCFI;
|
||||
}
|
||||
}
|
||||
const filteredSyncedConfig = Object.fromEntries(
|
||||
Object.entries(syncedConfig).filter(([_, value]) => value !== null && value !== undefined),
|
||||
);
|
||||
if (syncedConfig.updatedAt >= config.updatedAt) {
|
||||
setConfig(bookKey, { ...config, ...filteredSyncedConfig });
|
||||
} else {
|
||||
setConfig(bookKey, { ...filteredSyncedConfig, ...config });
|
||||
}
|
||||
// Currently, only reading progress is synced.
|
||||
// TODO: Configuration sync will be handled through a more robust profile-based solution in the future.
|
||||
if (remoteCFILocation && configCFI) {
|
||||
if (CFI.compare(configCFI, remoteCFILocation) < 0) {
|
||||
// While previewing a deep-link target, do NOT yank the view to the
|
||||
|
||||
Reference in New Issue
Block a user