- Introduced new translations for terms of use in French and English locales. - Added sync status detection logic for books in `BookList` and `BookCard` components. - Refactored `BookCard` to handle additional props and improve layout flexibility. - Enhanced `TermsOfUse` component with complete localization support and refuse functionality. - Updated data decryption logic in Rust services to handle optional fields and additional metadata consistently. - Improved offline/online synchronization workflows with extended context properties.
109 lines
3.4 KiB
TypeScript
109 lines
3.4 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState, useEffect, useCallback, ReactNode } from 'react';
|
|
import OfflineContext, { OfflineMode, defaultOfflineMode } from './OfflineContext';
|
|
import * as tauri from '@/lib/tauri';
|
|
|
|
interface OfflineProviderProps {
|
|
children: ReactNode;
|
|
}
|
|
|
|
export default function OfflineProvider({ children }: OfflineProviderProps) {
|
|
const [offlineMode, setOfflineMode] = useState<OfflineMode>(defaultOfflineMode);
|
|
|
|
const initializeDatabase = useCallback(async (userId: string, encryptionKey?: string): Promise<boolean> => {
|
|
try {
|
|
let userKey = encryptionKey;
|
|
if (!userKey) {
|
|
const storedKey = await tauri.getUserEncryptionKey(userId);
|
|
if (storedKey) {
|
|
userKey = storedKey;
|
|
} else {
|
|
throw new Error('No encryption key found for user');
|
|
}
|
|
}
|
|
|
|
await tauri.dbInitialize(userId, userKey);
|
|
|
|
setOfflineMode(prev => ({
|
|
...prev,
|
|
isDatabaseInitialized: true,
|
|
error: null
|
|
}));
|
|
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Failed to initialize database:', error, 'userId:', userId, 'hasKey:', !!encryptionKey);
|
|
setOfflineMode(prev => ({
|
|
...prev,
|
|
isDatabaseInitialized: false,
|
|
error: error instanceof Error ? error.message : 'Failed to initialize database'
|
|
}));
|
|
return false;
|
|
}
|
|
}, []);
|
|
|
|
const toggleOfflineMode = useCallback(() => {
|
|
setOfflineMode((prev:OfflineMode):OfflineMode => {
|
|
const newManuallyOffline:boolean = !prev.isManuallyOffline;
|
|
const newIsOffline:boolean = newManuallyOffline || !prev.isNetworkOnline;
|
|
|
|
return {
|
|
...prev,
|
|
isManuallyOffline: newManuallyOffline,
|
|
isOffline: newIsOffline
|
|
};
|
|
});
|
|
}, []);
|
|
|
|
const isCurrentlyOffline = useCallback((): boolean => {
|
|
return offlineMode.isOffline;
|
|
}, [offlineMode.isOffline]);
|
|
|
|
useEffect(() => {
|
|
const handleOnline = () => {
|
|
setOfflineMode(prev => {
|
|
const newIsOffline = prev.isManuallyOffline;
|
|
|
|
return {
|
|
...prev,
|
|
isNetworkOnline: true,
|
|
isOffline: newIsOffline
|
|
};
|
|
});
|
|
};
|
|
|
|
const handleOffline = () => {
|
|
setOfflineMode(prev => {
|
|
return {
|
|
...prev,
|
|
isNetworkOnline: false,
|
|
isOffline: true
|
|
};
|
|
});
|
|
};
|
|
|
|
window.addEventListener('online', handleOnline);
|
|
window.addEventListener('offline', handleOffline);
|
|
|
|
return () => {
|
|
window.removeEventListener('online', handleOnline);
|
|
window.removeEventListener('offline', handleOffline);
|
|
};
|
|
}, []);
|
|
|
|
const value = {
|
|
offlineMode,
|
|
setOfflineMode,
|
|
toggleOfflineMode,
|
|
initializeDatabase,
|
|
isCurrentlyOffline
|
|
};
|
|
|
|
return (
|
|
<OfflineContext.Provider value={value}>
|
|
{children}
|
|
</OfflineContext.Provider>
|
|
);
|
|
}
|