File size: 3,419 Bytes
3ca9355
 
 
 
 
 
 
 
 
 
 
 
 
34cfba1
 
 
3ca9355
 
 
34cfba1
3ca9355
 
 
 
 
 
 
 
 
34cfba1
3ca9355
 
 
34cfba1
3ca9355
34cfba1
 
 
 
 
3ca9355
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4f31b48
3ca9355
 
 
 
 
563a9a1
3ca9355
 
 
 
 
 
 
 
 
75007fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3ca9355
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
 * Synchronization Service
 * Migrated from Angular sync.service.ts
 * Handles offline-online data synchronization
 */

const syncService = {
    isSyncing: false,
    syncInterval: null,

    /**
     * Initialize sync service
     */
    async init() {
        console.log('Sync service initializing...');

        // Listen for online/offline events
        window.addEventListener('online', () => {
            console.log('Connection restored, syncing...');
            this.syncNow().catch(err => console.error('Auto-sync online failed:', err));
        });

        window.addEventListener('offline', () => {
            console.log('Connection lost, working offline');
        });

        // Auto-sync every 5 minutes when online
        this.syncInterval = setInterval(() => {
            if (navigator.onLine) {
                this.syncNow().catch(err => console.error('Periodic auto-sync failed:', err));
            }
        }, 5 * 60 * 1000);

        // Initial sync if online - wrapped in try-catch for stability
        if (navigator.onLine) {
            try {
                await this.syncNow();
            } catch (error) {
                console.warn('Initial sync failed (offline mode fallback):', error);
            }
        }
    },

    /**
     * Sync unsynced captures to backend
     */
    async syncNow() {
        if (this.isSyncing || !navigator.onLine) {
            return;
        }

        this.isSyncing = true;

        try {
            const unsyncedCaptures = await dbService.getUnsyncedCaptures();

            if (unsyncedCaptures.length === 0) {
                console.log('No captures to sync');
                this.isSyncing = false;
                return;
            }

            console.log(`Syncing ${unsyncedCaptures.length} captures...`);

            const result = await apiService.syncCaptures(unsyncedCaptures);

            // Update sync status for successfully synced captures
            for (const id of result.synced) {
                await dbService.updateSyncStatus(id, true);
            }

            console.log(`Successfully synced ${result.synced.length} captures`);

            // Dispatch event for UI updates
            window.dispatchEvent(new CustomEvent('syncComplete', {
                detail: {
                    synced: result.synced.length,
                    errors: result.errors ? result.errors.length : 0
                }
            }));

        } catch (error) {
            console.error('Sync failed:', error);
            throw error; // Re-throw to allow init() to catch it
        } finally {
            this.isSyncing = false;
        }
    },

    /**
     * Get sync status
     */
    async getSyncStatus() {
        try {
            const unsyncedCount = (await dbService.getUnsyncedCaptures()).length;
            return {
                isOnline: navigator.onLine,
                isSyncing: this.isSyncing,
                unsyncedCount: unsyncedCount
            };
        } catch (error) {
            console.warn('Could not get sync status from DB:', error);
            return {
                isOnline: navigator.onLine,
                isSyncing: this.isSyncing,
                unsyncedCount: 0
            };
        }
    },

    /**
     * Stop sync service
     */
    stop() {
        if (this.syncInterval) {
            clearInterval(this.syncInterval);
        }
    }
};