Skip to content

Commit 9844c02

Browse files
committed
chore: Merge branch 'main' into feat_grid_url
# Conflicts: # frontend/rust-lib/flowy-grid/src/event_handler.rs # shared-lib/flowy-grid-data-model/src/protobuf/model/grid.rs
2 parents 166438a + 81cf969 commit 9844c02

File tree

49 files changed

+610
-701
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+610
-701
lines changed

frontend/Makefile.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ extend = [
77
{ path = "scripts/makefile/docker.toml" },
88
{ path = "scripts/makefile/env.toml" },
99
{ path = "scripts/makefile/flutter.toml" },
10+
{ path = "scripts/makefile/tool.toml" },
1011
]
1112

1213
[config]

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
@@ -15,7 +15,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
1515
import 'package:app_flowy/workspace/application/grid/cell/cell_listener.dart';
1616
import 'package:app_flowy/workspace/application/grid/cell/select_option_service.dart';
1717
import 'package:app_flowy/workspace/application/grid/field/field_service.dart';
18-
18+
import 'dart:convert' show utf8;
1919
part 'cell_service.freezed.dart';
2020
part 'data_loader.dart';
2121
part 'context_builder.dart';

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

Lines changed: 34 additions & 16 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
typedef GridURLCellContext = _GridCellContext<Cell, String>;
@@ -17,26 +17,33 @@ class GridCellContextBuilder {
1717
_GridCellContext build() {
1818
switch (_gridCell.field.fieldType) {
1919
case FieldType.Checkbox:
20+
final cellDataLoader = GridCellDataLoader(
21+
gridCell: _gridCell,
22+
parser: StringCellDataParser(),
23+
);
2024
return GridCellContext(
2125
gridCell: _gridCell,
2226
cellCache: _cellCache,
23-
cellDataLoader: GridCellDataLoader(gridCell: _gridCell),
27+
cellDataLoader: cellDataLoader,
2428
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
2529
);
2630
case FieldType.DateTime:
31+
final cellDataLoader = GridCellDataLoader(
32+
gridCell: _gridCell,
33+
parser: DateCellDataParser(),
34+
);
35+
2736
return GridDateCellContext(
2837
gridCell: _gridCell,
2938
cellCache: _cellCache,
30-
cellDataLoader: DateCellDataLoader(gridCell: _gridCell),
39+
cellDataLoader: cellDataLoader,
3140
cellDataPersistence: DateCellDataPersistence(gridCell: _gridCell),
3241
);
3342
case FieldType.Number:
3443
final cellDataLoader = GridCellDataLoader(
3544
gridCell: _gridCell,
36-
config: const GridCellDataConfig(
37-
reloadOnCellChanged: true,
38-
reloadOnFieldChanged: true,
39-
),
45+
parser: StringCellDataParser(),
46+
config: const GridCellDataConfig(reloadOnCellChanged: true, reloadOnFieldChanged: true),
4047
);
4148
return GridCellContext(
4249
gridCell: _gridCell,
@@ -45,26 +52,40 @@ class GridCellContextBuilder {
4552
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
4653
);
4754
case FieldType.RichText:
55+
final cellDataLoader = GridCellDataLoader(
56+
gridCell: _gridCell,
57+
parser: StringCellDataParser(),
58+
);
4859
return GridCellContext(
4960
gridCell: _gridCell,
5061
cellCache: _cellCache,
51-
cellDataLoader: GridCellDataLoader(gridCell: _gridCell),
62+
cellDataLoader: cellDataLoader,
5263
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
5364
);
5465
case FieldType.MultiSelect:
5566
case FieldType.SingleSelect:
67+
final cellDataLoader = GridCellDataLoader(
68+
gridCell: _gridCell,
69+
parser: SelectOptionCellDataParser(),
70+
config: const GridCellDataConfig(reloadOnFieldChanged: true),
71+
);
72+
5673
return GridSelectOptionCellContext(
5774
gridCell: _gridCell,
5875
cellCache: _cellCache,
59-
cellDataLoader: SelectOptionCellDataLoader(gridCell: _gridCell),
76+
cellDataLoader: cellDataLoader,
6077
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
6178
);
6279

6380
case FieldType.URL:
81+
final cellDataLoader = GridCellDataLoader(
82+
gridCell: _gridCell,
83+
parser: URLCellDataParser(),
84+
);
6485
return GridURLCellContext(
6586
gridCell: _gridCell,
6687
cellCache: _cellCache,
67-
cellDataLoader: GridCellDataLoader(gridCell: _gridCell),
88+
cellDataLoader: cellDataLoader,
6889
cellDataPersistence: CellDataPersistence(gridCell: _gridCell),
6990
);
7091
}
@@ -141,10 +162,7 @@ class _GridCellContext<T, D> extends Equatable {
141162
}
142163

143164
onCellChangedFn() {
144-
final value = _cellDataNotifier.value;
145-
if (value is T) {
146-
onCellChanged(value);
147-
}
165+
onCellChanged(_cellDataNotifier.value as T);
148166

149167
if (cellDataLoader.config.reloadOnCellChanged) {
150168
_loadData();
@@ -159,9 +177,9 @@ class _GridCellContext<T, D> extends Equatable {
159177
_cellDataNotifier.removeListener(fn);
160178
}
161179

162-
T? getCellData() {
180+
T? getCellData({bool loadIfNoCache = true}) {
163181
final data = cellCache.get(_cacheKey);
164-
if (data == null) {
182+
if (data == null && loadIfNoCache) {
165183
_loadData();
166184
}
167185
return data;

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

Lines changed: 59 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,40 @@ 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+
}
124+
125+
class URLCellDataParser implements ICellDataParser<Cell> {
126+
@override
127+
Cell? parserData(List<int> data) {
128+
if (data.isEmpty) {
129+
return null;
130+
}
131+
return Cell.fromBuffer(data);
132+
}
133+
}

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
}

0 commit comments

Comments
 (0)