Skip to content

Commit 81cf969

Browse files
authored
Merge pull request #514 from AppFlowy-IO/refactor_cell_data
Refactor cell data
2 parents 78e979e + b8582b9 commit 81cf969

File tree

29 files changed

+432
-524
lines changed

29 files changed

+432
-524
lines changed

frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/cell_service.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
1616
import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
1717
import 'package:app_flowy/workspace/application/grid/cell/select_option_service.dart';
1818
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
19-
19+
import 'dart:convert' show utf8;
2020
part 'cell_service.freezed.dart';
2121
part 'data_loader.dart';
2222
part 'context_builder.dart';

frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
part of 'cell_service.dart';
22

3-
typedef GridCellContext = _GridCellContext<Cell, String>;
3+
typedef GridCellContext = _GridCellContext<String, String>;
44
typedef GridSelectOptionCellContext = _GridCellContext<SelectOptionCellData, String>;
55
typedef GridDateCellContext = _GridCellContext<DateCellData, DateCalData>;
66

@@ -16,26 +16,33 @@ class GridCellContextBuilder {
1616
_GridCellContext build() {
1717
switch (_gridCell.field.fieldType) {
1818
case FieldType.Checkbox:
19+
final cellDataLoader = GridCellDataLoader(
20+
gridCell: _gridCell,
21+
parser: StringCellDataParser(),
22+
);
1923
return GridCellContext(
2024
gridCell: _gridCell,
2125
cellCache: _cellCache,
22-
cellDataLoader: GridCellDataLoader(gridCell: _gridCell),
26+
cellDataLoader: cellDataLoader,
2327
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
2428
);
2529
case FieldType.DateTime:
30+
final cellDataLoader = GridCellDataLoader(
31+
gridCell: _gridCell,
32+
parser: DateCellDataParser(),
33+
);
34+
2635
return GridDateCellContext(
2736
gridCell: _gridCell,
2837
cellCache: _cellCache,
29-
cellDataLoader: DateCellDataLoader(gridCell: _gridCell),
38+
cellDataLoader: cellDataLoader,
3039
cellDataPersistence: DateCellDataPersistence(gridCell: _gridCell),
3140
);
3241
case FieldType.Number:
3342
final cellDataLoader = GridCellDataLoader(
3443
gridCell: _gridCell,
35-
config: const GridCellDataConfig(
36-
reloadOnCellChanged: true,
37-
reloadOnFieldChanged: true,
38-
),
44+
parser: StringCellDataParser(),
45+
config: const GridCellDataConfig(reloadOnCellChanged: true, reloadOnFieldChanged: true),
3946
);
4047
return GridCellContext(
4148
gridCell: _gridCell,
@@ -44,18 +51,28 @@ class GridCellContextBuilder {
4451
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
4552
);
4653
case FieldType.RichText:
54+
final cellDataLoader = GridCellDataLoader(
55+
gridCell: _gridCell,
56+
parser: StringCellDataParser(),
57+
);
4758
return GridCellContext(
4859
gridCell: _gridCell,
4960
cellCache: _cellCache,
50-
cellDataLoader: GridCellDataLoader(gridCell: _gridCell),
61+
cellDataLoader: cellDataLoader,
5162
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
5263
);
5364
case FieldType.MultiSelect:
5465
case FieldType.SingleSelect:
66+
final cellDataLoader = GridCellDataLoader(
67+
gridCell: _gridCell,
68+
parser: SelectOptionCellDataParser(),
69+
config: const GridCellDataConfig(reloadOnFieldChanged: true),
70+
);
71+
5572
return GridSelectOptionCellContext(
5673
gridCell: _gridCell,
5774
cellCache: _cellCache,
58-
cellDataLoader: SelectOptionCellDataLoader(gridCell: _gridCell),
75+
cellDataLoader: cellDataLoader,
5976
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
6077
);
6178
default:
@@ -131,10 +148,7 @@ class _GridCellContext<T, D> extends Equatable {
131148
}
132149

133150
onCellChangedFn() {
134-
final value = _cellDataNotifier.value;
135-
if (value is T) {
136-
onCellChanged(value);
137-
}
151+
onCellChanged(_cellDataNotifier.value as T);
138152

139153
if (cellDataLoader.config.reloadOnCellChanged) {
140154
_loadData();
@@ -149,9 +163,9 @@ class _GridCellContext<T, D> extends Equatable {
149163
_cellDataNotifier.removeListener(fn);
150164
}
151165

152-
T? getCellData() {
166+
T? getCellData({bool loadIfNoCache = true}) {
153167
final data = cellCache.get(_cacheKey);
154-
if (data == null) {
168+
if (data == null && loadIfNoCache) {
155169
_loadData();
156170
}
157171
return data;

frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_loader.dart

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ abstract class IGridCellDataConfig {
44
// The cell data will reload if it receives the field's change notification.
55
bool get reloadOnFieldChanged;
66

7-
// The cell data will reload if it receives the cell's change notification.
8-
// For example, the number cell should be reloaded after user input the number.
7+
// When the reloadOnCellChanged is true, it will load the cell data after user input.
8+
// For example: The number cell reload the cell data that carries the format
99
// user input: 12
1010
// cell display: $12
1111
bool get reloadOnCellChanged;
@@ -30,60 +30,45 @@ abstract class IGridCellDataLoader<T> {
3030
IGridCellDataConfig get config;
3131
}
3232

33-
class GridCellDataLoader extends IGridCellDataLoader<Cell> {
33+
abstract class ICellDataParser<T> {
34+
T? parserData(List<int> data);
35+
}
36+
37+
class GridCellDataLoader<T> extends IGridCellDataLoader<T> {
3438
final CellService service = CellService();
3539
final GridCell gridCell;
40+
final ICellDataParser<T> parser;
3641

3742
@override
3843
final IGridCellDataConfig config;
3944

4045
GridCellDataLoader({
4146
required this.gridCell,
47+
required this.parser,
4248
this.config = const GridCellDataConfig(),
4349
});
4450

4551
@override
46-
Future<Cell?> loadData() {
52+
Future<T?> loadData() {
4753
final fut = service.getCell(
4854
gridId: gridCell.gridId,
4955
fieldId: gridCell.field.id,
5056
rowId: gridCell.rowId,
5157
);
52-
return fut.then((result) {
53-
return result.fold((data) => data, (err) {
58+
return fut.then(
59+
(result) => result.fold((Cell cell) {
60+
try {
61+
return parser.parserData(cell.data);
62+
} catch (e, s) {
63+
Log.error('$parser parser cellData failed, $e');
64+
Log.error('Stack trace \n $s');
65+
return null;
66+
}
67+
}, (err) {
5468
Log.error(err);
5569
return null;
56-
});
57-
});
58-
}
59-
}
60-
61-
class DateCellDataLoader extends IGridCellDataLoader<DateCellData> {
62-
final GridCell gridCell;
63-
final IGridCellDataConfig _config;
64-
DateCellDataLoader({
65-
required this.gridCell,
66-
}) : _config = const GridCellDataConfig(reloadOnFieldChanged: true);
67-
68-
@override
69-
IGridCellDataConfig get config => _config;
70-
71-
@override
72-
Future<DateCellData?> loadData() {
73-
final payload = CellIdentifierPayload.create()
74-
..gridId = gridCell.gridId
75-
..fieldId = gridCell.field.id
76-
..rowId = gridCell.rowId;
77-
78-
return GridEventGetDateCellData(payload).send().then((result) {
79-
return result.fold(
80-
(data) => data,
81-
(err) {
82-
Log.error(err);
83-
return null;
84-
},
85-
);
86-
});
70+
}),
71+
);
8772
}
8873
}
8974

@@ -109,3 +94,30 @@ class SelectOptionCellDataLoader extends IGridCellDataLoader<SelectOptionCellDat
10994
@override
11095
IGridCellDataConfig get config => const GridCellDataConfig(reloadOnFieldChanged: true);
11196
}
97+
98+
class StringCellDataParser implements ICellDataParser<String> {
99+
@override
100+
String? parserData(List<int> data) {
101+
return utf8.decode(data);
102+
}
103+
}
104+
105+
class DateCellDataParser implements ICellDataParser<DateCellData> {
106+
@override
107+
DateCellData? parserData(List<int> data) {
108+
if (data.isEmpty) {
109+
return null;
110+
}
111+
return DateCellData.fromBuffer(data);
112+
}
113+
}
114+
115+
class SelectOptionCellDataParser implements ICellDataParser<SelectOptionCellData> {
116+
@override
117+
SelectOptionCellData? parserData(List<int> data) {
118+
if (data.isEmpty) {
119+
return null;
120+
}
121+
return SelectOptionCellData.fromBuffer(data);
122+
}
123+
}

frontend/app_flowy/lib/workspace/application/grid/cell/checkbox_cell_bloc.dart

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell;
21
import 'package:flutter_bloc/flutter_bloc.dart';
32
import 'package:freezed_annotation/freezed_annotation.dart';
43
import 'dart:async';
@@ -16,15 +15,15 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
1615
}) : super(CheckboxCellState.initial(cellContext)) {
1716
on<CheckboxCellEvent>(
1817
(event, emit) async {
19-
await event.map(
20-
initial: (_Initial value) {
18+
await event.when(
19+
initial: () {
2120
_startListening();
2221
},
23-
select: (_Selected value) async {
22+
select: () async {
2423
_updateCellData();
2524
},
26-
didReceiveCellUpdate: (_DidReceiveCellUpdate value) {
27-
emit(state.copyWith(isSelected: _isSelected(value.cell)));
25+
didReceiveCellUpdate: (cellData) {
26+
emit(state.copyWith(isSelected: _isSelected(cellData)));
2827
},
2928
);
3029
},
@@ -43,9 +42,9 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
4342
}
4443

4544
void _startListening() {
46-
_onCellChangedFn = cellContext.startListening(onCellChanged: ((cell) {
45+
_onCellChangedFn = cellContext.startListening(onCellChanged: ((cellData) {
4746
if (!isClosed) {
48-
add(CheckboxCellEvent.didReceiveCellUpdate(cell));
47+
add(CheckboxCellEvent.didReceiveCellUpdate(cellData));
4948
}
5049
}));
5150
}
@@ -59,7 +58,7 @@ class CheckboxCellBloc extends Bloc<CheckboxCellEvent, CheckboxCellState> {
5958
class CheckboxCellEvent with _$CheckboxCellEvent {
6059
const factory CheckboxCellEvent.initial() = _Initial;
6160
const factory CheckboxCellEvent.select() = _Selected;
62-
const factory CheckboxCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate;
61+
const factory CheckboxCellEvent.didReceiveCellUpdate(String cellData) = _DidReceiveCellUpdate;
6362
}
6463

6564
@freezed
@@ -73,7 +72,6 @@ class CheckboxCellState with _$CheckboxCellState {
7372
}
7473
}
7574

76-
bool _isSelected(Cell? cell) {
77-
final content = cell?.content ?? "";
78-
return content == "Yes";
75+
bool _isSelected(String? cellData) {
76+
return cellData == "Yes";
7977
}

frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart';
21
import 'package:flutter_bloc/flutter_bloc.dart';
32
import 'package:freezed_annotation/freezed_annotation.dart';
43
import 'dart:async';
@@ -20,7 +19,7 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
2019
_startListening();
2120
},
2221
didReceiveCellUpdate: (_DidReceiveCellUpdate value) {
23-
emit(state.copyWith(content: value.cell.content));
22+
emit(state.copyWith(content: value.cellContent));
2423
},
2524
updateCell: (_UpdateCell value) async {
2625
await _updateCellValue(value, emit);
@@ -46,9 +45,9 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
4645

4746
void _startListening() {
4847
_onCellChangedFn = cellContext.startListening(
49-
onCellChanged: ((cell) {
48+
onCellChanged: ((cellContent) {
5049
if (!isClosed) {
51-
add(NumberCellEvent.didReceiveCellUpdate(cell));
50+
add(NumberCellEvent.didReceiveCellUpdate(cellContent));
5251
}
5352
}),
5453
);
@@ -59,7 +58,7 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
5958
class NumberCellEvent with _$NumberCellEvent {
6059
const factory NumberCellEvent.initial() = _Initial;
6160
const factory NumberCellEvent.updateCell(String text) = _UpdateCell;
62-
const factory NumberCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate;
61+
const factory NumberCellEvent.didReceiveCellUpdate(String cellContent) = _DidReceiveCellUpdate;
6362
}
6463

6564
@freezed
@@ -69,7 +68,7 @@ class NumberCellState with _$NumberCellState {
6968
}) = _NumberCellState;
7069

7170
factory NumberCellState.initial(GridCellContext context) {
72-
final cell = context.getCellData();
73-
return NumberCellState(content: cell?.content ?? "");
71+
final cellContent = context.getCellData() ?? "";
72+
return NumberCellState(content: cellContent);
7473
}
7574
}

frontend/app_flowy/lib/workspace/application/grid/cell/select_option_cell_bloc.dart

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ class SelectOptionCellBloc extends Bloc<SelectOptionCellEvent, SelectOptionCellS
2121
},
2222
didReceiveOptions: (_DidReceiveOptions value) {
2323
emit(state.copyWith(
24-
options: value.options,
2524
selectedOptions: value.selectedOptions,
2625
));
2726
},
@@ -45,7 +44,6 @@ class SelectOptionCellBloc extends Bloc<SelectOptionCellEvent, SelectOptionCellS
4544
onCellChanged: ((selectOptionContext) {
4645
if (!isClosed) {
4746
add(SelectOptionCellEvent.didReceiveOptions(
48-
selectOptionContext.options,
4947
selectOptionContext.selectOptions,
5048
));
5149
}
@@ -58,23 +56,20 @@ class SelectOptionCellBloc extends Bloc<SelectOptionCellEvent, SelectOptionCellS
5856
class SelectOptionCellEvent with _$SelectOptionCellEvent {
5957
const factory SelectOptionCellEvent.initial() = _InitialCell;
6058
const factory SelectOptionCellEvent.didReceiveOptions(
61-
List<SelectOption> options,
6259
List<SelectOption> selectedOptions,
6360
) = _DidReceiveOptions;
6461
}
6562

6663
@freezed
6764
class SelectOptionCellState with _$SelectOptionCellState {
6865
const factory SelectOptionCellState({
69-
required List<SelectOption> options,
7066
required List<SelectOption> selectedOptions,
7167
}) = _SelectOptionCellState;
7268

7369
factory SelectOptionCellState.initial(GridSelectOptionCellContext context) {
7470
final data = context.getCellData();
7571

7672
return SelectOptionCellState(
77-
options: data?.options ?? [],
7873
selectedOptions: data?.selectOptions ?? [],
7974
);
8075
}

0 commit comments

Comments
 (0)