board_data_controller.dart 3.9 KB

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