board_data_controller.dart 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. _blocks = LinkedHashMap.new(),
  47. _gridFFIService = GridFFIService(gridId: view.id),
  48. fieldCache = GridFieldCache(gridId: view.id);
  49. void addListener({
  50. required OnGridChanged onGridChanged,
  51. OnFieldsChanged? onFieldsChanged,
  52. required DidLoadGroups didLoadGroups,
  53. required OnRowsChanged onRowsChanged,
  54. required OnUpdatedGroup onUpdatedGroup,
  55. required OnDeletedGroup onDeletedGroup,
  56. required OnInsertedGroup onInsertedGroup,
  57. required OnError? onError,
  58. }) {
  59. _onGridChanged = onGridChanged;
  60. _onFieldsChanged = onFieldsChanged;
  61. _didLoadGroup = didLoadGroups;
  62. _onRowsChanged = onRowsChanged;
  63. _onError = onError;
  64. fieldCache.addListener(onFields: (fields) {
  65. _onFieldsChanged?.call(UnmodifiableListView(fields));
  66. });
  67. _listener.start(onBoardChanged: (result) {
  68. result.fold(
  69. (changeset) {
  70. if (changeset.updateGroups.isNotEmpty) {
  71. onUpdatedGroup.call(changeset.updateGroups);
  72. }
  73. if (changeset.insertedGroups.isNotEmpty) {
  74. onInsertedGroup.call(changeset.insertedGroups);
  75. }
  76. if (changeset.deletedGroups.isNotEmpty) {
  77. onDeletedGroup.call(changeset.deletedGroups);
  78. }
  79. },
  80. (e) => _onError?.call(e),
  81. );
  82. });
  83. }
  84. Future<Either<Unit, FlowyError>> loadData() async {
  85. final result = await _gridFFIService.loadGrid();
  86. return Future(
  87. () => result.fold(
  88. (grid) async {
  89. _onGridChanged?.call(grid);
  90. return await _loadFields(grid).then((result) {
  91. return result.fold(
  92. (l) {
  93. _loadGroups(grid.blocks);
  94. return left(l);
  95. },
  96. (err) => right(err),
  97. );
  98. });
  99. },
  100. (err) => right(err),
  101. ),
  102. );
  103. }
  104. Future<Either<RowPB, FlowyError>> createBoardCard(String groupId) {
  105. return _gridFFIService.createBoardCard(groupId);
  106. }
  107. Future<void> dispose() async {
  108. await _gridFFIService.closeGrid();
  109. await fieldCache.dispose();
  110. for (final blockCache in _blocks.values) {
  111. blockCache.dispose();
  112. }
  113. }
  114. Future<Either<Unit, FlowyError>> _loadFields(GridPB grid) async {
  115. final result = await _gridFFIService.getFields(fieldIds: grid.fields);
  116. return Future(
  117. () => result.fold(
  118. (fields) {
  119. fieldCache.fields = fields.items;
  120. _onFieldsChanged?.call(UnmodifiableListView(fieldCache.fields));
  121. return left(unit);
  122. },
  123. (err) => right(err),
  124. ),
  125. );
  126. }
  127. Future<void> _loadGroups(List<BlockPB> blocks) async {
  128. for (final block in blocks) {
  129. final cache = GridBlockCache(
  130. gridId: gridId,
  131. block: block,
  132. fieldCache: fieldCache,
  133. );
  134. cache.addListener(onRowsChanged: (reason) {
  135. _onRowsChanged?.call(rowInfos, reason);
  136. });
  137. _blocks[block.id] = cache;
  138. }
  139. final result = await _gridFFIService.loadGroups();
  140. return Future(
  141. () => result.fold(
  142. (groups) {
  143. _didLoadGroup?.call(groups.items);
  144. },
  145. (err) => _onError?.call(err),
  146. ),
  147. );
  148. }
  149. }