mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-28 10:13:52 +00:00
fix(sync-md): sync file changes immediately when window is focused
- File changes now sync immediately without debounce when window is focused - Only use 10-second debounce when window is unfocused - This provides better UX when actively working in the app - Updated tests to reflect the new behavior
This commit is contained in:
parent
fd08e51319
commit
372d4f7be5
2 changed files with 72 additions and 15 deletions
|
|
@ -87,7 +87,7 @@ describe('Sync Manager Debounce Behavior', () => {
|
|||
});
|
||||
|
||||
describe('MD to SP sync debouncing', () => {
|
||||
it('should debounce MD to SP sync for 10 seconds', async () => {
|
||||
it('should sync immediately when window is focused', async () => {
|
||||
// Initialize sync manager - it will create file since getFileStats returns null
|
||||
initSyncManager(mockConfig);
|
||||
|
||||
|
|
@ -97,6 +97,30 @@ describe('Sync Manager Debounce Behavior', () => {
|
|||
// Clear mocks after initial sync
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Window is focused by default
|
||||
// Trigger file change
|
||||
mockFileChangeCallback();
|
||||
|
||||
// Should sync immediately without waiting
|
||||
await jest.runAllTimersAsync();
|
||||
|
||||
expect(mdToSp).toHaveBeenCalledTimes(1);
|
||||
expect(mdToSp).toHaveBeenCalledWith('- [ ] Test task', mockConfig.projectId);
|
||||
});
|
||||
|
||||
it('should debounce MD to SP sync for 10 seconds when window is not focused', async () => {
|
||||
// Initialize sync manager
|
||||
initSyncManager(mockConfig);
|
||||
|
||||
// Let initial sync complete
|
||||
await jest.runAllTimersAsync();
|
||||
|
||||
// Clear mocks after initial sync
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Set window as unfocused
|
||||
mockWindowFocusCallback(false);
|
||||
|
||||
// Trigger file change
|
||||
mockFileChangeCallback();
|
||||
|
||||
|
|
@ -118,11 +142,35 @@ describe('Sync Manager Debounce Behavior', () => {
|
|||
expect(mdToSp).toHaveBeenCalledWith('- [ ] Test task', mockConfig.projectId);
|
||||
});
|
||||
|
||||
it('should reset debounce timer on multiple file changes', async () => {
|
||||
it('should handle multiple file changes when window is focused', async () => {
|
||||
initSyncManager(mockConfig);
|
||||
await jest.runAllTimersAsync();
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Window is focused - each file change triggers immediate sync
|
||||
|
||||
// First file change
|
||||
mockFileChangeCallback();
|
||||
await jest.runAllTimersAsync();
|
||||
|
||||
expect(mdToSp).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Second file change
|
||||
mockFileChangeCallback();
|
||||
await jest.runAllTimersAsync();
|
||||
|
||||
// Should be called again (not debounced when focused)
|
||||
expect(mdToSp).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should reset debounce timer on multiple file changes when unfocused', async () => {
|
||||
initSyncManager(mockConfig);
|
||||
await jest.runAllTimersAsync();
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Set window as unfocused
|
||||
mockWindowFocusCallback(false);
|
||||
|
||||
// First file change
|
||||
mockFileChangeCallback();
|
||||
|
||||
|
|
@ -144,7 +192,7 @@ describe('Sync Manager Debounce Behavior', () => {
|
|||
// Run all timers and wait for async operations
|
||||
await jest.runAllTimersAsync();
|
||||
|
||||
// Now sync should be called
|
||||
// Now sync should be called only once
|
||||
expect(mdToSp).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
|
@ -202,7 +250,10 @@ describe('Sync Manager Debounce Behavior', () => {
|
|||
await jest.runAllTimersAsync();
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Trigger file change
|
||||
// Set window as unfocused first
|
||||
mockWindowFocusCallback(false);
|
||||
|
||||
// Trigger file change while unfocused
|
||||
mockFileChangeCallback();
|
||||
|
||||
// Fast forward to complete the sync
|
||||
|
|
@ -213,8 +264,7 @@ describe('Sync Manager Debounce Behavior', () => {
|
|||
|
||||
expect(mdToSp).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Window loses focus then gains focus
|
||||
mockWindowFocusCallback(false);
|
||||
// Window gains focus after sync completed
|
||||
mockWindowFocusCallback(true);
|
||||
|
||||
await jest.runAllTimersAsync();
|
||||
|
|
@ -228,15 +278,12 @@ describe('Sync Manager Debounce Behavior', () => {
|
|||
await jest.runAllTimersAsync();
|
||||
jest.clearAllMocks();
|
||||
|
||||
// Window starts focused
|
||||
mockWindowFocusCallback(true);
|
||||
|
||||
// Trigger file change
|
||||
mockFileChangeCallback();
|
||||
|
||||
// Window loses focus
|
||||
// Start with window unfocused
|
||||
mockWindowFocusCallback(false);
|
||||
|
||||
// Trigger file change while unfocused
|
||||
mockFileChangeCallback();
|
||||
|
||||
// Fast forward 5 seconds (half of debounce time)
|
||||
jest.advanceTimersByTime(5000);
|
||||
expect(mdToSp).not.toHaveBeenCalled();
|
||||
|
|
|
|||
|
|
@ -78,12 +78,21 @@ const handleFileChange = (config: LocalUserCfg): void => {
|
|||
clearTimeout(mdToSpDebounceTimer);
|
||||
}
|
||||
|
||||
// If window is focused, sync immediately without debounce
|
||||
if (isWindowFocused) {
|
||||
console.log(
|
||||
'[sync-md] File change detected while window is focused, syncing immediately',
|
||||
);
|
||||
handleMdToSpSync(config);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark that we have a pending MD to SP sync
|
||||
pendingMdToSpSync = config;
|
||||
|
||||
// Always use 10 second debounce for MD to SP sync
|
||||
// Use 10 second debounce for MD to SP sync when window is not focused
|
||||
console.log(
|
||||
`[sync-md] File change detected, debouncing for ${SYNC_DEBOUNCE_MS_MD_TO_SP}ms (10 seconds), window focused: ${isWindowFocused}`,
|
||||
`[sync-md] File change detected while window is unfocused, debouncing for ${SYNC_DEBOUNCE_MS_MD_TO_SP}ms (10 seconds)`,
|
||||
);
|
||||
|
||||
mdToSpDebounceTimer = setTimeout(() => {
|
||||
|
|
@ -208,6 +217,7 @@ const setupWindowFocusTracking = (): void => {
|
|||
|
||||
// Trigger the sync immediately with the stored config
|
||||
const configToSync = pendingMdToSpSync;
|
||||
pendingMdToSpSync = null;
|
||||
handleMdToSpSync(configToSync);
|
||||
} else {
|
||||
console.log(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue