import method
Accepts export output (base64 or JSON) and the legacy SinApp
{"markers":[{"seconds":…, "text":…, "color":…}]} payload.
Implementation
bool import(String data, {bool merge = false, bool notify = true}) {
final Map<String, Object?>? json = UDocAnnotationController.decode(data);
if (json == null) return false;
final List<UMediaNote> incoming = <UMediaNote>[];
final List<UDocShape> drawings = <UDocShape>[];
for (final Object? entry in (json["shapes"] as List<Object?>?) ?? const <Object?>[]) {
if (entry is Map<String, Object?>) drawings.add(UDocShape.fromJson(entry));
}
if (json["notes"] is List<Object?> || drawings.isNotEmpty) {
for (final Object? entry in (json["notes"] as List<Object?>?) ?? const <Object?>[]) {
if (entry is Map<String, Object?>) incoming.add(UMediaNote.fromJson(entry));
}
_updatedAt = DateTime.tryParse((json["updated"] as String?) ?? "") ?? DateTime.now();
} else if (json["markers"] is List<Object?>) {
for (final Object? entry in json["markers"]! as List<Object?>) {
if (entry is! Map<String, Object?>) continue;
final num seconds = (entry["seconds"] as num?) ?? 0;
incoming.add(
UMediaNote.create(
position: Duration(milliseconds: (seconds * 1000).round()),
text: (entry["text"] as String?) ?? "",
color: Color((entry["color"] as num?)?.toInt() ?? 0xFFFFC107),
),
);
}
_updatedAt = DateTime.now();
} else {
return false;
}
if (notify) _checkpoint();
if (!merge) {
_notes.clear();
_shapes.clear();
}
final Set<String> drawn = _shapes.map((UDocShape shape) => shape.id).toSet();
_shapes.addAll(drawings.where((UDocShape shape) => !drawn.contains(shape.id)));
final Set<String> known = _notes.map((UMediaNote note) => note.id).toSet();
_notes.addAll(incoming.where((UMediaNote note) => !known.contains(note.id)));
_notes.sort((UMediaNote a, UMediaNote b) => a.position.compareTo(b.position));
if (notify) {
notifyListeners();
unawaited(save());
}
return true;
}