board_data_controller.dart 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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_controller.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<GridFieldContext>);
  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 OnResetGroups = void Function(List<GroupPB>);
  19. typedef OnRowsChanged = void Function(
  20. List<RowInfo>,
  21. RowsChangedReason,
  22. );
  23. typedef OnError = void Function(FlowyError);
  24. class BoardDataController {
  25. final String gridId;
  26. final GridFFIService _gridFFIService;
  27. final GridFieldController fieldController;
  28. final BoardListener _listener;
  29. // key: the block id
  30. final LinkedHashMap<String, GridBlockCache> _blocks;
  31. LinkedHashMap<String, GridBlockCache> get blocks => _blocks;
  32. OnFieldsChanged? _onFieldsChanged;
  33. OnGridChanged? _onGridChanged;
  34. DidLoadGroups? _didLoadGroup;
  35. OnRowsChanged? _onRowsChanged;
  36. OnError? _onError;
  37. List<RowInfo> get rowInfos {
  38. final List<RowInfo> rows = [];
  39. for (var block in _blocks.values) {
  40. rows.addAll(block.rows);
  41. }
  42. return rows;
  43. }
  44. BoardDataController({required ViewPB view})
  45. : gridId = view.id,
  46. _listener = BoardListener(view.id),
  47. // ignore: prefer_collection_literals
  48. _blocks = LinkedHashMap(),
  49. _gridFFIService = GridFFIService(gridId: view.id),
  50. fieldController = GridFieldController(gridId: view.id);
  51. void addListener({
  52. required OnGridChanged onGridChanged,
  53. OnFieldsChanged? onFieldsChanged,
  54. required DidLoadGroups didLoadGroups,
  55. OnRowsChanged? onRowsChanged,
  56. required OnUpdatedGroup onUpdatedGroup,
  57. required OnDeletedGroup onDeletedGroup,
  58. required OnInsertedGroup onInsertedGroup,
  59. required OnResetGroups onResetGroups,
  60. required OnError? onError,
  61. }) {
  62. _onGridChanged = onGridChanged;
  63. _onFieldsChanged = onFieldsChanged;
  64. _didLoadGroup = didLoadGroups;
  65. _onRowsChanged = onRowsChanged;
  66. _onError = onError;
  67. fieldController.addListener(onFields: (fields) {
  68. _onFieldsChanged?.call(UnmodifiableListView(fields));
  69. });
  70. _listener.start(
  71. onBoardChanged: (result) {
  72. result.fold(
  73. (changeset) {
  74. if (changeset.updateGroups.isNotEmpty) {
  75. onUpdatedGroup.call(changeset.updateGroups);
  76. }
  77. if (changeset.insertedGroups.isNotEmpty) {
  78. onInsertedGroup.call(changeset.insertedGroups);
  79. }
  80. if (changeset.deletedGroups.isNotEmpty) {
  81. onDeletedGroup.call(changeset.deletedGroups);
  82. }
  83. },
  84. (e) => _onError?.call(e),
  85. );
  86. },
  87. onGroupByNewField: (result) {
  88. result.fold(
  89. (groups) => onResetGroups(groups),
  90. (e) => _onError?.call(e),
  91. );
  92. },
  93. );
  94. }
  95. Future<Either<Unit, FlowyError>> loadData() async {
  96. final result = await _gridFFIService.loadGrid();
  97. return Future(
  98. () => result.fold(
  99. (grid) async {
  100. _onGridChanged?.call(grid);
  101. return await fieldController.loadFields(fieldIds: grid.fields).then(
  102. (result) => result.fold(
  103. (l) {
  104. _loadGroups(grid.blocks);
  105. return left(l);
  106. },
  107. (err) => right(err),
  108. ),
  109. );
  110. },
  111. (err) => right(err),
  112. ),
  113. );
  114. }
  115. Future<Either<RowPB, FlowyError>> createBoardCard(String groupId,
  116. {String? startRowId}) {
  117. return _gridFFIService.createBoardCard(groupId, startRowId);
  118. }
  119. Future<void> dispose() async {
  120. await _gridFFIService.closeGrid();
  121. await fieldController.dispose();
  122. for (final blockCache in _blocks.values) {
  123. blockCache.dispose();
  124. }
  125. }
  126. Future<void> _loadGroups(List<BlockPB> blocks) async {
  127. for (final block in blocks) {
  128. final cache = GridBlockCache(
  129. gridId: gridId,
  130. block: block,
  131. fieldController: fieldController,
  132. );
  133. cache.addListener(onRowsChanged: (reason) {
  134. _onRowsChanged?.call(rowInfos, reason);
  135. });
  136. _blocks[block.id] = cache;
  137. }
  138. final result = await _gridFFIService.loadGroups();
  139. return Future(
  140. () => result.fold(
  141. (groups) {
  142. _didLoadGroup?.call(groups.items);
  143. },
  144. (err) => _onError?.call(err),
  145. ),
  146. );
  147. }
  148. }