import method

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

Accepts export output (base64 or raw JSON) and the legacy SinApp {"markers": [...], "pageMarks": [...]} format. Returns false when the payload is not understood.

Implementation

bool import(String data, {bool merge = false, bool notify = true}) {
  final Map<String, Object?>? json = decode(data);
  if (json == null) return false;
  final List<UDocMarkup> markups = <UDocMarkup>[];
  final List<UDocBookmark> bookmarks = <UDocBookmark>[];
  final List<UDocShape> shapes = <UDocShape>[];
  if (json.containsKey("markups") || json.containsKey("bookmarks") || json.containsKey("shapes")) {
    for (final Object? entry in (json["shapes"] as List<Object?>?) ?? const <Object?>[]) {
      if (entry is Map<String, Object?>) shapes.add(UDocShape.fromJson(entry));
    }
    for (final Object? entry in (json["markups"] as List<Object?>?) ?? const <Object?>[]) {
      if (entry is Map<String, Object?>) markups.add(UDocMarkup.fromJson(entry));
    }
    for (final Object? entry in (json["bookmarks"] as List<Object?>?) ?? const <Object?>[]) {
      if (entry is Map<String, Object?>) bookmarks.add(UDocBookmark.fromJson(entry));
    }
    _updatedAt = DateTime.tryParse((json["updated"] as String?) ?? "") ?? DateTime.now();
  } else if (json.containsKey("markers") || json.containsKey("pageMarks")) {
    _importLegacy(json, markups, bookmarks);
    _updatedAt = DateTime.now();
  } else {
    return false;
  }
  if (notify) _checkpoint();
  if (!merge) {
    _markups.clear();
    _bookmarks.clear();
    _shapes.clear();
  }
  final Set<String> drawn = _shapes.map((UDocShape shape) => shape.id).toSet();
  _shapes.addAll(shapes.where((UDocShape shape) => !drawn.contains(shape.id)));
  _shapesByPage = null;
  final Set<String> known = _markups.map((UDocMarkup markup) => markup.id).toSet();
  _markups.addAll(markups.where((UDocMarkup markup) => !known.contains(markup.id)));
  final Set<String> marked = _bookmarks.map((UDocBookmark bookmark) => "${bookmark.id}|${bookmark.pageIndex}:${bookmark.blockIndex}").toSet();
  final Set<String> positions = _bookmarks.map((UDocBookmark bookmark) => "${bookmark.pageIndex}:${bookmark.blockIndex}").toSet();
  _bookmarks.addAll(
    bookmarks.where(
      (UDocBookmark bookmark) => !marked.contains("${bookmark.id}|${bookmark.pageIndex}:${bookmark.blockIndex}") && !positions.contains("${bookmark.pageIndex}:${bookmark.blockIndex}"),
    ),
  );
  _bookmarks.sort((UDocBookmark a, UDocBookmark b) => a.pageIndex != b.pageIndex ? a.pageIndex.compareTo(b.pageIndex) : a.blockIndex.compareTo(b.blockIndex));
  _byPage = null;
  if (notify) {
    notifyListeners();
    unawaited(save());
  }
  return true;
}