grid_data_controller.dart 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import 'dart:collection';
  2. import 'package:flowy_sdk/log.dart';
  3. import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
  4. import 'package:flowy_sdk/protobuf/flowy-folder/view.pb.dart';
  5. import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart';
  6. import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart';
  7. import 'dart:async';
  8. import 'package:dartz/dartz.dart';
  9. import 'block/block_cache.dart';
  10. import 'field/field_cache.dart';
  11. import 'prelude.dart';
  12. import 'row/row_cache.dart';
  13. typedef OnFieldsChanged = void Function(UnmodifiableListView<GridFieldContext>);
  14. typedef OnGridChanged = void Function(GridPB);
  15. typedef OnRowsChanged = void Function(
  16. List<RowInfo> rowInfos,
  17. RowsChangedReason,
  18. );
  19. typedef ListenOnRowChangedCondition = bool Function();
  20. class GridDataController {
  21. final String gridId;
  22. final GridFFIService _gridFFIService;
  23. final GridFieldController fieldController;
  24. // key: the block id
  25. final LinkedHashMap<String, GridBlockCache> _blocks;
  26. UnmodifiableMapView<String, GridBlockCache> get blocks =>
  27. UnmodifiableMapView(_blocks);
  28. OnRowsChanged? _onRowChanged;
  29. OnFieldsChanged? _onFieldsChanged;
  30. OnGridChanged? _onGridChanged;
  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. GridDataController({required ViewPB view})
  39. : gridId = view.id,
  40. // ignore: prefer_collection_literals
  41. _blocks = LinkedHashMap(),
  42. _gridFFIService = GridFFIService(gridId: view.id),
  43. fieldController = GridFieldController(gridId: view.id);
  44. void addListener({
  45. required OnGridChanged onGridChanged,
  46. required OnRowsChanged onRowsChanged,
  47. required OnFieldsChanged onFieldsChanged,
  48. }) {
  49. _onGridChanged = onGridChanged;
  50. _onRowChanged = onRowsChanged;
  51. _onFieldsChanged = onFieldsChanged;
  52. fieldController.addListener(onFields: (fields) {
  53. _onFieldsChanged?.call(UnmodifiableListView(fields));
  54. });
  55. }
  56. Future<Either<Unit, FlowyError>> loadData() async {
  57. final result = await _gridFFIService.loadGrid();
  58. return Future(
  59. () => result.fold(
  60. (grid) async {
  61. _initialBlocks(grid.blocks);
  62. _onGridChanged?.call(grid);
  63. return await fieldController.loadFields(fieldIds: grid.fields);
  64. },
  65. (err) => right(err),
  66. ),
  67. );
  68. }
  69. void createRow() {
  70. _gridFFIService.createRow();
  71. }
  72. Future<void> dispose() async {
  73. await _gridFFIService.closeGrid();
  74. await fieldController.dispose();
  75. for (final blockCache in _blocks.values) {
  76. blockCache.dispose();
  77. }
  78. }
  79. void _initialBlocks(List<BlockPB> blocks) {
  80. for (final block in blocks) {
  81. if (_blocks[block.id] != null) {
  82. Log.warn("Initial duplicate block's cache: ${block.id}");
  83. return;
  84. }
  85. final cache = GridBlockCache(
  86. gridId: gridId,
  87. block: block,
  88. fieldController: fieldController,
  89. );
  90. cache.addListener(
  91. onRowsChanged: (reason) {
  92. _onRowChanged?.call(rowInfos, reason);
  93. },
  94. );
  95. _blocks[block.id] = cache;
  96. }
  97. }
  98. }