Only save annotations on changes
This commit is contained in:
@@ -51,6 +51,9 @@ class DrawingController extends ChangeNotifier {
|
||||
/// Maximum number of history steps to keep
|
||||
final int maxHistorySteps;
|
||||
|
||||
/// Whether there are unsaved changes since last load/clear
|
||||
bool _hasUnsavedChanges = false;
|
||||
|
||||
DrawingController({this.maxHistorySteps = 50});
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -75,6 +78,9 @@ class DrawingController extends ChangeNotifier {
|
||||
/// Whether redo is available
|
||||
bool get canRedo => _redoStack.isNotEmpty;
|
||||
|
||||
/// Whether there are unsaved changes since last load/clear/markSaved
|
||||
bool get hasUnsavedChanges => _hasUnsavedChanges;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Drawing Operations
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -120,6 +126,7 @@ class DrawingController extends ChangeNotifier {
|
||||
_redoStack.clear();
|
||||
_trimHistory();
|
||||
_currentErasedLines.clear();
|
||||
_hasUnsavedChanges = true;
|
||||
notifyListeners(); // Update UI to enable undo button
|
||||
}
|
||||
return;
|
||||
@@ -133,6 +140,7 @@ class DrawingController extends ChangeNotifier {
|
||||
_undoStack.add(AddLineAction(_currentLine!));
|
||||
_redoStack.clear();
|
||||
_trimHistory();
|
||||
_hasUnsavedChanges = true;
|
||||
}
|
||||
|
||||
_currentLine = null;
|
||||
@@ -257,6 +265,7 @@ class DrawingController extends ChangeNotifier {
|
||||
_redoStack.add(action);
|
||||
}
|
||||
|
||||
_hasUnsavedChanges = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -279,6 +288,7 @@ class DrawingController extends ChangeNotifier {
|
||||
_undoStack.add(action);
|
||||
}
|
||||
|
||||
_hasUnsavedChanges = true;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -289,6 +299,7 @@ class DrawingController extends ChangeNotifier {
|
||||
_redoStack.clear();
|
||||
_currentLine = null;
|
||||
_currentErasedLines.clear();
|
||||
_hasUnsavedChanges = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -324,6 +335,7 @@ class DrawingController extends ChangeNotifier {
|
||||
_redoStack.clear();
|
||||
_currentLine = null;
|
||||
_currentErasedLines.clear();
|
||||
_hasUnsavedChanges = false;
|
||||
|
||||
for (final json in jsonList) {
|
||||
_lines.add(DrawingLine.fromJson(json));
|
||||
@@ -354,6 +366,11 @@ class DrawingController extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
/// Marks the current state as saved (resets unsaved changes flag).
|
||||
void markSaved() {
|
||||
_hasUnsavedChanges = false;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_lines.clear();
|
||||
|
||||
@@ -103,7 +103,7 @@ class _SheetViewerPageState extends State<SheetViewerPage>
|
||||
});
|
||||
|
||||
// Sync annotations from server (downloads newer versions)
|
||||
await _syncService.syncAnnotationsFromServer(widget.sheet.uuid);
|
||||
await _syncService.syncFromServer(widget.sheet.uuid);
|
||||
|
||||
// Load annotations for current page(s)
|
||||
await _loadAnnotationsForCurrentPages();
|
||||
@@ -143,10 +143,13 @@ class _SheetViewerPageState extends State<SheetViewerPage>
|
||||
}
|
||||
|
||||
/// Saves the current page(s) annotations to storage and uploads to server.
|
||||
///
|
||||
/// Only saves if there are actual changes to avoid unnecessary writes/uploads.
|
||||
Future<void> _saveCurrentAnnotations() async {
|
||||
final now = DateTime.now();
|
||||
|
||||
// Save left page
|
||||
// Save left page only if changed
|
||||
if (_leftDrawingController.hasUnsavedChanges) {
|
||||
final leftJson = _leftDrawingController.toJsonString();
|
||||
final leftHasContent = leftJson.isNotEmpty && leftJson != '[]';
|
||||
|
||||
@@ -167,8 +170,13 @@ class _SheetViewerPageState extends State<SheetViewerPage>
|
||||
);
|
||||
}
|
||||
|
||||
// Save right page (two-page mode)
|
||||
if (widget.config.twoPageMode && _currentPage < _totalPages) {
|
||||
_leftDrawingController.markSaved();
|
||||
}
|
||||
|
||||
// Save right page (two-page mode) only if changed
|
||||
if (widget.config.twoPageMode &&
|
||||
_currentPage < _totalPages &&
|
||||
_rightDrawingController.hasUnsavedChanges) {
|
||||
final rightJson = _rightDrawingController.toJsonString();
|
||||
final rightHasContent = rightJson.isNotEmpty && rightJson != '[]';
|
||||
|
||||
@@ -188,6 +196,8 @@ class _SheetViewerPageState extends State<SheetViewerPage>
|
||||
lastModified: now,
|
||||
);
|
||||
}
|
||||
|
||||
_rightDrawingController.markSaved();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,9 +300,8 @@ class _SheetViewerPageState extends State<SheetViewerPage>
|
||||
icon: Icon(
|
||||
widget.config.fullscreen ? Icons.fullscreen_exit : Icons.fullscreen,
|
||||
),
|
||||
tooltip: widget.config.fullscreen
|
||||
? 'Exit Fullscreen'
|
||||
: 'Enter Fullscreen',
|
||||
tooltip:
|
||||
widget.config.fullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen',
|
||||
onPressed: _toggleFullscreen,
|
||||
),
|
||||
IconButton(
|
||||
@@ -304,9 +313,8 @@ class _SheetViewerPageState extends State<SheetViewerPage>
|
||||
icon: Icon(
|
||||
widget.config.twoPageMode ? Icons.filter_1 : Icons.filter_2,
|
||||
),
|
||||
tooltip: widget.config.twoPageMode
|
||||
? 'Single Page Mode'
|
||||
: 'Two Page Mode',
|
||||
tooltip:
|
||||
widget.config.twoPageMode ? 'Single Page Mode' : 'Two Page Mode',
|
||||
onPressed: _toggleTwoPageMode,
|
||||
),
|
||||
],
|
||||
@@ -338,9 +346,8 @@ class _SheetViewerPageState extends State<SheetViewerPage>
|
||||
currentPageNumber: _currentPage,
|
||||
config: widget.config,
|
||||
leftDrawingController: _leftDrawingController,
|
||||
rightDrawingController: widget.config.twoPageMode
|
||||
? _rightDrawingController
|
||||
: null,
|
||||
rightDrawingController:
|
||||
widget.config.twoPageMode ? _rightDrawingController : null,
|
||||
drawingEnabled: _isPaintMode,
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user