board_data_controller.dart 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import 'dart:collection';
  2. import 'package:app_flowy/plugins/grid/application/block/block_cache.dart';
  3. import 'package:app_flowy/plugins/grid/application/field/field_cache.dart';
  4. import 'package:app_flowy/plugins/grid/application/grid_service.dart';
  5. import 'package:app_flowy/plugins/grid/application/row/row_cache.dart';
  6. import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
  7. import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
  8. import 'dart:async';
  9. import 'package:dartz/dartz.dart';
  10. import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
  11. import 'board_listener.dart';
  12. typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>);
  13. typedef OnGridChanged = void Function(GridPB);
  14. typedef DidLoadGroups = void Function(List<GroupPB>);
  15. typedef OnUpdatedGroup = void Function(List<GroupPB>);
  16. typedef OnDeletedGroup = void Function(List<String>);
  17. typedef OnInsertedGroup = void Function(List<InsertedGroupPB>);
  18. typedef OnRowsChanged = void Function(
  19. List<RowInfo>,
  20. RowsChangedReason,
  21. );
  22. typedef OnError = void Function(FlowyError);
  23. class BoardDataController {
  24. final String gridId;
  25. final GridFFIService _gridFFIService;
  26. final GridFieldCache fieldCache;
  27. final BoardListener _listener;
  28. // key: the block id
  29. final LinkedHashMap<String, GridBlockCache> _blocks;
  30. LinkedHashMap<String, GridBlockCache> get blocks => _blocks;
  31. OnFieldsChanged? _onFieldsChanged;
  32. OnGridChanged? _onGridChanged;
  33. DidLoadGroups? _didLoadGroup;
  34. OnRowsChanged? _onRowsChanged;
  35. OnError? _onError;
  36. List<RowInfo> get rowInfos {
  37. final List<RowInfo> rows = [];
  38. for (var block in _blocks.values) {
  39. rows.addAll(block.rows);
  40. }
  41. return rows;
  42. }
  43. BoardDataController({required ViewPB view})
  44. : gridId = view.id,
  45. _listener = BoardListener(view.id),
  46. // ignore: prefer_collection_literals
  47. _blocks = LinkedHashMap(),
  48. _gridFFIService = GridFFIService(gridId: view.id),
  49. fieldCache = GridFieldCache(gridId: view.id);
  50. void addListener({
  51. required OnGridChanged onGridChanged,
  52. OnFieldsChanged? onFieldsChanged,
  53. required DidLoadGroups didLoadGroups,
  54. OnRowsChanged? onRowsChanged,
  55. required OnUpdatedGroup onUpdatedGroup,
  56. required OnDeletedGroup onDeletedGroup,
  57. required OnInsertedGroup onInsertedGroup,
  58. required OnError? onError,
  59. }) {
  60. _onGridChanged = onGridChanged;
  61. _onFieldsChanged = onFieldsChanged;
  62. _didLoadGroup = didLoadGroups;
  63. _onRowsChanged = onRowsChanged;
  64. _onError = onError;
  65. fieldCache.addListener(onFields: (fields) {
  66. _onFieldsChanged?.call(UnmodifiableListView(fields));
  67. });
  68. _listener.start(onBoardChanged: (result) {
  69. result.fold(
  70. (changeset) {
  71. if (changeset.updateGroups.isNotEmpty) {
  72. onUpdatedGroup.call(changeset.updateGroups);
  73. }
  74. if (changeset.insertedGroups.isNotEmpty) {
  75. onInsertedGroup.call(changeset.insertedGroups);
  76. }
  77. if (changeset.deletedGroups.isNotEmpty) {
  78. onDeletedGroup.call(changeset.deletedGroups);
  79. }
  80. },
  81. (e) => _onError?.call(e),
  82. );
  83. });
  84. }
  85. Future<Either<Unit, FlowyError>> loadData() async {
  86. final result = await _gridFFIService.loadGrid();
  87. return Future(
  88. () => result.fold(
  89. (grid) async {
  90. _onGridChanged?.call(grid);
  91. return await _loadFields(grid).then((result) {
  92. return result.fold(
  93. (l) {
  94. _loadGroups(grid.blocks);
  95. return left(l);
  96. },
  97. (err) => right(err),
  98. );
  99. });
  100. },
  101. (err) => right(err),
  102. ),
  103. );
  104. }
  105. Future<Either<RowPB, FlowyError>> createBoardCard(String groupId,
  106. {String? startRowId}) {
  107. return _gridFFIService.createBoardCard(groupId, startRowId);
  108. }
  109. Future<void> dispose() async {
  110. await _gridFFIService.closeGrid();
  111. await fieldCache.dispose();
  112. for (final blockCache in _blocks.values) {
  113. blockCache.dispose();
  114. }
  115. }
  116. Future<Either<Unit, FlowyError>> _loadFields(GridPB grid) async {
  117. final result = await _gridFFIService.getFields(fieldIds: grid.fields);
  118. return Future(
  119. () => result.fold(
  120. (fields) {
  121. fieldCache.fields = fields.items;
  122. _onFieldsChanged?.call(UnmodifiableListView(fieldCache.fields));
  123. return left(unit);
  124. },
  125. (err) => right(err),
  126. ),
  127. );
  128. }
  129. Future<void> _loadGroups(List<BlockPB> blocks) async {
  130. for (final block in blocks) {
  131. final cache = GridBlockCache(
  132. gridId: gridId,
  133. block: block,
  134. fieldCache: fieldCache,
  135. );
  136. cache.addListener(onRowsChanged: (reason) {
  137. _onRowsChanged?.call(rowInfos, reason);
  138. });
  139. _blocks[block.id] = cache;
  140. }
  141. final result = await _gridFFIService.loadGroups();
  142. return Future(
  143. () => result.fold(
  144. (groups) {
  145. _didLoadGroup?.call(groups.items);
  146. },
  147. (err) => _onError?.call(err),
  148. ),
  149. );
  150. }
  151. }