97 lines
2.6 KiB
Dart
97 lines
2.6 KiB
Dart
import 'dart:collection';
|
|
|
|
import 'sheet.dart';
|
|
|
|
/// Types of changes that can be queued for server synchronization.
|
|
enum ChangeType {
|
|
sheetNameChange,
|
|
composerNameChange,
|
|
addTagChange,
|
|
removeTagChange,
|
|
}
|
|
|
|
/// Represents a single pending change to be synced with the server.
|
|
///
|
|
/// Changes are stored locally when offline and applied once
|
|
/// the device regains connectivity.
|
|
class Change {
|
|
final ChangeType type;
|
|
final String sheetUuid;
|
|
final String value;
|
|
|
|
Change({
|
|
required this.type,
|
|
required this.sheetUuid,
|
|
required this.value,
|
|
});
|
|
|
|
/// Serializes this change to a map for storage.
|
|
Map<String, dynamic> toMap() => {
|
|
'type': type.index,
|
|
'sheetUuid': sheetUuid,
|
|
'value': value,
|
|
};
|
|
|
|
/// Deserializes a change from a stored map.
|
|
///
|
|
/// Note: Adding new [ChangeType] values may cause issues with
|
|
/// previously stored changes that use index-based serialization.
|
|
factory Change.fromMap(Map<dynamic, dynamic> map) {
|
|
return Change(
|
|
type: ChangeType.values[map['type']],
|
|
sheetUuid: map['sheetUuid'],
|
|
value: map['value'],
|
|
);
|
|
}
|
|
}
|
|
|
|
/// A queue of pending changes to be synchronized with the server.
|
|
///
|
|
/// Changes are stored in FIFO order (oldest first) and applied
|
|
/// to sheets in sequence when syncing.
|
|
class ChangeQueue {
|
|
final Queue<Change> _queue = Queue();
|
|
|
|
ChangeQueue();
|
|
|
|
/// Adds a change to the end of the queue.
|
|
void addChange(Change change) {
|
|
_queue.addLast(change);
|
|
}
|
|
|
|
/// Returns the number of pending changes.
|
|
int get length => _queue.length;
|
|
|
|
/// Whether the queue has any pending changes.
|
|
bool get isEmpty => _queue.isEmpty;
|
|
|
|
/// Whether the queue has pending changes.
|
|
bool get isNotEmpty => _queue.isNotEmpty;
|
|
|
|
/// Applies all queued changes to the provided list of sheets.
|
|
///
|
|
/// Each change modifies the corresponding sheet's properties
|
|
/// based on the change type.
|
|
void applyToSheets(List<Sheet> sheets) {
|
|
for (final change in _queue) {
|
|
final sheet = sheets.firstWhere(
|
|
(s) => s.uuid == change.sheetUuid,
|
|
orElse: () => throw StateError(
|
|
'Sheet with UUID ${change.sheetUuid} not found',
|
|
),
|
|
);
|
|
|
|
switch (change.type) {
|
|
case ChangeType.sheetNameChange:
|
|
sheet.name = change.value;
|
|
case ChangeType.composerNameChange:
|
|
sheet.composerName = change.value;
|
|
case ChangeType.addTagChange:
|
|
throw UnimplementedError('Tag support not yet implemented');
|
|
case ChangeType.removeTagChange:
|
|
throw UnimplementedError('Tag support not yet implemented');
|
|
}
|
|
}
|
|
}
|
|
}
|