From a73987456ec75ba467e31d73b926bcdab507b151 Mon Sep 17 00:00:00 2001 From: appflowy Date: Sat, 16 Jul 2022 11:53:39 +0800 Subject: [PATCH] chore: add documentation --- .../application/grid/block/block_service.dart | 6 +- .../grid/cell/cell_service/cache.dart | 39 ++++---- .../cell/cell_service/cell_data_loader.dart | 26 +---- .../cell_service/cell_data_persistence.dart | 8 +- .../cell_service/cell_field_notifier.dart | 7 +- .../grid/cell/cell_service/cell_service.dart | 15 +-- .../cell/cell_service/context_builder.dart | 94 ++++++++++++------- .../grid/cell/select_option_editor_bloc.dart | 2 +- .../grid/cell/select_option_service.dart | 2 +- .../application/grid/field/field_service.dart | 4 + .../grid/field/type_option/date_bloc.dart | 2 +- .../type_option/multi_select_type_option.dart | 4 +- .../grid/field/type_option/number_bloc.dart | 2 +- .../single_select_type_option.dart | 4 +- .../type_option/type_option_service.dart | 10 +- .../workspace/application/grid/grid_bloc.dart | 6 +- .../application/grid/grid_service.dart | 4 +- .../application/grid/row/row_detail_bloc.dart | 4 +- .../application/grid/row/row_service.dart | 20 ++-- .../grid/src/widgets/cell/cell_builder.dart | 6 +- .../src/widgets/cell/date_cell/date_cell.dart | 2 +- .../widgets/cell/date_cell/date_editor.dart | 10 +- .../widgets/cell/url_cell/cell_editor.dart | 8 +- .../src/widgets/cell/url_cell/url_cell.dart | 2 +- .../widgets/header/type_option/builder.dart | 10 +- .../widgets/header/type_option/checkbox.dart | 2 +- .../widgets/header/type_option/rich_text.dart | 2 +- .../src/widgets/header/type_option/url.dart | 2 +- .../grid/src/widgets/row/row_detail.dart | 2 +- 29 files changed, 161 insertions(+), 144 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/block/block_service.dart b/frontend/app_flowy/lib/workspace/application/grid/block/block_service.dart index a531e65d2e..2a4c82bdd4 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/block/block_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/block/block_service.dart @@ -6,7 +6,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/block_entities.pb.dart'; import 'block_listener.dart'; -class GridBlockCacheService { +class GridBlockCache { final String gridId; final GridBlock block; late GridRowsCache _rowCache; @@ -15,7 +15,7 @@ class GridBlockCacheService { List get rows => _rowCache.rows; GridRowsCache get rowCache => _rowCache; - GridBlockCacheService({ + GridBlockCache({ required this.gridId, required this.block, required GridFieldCache fieldCache, @@ -23,7 +23,7 @@ class GridBlockCacheService { _rowCache = GridRowsCache( gridId: gridId, block: block, - delegate: GridRowCacheDelegateImpl(fieldCache), + notifier: GridRowCacheFieldNotifierImpl(fieldCache), ); _listener = GridBlockListener(blockId: block.id); diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cache.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cache.dart index a6079bae6d..dd50e98cd5 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cache.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cache.dart @@ -1,25 +1,29 @@ part of 'cell_service.dart'; -typedef GridCellMap = LinkedHashMap; +typedef GridCellMap = LinkedHashMap; -class _GridCellCacheItem { - GridCellId key; +class _GridCellCacheValue { + GridCellCacheKey key; dynamic object; - _GridCellCacheItem({ + _GridCellCacheValue({ required this.key, required this.object, }); } -class GridCellId { +/// Use to index the cell in the grid. +/// We use [fieldId + rowId] to identify the cell. +class GridCellCacheKey { final String fieldId; final String rowId; - GridCellId({ + GridCellCacheKey({ required this.fieldId, required this.rowId, }); } +/// GridCellsCache is used to cache cell data of each Grid. +/// We use GridCellCacheKey to index the cell in the cache. class GridCellsCache { final String gridId; @@ -33,29 +37,28 @@ class GridCellsCache { _cellDataByFieldId.remove(fieldId); } - void insert(T item) { - var map = _cellDataByFieldId[item.key.fieldId]; + void insert(T value) { + var map = _cellDataByFieldId[value.key.fieldId]; if (map == null) { - _cellDataByFieldId[item.key.fieldId] = {}; - map = _cellDataByFieldId[item.key.fieldId]; + _cellDataByFieldId[value.key.fieldId] = {}; + map = _cellDataByFieldId[value.key.fieldId]; } - map![item.key.rowId] = item.object; + map![value.key.rowId] = value.object; } - T? get(GridCellId key) { + T? get(GridCellCacheKey key) { final map = _cellDataByFieldId[key.fieldId]; if (map == null) { return null; } else { - final object = map[key.rowId]; - if (object is T) { - return object; + final value = map[key.rowId]; + if (value is T) { + return value; } else { - if (object != null) { - Log.error("Cache data type does not match the cache data type"); + if (value != null) { + Log.error("Expected value type: $T, but receive $value"); } - return null; } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_data_loader.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_data_loader.dart index 95b7b77b61..dfbd7e197b 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_data_loader.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_data_loader.dart @@ -5,40 +5,22 @@ abstract class IGridCellDataConfig { bool get reloadOnFieldChanged; } -class GridCellDataConfig implements IGridCellDataConfig { - @override - final bool reloadOnFieldChanged; - - const GridCellDataConfig({ - this.reloadOnFieldChanged = false, - }); -} - -abstract class IGridCellDataLoader { - Future loadData(); - - IGridCellDataConfig get config; -} - abstract class ICellDataParser { T? parserData(List data); } -class GridCellDataLoader extends IGridCellDataLoader { +class GridCellDataLoader { final CellService service = CellService(); - final GridCell gridCell; + final GridCellIdentifier gridCell; final ICellDataParser parser; - - @override - final IGridCellDataConfig config; + final bool reloadOnFieldChanged; GridCellDataLoader({ required this.gridCell, required this.parser, - this.config = const GridCellDataConfig(), + this.reloadOnFieldChanged = false, }); - @override Future loadData() { final fut = service.getCell( gridId: gridCell.gridId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_data_persistence.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_data_persistence.dart index 9e2f577d7c..4eebda7839 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_data_persistence.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_data_persistence.dart @@ -1,11 +1,13 @@ part of 'cell_service.dart'; +/// Save the cell data to disk +/// You can extend this class to do custom operations. For example, the DateCellDataPersistence. abstract class IGridCellDataPersistence { Future> save(D data); } class CellDataPersistence implements IGridCellDataPersistence { - final GridCell gridCell; + final GridCellIdentifier gridCell; CellDataPersistence({ required this.gridCell, @@ -36,7 +38,7 @@ class CalendarData with _$CalendarData { } class DateCellDataPersistence implements IGridCellDataPersistence { - final GridCell gridCell; + final GridCellIdentifier gridCell; DateCellDataPersistence({ required this.gridCell, }); @@ -61,7 +63,7 @@ class DateCellDataPersistence implements IGridCellDataPersistence } } -CellIdentifierPayload _cellIdentifier(GridCell gridCell) { +CellIdentifierPayload _cellIdentifier(GridCellIdentifier gridCell) { return CellIdentifierPayload.create() ..gridId = gridCell.gridId ..fieldId = gridCell.field.id diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_field_notifier.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_field_notifier.dart index 1c043e2096..e4c909d501 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_field_notifier.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_field_notifier.dart @@ -8,6 +8,8 @@ abstract class GridFieldChangedNotifier { void dispose(); } +/// Grid's cell helper wrapper that enables each cell will get notified when the corresponding field was changed. +/// You Register an onFieldChanged callback to listen to the cell changes, and unregister if you don't want to listen. class GridCellFieldNotifier { /// fieldId: {objectId: callback} final Map>> _fieldListenerByFieldId = {}; @@ -27,7 +29,8 @@ class GridCellFieldNotifier { ); } - void addFieldListener(GridCellId cacheKey, VoidCallback onFieldChanged) { + /// + void register(GridCellCacheKey cacheKey, VoidCallback onFieldChanged) { var map = _fieldListenerByFieldId[cacheKey.fieldId]; if (map == null) { _fieldListenerByFieldId[cacheKey.fieldId] = {}; @@ -43,7 +46,7 @@ class GridCellFieldNotifier { } } - void removeFieldListener(GridCellId cacheKey, VoidCallback fn) { + void unregister(GridCellCacheKey cacheKey, VoidCallback fn) { var callbacks = _fieldListenerByFieldId[cacheKey.fieldId]?[cacheKey.rowId]; final index = callbacks?.indexWhere((callback) => callback == fn); if (index != null && index != -1) { diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart index 6c7791af92..2cf9536f2d 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart @@ -18,6 +18,7 @@ import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/field/field_service.dart'; import 'dart:convert' show utf8; +import '../../field/type_option/type_option_service.dart'; import 'cell_field_notifier.dart'; part 'cell_service.freezed.dart'; part 'cell_data_loader.dart'; @@ -57,18 +58,20 @@ class CellService { } } +/// Id of the cell +/// We can locate the cell by using gridId + rowId + field.id. @freezed -class GridCell with _$GridCell { - const factory GridCell({ +class GridCellIdentifier with _$GridCellIdentifier { + const factory GridCellIdentifier({ required String gridId, required String rowId, required Field field, - }) = _GridCell; + }) = _GridCellIdentifier; // ignore: unused_element - const GridCell._(); + const GridCellIdentifier._(); - String cellId() { - return rowId + field.id + "${field.fieldType}"; + ValueKey key() { + return ValueKey(rowId + field.id + "${field.fieldType}"); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart index f45520c602..0ec9e1753f 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart @@ -6,12 +6,12 @@ typedef GridDateCellController = IGridCellController typedef GridURLCellController = IGridCellController; class GridCellControllerBuilder { - final GridCell _gridCell; + final GridCellIdentifier _gridCell; final GridCellsCache _cellCache; final GridFieldCache _fieldCache; GridCellControllerBuilder( - {required GridCell gridCell, required GridCellsCache cellCache, required GridFieldCache fieldCache}) + {required GridCellIdentifier gridCell, required GridCellsCache cellCache, required GridFieldCache fieldCache}) : _cellCache = cellCache, _fieldCache = fieldCache, _gridCell = gridCell; @@ -29,34 +29,33 @@ class GridCellControllerBuilder { gridCell: _gridCell, cellCache: _cellCache, cellDataLoader: cellDataLoader, - cellFieldNotifier: cellFieldNotifier, + fieldNotifier: cellFieldNotifier, cellDataPersistence: CellDataPersistence(gridCell: _gridCell), ); case FieldType.DateTime: final cellDataLoader = GridCellDataLoader( gridCell: _gridCell, parser: DateCellDataParser(), - config: const GridCellDataConfig(reloadOnFieldChanged: true), + reloadOnFieldChanged: true, ); return GridDateCellController( gridCell: _gridCell, cellCache: _cellCache, cellDataLoader: cellDataLoader, - cellFieldNotifier: cellFieldNotifier, + fieldNotifier: cellFieldNotifier, cellDataPersistence: DateCellDataPersistence(gridCell: _gridCell), ); case FieldType.Number: final cellDataLoader = GridCellDataLoader( gridCell: _gridCell, parser: StringCellDataParser(), - config: const GridCellDataConfig(reloadOnFieldChanged: true), ); return GridCellController( gridCell: _gridCell, cellCache: _cellCache, cellDataLoader: cellDataLoader, - cellFieldNotifier: cellFieldNotifier, + fieldNotifier: cellFieldNotifier, cellDataPersistence: CellDataPersistence(gridCell: _gridCell), ); case FieldType.RichText: @@ -68,7 +67,7 @@ class GridCellControllerBuilder { gridCell: _gridCell, cellCache: _cellCache, cellDataLoader: cellDataLoader, - cellFieldNotifier: cellFieldNotifier, + fieldNotifier: cellFieldNotifier, cellDataPersistence: CellDataPersistence(gridCell: _gridCell), ); case FieldType.MultiSelect: @@ -76,14 +75,14 @@ class GridCellControllerBuilder { final cellDataLoader = GridCellDataLoader( gridCell: _gridCell, parser: SelectOptionCellDataParser(), - config: const GridCellDataConfig(reloadOnFieldChanged: true), + reloadOnFieldChanged: true, ); return GridSelectOptionCellController( gridCell: _gridCell, cellCache: _cellCache, cellDataLoader: cellDataLoader, - cellFieldNotifier: cellFieldNotifier, + fieldNotifier: cellFieldNotifier, cellDataPersistence: CellDataPersistence(gridCell: _gridCell), ); @@ -96,7 +95,7 @@ class GridCellControllerBuilder { gridCell: _gridCell, cellCache: _cellCache, cellDataLoader: cellDataLoader, - cellFieldNotifier: cellFieldNotifier, + fieldNotifier: cellFieldNotifier, cellDataPersistence: CellDataPersistence(gridCell: _gridCell), ); } @@ -104,17 +103,21 @@ class GridCellControllerBuilder { } } -// T: the type of the CellData -// D: the type of the data that will be saved to disk +/// IGridCellController is used to manipulate the cell and receive notifications. +/// * Read/Write cell data +/// * Listen on field/cell notifications. +/// +/// Generic T represents the type of the cell data. +/// Generic D represents the type of data that will be saved to the disk +/// // ignore: must_be_immutable class IGridCellController extends Equatable { - final GridCell gridCell; + final GridCellIdentifier gridCell; final GridCellsCache _cellsCache; - final GridCellId _cacheKey; + final GridCellCacheKey _cacheKey; final FieldService _fieldService; - final GridCellFieldNotifier _cellFieldNotifier; - // final GridCellFieldNotifier _fieldNotifier; - final IGridCellDataLoader _cellDataLoader; + final GridCellFieldNotifier _fieldNotifier; + final GridCellDataLoader _cellDataLoader; final IGridCellDataPersistence _cellDataPersistence; late final CellListener _cellListener; @@ -124,28 +127,27 @@ class IGridCellController extends Equatable { VoidCallback? _onFieldChangedFn; Timer? _loadDataOperation; Timer? _saveDataOperation; - bool isDispose = false; + bool _isDispose = false; IGridCellController({ required this.gridCell, required GridCellsCache cellCache, - required GridCellFieldNotifier cellFieldNotifier, - required IGridCellDataLoader cellDataLoader, + required GridCellFieldNotifier fieldNotifier, + required GridCellDataLoader cellDataLoader, required IGridCellDataPersistence cellDataPersistence, - // required GridFieldChangedNotifier notifierDelegate, }) : _cellsCache = cellCache, _cellDataLoader = cellDataLoader, _cellDataPersistence = cellDataPersistence, - _cellFieldNotifier = cellFieldNotifier, + _fieldNotifier = fieldNotifier, _fieldService = FieldService(gridId: gridCell.gridId, fieldId: gridCell.field.id), - _cacheKey = GridCellId(rowId: gridCell.rowId, fieldId: gridCell.field.id); + _cacheKey = GridCellCacheKey(rowId: gridCell.rowId, fieldId: gridCell.field.id); IGridCellController clone() { return IGridCellController( gridCell: gridCell, cellDataLoader: _cellDataLoader, cellCache: _cellsCache, - cellFieldNotifier: _cellFieldNotifier, + fieldNotifier: _fieldNotifier, cellDataPersistence: _cellDataPersistence); } @@ -191,16 +193,18 @@ class IGridCellController extends Equatable { onCellFieldChanged(); } - if (_cellDataLoader.config.reloadOnFieldChanged) { + if (_cellDataLoader.reloadOnFieldChanged) { _loadData(); } }; - _cellFieldNotifier.addFieldListener(_cacheKey, _onFieldChangedFn!); + _fieldNotifier.register(_cacheKey, _onFieldChangedFn!); /// Notify the listener, the cell data was changed. onCellChangedFn() => onCellChanged(_cellDataNotifier?.value); _cellDataNotifier?.addListener(onCellChangedFn); + + // Return the function pointer that can be used when calling removeListener. return onCellChangedFn; } @@ -208,22 +212,38 @@ class IGridCellController extends Equatable { _cellDataNotifier?.removeListener(fn); } - T? getCellData({bool loadIfNoCache = true}) { + /// Return the cell data. + /// The cell data will be read from the Cache first, and load from disk if it does not exist. + /// You can set [loadIfNotExist] to false (default is true) to disable loading the cell data. + T? getCellData({bool loadIfNotExist = true}) { final data = _cellsCache.get(_cacheKey); - if (data == null && loadIfNoCache) { + if (data == null && loadIfNotExist) { _loadData(); } return data; } - Future> getTypeOptionData() { - return _fieldService.getFieldTypeOptionData(fieldType: fieldType); + /// Return the FieldTypeOptionData that can be parsed into corresponding class using the [parser]. + /// [PD] is the type that the parser return. + Future> getFieldTypeOption(P parser) { + return _fieldService.getFieldTypeOptionData(fieldType: fieldType).then((result) { + return result.fold( + (data) => parser.fromBuffer(data.typeOptionData), + (err) => right(err), + ); + }); } + /// Save the cell data to disk + /// You can set [dedeplicate] to true (default is false) to reduce the save operation. + /// It's useful when you call this method when user editing the [TextField]. + /// The default debounce interval is 300 milliseconds. void saveCellData(D data, {bool deduplicate = false, void Function(Option)? resultCallback}) async { if (deduplicate) { _loadDataOperation?.cancel(); - _loadDataOperation = Timer(const Duration(milliseconds: 300), () async { + + _saveDataOperation?.cancel(); + _saveDataOperation = Timer(const Duration(milliseconds: 300), () async { final result = await _cellDataPersistence.save(data); if (resultCallback != null) { resultCallback(result); @@ -238,28 +258,30 @@ class IGridCellController extends Equatable { } void _loadData() { + _saveDataOperation?.cancel(); + _loadDataOperation?.cancel(); _loadDataOperation = Timer(const Duration(milliseconds: 10), () { _cellDataLoader.loadData().then((data) { _cellDataNotifier?.value = data; - _cellsCache.insert(_GridCellCacheItem(key: _cacheKey, object: data)); + _cellsCache.insert(_GridCellCacheValue(key: _cacheKey, object: data)); }); }); } void dispose() { - if (isDispose) { + if (_isDispose) { Log.error("$this should only dispose once"); return; } - isDispose = true; + _isDispose = true; _cellListener.stop(); _loadDataOperation?.cancel(); _saveDataOperation?.cancel(); _cellDataNotifier = null; if (_onFieldChangedFn != null) { - _cellFieldNotifier.removeFieldListener(_cacheKey, _onFieldChangedFn!); + _fieldNotifier.unregister(_cacheKey, _onFieldChangedFn!); _onFieldChangedFn = null; } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_editor_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_editor_bloc.dart index 139d29141b..b531955ab7 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_editor_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_editor_bloc.dart @@ -184,7 +184,7 @@ class SelectOptionEditorState with _$SelectOptionEditorState { }) = _SelectOptionEditorState; factory SelectOptionEditorState.initial(GridSelectOptionCellController context) { - final data = context.getCellData(loadIfNoCache: false); + final data = context.getCellData(loadIfNotExist: false); return SelectOptionEditorState( options: data?.options ?? [], allOptions: data?.options ?? [], diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart index f3458454d1..147b24d468 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/select_option_service.dart @@ -7,7 +7,7 @@ import 'package:flowy_sdk/protobuf/flowy-grid/select_option.pb.dart'; import 'cell_service/cell_service.dart'; class SelectOptionService { - final GridCell gridCell; + final GridCellIdentifier gridCell; SelectOptionService({required this.gridCell}); String get gridId => gridCell.gridId; diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart index 99fef626c0..879cf599dd 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/field_service.dart @@ -9,6 +9,10 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:protobuf/protobuf.dart'; part 'field_service.freezed.dart'; +/// FieldService consists of lots of event functions. We define the events in the backend(Rust), +/// you can find the corresponding event implementation in event_map.rs of the corresponding crate. +/// +/// You could check out the rust-lib/flowy-grid/event_map.rs for more information. class FieldService { final String gridId; final String fieldId; diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart index 73be8a427e..7258854ec6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/date_bloc.dart @@ -8,7 +8,7 @@ part 'date_bloc.freezed.dart'; typedef DateTypeOptionContext = TypeOptionWidgetContext; -class DateTypeOptionDataParser extends TypeOptionWidgetDataParser { +class DateTypeOptionDataParser extends TypeOptionDataParser { @override DateTypeOption fromBuffer(List buffer) { return DateTypeOption.fromBuffer(buffer); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_type_option.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_type_option.dart index f36974f8e3..eae1765396 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_type_option.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/multi_select_type_option.dart @@ -18,7 +18,7 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext Function(SelectOption) get deleteOption { @@ -71,7 +71,7 @@ class MultiSelectTypeOptionContext extends TypeOptionWidgetContext { +class MultiSelectTypeOptionWidgetDataParser extends TypeOptionDataParser { @override MultiSelectTypeOption fromBuffer(List buffer) { return MultiSelectTypeOption.fromBuffer(buffer); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart index ea51970b32..804ce3ee11 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_bloc.dart @@ -10,7 +10,7 @@ part 'number_bloc.freezed.dart'; typedef NumberTypeOptionContext = TypeOptionWidgetContext; -class NumberTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser { +class NumberTypeOptionWidgetDataParser extends TypeOptionDataParser { @override NumberTypeOption fromBuffer(List buffer) { return NumberTypeOption.fromBuffer(buffer); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_type_option.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_type_option.dart index 0dc05e8e1f..16e686fb44 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_type_option.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/single_select_type_option.dart @@ -18,7 +18,7 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext Function(SelectOption) get deleteOption { @@ -71,7 +71,7 @@ class SingleSelectTypeOptionContext extends TypeOptionWidgetContext { +class SingleSelectTypeOptionWidgetDataParser extends TypeOptionDataParser { @override SingleSelectTypeOption fromBuffer(List buffer) { return SingleSelectTypeOption.fromBuffer(buffer); diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart index 84faa3c35a..05ca9e9aa1 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/type_option_service.dart @@ -33,17 +33,17 @@ class TypeOptionService { } } -abstract class TypeOptionWidgetDataParser { +abstract class TypeOptionDataParser { T fromBuffer(List buffer); } class TypeOptionWidgetContext { T? _typeOptionObject; final GridFieldContext _fieldContext; - final TypeOptionWidgetDataParser dataBuilder; + final TypeOptionDataParser dataParser; TypeOptionWidgetContext({ - required this.dataBuilder, + required this.dataParser, required GridFieldContext fieldContext, }) : _fieldContext = fieldContext; @@ -56,7 +56,7 @@ class TypeOptionWidgetContext { return _typeOptionObject!; } - final T object = dataBuilder.fromBuffer(_fieldContext.typeOptionData); + final T object = dataParser.fromBuffer(_fieldContext.typeOptionData); _typeOptionObject = object; return object; } @@ -77,7 +77,7 @@ class TypeOptionContext2 { final Field field; final FieldService _fieldService; T? _data; - final TypeOptionWidgetDataParser dataBuilder; + final TypeOptionDataParser dataBuilder; TypeOptionContext2({ required this.gridId, diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart index e6fff41317..3098ca1609 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_bloc.dart @@ -20,7 +20,7 @@ class GridBloc extends Bloc { final GridFieldCache fieldCache; // key: the block id - final LinkedHashMap _blocks; + final LinkedHashMap _blocks; List get rows { final List rows = []; @@ -69,7 +69,7 @@ class GridBloc extends Bloc { } GridRowsCache? getRowCache(String blockId, String rowId) { - final GridBlockCacheService? blockCache = _blocks[blockId]; + final GridBlockCache? blockCache = _blocks[blockId]; return blockCache?.rowCache; } @@ -119,7 +119,7 @@ class GridBloc extends Bloc { return; } - final cache = GridBlockCacheService( + final cache = GridBlockCache( gridId: gridId, block: block, fieldCache: fieldCache, diff --git a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart index 3e9cbc2eee..0e176df919 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/grid_service.dart @@ -186,11 +186,11 @@ class GridFieldCache { } } -class GridRowCacheDelegateImpl extends GridRowCacheDelegate { +class GridRowCacheFieldNotifierImpl extends GridRowCacheFieldNotifier { final GridFieldCache _cache; FieldChangesetCallback? _onChangesetFn; FieldsCallback? _onFieldFn; - GridRowCacheDelegateImpl(GridFieldCache cache) : _cache = cache; + GridRowCacheFieldNotifierImpl(GridFieldCache cache) : _cache = cache; @override UnmodifiableListView get fields => _cache.unmodifiableFields; diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart index 0613b388a4..405c0ef523 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_detail_bloc.dart @@ -58,13 +58,13 @@ class RowDetailBloc extends Bloc { @freezed class RowDetailEvent with _$RowDetailEvent { const factory RowDetailEvent.initial() = _Initial; - const factory RowDetailEvent.didReceiveCellDatas(List gridCells) = _DidReceiveCellDatas; + const factory RowDetailEvent.didReceiveCellDatas(List gridCells) = _DidReceiveCellDatas; } @freezed class RowDetailState with _$RowDetailState { const factory RowDetailState({ - required List gridCells, + required List gridCells, }) = _RowDetailState; factory RowDetailState.initial() => RowDetailState( diff --git a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart index 27749083b4..df8a068598 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/row/row_service.dart @@ -14,7 +14,7 @@ part 'row_service.freezed.dart'; typedef RowUpdateCallback = void Function(); -abstract class GridRowCacheDelegate { +abstract class GridRowCacheFieldNotifier { UnmodifiableListView get fields; void onFieldsChanged(VoidCallback callback); void onFieldChanged(void Function(Field) callback); @@ -27,7 +27,7 @@ class GridRowsCache { final _Notifier _notifier; List _rows = []; final HashMap _rowByRowId; - final GridRowCacheDelegate _delegate; + final GridRowCacheFieldNotifier _fieldNotifier; final GridCellsCache _cellCache; List get rows => _rows; @@ -36,19 +36,19 @@ class GridRowsCache { GridRowsCache({ required this.gridId, required this.block, - required GridRowCacheDelegate delegate, + required GridRowCacheFieldNotifier notifier, }) : _cellCache = GridCellsCache(gridId: gridId), _rowByRowId = HashMap(), _notifier = _Notifier(), - _delegate = delegate { + _fieldNotifier = notifier { // - delegate.onFieldsChanged(() => _notifier.receive(const GridRowChangeReason.fieldDidChange())); - delegate.onFieldChanged((field) => _cellCache.remove(field.id)); + notifier.onFieldsChanged(() => _notifier.receive(const GridRowChangeReason.fieldDidChange())); + notifier.onFieldChanged((field) => _cellCache.remove(field.id)); _rows = block.rowInfos.map((rowInfo) => buildGridRow(rowInfo.rowId, rowInfo.height.toDouble())).toList(); } Future dispose() async { - _delegate.dispose(); + _fieldNotifier.dispose(); _notifier.dispose(); await _cellCache.dispose(); } @@ -195,9 +195,9 @@ class GridRowsCache { GridCellMap _makeGridCells(String rowId, Row? row) { var cellDataMap = GridCellMap.new(); - for (final field in _delegate.fields) { + for (final field in _fieldNotifier.fields) { if (field.visibility) { - cellDataMap[field.id] = GridCell( + cellDataMap[field.id] = GridCellIdentifier( rowId: rowId, gridId: gridId, field: field, @@ -236,7 +236,7 @@ class GridRowsCache { return GridRow( gridId: gridId, blockId: block.id, - fields: _delegate.fields, + fields: _fieldNotifier.fields, rowId: rowId, height: rowHeight, ); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart index a17384dd59..1fd4c726be 100755 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/cell_builder.dart @@ -21,15 +21,13 @@ class GridCellBuilder { required this.fieldCache, }); - GridCellWidget build(GridCell cell, {GridCellStyle? style}) { - final key = ValueKey(cell.cellId()); - + GridCellWidget build(GridCellIdentifier cell, {GridCellStyle? style}) { final cellControllerBuilder = GridCellControllerBuilder( gridCell: cell, cellCache: cellCache, fieldCache: fieldCache, ); - + final key = cell.key(); switch (cell.field.fieldType) { case FieldType.Checkbox: return CheckboxCell(cellControllerBuilder: cellControllerBuilder, key: key); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/date_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/date_cell.dart index efcb107e55..7436d0ac7f 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/date_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/date_cell.dart @@ -80,7 +80,7 @@ class _DateCellState extends GridCellState { final calendar = DateCellEditor(onDismissed: () => widget.onCellEditing.value = false); calendar.show( context, - cellContext: bloc.cellContext.clone(), + cellController: bloc.cellContext.clone(), ); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/date_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/date_editor.dart index 5dcd552fef..36ad22ec53 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/date_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/date_editor.dart @@ -31,16 +31,16 @@ class DateCellEditor with FlowyOverlayDelegate { Future show( BuildContext context, { - required GridDateCellController cellContext, + required GridDateCellController cellController, }) async { DateCellEditor.remove(context); - final result = await cellContext.getTypeOptionData(); + final result = await cellController.getFieldTypeOption(DateTypeOptionDataParser()); result.fold( - (data) { + (dateTypeOption) { final calendar = _CellCalendarWidget( - cellContext: cellContext, - dateTypeOption: DateTypeOption.fromBuffer(data.typeOptionData), + cellContext: cellController, + dateTypeOption: dateTypeOption, ); FlowyOverlay.of(context).insertWithAnchor( diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/cell_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/cell_editor.dart index f756bceb32..b6bc8daa21 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/cell_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/cell_editor.dart @@ -7,9 +7,9 @@ import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate { - final GridURLCellController cellContext; + final GridURLCellController cellController; final VoidCallback completed; - const URLCellEditor({required this.cellContext, required this.completed, Key? key}) : super(key: key); + const URLCellEditor({required this.cellController, required this.completed, Key? key}) : super(key: key); @override State createState() => _URLCellEditorState(); @@ -21,7 +21,7 @@ class URLCellEditor extends StatefulWidget with FlowyOverlayDelegate { ) { FlowyOverlay.of(context).remove(identifier()); final editor = URLCellEditor( - cellContext: cellContext, + cellController: cellContext, completed: completed, ); @@ -62,7 +62,7 @@ class _URLCellEditorState extends State { @override void initState() { - _cellBloc = URLCellEditorBloc(cellContext: widget.cellContext); + _cellBloc = URLCellEditorBloc(cellContext: widget.cellController); _cellBloc.add(const URLCellEditorEvent.initial()); _controller = TextEditingController(text: _cellBloc.state.content); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/url_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/url_cell.dart index 0edb65a7dc..9cc14fbbda 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/url_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/url_cell/url_cell.dart @@ -187,7 +187,7 @@ class _CopyURLAccessory extends StatelessWidget with GridCellAccessory { @override void onTap() { - final content = cellContext.getCellData(loadIfNoCache: false)?.content ?? ""; + final content = cellContext.getCellData(loadIfNotExist: false)?.content ?? ""; Clipboard.setData(ClipboardData(text: content)); showMessageToast(LocaleKeys.grid_row_copyProperty.tr()); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/builder.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/builder.dart index 872a501f90..f63edbac14 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/builder.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/builder.dart @@ -51,13 +51,13 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder( case FieldType.Checkbox: final context = CheckboxTypeOptionContext( fieldContext: fieldContext, - dataBuilder: CheckboxTypeOptionWidgetDataParser(), + dataParser: CheckboxTypeOptionWidgetDataParser(), ); return CheckboxTypeOptionWidgetBuilder(context); case FieldType.DateTime: final context = DateTypeOptionContext( fieldContext: fieldContext, - dataBuilder: DateTypeOptionDataParser(), + dataParser: DateTypeOptionDataParser(), ); return DateTypeOptionWidgetBuilder( context, @@ -84,7 +84,7 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder( case FieldType.Number: final context = NumberTypeOptionContext( fieldContext: fieldContext, - dataBuilder: NumberTypeOptionWidgetDataParser(), + dataParser: NumberTypeOptionWidgetDataParser(), ); return NumberTypeOptionWidgetBuilder( context, @@ -93,14 +93,14 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder( case FieldType.RichText: final context = RichTextTypeOptionContext( fieldContext: fieldContext, - dataBuilder: RichTextTypeOptionWidgetDataParser(), + dataParser: RichTextTypeOptionWidgetDataParser(), ); return RichTextTypeOptionWidgetBuilder(context); case FieldType.URL: final context = URLTypeOptionContext( fieldContext: fieldContext, - dataBuilder: URLTypeOptionWidgetDataParser(), + dataParser: URLTypeOptionWidgetDataParser(), ); return URLTypeOptionWidgetBuilder(context); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart index 79622a6731..beca8acd09 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/checkbox.dart @@ -5,7 +5,7 @@ import 'builder.dart'; typedef CheckboxTypeOptionContext = TypeOptionWidgetContext; -class CheckboxTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser { +class CheckboxTypeOptionWidgetDataParser extends TypeOptionDataParser { @override CheckboxTypeOption fromBuffer(List buffer) { return CheckboxTypeOption.fromBuffer(buffer); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/rich_text.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/rich_text.dart index f79fb2dd9d..2375918f11 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/rich_text.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/rich_text.dart @@ -5,7 +5,7 @@ import 'builder.dart'; typedef RichTextTypeOptionContext = TypeOptionWidgetContext; -class RichTextTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser { +class RichTextTypeOptionWidgetDataParser extends TypeOptionDataParser { @override RichTextTypeOption fromBuffer(List buffer) { return RichTextTypeOption.fromBuffer(buffer); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/url.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/url.dart index a55711bd05..97c0db0814 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/url.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/url.dart @@ -5,7 +5,7 @@ import 'builder.dart'; typedef URLTypeOptionContext = TypeOptionWidgetContext; -class URLTypeOptionWidgetDataParser extends TypeOptionWidgetDataParser { +class URLTypeOptionWidgetDataParser extends TypeOptionDataParser { @override URLTypeOption fromBuffer(List buffer) { return URLTypeOption.fromBuffer(buffer); diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart index 45dd63eb7f..b342101bc8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/row/row_detail.dart @@ -137,7 +137,7 @@ class _PropertyList extends StatelessWidget { } class _RowDetailCell extends StatelessWidget { - final GridCell gridCell; + final GridCellIdentifier gridCell; final GridCellBuilder cellBuilder; const _RowDetailCell({ required this.gridCell,