Custom drawing implementation
This commit is contained in:
@@ -9,12 +9,14 @@ enum SecureStorageKey { url, jwt, email }
|
||||
/// Service for managing local storage operations.
|
||||
///
|
||||
/// Uses [FlutterSecureStorage] for sensitive data (credentials, tokens)
|
||||
/// and [Hive] for general app data (config, sheet access times, change queue).
|
||||
/// and [Hive] for general app data (config, sheet access times, change queue,
|
||||
/// and PDF annotations).
|
||||
class StorageService {
|
||||
// Hive box names
|
||||
static const String _sheetAccessTimesBox = 'sheetAccessTimes';
|
||||
static const String _configBox = 'config';
|
||||
static const String _changeQueueBox = 'changeQueue';
|
||||
static const String _annotationsBox = 'annotations';
|
||||
|
||||
late final FlutterSecureStorage _secureStorage;
|
||||
|
||||
@@ -75,8 +77,9 @@ class StorageService {
|
||||
Future<Map<String, DateTime>> readSheetAccessTimes() async {
|
||||
final box = await Hive.openBox(_sheetAccessTimesBox);
|
||||
return box.toMap().map(
|
||||
(key, value) => MapEntry(key as String, DateTime.parse(value as String)),
|
||||
);
|
||||
(key, value) =>
|
||||
MapEntry(key as String, DateTime.parse(value as String)),
|
||||
);
|
||||
}
|
||||
|
||||
/// Records when a sheet was last accessed.
|
||||
@@ -116,4 +119,75 @@ class StorageService {
|
||||
await box.deleteAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Annotations (PDF Drawing Persistence)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Generates a storage key for a specific page's annotations.
|
||||
String _annotationKey(String sheetUuid, int pageNumber) {
|
||||
return '${sheetUuid}_page_$pageNumber';
|
||||
}
|
||||
|
||||
/// Reads annotations for a specific sheet page.
|
||||
///
|
||||
/// Returns the JSON string of annotations, or null if none exist.
|
||||
Future<String?> readAnnotations(String sheetUuid, int pageNumber) async {
|
||||
final box = await Hive.openBox(_annotationsBox);
|
||||
return box.get(_annotationKey(sheetUuid, pageNumber));
|
||||
}
|
||||
|
||||
/// Writes annotations for a specific sheet page.
|
||||
///
|
||||
/// Pass null or empty string to delete annotations for that page.
|
||||
Future<void> writeAnnotations(
|
||||
String sheetUuid,
|
||||
int pageNumber,
|
||||
String? annotationsJson,
|
||||
) async {
|
||||
final box = await Hive.openBox(_annotationsBox);
|
||||
final key = _annotationKey(sheetUuid, pageNumber);
|
||||
|
||||
if (annotationsJson == null || annotationsJson.isEmpty) {
|
||||
await box.delete(key);
|
||||
} else {
|
||||
await box.put(key, annotationsJson);
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads all annotations for a sheet (all pages).
|
||||
///
|
||||
/// Returns a map of page number to JSON string.
|
||||
Future<Map<int, String>> readAllAnnotations(String sheetUuid) async {
|
||||
final box = await Hive.openBox(_annotationsBox);
|
||||
final prefix = '${sheetUuid}_page_';
|
||||
final result = <int, String>{};
|
||||
|
||||
for (final key in box.keys) {
|
||||
if (key is String && key.startsWith(prefix)) {
|
||||
final pageStr = key.substring(prefix.length);
|
||||
final pageNumber = int.tryParse(pageStr);
|
||||
if (pageNumber != null) {
|
||||
final value = box.get(key);
|
||||
if (value != null && value is String && value.isNotEmpty) {
|
||||
result[pageNumber] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Deletes all annotations for a sheet.
|
||||
Future<void> deleteAllAnnotations(String sheetUuid) async {
|
||||
final box = await Hive.openBox(_annotationsBox);
|
||||
final prefix = '${sheetUuid}_page_';
|
||||
final keysToDelete =
|
||||
box.keys.where((key) => key is String && key.startsWith(prefix));
|
||||
|
||||
for (final key in keysToDelete.toList()) {
|
||||
await box.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user