Enhance security and offline functionality

- Implement stricter security measures in the Electron app, including navigation blocking, URL validation, and external request handling.
- Add offline mode handling and UI improvements in components like `ScribeFooterBar` and `AddNewBookForm`.
- Refactor `DeleteBook` logic to include offline sync methods.
- Improve user feedback for online/offline states and synchronization errors.
This commit is contained in:
natreex
2025-12-24 15:20:26 -05:00
parent 4bc6a40b38
commit a315e96633
5 changed files with 143 additions and 15 deletions

View File

@@ -3,12 +3,13 @@ import {EditorContext} from "@/context/EditorContext";
import {useContext, useEffect, useState} from "react";
import {Editor} from "@tiptap/react";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faBook, faChartSimple, faHeart, faSheetPlastic} from "@fortawesome/free-solid-svg-icons";
import {faBook, faChartSimple, faHeart, faSheetPlastic, faHardDrive} from "@fortawesome/free-solid-svg-icons";
import {SessionContext} from "@/context/SessionContext";
import {useTranslations} from "next-intl";
import {AlertContext} from "@/context/AlertContext";
import {BookContext} from "@/context/BookContext";
import {BooksSyncContext, BooksSyncContextProps} from "@/context/BooksSyncContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
export default function ScribeFooterBar() {
const t = useTranslations();
@@ -16,6 +17,7 @@ export default function ScribeFooterBar() {
const {book} = useContext(BookContext);
const editor: Editor | null = useContext(EditorContext).editor;
const {errorMessage} = useContext(AlertContext)
const {offlineMode} = useContext<OfflineContextType>(OfflineContext)
const {serverOnlyBooks,localOnlyBooks} = useContext<BooksSyncContextProps>(BooksSyncContext);
const [wordsCount, setWordsCount] = useState<number>(0);
@@ -48,6 +50,12 @@ export default function ScribeFooterBar() {
}
}
useEffect(() => {
console.log(localOnlyBooks.length > 0 || offlineMode.isOffline);
console.log(localOnlyBooks.length);
console.log(offlineMode.isOffline);
}, []);
return (
<div
className="px-6 py-3 bg-tertiary/90 backdrop-blur-sm border-t border-secondary/50 text-text-primary flex justify-between items-center shadow-lg">
@@ -88,12 +96,20 @@ export default function ScribeFooterBar() {
</div>
) : (
<div className="flex items-center space-x-3">
<div
className="flex items-center gap-2 bg-secondary/50 px-4 py-2 rounded-xl border border-secondary shadow-sm">
<FontAwesomeIcon icon={faBook} className={'text-primary w-4 h-4'}/>
<span className="text-muted text-sm font-medium mr-1">{t('scribeFooterBar.books')}:</span>
<span className="text-text-primary font-bold">{(serverOnlyBooks.length+localOnlyBooks.length)}</span>
</div>
{
!offlineMode.isOffline && <div
className="flex items-center gap-2 bg-secondary/50 px-4 py-2 rounded-xl border border-secondary shadow-sm">
<FontAwesomeIcon icon={faBook} className={'text-primary w-4 h-4'}/>
<span className="text-text-primary font-bold">{serverOnlyBooks.length}</span>
</div>
}
{(localOnlyBooks.length > 0 || offlineMode.isOffline) && (
<div
className="flex items-center gap-2 bg-secondary/50 px-4 py-2 rounded-xl border border-secondary shadow-sm">
<FontAwesomeIcon icon={faHardDrive} className={'text-primary w-4 h-4'}/>
<span className="text-text-primary font-bold">{localOnlyBooks.length}</span>
</div>
)}
</div>
)
}