Implement annotation syncing to and from server

This commit is contained in:
2026-02-06 16:05:55 +01:00
parent e5c71c9261
commit 9a11e42571
4 changed files with 348 additions and 9 deletions

View File

@@ -6,6 +6,7 @@ import 'package:logging/logging.dart';
import 'package:pdfrx/pdfrx.dart';
import 'package:sheetless/core/models/config.dart';
import 'package:sheetless/core/models/sheet.dart';
import 'package:sheetless/core/services/annotation_sync_service.dart';
import 'package:sheetless/core/services/api_client.dart';
import 'package:sheetless/core/services/storage_service.dart';
@@ -35,6 +36,7 @@ class _SheetViewerPageState extends State<SheetViewerPage>
with FullScreenListener {
final _log = Logger('SheetViewerPage');
final _storageService = StorageService();
late final AnnotationSyncService _syncService;
PdfDocument? _document;
late Future<bool> _documentLoaded;
@@ -52,6 +54,12 @@ class _SheetViewerPageState extends State<SheetViewerPage>
void initState() {
super.initState();
// Initialize sync service
_syncService = AnnotationSyncService(
apiClient: widget.apiClient,
storageService: _storageService,
);
// Initialize drawing controllers
_leftDrawingController = DrawingController(maxHistorySteps: 50);
_rightDrawingController = DrawingController(maxHistorySteps: 50);
@@ -94,6 +102,9 @@ class _SheetViewerPageState extends State<SheetViewerPage>
_totalPages = _document!.pages.length;
});
// Sync annotations from server (downloads newer versions)
await _syncService.syncAnnotationsFromServer(widget.sheet.uuid);
// Load annotations for current page(s)
await _loadAnnotationsForCurrentPages();
@@ -131,24 +142,52 @@ class _SheetViewerPageState extends State<SheetViewerPage>
}
}
/// Saves the current page(s) annotations to storage.
/// Saves the current page(s) annotations to storage and uploads to server.
Future<void> _saveCurrentAnnotations() async {
final now = DateTime.now();
// Save left page
final leftJson = _leftDrawingController.toJsonString();
await _storageService.writeAnnotations(
final leftHasContent = leftJson.isNotEmpty && leftJson != '[]';
await _storageService.writeAnnotationsWithMetadata(
widget.sheet.uuid,
_currentPage,
leftJson.isEmpty || leftJson == '[]' ? null : leftJson,
leftHasContent ? leftJson : null,
now,
);
// Upload left page to server
if (leftHasContent) {
_syncService.uploadAnnotation(
sheetUuid: widget.sheet.uuid,
page: _currentPage,
annotationsJson: leftJson,
lastModified: now,
);
}
// Save right page (two-page mode)
if (widget.config.twoPageMode && _currentPage < _totalPages) {
final rightJson = _rightDrawingController.toJsonString();
await _storageService.writeAnnotations(
final rightHasContent = rightJson.isNotEmpty && rightJson != '[]';
await _storageService.writeAnnotationsWithMetadata(
widget.sheet.uuid,
_currentPage + 1,
rightJson.isEmpty || rightJson == '[]' ? null : rightJson,
rightHasContent ? rightJson : null,
now,
);
// Upload right page to server
if (rightHasContent) {
_syncService.uploadAnnotation(
sheetUuid: widget.sheet.uuid,
page: _currentPage + 1,
annotationsJson: rightJson,
lastModified: now,
);
}
}
}