import method

bool import(
  1. String data, {
  2. bool merge = false,
  3. bool notify = true,
})

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;
}