board_data_controller.dart 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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/log.dart';
  7. import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
  8. import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
  9. import 'dart:async';
  10. import 'package:dartz/dartz.dart';
  11. import 'package:flowy_sdk/protobuf/flowy-grid/protobuf.dart';
  12. typedef OnFieldsChanged = void Function(UnmodifiableListView<FieldPB>);
  13. typedef OnGridChanged = void Function(GridPB);
  14. typedef OnGroupChanged = void Function(List<GroupPB>);
  15. typedef OnRowsChanged = void Function(
  16. List<RowInfo> rowInfos,
  17. RowChangeReason,
  18. );
  19. typedef OnError = void Function(FlowyError);
  20. class BoardDataController {
  21. final String gridId;
  22. final GridService _gridFFIService;
  23. final GridFieldCache fieldCache;
  24. // key: the block id
  25. final LinkedHashMap<String, GridBlockCache> _blocks;
  26. LinkedHashMap<String, GridBlockCache> get blocks => _blocks;
  27. OnFieldsChanged? _onFieldsChanged;
  28. OnGridChanged? _onGridChanged;
  29. OnGroupChanged? _onGroupChanged;
  30. OnRowsChanged? _onRowsChanged;
  31. OnError? _onError;
  32. List<RowInfo> get rowInfos {
  33. final List<RowInfo> rows = [];
  34. for (var block in _blocks.values) {
  35. rows.addAll(block.rows);
  36. }
  37. return rows;
  38. }
  39. BoardDataController({required ViewPB view})
  40. : gridId = view.id,
  41. _blocks = LinkedHashMap.new(),
  42. _gridFFIService = GridService(gridId: view.id),
  43. fieldCache = GridFieldCache(gridId: view.id);
  44. void addListener({
  45. OnGridChanged? onGridChanged,
  46. OnFieldsChanged? onFieldsChanged,
  47. OnGroupChanged? onGroupChanged,
  48. OnRowsChanged? onRowsChanged,
  49. OnError? onError,
  50. }) {
  51. _onGridChanged = onGridChanged;
  52. _onFieldsChanged = onFieldsChanged;
  53. _onGroupChanged = onGroupChanged;
  54. _onRowsChanged = onRowsChanged;
  55. _onError = onError;
  56. fieldCache.addListener(onFields: (fields) {
  57. _onFieldsChanged?.call(UnmodifiableListView(fields));
  58. });
  59. }
  60. Future<Either<Unit, FlowyError>> loadData() async {
  61. final result = await _gridFFIService.loadGrid();
  62. return Future(
  63. () => result.fold(
  64. (grid) async {
  65. _onGridChanged?.call(grid);
  66. _initialBlocks(grid.blocks);
  67. return await _loadFields(grid).then((result) {
  68. return result.fold(
  69. (l) {
  70. _loadGroups();
  71. return left(l);
  72. },
  73. (err) => right(err),
  74. );
  75. });
  76. },
  77. (err) => right(err),
  78. ),
  79. );
  80. }
  81. void createRow() {
  82. _gridFFIService.createRow();
  83. }
  84. Future<void> dispose() async {
  85. await _gridFFIService.closeGrid();
  86. await fieldCache.dispose();
  87. for (final blockCache in _blocks.values) {
  88. blockCache.dispose();
  89. }
  90. }
  91. void _initialBlocks(List<BlockPB> blocks) {
  92. for (final block in blocks) {
  93. if (_blocks[block.id] != null) {
  94. Log.warn("Initial duplicate block's cache: ${block.id}");
  95. return;
  96. }
  97. final cache = GridBlockCache(
  98. gridId: gridId,
  99. block: block,
  100. fieldCache: fieldCache,
  101. );
  102. cache.addListener(
  103. onChangeReason: (reason) {
  104. _onRowsChanged?.call(rowInfos, reason);
  105. },
  106. );
  107. _blocks[block.id] = cache;
  108. }
  109. }
  110. Future<Either<Unit, FlowyError>> _loadFields(GridPB grid) async {
  111. final result = await _gridFFIService.getFields(fieldIds: grid.fields);
  112. return Future(
  113. () => result.fold(
  114. (fields) {
  115. fieldCache.fields = fields.items;
  116. _onFieldsChanged?.call(UnmodifiableListView(fieldCache.fields));
  117. return left(unit);
  118. },
  119. (err) => right(err),
  120. ),
  121. );
  122. }
  123. Future<void> _loadGroups() async {
  124. final result = await _gridFFIService.loadGroups();
  125. return Future(
  126. () => result.fold(
  127. (groups) {
  128. _onGroupChanged?.call(groups.items);
  129. },
  130. (err) => _onError?.call(err),
  131. ),
  132. );
  133. }
  134. }