瀏覽代碼

chore: reset content when number is not valid

appflowy 2 年之前
父節點
當前提交
76da44999c

+ 12 - 6
frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_loader.dart

@@ -58,11 +58,7 @@ class GridCellDataLoader<T> extends IGridCellDataLoader<T> {
     return fut.then(
       (result) => result.fold((Cell cell) {
         try {
-          if (cell.data.isEmpty) {
-            return null;
-          } else {
-            return parser.parserData(cell.data);
-          }
+          return parser.parserData(cell.data);
         } catch (e, s) {
           Log.error('$parser parser cellData failed, $e');
           Log.error('Stack trace \n $s');
@@ -102,13 +98,17 @@ class SelectOptionCellDataLoader extends IGridCellDataLoader<SelectOptionCellDat
 class StringCellDataParser implements ICellDataParser<String> {
   @override
   String? parserData(List<int> data) {
-    return utf8.decode(data);
+    final s = utf8.decode(data);
+    return s;
   }
 }
 
 class DateCellDataParser implements ICellDataParser<DateCellData> {
   @override
   DateCellData? parserData(List<int> data) {
+    if (data.isEmpty) {
+      return null;
+    }
     return DateCellData.fromBuffer(data);
   }
 }
@@ -116,6 +116,9 @@ class DateCellDataParser implements ICellDataParser<DateCellData> {
 class SelectOptionCellDataParser implements ICellDataParser<SelectOptionCellData> {
   @override
   SelectOptionCellData? parserData(List<int> data) {
+    if (data.isEmpty) {
+      return null;
+    }
     return SelectOptionCellData.fromBuffer(data);
   }
 }
@@ -123,6 +126,9 @@ class SelectOptionCellDataParser implements ICellDataParser<SelectOptionCellData
 class URLCellDataParser implements ICellDataParser<URLCellData> {
   @override
   URLCellData? parserData(List<int> data) {
+    if (data.isEmpty) {
+      return null;
+    }
     return URLCellData.fromBuffer(data);
   }
 }

+ 19 - 11
frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart

@@ -1,7 +1,8 @@
-import 'package:flowy_sdk/log.dart';
+import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
 import 'package:freezed_annotation/freezed_annotation.dart';
 import 'dart:async';
+import 'package:dartz/dartz.dart';
 import 'cell_service/cell_service.dart';
 
 part 'number_cell_bloc.freezed.dart';
@@ -15,16 +16,21 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
   }) : super(NumberCellState.initial(cellContext)) {
     on<NumberCellEvent>(
       (event, emit) async {
-        await event.when(
-          initial: () async {
+        event.when(
+          initial: () {
             _startListening();
           },
-          didReceiveCellUpdate: (cellContent) {
-            emit(state.copyWith(content: cellContent ?? ""));
+          didReceiveCellUpdate: (content) {
+            emit(state.copyWith(content: content));
           },
-          updateCell: (text) async {
+          updateCell: (text) {
             cellContext.saveCellData(text, resultCallback: (result) {
-              result.fold(() => null, (err) => Log.error(err));
+              result.fold(
+                () => null,
+                (err) {
+                  if (!isClosed) add(NumberCellEvent.didReceiveCellUpdate(right(err)));
+                },
+              );
             });
           },
         );
@@ -46,7 +52,7 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
     _onCellChangedFn = cellContext.startListening(
       onCellChanged: ((cellContent) {
         if (!isClosed) {
-          add(NumberCellEvent.didReceiveCellUpdate(cellContent));
+          add(NumberCellEvent.didReceiveCellUpdate(left(cellContent ?? "")));
         }
       }),
     );
@@ -57,17 +63,19 @@ class NumberCellBloc extends Bloc<NumberCellEvent, NumberCellState> {
 class NumberCellEvent with _$NumberCellEvent {
   const factory NumberCellEvent.initial() = _Initial;
   const factory NumberCellEvent.updateCell(String text) = _UpdateCell;
-  const factory NumberCellEvent.didReceiveCellUpdate(String? cellContent) = _DidReceiveCellUpdate;
+  const factory NumberCellEvent.didReceiveCellUpdate(Either<String, FlowyError> cellContent) = _DidReceiveCellUpdate;
 }
 
 @freezed
 class NumberCellState with _$NumberCellState {
   const factory NumberCellState({
-    required String content,
+    required Either<String, FlowyError> content,
   }) = _NumberCellState;
 
   factory NumberCellState.initial(GridCellContext context) {
     final cellContent = context.getCellData() ?? "";
-    return NumberCellState(content: cellContent);
+    return NumberCellState(
+      content: left(cellContent),
+    );
   }
 }

+ 25 - 22
frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart

@@ -29,7 +29,7 @@ class _NumberCellState extends State<NumberCell> {
   void initState() {
     final cellContext = widget.cellContextBuilder.build();
     _cellBloc = getIt<NumberCellBloc>(param1: cellContext)..add(const NumberCellEvent.initial());
-    _controller = TextEditingController(text: _cellBloc.state.content);
+    _controller = TextEditingController(text: contentFromState(_cellBloc.state));
     _focusNode = CellSingleFocusNode();
     _listenFocusNode();
     super.initState();
@@ -40,26 +40,25 @@ class _NumberCellState extends State<NumberCell> {
     _listenCellRequestFocus(context);
     return BlocProvider.value(
       value: _cellBloc,
-      child: BlocConsumer<NumberCellBloc, NumberCellState>(
-        listener: (context, state) {
-          if (_controller.text != state.content) {
-            _controller.text = state.content;
-          }
-        },
-        builder: (context, state) {
-          return TextField(
-            controller: _controller,
-            focusNode: _focusNode,
-            onEditingComplete: () => _focusNode.unfocus(),
-            maxLines: null,
-            style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
-            decoration: const InputDecoration(
-              contentPadding: EdgeInsets.zero,
-              border: InputBorder.none,
-              isDense: true,
-            ),
-          );
-        },
+      child: MultiBlocListener(
+        listeners: [
+          BlocListener<NumberCellBloc, NumberCellState>(
+            listenWhen: (p, c) => p.content != c.content,
+            listener: (context, state) => _controller.text = contentFromState(state),
+          ),
+        ],
+        child: TextField(
+          controller: _controller,
+          focusNode: _focusNode,
+          onEditingComplete: () => _focusNode.unfocus(),
+          maxLines: null,
+          style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
+          decoration: const InputDecoration(
+            contentPadding: EdgeInsets.zero,
+            border: InputBorder.none,
+            isDense: true,
+          ),
+        ),
       ),
     );
   }
@@ -86,7 +85,7 @@ class _NumberCellState extends State<NumberCell> {
     if (mounted) {
       _delayOperation?.cancel();
       _delayOperation = Timer(const Duration(milliseconds: 300), () {
-        if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) {
+        if (_cellBloc.isClosed == false && _controller.text != contentFromState(_cellBloc.state)) {
           _cellBloc.add(NumberCellEvent.updateCell(_controller.text));
         }
       });
@@ -108,4 +107,8 @@ class _NumberCellState extends State<NumberCell> {
       }
     });
   }
+
+  String contentFromState(NumberCellState state) {
+    return state.content.fold((l) => l, (r) => "");
+  }
 }