From 5da8144456ae60e3711f394f0497ec7a919e5cad Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 30 May 2022 08:56:08 +0800 Subject: [PATCH 1/4] chore: show url cell editor when tap on edit button --- .../plugins/grid/src/widgets/cell/url_cell/url_cell.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) 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 db0dcade79..917cee66d2 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 @@ -72,7 +72,10 @@ class _GridURLCellState extends State { return CellEnterRegion( child: Align(alignment: Alignment.centerLeft, child: richText), - expander: _EditCellIndicator(onTap: () {}), + expander: _EditCellIndicator(onTap: () { + final cellContext = widget.cellContextBuilder.build() as GridURLCellContext; + URLCellEditor.show(context, cellContext); + }), ); }, ), From 546b1d22f4370721883b81002f31ecdee2f735ff Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 30 May 2022 10:42:30 +0800 Subject: [PATCH 2/4] fix: #509 enable select on tag --- .../cell/select_option_cell/extension.dart | 28 ++++++++++--------- .../select_option_editor.dart | 6 +++- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart index 6f8212106a..24817087c7 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart @@ -1,6 +1,7 @@ import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -64,9 +65,11 @@ class SelectOptionTag extends StatelessWidget { final String name; final Color color; final bool isSelected; + final VoidCallback? onSelected; const SelectOptionTag({ required this.name, required this.color, + this.onSelected, this.isSelected = false, Key? key, }) : super(key: key); @@ -74,12 +77,14 @@ class SelectOptionTag extends StatelessWidget { factory SelectOptionTag.fromSelectOption({ required BuildContext context, required SelectOption option, + VoidCallback? onSelected, bool isSelected = false, }) { return SelectOptionTag( name: option.name, color: option.color.make(context), isSelected: isSelected, + onSelected: onSelected, ); } @@ -92,19 +97,12 @@ class SelectOptionTag extends StatelessWidget { backgroundColor: color, labelPadding: const EdgeInsets.symmetric(horizontal: 6), selected: true, - onSelected: (_) {}, + onSelected: (_) { + if (onSelected != null) { + onSelected!(); + } + }, ); - - // return Container( - // decoration: BoxDecoration( - // color: option.color.make(context), - // shape: BoxShape.rectangle, - // borderRadius: BorderRadius.circular(8.0), - // ), - // child: Center(child: FlowyText.medium(option.name, fontSize: 12)), - // margin: const EdgeInsets.symmetric(horizontal: 3.0), - // padding: const EdgeInsets.symmetric(horizontal: 6.0), - // ); } } @@ -136,7 +134,11 @@ class SelectOptionTagCell extends StatelessWidget { Flexible( fit: FlexFit.loose, flex: 2, - child: SelectOptionTag.fromSelectOption(context: context, option: option), + child: SelectOptionTag.fromSelectOption( + context: context, + option: option, + onSelected: () => onSelected(option), + ), ), const Spacer(), ...children, diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/select_option_editor.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/select_option_editor.dart index 01972eb41a..1829157f51 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/select_option_editor.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/select_option_editor.dart @@ -233,7 +233,11 @@ class _SelectOptionCell extends StatelessWidget { context.read().add(SelectOptionEditorEvent.selectOption(option.id)); }, children: [ - if (isSelected) svgWidget("grid/checkmark"), + if (isSelected) + Padding( + padding: const EdgeInsets.only(right: 6), + child: svgWidget("grid/checkmark"), + ), ], ), ), From 84454469b425265c6563d016281c7073f3453496 Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 30 May 2022 18:40:42 +0800 Subject: [PATCH 3/4] fix: #508 auto format number --- .../grid/cell/number_cell_bloc.dart | 19 +- .../grid/field/type_option/number_bloc.dart | 1 + .../field/type_option/number_format_bloc.dart | 2 +- .../grid/src/widgets/cell/number_cell.dart | 7 +- .../cell/select_option_cell/extension.dart | 1 - .../widgets/header/type_option/number.dart | 2 +- .../lib/protobuf/flowy-grid/format.pb.dart | 11 + .../protobuf/flowy-grid/format.pbenum.dart | 94 +++++ .../protobuf/flowy-grid/format.pbjson.dart | 55 +++ .../protobuf/flowy-grid/format.pbserver.dart | 9 + .../flowy-grid/number_type_option.pb.dart | 12 +- .../flowy-grid/number_type_option.pbenum.dart | 87 ----- .../flowy-grid/number_type_option.pbjson.dart | 45 --- .../lib/protobuf/flowy-grid/protobuf.dart | 1 + .../flowy-grid/src/protobuf/model/format.rs | 207 +++++++++++ .../flowy-grid/src/protobuf/model/mod.rs | 3 + .../src/protobuf/model/number_type_option.rs | 194 +--------- .../src/protobuf/proto/format.proto | 40 ++ .../protobuf/proto/number_type_option.proto | 39 +- .../format.rs} | 312 +--------------- .../type_options/number_type_option/mod.rs | 6 + .../number_type_option/number_type_option.rs | 348 ++++++++++++++++++ 22 files changed, 813 insertions(+), 682 deletions(-) create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pb.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbenum.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbjson.dart create mode 100644 frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbserver.dart create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/model/format.rs create mode 100644 frontend/rust-lib/flowy-grid/src/protobuf/proto/format.proto rename frontend/rust-lib/flowy-grid/src/services/field/type_options/{number_type_option.rs => number_type_option/format.rs} (54%) create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/mod.rs create mode 100644 frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option.rs diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart index 8157f6a3f2..b694ac5059 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart @@ -1,3 +1,4 @@ +import 'package:flowy_sdk/log.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -14,25 +15,23 @@ class NumberCellBloc extends Bloc { }) : super(NumberCellState.initial(cellContext)) { on( (event, emit) async { - await event.map( - initial: (_Initial value) async { + await event.when( + initial: () async { _startListening(); }, - didReceiveCellUpdate: (_DidReceiveCellUpdate value) { - emit(state.copyWith(content: value.cellContent ?? "")); + didReceiveCellUpdate: (cellContent) { + emit(state.copyWith(content: cellContent ?? "")); }, - updateCell: (_UpdateCell value) async { - await _updateCellValue(value, emit); + updateCell: (text) async { + cellContext.saveCellData(text, resultCallback: (result) { + result.fold(() => null, (err) => Log.error(err)); + }); }, ); }, ); } - Future _updateCellValue(_UpdateCell value, Emitter emit) async { - cellContext.saveCellData(value.text); - } - @override Future close() async { if (_onCellChangedFn != null) { 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 951bdb9261..a708668066 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 @@ -1,4 +1,5 @@ import 'package:app_flowy/workspace/application/grid/field/type_option/type_option_service.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/format.pbenum.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; diff --git a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_format_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_format_bloc.dart index 74f1531ce3..a0a853913c 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_format_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/field/type_option/number_format_bloc.dart @@ -1,4 +1,4 @@ -import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/format.pbenum.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index dc694f48f9..da0b222d25 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -87,12 +87,7 @@ class _NumberCellState extends State { _delayOperation?.cancel(); _delayOperation = Timer(const Duration(milliseconds: 300), () { if (_cellBloc.isClosed == false && _controller.text != _cellBloc.state.content) { - final number = num.tryParse(_controller.text); - if (number != null) { - _cellBloc.add(NumberCellEvent.updateCell(_controller.text)); - } else { - _controller.text = ""; - } + _cellBloc.add(NumberCellEvent.updateCell(_controller.text)); } }); } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart index 24817087c7..27e36ad46d 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/select_option_cell/extension.dart @@ -1,7 +1,6 @@ import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/hover.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -import 'package:flowy_infra_ui/widget/spacing.dart'; import 'package:flowy_sdk/protobuf/flowy-grid/selection_type_option.pb.dart'; import 'package:flutter/material.dart'; import 'package:easy_localization/easy_localization.dart'; diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart index 3a330a02b7..bca17e1cd8 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/header/type_option/number.dart @@ -9,7 +9,7 @@ import 'package:flowy_infra_ui/flowy_infra_ui.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; import 'package:flowy_infra_ui/widget/spacing.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid/number_type_option.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/format.pbenum.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:easy_localization/easy_localization.dart' hide NumberFormat; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pb.dart new file mode 100644 index 0000000000..6983d0e025 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pb.dart @@ -0,0 +1,11 @@ +/// +// Generated code. Do not modify. +// source: format.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +import 'dart:core' as $core; + +export 'format.pbenum.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbenum.dart new file mode 100644 index 0000000000..73c544f8a5 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbenum.dart @@ -0,0 +1,94 @@ +/// +// Generated code. Do not modify. +// source: format.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields + +// ignore_for_file: UNDEFINED_SHOWN_NAME +import 'dart:core' as $core; +import 'package:protobuf/protobuf.dart' as $pb; + +class NumberFormat extends $pb.ProtobufEnum { + static const NumberFormat Number = NumberFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); + static const NumberFormat USD = NumberFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); + static const NumberFormat CanadianDollar = NumberFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CanadianDollar'); + static const NumberFormat EUR = NumberFormat._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); + static const NumberFormat Pound = NumberFormat._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Pound'); + static const NumberFormat Yen = NumberFormat._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Yen'); + static const NumberFormat Ruble = NumberFormat._(7, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Ruble'); + static const NumberFormat Rupee = NumberFormat._(8, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Rupee'); + static const NumberFormat Won = NumberFormat._(9, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Won'); + static const NumberFormat Yuan = NumberFormat._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Yuan'); + static const NumberFormat Real = NumberFormat._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Real'); + static const NumberFormat Lira = NumberFormat._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Lira'); + static const NumberFormat Rupiah = NumberFormat._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Rupiah'); + static const NumberFormat Franc = NumberFormat._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Franc'); + static const NumberFormat HongKongDollar = NumberFormat._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'HongKongDollar'); + static const NumberFormat NewZealandDollar = NumberFormat._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NewZealandDollar'); + static const NumberFormat Krona = NumberFormat._(17, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Krona'); + static const NumberFormat NorwegianKrone = NumberFormat._(18, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NorwegianKrone'); + static const NumberFormat MexicanPeso = NumberFormat._(19, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MexicanPeso'); + static const NumberFormat Rand = NumberFormat._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Rand'); + static const NumberFormat NewTaiwanDollar = NumberFormat._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NewTaiwanDollar'); + static const NumberFormat DanishKrone = NumberFormat._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DanishKrone'); + static const NumberFormat Baht = NumberFormat._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Baht'); + static const NumberFormat Forint = NumberFormat._(24, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Forint'); + static const NumberFormat Koruna = NumberFormat._(25, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Koruna'); + static const NumberFormat Shekel = NumberFormat._(26, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Shekel'); + static const NumberFormat ChileanPeso = NumberFormat._(27, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ChileanPeso'); + static const NumberFormat PhilippinePeso = NumberFormat._(28, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PhilippinePeso'); + static const NumberFormat Dirham = NumberFormat._(29, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Dirham'); + static const NumberFormat ColombianPeso = NumberFormat._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ColombianPeso'); + static const NumberFormat Riyal = NumberFormat._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Riyal'); + static const NumberFormat Ringgit = NumberFormat._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Ringgit'); + static const NumberFormat Leu = NumberFormat._(33, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Leu'); + static const NumberFormat ArgentinePeso = NumberFormat._(34, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ArgentinePeso'); + static const NumberFormat UruguayanPeso = NumberFormat._(35, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UruguayanPeso'); + static const NumberFormat Percent = NumberFormat._(36, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Percent'); + + static const $core.List values = [ + Number, + USD, + CanadianDollar, + EUR, + Pound, + Yen, + Ruble, + Rupee, + Won, + Yuan, + Real, + Lira, + Rupiah, + Franc, + HongKongDollar, + NewZealandDollar, + Krona, + NorwegianKrone, + MexicanPeso, + Rand, + NewTaiwanDollar, + DanishKrone, + Baht, + Forint, + Koruna, + Shekel, + ChileanPeso, + PhilippinePeso, + Dirham, + ColombianPeso, + Riyal, + Ringgit, + Leu, + ArgentinePeso, + UruguayanPeso, + Percent, + ]; + + static final $core.Map<$core.int, NumberFormat> _byValue = $pb.ProtobufEnum.initByValue(values); + static NumberFormat? valueOf($core.int value) => _byValue[value]; + + const NumberFormat._($core.int v, $core.String n) : super(v, n); +} + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbjson.dart new file mode 100644 index 0000000000..69071ef303 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbjson.dart @@ -0,0 +1,55 @@ +/// +// Generated code. Do not modify. +// source: format.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +import 'dart:core' as $core; +import 'dart:convert' as $convert; +import 'dart:typed_data' as $typed_data; +@$core.Deprecated('Use numberFormatDescriptor instead') +const NumberFormat$json = const { + '1': 'NumberFormat', + '2': const [ + const {'1': 'Number', '2': 0}, + const {'1': 'USD', '2': 1}, + const {'1': 'CanadianDollar', '2': 2}, + const {'1': 'EUR', '2': 4}, + const {'1': 'Pound', '2': 5}, + const {'1': 'Yen', '2': 6}, + const {'1': 'Ruble', '2': 7}, + const {'1': 'Rupee', '2': 8}, + const {'1': 'Won', '2': 9}, + const {'1': 'Yuan', '2': 10}, + const {'1': 'Real', '2': 11}, + const {'1': 'Lira', '2': 12}, + const {'1': 'Rupiah', '2': 13}, + const {'1': 'Franc', '2': 14}, + const {'1': 'HongKongDollar', '2': 15}, + const {'1': 'NewZealandDollar', '2': 16}, + const {'1': 'Krona', '2': 17}, + const {'1': 'NorwegianKrone', '2': 18}, + const {'1': 'MexicanPeso', '2': 19}, + const {'1': 'Rand', '2': 20}, + const {'1': 'NewTaiwanDollar', '2': 21}, + const {'1': 'DanishKrone', '2': 22}, + const {'1': 'Baht', '2': 23}, + const {'1': 'Forint', '2': 24}, + const {'1': 'Koruna', '2': 25}, + const {'1': 'Shekel', '2': 26}, + const {'1': 'ChileanPeso', '2': 27}, + const {'1': 'PhilippinePeso', '2': 28}, + const {'1': 'Dirham', '2': 29}, + const {'1': 'ColombianPeso', '2': 30}, + const {'1': 'Riyal', '2': 31}, + const {'1': 'Ringgit', '2': 32}, + const {'1': 'Leu', '2': 33}, + const {'1': 'ArgentinePeso', '2': 34}, + const {'1': 'UruguayanPeso', '2': 35}, + const {'1': 'Percent', '2': 36}, + ], +}; + +/// Descriptor for `NumberFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List numberFormatDescriptor = $convert.base64Decode('CgxOdW1iZXJGb3JtYXQSCgoGTnVtYmVyEAASBwoDVVNEEAESEgoOQ2FuYWRpYW5Eb2xsYXIQAhIHCgNFVVIQBBIJCgVQb3VuZBAFEgcKA1llbhAGEgkKBVJ1YmxlEAcSCQoFUnVwZWUQCBIHCgNXb24QCRIICgRZdWFuEAoSCAoEUmVhbBALEggKBExpcmEQDBIKCgZSdXBpYWgQDRIJCgVGcmFuYxAOEhIKDkhvbmdLb25nRG9sbGFyEA8SFAoQTmV3WmVhbGFuZERvbGxhchAQEgkKBUtyb25hEBESEgoOTm9yd2VnaWFuS3JvbmUQEhIPCgtNZXhpY2FuUGVzbxATEggKBFJhbmQQFBITCg9OZXdUYWl3YW5Eb2xsYXIQFRIPCgtEYW5pc2hLcm9uZRAWEggKBEJhaHQQFxIKCgZGb3JpbnQQGBIKCgZLb3J1bmEQGRIKCgZTaGVrZWwQGhIPCgtDaGlsZWFuUGVzbxAbEhIKDlBoaWxpcHBpbmVQZXNvEBwSCgoGRGlyaGFtEB0SEQoNQ29sb21iaWFuUGVzbxAeEgkKBVJpeWFsEB8SCwoHUmluZ2dpdBAgEgcKA0xldRAhEhEKDUFyZ2VudGluZVBlc28QIhIRCg1VcnVndWF5YW5QZXNvECMSCwoHUGVyY2VudBAk'); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbserver.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbserver.dart new file mode 100644 index 0000000000..f61c8f2533 --- /dev/null +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/format.pbserver.dart @@ -0,0 +1,9 @@ +/// +// Generated code. Do not modify. +// source: format.proto +// +// @dart = 2.12 +// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package + +export 'format.pb.dart'; + diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pb.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pb.dart index 54f4d9546f..83ded2177b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pb.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pb.dart @@ -9,13 +9,11 @@ import 'dart:core' as $core; import 'package:protobuf/protobuf.dart' as $pb; -import 'number_type_option.pbenum.dart'; - -export 'number_type_option.pbenum.dart'; +import 'format.pbenum.dart' as $0; class NumberTypeOption extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'NumberTypeOption', createEmptyInstance: create) - ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format', $pb.PbFieldType.OE, defaultOrMaker: NumberFormat.Number, valueOf: NumberFormat.valueOf, enumValues: NumberFormat.values) + ..e<$0.NumberFormat>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'format', $pb.PbFieldType.OE, defaultOrMaker: $0.NumberFormat.Number, valueOf: $0.NumberFormat.valueOf, enumValues: $0.NumberFormat.values) ..a<$core.int>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'scale', $pb.PbFieldType.OU3) ..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'symbol') ..aOB(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signPositive') @@ -25,7 +23,7 @@ class NumberTypeOption extends $pb.GeneratedMessage { NumberTypeOption._() : super(); factory NumberTypeOption({ - NumberFormat? format, + $0.NumberFormat? format, $core.int? scale, $core.String? symbol, $core.bool? signPositive, @@ -71,9 +69,9 @@ class NumberTypeOption extends $pb.GeneratedMessage { static NumberTypeOption? _defaultInstance; @$pb.TagNumber(1) - NumberFormat get format => $_getN(0); + $0.NumberFormat get format => $_getN(0); @$pb.TagNumber(1) - set format(NumberFormat v) { setField(1, v); } + set format($0.NumberFormat v) { setField(1, v); } @$pb.TagNumber(1) $core.bool hasFormat() => $_has(0); @$pb.TagNumber(1) diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbenum.dart index baa7e2f043..06034a2f8b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbenum.dart @@ -5,90 +5,3 @@ // @dart = 2.12 // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields -// ignore_for_file: UNDEFINED_SHOWN_NAME -import 'dart:core' as $core; -import 'package:protobuf/protobuf.dart' as $pb; - -class NumberFormat extends $pb.ProtobufEnum { - static const NumberFormat Number = NumberFormat._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Number'); - static const NumberFormat USD = NumberFormat._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'USD'); - static const NumberFormat CanadianDollar = NumberFormat._(2, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CanadianDollar'); - static const NumberFormat EUR = NumberFormat._(4, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'EUR'); - static const NumberFormat Pound = NumberFormat._(5, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Pound'); - static const NumberFormat Yen = NumberFormat._(6, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Yen'); - static const NumberFormat Ruble = NumberFormat._(7, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Ruble'); - static const NumberFormat Rupee = NumberFormat._(8, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Rupee'); - static const NumberFormat Won = NumberFormat._(9, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Won'); - static const NumberFormat Yuan = NumberFormat._(10, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Yuan'); - static const NumberFormat Real = NumberFormat._(11, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Real'); - static const NumberFormat Lira = NumberFormat._(12, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Lira'); - static const NumberFormat Rupiah = NumberFormat._(13, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Rupiah'); - static const NumberFormat Franc = NumberFormat._(14, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Franc'); - static const NumberFormat HongKongDollar = NumberFormat._(15, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'HongKongDollar'); - static const NumberFormat NewZealandDollar = NumberFormat._(16, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NewZealandDollar'); - static const NumberFormat Krona = NumberFormat._(17, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Krona'); - static const NumberFormat NorwegianKrone = NumberFormat._(18, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NorwegianKrone'); - static const NumberFormat MexicanPeso = NumberFormat._(19, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'MexicanPeso'); - static const NumberFormat Rand = NumberFormat._(20, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Rand'); - static const NumberFormat NewTaiwanDollar = NumberFormat._(21, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NewTaiwanDollar'); - static const NumberFormat DanishKrone = NumberFormat._(22, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'DanishKrone'); - static const NumberFormat Baht = NumberFormat._(23, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Baht'); - static const NumberFormat Forint = NumberFormat._(24, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Forint'); - static const NumberFormat Koruna = NumberFormat._(25, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Koruna'); - static const NumberFormat Shekel = NumberFormat._(26, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Shekel'); - static const NumberFormat ChileanPeso = NumberFormat._(27, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ChileanPeso'); - static const NumberFormat PhilippinePeso = NumberFormat._(28, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'PhilippinePeso'); - static const NumberFormat Dirham = NumberFormat._(29, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Dirham'); - static const NumberFormat ColombianPeso = NumberFormat._(30, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ColombianPeso'); - static const NumberFormat Riyal = NumberFormat._(31, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Riyal'); - static const NumberFormat Ringgit = NumberFormat._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Ringgit'); - static const NumberFormat Leu = NumberFormat._(33, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Leu'); - static const NumberFormat ArgentinePeso = NumberFormat._(34, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ArgentinePeso'); - static const NumberFormat UruguayanPeso = NumberFormat._(35, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UruguayanPeso'); - static const NumberFormat Percent = NumberFormat._(36, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'Percent'); - - static const $core.List values = [ - Number, - USD, - CanadianDollar, - EUR, - Pound, - Yen, - Ruble, - Rupee, - Won, - Yuan, - Real, - Lira, - Rupiah, - Franc, - HongKongDollar, - NewZealandDollar, - Krona, - NorwegianKrone, - MexicanPeso, - Rand, - NewTaiwanDollar, - DanishKrone, - Baht, - Forint, - Koruna, - Shekel, - ChileanPeso, - PhilippinePeso, - Dirham, - ColombianPeso, - Riyal, - Ringgit, - Leu, - ArgentinePeso, - UruguayanPeso, - Percent, - ]; - - static final $core.Map<$core.int, NumberFormat> _byValue = $pb.ProtobufEnum.initByValue(values); - static NumberFormat? valueOf($core.int value) => _byValue[value]; - - const NumberFormat._($core.int v, $core.String n) : super(v, n); -} - diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbjson.dart index f5e89367e2..492dc3689a 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/number_type_option.pbjson.dart @@ -8,51 +8,6 @@ import 'dart:core' as $core; import 'dart:convert' as $convert; import 'dart:typed_data' as $typed_data; -@$core.Deprecated('Use numberFormatDescriptor instead') -const NumberFormat$json = const { - '1': 'NumberFormat', - '2': const [ - const {'1': 'Number', '2': 0}, - const {'1': 'USD', '2': 1}, - const {'1': 'CanadianDollar', '2': 2}, - const {'1': 'EUR', '2': 4}, - const {'1': 'Pound', '2': 5}, - const {'1': 'Yen', '2': 6}, - const {'1': 'Ruble', '2': 7}, - const {'1': 'Rupee', '2': 8}, - const {'1': 'Won', '2': 9}, - const {'1': 'Yuan', '2': 10}, - const {'1': 'Real', '2': 11}, - const {'1': 'Lira', '2': 12}, - const {'1': 'Rupiah', '2': 13}, - const {'1': 'Franc', '2': 14}, - const {'1': 'HongKongDollar', '2': 15}, - const {'1': 'NewZealandDollar', '2': 16}, - const {'1': 'Krona', '2': 17}, - const {'1': 'NorwegianKrone', '2': 18}, - const {'1': 'MexicanPeso', '2': 19}, - const {'1': 'Rand', '2': 20}, - const {'1': 'NewTaiwanDollar', '2': 21}, - const {'1': 'DanishKrone', '2': 22}, - const {'1': 'Baht', '2': 23}, - const {'1': 'Forint', '2': 24}, - const {'1': 'Koruna', '2': 25}, - const {'1': 'Shekel', '2': 26}, - const {'1': 'ChileanPeso', '2': 27}, - const {'1': 'PhilippinePeso', '2': 28}, - const {'1': 'Dirham', '2': 29}, - const {'1': 'ColombianPeso', '2': 30}, - const {'1': 'Riyal', '2': 31}, - const {'1': 'Ringgit', '2': 32}, - const {'1': 'Leu', '2': 33}, - const {'1': 'ArgentinePeso', '2': 34}, - const {'1': 'UruguayanPeso', '2': 35}, - const {'1': 'Percent', '2': 36}, - ], -}; - -/// Descriptor for `NumberFormat`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List numberFormatDescriptor = $convert.base64Decode('CgxOdW1iZXJGb3JtYXQSCgoGTnVtYmVyEAASBwoDVVNEEAESEgoOQ2FuYWRpYW5Eb2xsYXIQAhIHCgNFVVIQBBIJCgVQb3VuZBAFEgcKA1llbhAGEgkKBVJ1YmxlEAcSCQoFUnVwZWUQCBIHCgNXb24QCRIICgRZdWFuEAoSCAoEUmVhbBALEggKBExpcmEQDBIKCgZSdXBpYWgQDRIJCgVGcmFuYxAOEhIKDkhvbmdLb25nRG9sbGFyEA8SFAoQTmV3WmVhbGFuZERvbGxhchAQEgkKBUtyb25hEBESEgoOTm9yd2VnaWFuS3JvbmUQEhIPCgtNZXhpY2FuUGVzbxATEggKBFJhbmQQFBITCg9OZXdUYWl3YW5Eb2xsYXIQFRIPCgtEYW5pc2hLcm9uZRAWEggKBEJhaHQQFxIKCgZGb3JpbnQQGBIKCgZLb3J1bmEQGRIKCgZTaGVrZWwQGhIPCgtDaGlsZWFuUGVzbxAbEhIKDlBoaWxpcHBpbmVQZXNvEBwSCgoGRGlyaGFtEB0SEQoNQ29sb21iaWFuUGVzbxAeEgkKBVJpeWFsEB8SCwoHUmluZ2dpdBAgEgcKA0xldRAhEhEKDUFyZ2VudGluZVBlc28QIhIRCg1VcnVndWF5YW5QZXNvECMSCwoHUGVyY2VudBAk'); @$core.Deprecated('Use numberTypeOptionDescriptor instead') const NumberTypeOption$json = const { '1': 'NumberTypeOption', diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart index c056e2799a..b0cac042fd 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/protobuf.dart @@ -7,6 +7,7 @@ export './row_entities.pb.dart'; export './cell_entities.pb.dart'; export './url_type_option.pb.dart'; export './checkbox_type_option.pb.dart'; +export './format.pb.dart'; export './event_map.pb.dart'; export './text_type_option.pb.dart'; export './date_type_option.pb.dart'; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/format.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/format.rs new file mode 100644 index 0000000000..bba24f9e4c --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/format.rs @@ -0,0 +1,207 @@ +// This file is generated by rust-protobuf 2.25.2. Do not edit +// @generated + +// https://github.com/rust-lang/rust-clippy/issues/702 +#![allow(unknown_lints)] +#![allow(clippy::all)] + +#![allow(unused_attributes)] +#![cfg_attr(rustfmt, rustfmt::skip)] + +#![allow(box_pointers)] +#![allow(dead_code)] +#![allow(missing_docs)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(trivial_casts)] +#![allow(unused_imports)] +#![allow(unused_results)] +//! Generated file from `format.proto` + +/// Generated files are compatible only with the same version +/// of protobuf runtime. +// const _PROTOBUF_VERSION_CHECK: () = ::protobuf::VERSION_2_25_2; + +#[derive(Clone,PartialEq,Eq,Debug,Hash)] +pub enum NumberFormat { + Number = 0, + USD = 1, + CanadianDollar = 2, + EUR = 4, + Pound = 5, + Yen = 6, + Ruble = 7, + Rupee = 8, + Won = 9, + Yuan = 10, + Real = 11, + Lira = 12, + Rupiah = 13, + Franc = 14, + HongKongDollar = 15, + NewZealandDollar = 16, + Krona = 17, + NorwegianKrone = 18, + MexicanPeso = 19, + Rand = 20, + NewTaiwanDollar = 21, + DanishKrone = 22, + Baht = 23, + Forint = 24, + Koruna = 25, + Shekel = 26, + ChileanPeso = 27, + PhilippinePeso = 28, + Dirham = 29, + ColombianPeso = 30, + Riyal = 31, + Ringgit = 32, + Leu = 33, + ArgentinePeso = 34, + UruguayanPeso = 35, + Percent = 36, +} + +impl ::protobuf::ProtobufEnum for NumberFormat { + fn value(&self) -> i32 { + *self as i32 + } + + fn from_i32(value: i32) -> ::std::option::Option { + match value { + 0 => ::std::option::Option::Some(NumberFormat::Number), + 1 => ::std::option::Option::Some(NumberFormat::USD), + 2 => ::std::option::Option::Some(NumberFormat::CanadianDollar), + 4 => ::std::option::Option::Some(NumberFormat::EUR), + 5 => ::std::option::Option::Some(NumberFormat::Pound), + 6 => ::std::option::Option::Some(NumberFormat::Yen), + 7 => ::std::option::Option::Some(NumberFormat::Ruble), + 8 => ::std::option::Option::Some(NumberFormat::Rupee), + 9 => ::std::option::Option::Some(NumberFormat::Won), + 10 => ::std::option::Option::Some(NumberFormat::Yuan), + 11 => ::std::option::Option::Some(NumberFormat::Real), + 12 => ::std::option::Option::Some(NumberFormat::Lira), + 13 => ::std::option::Option::Some(NumberFormat::Rupiah), + 14 => ::std::option::Option::Some(NumberFormat::Franc), + 15 => ::std::option::Option::Some(NumberFormat::HongKongDollar), + 16 => ::std::option::Option::Some(NumberFormat::NewZealandDollar), + 17 => ::std::option::Option::Some(NumberFormat::Krona), + 18 => ::std::option::Option::Some(NumberFormat::NorwegianKrone), + 19 => ::std::option::Option::Some(NumberFormat::MexicanPeso), + 20 => ::std::option::Option::Some(NumberFormat::Rand), + 21 => ::std::option::Option::Some(NumberFormat::NewTaiwanDollar), + 22 => ::std::option::Option::Some(NumberFormat::DanishKrone), + 23 => ::std::option::Option::Some(NumberFormat::Baht), + 24 => ::std::option::Option::Some(NumberFormat::Forint), + 25 => ::std::option::Option::Some(NumberFormat::Koruna), + 26 => ::std::option::Option::Some(NumberFormat::Shekel), + 27 => ::std::option::Option::Some(NumberFormat::ChileanPeso), + 28 => ::std::option::Option::Some(NumberFormat::PhilippinePeso), + 29 => ::std::option::Option::Some(NumberFormat::Dirham), + 30 => ::std::option::Option::Some(NumberFormat::ColombianPeso), + 31 => ::std::option::Option::Some(NumberFormat::Riyal), + 32 => ::std::option::Option::Some(NumberFormat::Ringgit), + 33 => ::std::option::Option::Some(NumberFormat::Leu), + 34 => ::std::option::Option::Some(NumberFormat::ArgentinePeso), + 35 => ::std::option::Option::Some(NumberFormat::UruguayanPeso), + 36 => ::std::option::Option::Some(NumberFormat::Percent), + _ => ::std::option::Option::None + } + } + + fn values() -> &'static [Self] { + static values: &'static [NumberFormat] = &[ + NumberFormat::Number, + NumberFormat::USD, + NumberFormat::CanadianDollar, + NumberFormat::EUR, + NumberFormat::Pound, + NumberFormat::Yen, + NumberFormat::Ruble, + NumberFormat::Rupee, + NumberFormat::Won, + NumberFormat::Yuan, + NumberFormat::Real, + NumberFormat::Lira, + NumberFormat::Rupiah, + NumberFormat::Franc, + NumberFormat::HongKongDollar, + NumberFormat::NewZealandDollar, + NumberFormat::Krona, + NumberFormat::NorwegianKrone, + NumberFormat::MexicanPeso, + NumberFormat::Rand, + NumberFormat::NewTaiwanDollar, + NumberFormat::DanishKrone, + NumberFormat::Baht, + NumberFormat::Forint, + NumberFormat::Koruna, + NumberFormat::Shekel, + NumberFormat::ChileanPeso, + NumberFormat::PhilippinePeso, + NumberFormat::Dirham, + NumberFormat::ColombianPeso, + NumberFormat::Riyal, + NumberFormat::Ringgit, + NumberFormat::Leu, + NumberFormat::ArgentinePeso, + NumberFormat::UruguayanPeso, + NumberFormat::Percent, + ]; + values + } + + fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { + static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; + descriptor.get(|| { + ::protobuf::reflect::EnumDescriptor::new_pb_name::("NumberFormat", file_descriptor_proto()) + }) + } +} + +impl ::std::marker::Copy for NumberFormat { +} + +impl ::std::default::Default for NumberFormat { + fn default() -> Self { + NumberFormat::Number + } +} + +impl ::protobuf::reflect::ProtobufValue for NumberFormat { + fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { + ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) + } +} + +static file_descriptor_proto_data: &'static [u8] = b"\ + \n\x0cformat.proto*\xf8\x03\n\x0cNumberFormat\x12\n\n\x06Number\x10\0\ + \x12\x07\n\x03USD\x10\x01\x12\x12\n\x0eCanadianDollar\x10\x02\x12\x07\n\ + \x03EUR\x10\x04\x12\t\n\x05Pound\x10\x05\x12\x07\n\x03Yen\x10\x06\x12\t\ + \n\x05Ruble\x10\x07\x12\t\n\x05Rupee\x10\x08\x12\x07\n\x03Won\x10\t\x12\ + \x08\n\x04Yuan\x10\n\x12\x08\n\x04Real\x10\x0b\x12\x08\n\x04Lira\x10\x0c\ + \x12\n\n\x06Rupiah\x10\r\x12\t\n\x05Franc\x10\x0e\x12\x12\n\x0eHongKongD\ + ollar\x10\x0f\x12\x14\n\x10NewZealandDollar\x10\x10\x12\t\n\x05Krona\x10\ + \x11\x12\x12\n\x0eNorwegianKrone\x10\x12\x12\x0f\n\x0bMexicanPeso\x10\ + \x13\x12\x08\n\x04Rand\x10\x14\x12\x13\n\x0fNewTaiwanDollar\x10\x15\x12\ + \x0f\n\x0bDanishKrone\x10\x16\x12\x08\n\x04Baht\x10\x17\x12\n\n\x06Forin\ + t\x10\x18\x12\n\n\x06Koruna\x10\x19\x12\n\n\x06Shekel\x10\x1a\x12\x0f\n\ + \x0bChileanPeso\x10\x1b\x12\x12\n\x0ePhilippinePeso\x10\x1c\x12\n\n\x06D\ + irham\x10\x1d\x12\x11\n\rColombianPeso\x10\x1e\x12\t\n\x05Riyal\x10\x1f\ + \x12\x0b\n\x07Ringgit\x10\x20\x12\x07\n\x03Leu\x10!\x12\x11\n\rArgentine\ + Peso\x10\"\x12\x11\n\rUruguayanPeso\x10#\x12\x0b\n\x07Percent\x10$b\x06p\ + roto3\ +"; + +static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; + +fn parse_descriptor_proto() -> ::protobuf::descriptor::FileDescriptorProto { + ::protobuf::Message::parse_from_bytes(file_descriptor_proto_data).unwrap() +} + +pub fn file_descriptor_proto() -> &'static ::protobuf::descriptor::FileDescriptorProto { + file_descriptor_proto_lazy.get(|| { + parse_descriptor_proto() + }) +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs index c0f74e1e9c..8c29b9015a 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/mod.rs @@ -25,6 +25,9 @@ pub use url_type_option::*; mod checkbox_type_option; pub use checkbox_type_option::*; +mod format; +pub use format::*; + mod event_map; pub use event_map::*; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_type_option.rs index 790f3eaaf3..8f3c0e70af 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/number_type_option.rs @@ -26,7 +26,7 @@ #[derive(PartialEq,Clone,Default)] pub struct NumberTypeOption { // message fields - pub format: NumberFormat, + pub format: super::format::NumberFormat, pub scale: u32, pub symbol: ::std::string::String, pub sign_positive: bool, @@ -50,15 +50,15 @@ impl NumberTypeOption { // .NumberFormat format = 1; - pub fn get_format(&self) -> NumberFormat { + pub fn get_format(&self) -> super::format::NumberFormat { self.format } pub fn clear_format(&mut self) { - self.format = NumberFormat::Number; + self.format = super::format::NumberFormat::Number; } // Param is passed by value, moved - pub fn set_format(&mut self, v: NumberFormat) { + pub fn set_format(&mut self, v: super::format::NumberFormat) { self.format = v; } @@ -189,7 +189,7 @@ impl ::protobuf::Message for NumberTypeOption { #[allow(unused_variables)] fn compute_size(&self) -> u32 { let mut my_size = 0; - if self.format != NumberFormat::Number { + if self.format != super::format::NumberFormat::Number { my_size += ::protobuf::rt::enum_size(1, self.format); } if self.scale != 0 { @@ -210,7 +210,7 @@ impl ::protobuf::Message for NumberTypeOption { } fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::ProtobufResult<()> { - if self.format != NumberFormat::Number { + if self.format != super::format::NumberFormat::Number { os.write_enum(1, ::protobuf::ProtobufEnum::value(&self.format))?; } if self.scale != 0 { @@ -263,7 +263,7 @@ impl ::protobuf::Message for NumberTypeOption { static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::LazyV2::INIT; descriptor.get(|| { let mut fields = ::std::vec::Vec::new(); - fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( + fields.push(::protobuf::reflect::accessor::make_simple_field_accessor::<_, ::protobuf::types::ProtobufTypeEnum>( "format", |m: &NumberTypeOption| { &m.format }, |m: &mut NumberTypeOption| { &mut m.format }, @@ -304,7 +304,7 @@ impl ::protobuf::Message for NumberTypeOption { impl ::protobuf::Clear for NumberTypeOption { fn clear(&mut self) { - self.format = NumberFormat::Number; + self.format = super::format::NumberFormat::Number; self.scale = 0; self.symbol.clear(); self.sign_positive = false; @@ -325,179 +325,13 @@ impl ::protobuf::reflect::ProtobufValue for NumberTypeOption { } } -#[derive(Clone,PartialEq,Eq,Debug,Hash)] -pub enum NumberFormat { - Number = 0, - USD = 1, - CanadianDollar = 2, - EUR = 4, - Pound = 5, - Yen = 6, - Ruble = 7, - Rupee = 8, - Won = 9, - Yuan = 10, - Real = 11, - Lira = 12, - Rupiah = 13, - Franc = 14, - HongKongDollar = 15, - NewZealandDollar = 16, - Krona = 17, - NorwegianKrone = 18, - MexicanPeso = 19, - Rand = 20, - NewTaiwanDollar = 21, - DanishKrone = 22, - Baht = 23, - Forint = 24, - Koruna = 25, - Shekel = 26, - ChileanPeso = 27, - PhilippinePeso = 28, - Dirham = 29, - ColombianPeso = 30, - Riyal = 31, - Ringgit = 32, - Leu = 33, - ArgentinePeso = 34, - UruguayanPeso = 35, - Percent = 36, -} - -impl ::protobuf::ProtobufEnum for NumberFormat { - fn value(&self) -> i32 { - *self as i32 - } - - fn from_i32(value: i32) -> ::std::option::Option { - match value { - 0 => ::std::option::Option::Some(NumberFormat::Number), - 1 => ::std::option::Option::Some(NumberFormat::USD), - 2 => ::std::option::Option::Some(NumberFormat::CanadianDollar), - 4 => ::std::option::Option::Some(NumberFormat::EUR), - 5 => ::std::option::Option::Some(NumberFormat::Pound), - 6 => ::std::option::Option::Some(NumberFormat::Yen), - 7 => ::std::option::Option::Some(NumberFormat::Ruble), - 8 => ::std::option::Option::Some(NumberFormat::Rupee), - 9 => ::std::option::Option::Some(NumberFormat::Won), - 10 => ::std::option::Option::Some(NumberFormat::Yuan), - 11 => ::std::option::Option::Some(NumberFormat::Real), - 12 => ::std::option::Option::Some(NumberFormat::Lira), - 13 => ::std::option::Option::Some(NumberFormat::Rupiah), - 14 => ::std::option::Option::Some(NumberFormat::Franc), - 15 => ::std::option::Option::Some(NumberFormat::HongKongDollar), - 16 => ::std::option::Option::Some(NumberFormat::NewZealandDollar), - 17 => ::std::option::Option::Some(NumberFormat::Krona), - 18 => ::std::option::Option::Some(NumberFormat::NorwegianKrone), - 19 => ::std::option::Option::Some(NumberFormat::MexicanPeso), - 20 => ::std::option::Option::Some(NumberFormat::Rand), - 21 => ::std::option::Option::Some(NumberFormat::NewTaiwanDollar), - 22 => ::std::option::Option::Some(NumberFormat::DanishKrone), - 23 => ::std::option::Option::Some(NumberFormat::Baht), - 24 => ::std::option::Option::Some(NumberFormat::Forint), - 25 => ::std::option::Option::Some(NumberFormat::Koruna), - 26 => ::std::option::Option::Some(NumberFormat::Shekel), - 27 => ::std::option::Option::Some(NumberFormat::ChileanPeso), - 28 => ::std::option::Option::Some(NumberFormat::PhilippinePeso), - 29 => ::std::option::Option::Some(NumberFormat::Dirham), - 30 => ::std::option::Option::Some(NumberFormat::ColombianPeso), - 31 => ::std::option::Option::Some(NumberFormat::Riyal), - 32 => ::std::option::Option::Some(NumberFormat::Ringgit), - 33 => ::std::option::Option::Some(NumberFormat::Leu), - 34 => ::std::option::Option::Some(NumberFormat::ArgentinePeso), - 35 => ::std::option::Option::Some(NumberFormat::UruguayanPeso), - 36 => ::std::option::Option::Some(NumberFormat::Percent), - _ => ::std::option::Option::None - } - } - - fn values() -> &'static [Self] { - static values: &'static [NumberFormat] = &[ - NumberFormat::Number, - NumberFormat::USD, - NumberFormat::CanadianDollar, - NumberFormat::EUR, - NumberFormat::Pound, - NumberFormat::Yen, - NumberFormat::Ruble, - NumberFormat::Rupee, - NumberFormat::Won, - NumberFormat::Yuan, - NumberFormat::Real, - NumberFormat::Lira, - NumberFormat::Rupiah, - NumberFormat::Franc, - NumberFormat::HongKongDollar, - NumberFormat::NewZealandDollar, - NumberFormat::Krona, - NumberFormat::NorwegianKrone, - NumberFormat::MexicanPeso, - NumberFormat::Rand, - NumberFormat::NewTaiwanDollar, - NumberFormat::DanishKrone, - NumberFormat::Baht, - NumberFormat::Forint, - NumberFormat::Koruna, - NumberFormat::Shekel, - NumberFormat::ChileanPeso, - NumberFormat::PhilippinePeso, - NumberFormat::Dirham, - NumberFormat::ColombianPeso, - NumberFormat::Riyal, - NumberFormat::Ringgit, - NumberFormat::Leu, - NumberFormat::ArgentinePeso, - NumberFormat::UruguayanPeso, - NumberFormat::Percent, - ]; - values - } - - fn enum_descriptor_static() -> &'static ::protobuf::reflect::EnumDescriptor { - static descriptor: ::protobuf::rt::LazyV2<::protobuf::reflect::EnumDescriptor> = ::protobuf::rt::LazyV2::INIT; - descriptor.get(|| { - ::protobuf::reflect::EnumDescriptor::new_pb_name::("NumberFormat", file_descriptor_proto()) - }) - } -} - -impl ::std::marker::Copy for NumberFormat { -} - -impl ::std::default::Default for NumberFormat { - fn default() -> Self { - NumberFormat::Number - } -} - -impl ::protobuf::reflect::ProtobufValue for NumberFormat { - fn as_ref(&self) -> ::protobuf::reflect::ReflectValueRef { - ::protobuf::reflect::ReflectValueRef::Enum(::protobuf::ProtobufEnum::descriptor(self)) - } -} - static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x18number_type_option.proto\"\xa0\x01\n\x10NumberTypeOption\x12%\n\ - \x06format\x18\x01\x20\x01(\x0e2\r.NumberFormatR\x06format\x12\x14\n\x05\ - scale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\x18\x03\x20\x01(\ - \tR\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\x08R\x0csignPositiv\ - e\x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04name*\xf8\x03\n\x0cNumberForm\ - at\x12\n\n\x06Number\x10\0\x12\x07\n\x03USD\x10\x01\x12\x12\n\x0eCanadia\ - nDollar\x10\x02\x12\x07\n\x03EUR\x10\x04\x12\t\n\x05Pound\x10\x05\x12\ - \x07\n\x03Yen\x10\x06\x12\t\n\x05Ruble\x10\x07\x12\t\n\x05Rupee\x10\x08\ - \x12\x07\n\x03Won\x10\t\x12\x08\n\x04Yuan\x10\n\x12\x08\n\x04Real\x10\ - \x0b\x12\x08\n\x04Lira\x10\x0c\x12\n\n\x06Rupiah\x10\r\x12\t\n\x05Franc\ - \x10\x0e\x12\x12\n\x0eHongKongDollar\x10\x0f\x12\x14\n\x10NewZealandDoll\ - ar\x10\x10\x12\t\n\x05Krona\x10\x11\x12\x12\n\x0eNorwegianKrone\x10\x12\ - \x12\x0f\n\x0bMexicanPeso\x10\x13\x12\x08\n\x04Rand\x10\x14\x12\x13\n\ - \x0fNewTaiwanDollar\x10\x15\x12\x0f\n\x0bDanishKrone\x10\x16\x12\x08\n\ - \x04Baht\x10\x17\x12\n\n\x06Forint\x10\x18\x12\n\n\x06Koruna\x10\x19\x12\ - \n\n\x06Shekel\x10\x1a\x12\x0f\n\x0bChileanPeso\x10\x1b\x12\x12\n\x0ePhi\ - lippinePeso\x10\x1c\x12\n\n\x06Dirham\x10\x1d\x12\x11\n\rColombianPeso\ - \x10\x1e\x12\t\n\x05Riyal\x10\x1f\x12\x0b\n\x07Ringgit\x10\x20\x12\x07\n\ - \x03Leu\x10!\x12\x11\n\rArgentinePeso\x10\"\x12\x11\n\rUruguayanPeso\x10\ - #\x12\x0b\n\x07Percent\x10$b\x06proto3\ + \n\x18number_type_option.proto\x1a\x0cformat.proto\"\xa0\x01\n\x10Number\ + TypeOption\x12%\n\x06format\x18\x01\x20\x01(\x0e2\r.NumberFormatR\x06for\ + mat\x12\x14\n\x05scale\x18\x02\x20\x01(\rR\x05scale\x12\x16\n\x06symbol\ + \x18\x03\x20\x01(\tR\x06symbol\x12#\n\rsign_positive\x18\x04\x20\x01(\ + \x08R\x0csignPositive\x12\x12\n\x04name\x18\x05\x20\x01(\tR\x04nameb\x06\ + proto3\ "; static file_descriptor_proto_lazy: ::protobuf::rt::LazyV2<::protobuf::descriptor::FileDescriptorProto> = ::protobuf::rt::LazyV2::INIT; diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/format.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/format.proto new file mode 100644 index 0000000000..6a1e497aaf --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/format.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +enum NumberFormat { + Number = 0; + USD = 1; + CanadianDollar = 2; + EUR = 4; + Pound = 5; + Yen = 6; + Ruble = 7; + Rupee = 8; + Won = 9; + Yuan = 10; + Real = 11; + Lira = 12; + Rupiah = 13; + Franc = 14; + HongKongDollar = 15; + NewZealandDollar = 16; + Krona = 17; + NorwegianKrone = 18; + MexicanPeso = 19; + Rand = 20; + NewTaiwanDollar = 21; + DanishKrone = 22; + Baht = 23; + Forint = 24; + Koruna = 25; + Shekel = 26; + ChileanPeso = 27; + PhilippinePeso = 28; + Dirham = 29; + ColombianPeso = 30; + Riyal = 31; + Ringgit = 32; + Leu = 33; + ArgentinePeso = 34; + UruguayanPeso = 35; + Percent = 36; +} diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_type_option.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_type_option.proto index af08761ad9..47a76e40cd 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_type_option.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/number_type_option.proto @@ -1,4 +1,5 @@ syntax = "proto3"; +import "format.proto"; message NumberTypeOption { NumberFormat format = 1; @@ -7,41 +8,3 @@ message NumberTypeOption { bool sign_positive = 4; string name = 5; } -enum NumberFormat { - Number = 0; - USD = 1; - CanadianDollar = 2; - EUR = 4; - Pound = 5; - Yen = 6; - Ruble = 7; - Rupee = 8; - Won = 9; - Yuan = 10; - Real = 11; - Lira = 12; - Rupiah = 13; - Franc = 14; - HongKongDollar = 15; - NewZealandDollar = 16; - Krona = 17; - NorwegianKrone = 18; - MexicanPeso = 19; - Rand = 20; - NewTaiwanDollar = 21; - DanishKrone = 22; - Baht = 23; - Forint = 24; - Koruna = 25; - Shekel = 26; - ChileanPeso = 27; - PhilippinePeso = 28; - Dirham = 29; - ColombianPeso = 30; - Riyal = 31; - Ringgit = 32; - Leu = 33; - ArgentinePeso = 34; - UruguayanPeso = 35; - Percent = 36; -} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/format.rs similarity index 54% rename from frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs rename to frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/format.rs index cf4bd22e3d..149404fa9f 100644 --- a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option.rs +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/format.rs @@ -1,182 +1,16 @@ -use crate::impl_type_option; -use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; -use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData}; -use bytes::Bytes; -use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; -use flowy_error::{FlowyError, FlowyResult}; -use flowy_grid_data_model::entities::{ - CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, -}; +use flowy_derive::ProtoBuf_Enum; use lazy_static::lazy_static; -use rust_decimal::Decimal; + use rusty_money::define_currency_set; use serde::{Deserialize, Serialize}; -use std::str::FromStr; use strum::IntoEnumIterator; use strum_macros::EnumIter; lazy_static! { - static ref STRIP_SYMBOL: Vec = make_strip_symbol(); -} - -#[derive(Default)] -pub struct NumberTypeOptionBuilder(NumberTypeOption); -impl_into_box_type_option_builder!(NumberTypeOptionBuilder); -impl_builder_from_json_str_and_from_bytes!(NumberTypeOptionBuilder, NumberTypeOption); - -impl NumberTypeOptionBuilder { - pub fn name(mut self, name: &str) -> Self { - self.0.name = name.to_string(); - self - } - - pub fn set_format(mut self, format: NumberFormat) -> Self { - self.0.set_format(format); - self - } - - pub fn scale(mut self, scale: u32) -> Self { - self.0.scale = scale; - self - } - - pub fn positive(mut self, positive: bool) -> Self { - self.0.sign_positive = positive; - self - } -} - -impl TypeOptionBuilder for NumberTypeOptionBuilder { - fn field_type(&self) -> FieldType { - self.0.field_type() - } - - fn entry(&self) -> &dyn TypeOptionDataEntry { - &self.0 - } -} - -// Number -#[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] -pub struct NumberTypeOption { - #[pb(index = 1)] - pub format: NumberFormat, - - #[pb(index = 2)] - pub scale: u32, - - #[pb(index = 3)] - pub symbol: String, - - #[pb(index = 4)] - pub sign_positive: bool, - - #[pb(index = 5)] - pub name: String, -} -impl_type_option!(NumberTypeOption, FieldType::Number); - -impl CellDataOperation for NumberTypeOption { - fn decode_cell_data( - &self, - encoded_data: T, - decoded_field_type: &FieldType, - _field_meta: &FieldMeta, - ) -> FlowyResult - where - T: Into, - { - if decoded_field_type.is_date() { - return Ok(DecodedCellData::default()); - } - - let cell_data = encoded_data.into(); - match self.format { - NumberFormat::Number => { - if let Ok(v) = cell_data.parse::() { - return Ok(DecodedCellData::new(v.to_string())); - } - - if let Ok(v) = cell_data.parse::() { - return Ok(DecodedCellData::new(v.to_string())); - } - - Ok(DecodedCellData::default()) - } - NumberFormat::Percent => { - let content = cell_data.parse::().map_or(String::new(), |v| v.to_string()); - Ok(DecodedCellData::new(content)) - } - _ => { - let content = self.money_from_str(&cell_data); - Ok(DecodedCellData::new(content)) - } - } - } - - fn apply_changeset(&self, changeset: C, _cell_meta: Option) -> Result - where - C: Into, - { - let changeset = changeset.into(); - let mut data = changeset.trim().to_string(); - - if self.format != NumberFormat::Number { - data = self.strip_symbol(data); - if !data.chars().all(char::is_numeric) { - return Err(FlowyError::invalid_data().context("Should only contain numbers")); - } - } - - Ok(data) - } -} - -impl std::default::Default for NumberTypeOption { - fn default() -> Self { - let format = NumberFormat::default(); - let symbol = format.symbol(); - NumberTypeOption { - format, - scale: 0, - symbol, - sign_positive: true, - name: "Number".to_string(), - } - } -} - -impl NumberTypeOption { - pub fn set_format(&mut self, format: NumberFormat) { - self.format = format; - self.symbol = format.symbol(); - } - - fn money_from_str(&self, s: &str) -> String { - match Decimal::from_str(s) { - Ok(mut decimal) => { - match decimal.set_scale(self.scale) { - Ok(_) => {} - Err(e) => { - tracing::error!("Set decimal scale failed: {:?}", e); - } - } - - decimal.set_sign_positive(self.sign_positive); - let money = rusty_money::Money::from_decimal(decimal, self.format.currency()); - money.to_string() - } - Err(_) => String::new(), - } - } - - fn strip_symbol(&self, s: T) -> String { - let mut s = s.to_string(); - if !s.chars().all(char::is_numeric) { - s.retain(|c| !STRIP_SYMBOL.contains(&c.to_string())); - } - s - } + pub static ref CURRENCY_SYMBOL: Vec = NumberFormat::iter() + .map(|format| format.symbol()) + .collect::>(); + pub static ref STRIP_SYMBOL: Vec = vec![",".to_owned(), ".".to_owned()]; } #[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter, Serialize, Deserialize, ProtoBuf_Enum)] @@ -609,137 +443,3 @@ impl NumberFormat { self.currency().symbol.to_string() } } - -fn make_strip_symbol() -> Vec { - let mut symbols = vec![",".to_owned(), ".".to_owned()]; - for format in NumberFormat::iter() { - symbols.push(format.symbol()); - } - symbols -} - -#[cfg(test)] -mod tests { - use crate::services::field::FieldBuilder; - use crate::services::field::{NumberFormat, NumberTypeOption}; - use crate::services::row::CellDataOperation; - use flowy_grid_data_model::entities::{FieldMeta, FieldType}; - use strum::IntoEnumIterator; - - #[test] - fn number_description_invalid_input_test() { - let type_option = NumberTypeOption::default(); - let field_type = FieldType::Number; - let field_meta = FieldBuilder::from_field_type(&field_type).build(); - assert_equal(&type_option, "", "", &field_type, &field_meta); - assert_equal(&type_option, "abc", "", &field_type, &field_meta); - } - - #[test] - fn number_description_test() { - let mut type_option = NumberTypeOption::default(); - let field_type = FieldType::Number; - let field_meta = FieldBuilder::from_field_type(&field_type).build(); - assert_eq!(type_option.strip_symbol("¥18,443"), "18443".to_owned()); - assert_eq!(type_option.strip_symbol("$18,443"), "18443".to_owned()); - assert_eq!(type_option.strip_symbol("€18.443"), "18443".to_owned()); - - for format in NumberFormat::iter() { - type_option.format = format; - match format { - NumberFormat::Number => { - assert_equal(&type_option, "18443", "18443", &field_type, &field_meta); - } - NumberFormat::USD => { - assert_equal(&type_option, "18443", "$18,443", &field_type, &field_meta); - assert_equal(&type_option, "", "", &field_type, &field_meta); - assert_equal(&type_option, "abc", "", &field_type, &field_meta); - } - NumberFormat::Yen => { - assert_equal(&type_option, "18443", "¥18,443", &field_type, &field_meta); - } - NumberFormat::Yuan => { - assert_equal(&type_option, "18443", "CN¥18,443", &field_type, &field_meta); - } - NumberFormat::EUR => { - assert_equal(&type_option, "18443", "€18.443", &field_type, &field_meta); - } - _ => {} - } - } - } - - #[test] - fn number_description_scale_test() { - let mut type_option = NumberTypeOption { - scale: 1, - ..Default::default() - }; - let field_type = FieldType::Number; - let field_meta = FieldBuilder::from_field_type(&field_type).build(); - - for format in NumberFormat::iter() { - type_option.format = format; - match format { - NumberFormat::Number => { - assert_equal(&type_option, "18443", "18443", &field_type, &field_meta); - } - NumberFormat::USD => { - assert_equal(&type_option, "18443", "$1,844.3", &field_type, &field_meta); - } - NumberFormat::Yen => { - assert_equal(&type_option, "18443", "¥1,844.3", &field_type, &field_meta); - } - NumberFormat::EUR => { - assert_equal(&type_option, "18443", "€1.844,3", &field_type, &field_meta); - } - _ => {} - } - } - } - - #[test] - fn number_description_sign_test() { - let mut type_option = NumberTypeOption { - sign_positive: false, - ..Default::default() - }; - let field_type = FieldType::Number; - let field_meta = FieldBuilder::from_field_type(&field_type).build(); - - for format in NumberFormat::iter() { - type_option.format = format; - match format { - NumberFormat::Number => { - assert_equal(&type_option, "18443", "18443", &field_type, &field_meta); - } - NumberFormat::USD => { - assert_equal(&type_option, "18443", "-$18,443", &field_type, &field_meta); - } - NumberFormat::Yen => { - assert_equal(&type_option, "18443", "-¥18,443", &field_type, &field_meta); - } - NumberFormat::EUR => { - assert_equal(&type_option, "18443", "-€18.443", &field_type, &field_meta); - } - _ => {} - } - } - } - - fn assert_equal( - type_option: &NumberTypeOption, - cell_data: &str, - expected_str: &str, - field_type: &FieldType, - field_meta: &FieldMeta, - ) { - assert_eq!( - type_option - .decode_cell_data(cell_data, field_type, field_meta) - .unwrap() - .to_string(), - expected_str.to_owned() - ); - } -} diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/mod.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/mod.rs new file mode 100644 index 0000000000..fffbad97bf --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/mod.rs @@ -0,0 +1,6 @@ +#![allow(clippy::module_inception)] +mod format; +mod number_type_option; + +pub use format::*; +pub use number_type_option::*; diff --git a/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option.rs b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option.rs new file mode 100644 index 0000000000..f1000cbcfa --- /dev/null +++ b/frontend/rust-lib/flowy-grid/src/services/field/type_options/number_type_option/number_type_option.rs @@ -0,0 +1,348 @@ +use crate::impl_type_option; + +use crate::services::field::type_options::number_type_option::format::*; +use crate::services::field::{BoxTypeOptionBuilder, TypeOptionBuilder}; +use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellData}; +use bytes::Bytes; +use flowy_derive::ProtoBuf; +use flowy_error::{FlowyError, FlowyResult}; +use flowy_grid_data_model::entities::{ + CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry, +}; +use rust_decimal::Decimal; + +use serde::{Deserialize, Serialize}; +use std::str::FromStr; + +#[derive(Default)] +pub struct NumberTypeOptionBuilder(NumberTypeOption); +impl_into_box_type_option_builder!(NumberTypeOptionBuilder); +impl_builder_from_json_str_and_from_bytes!(NumberTypeOptionBuilder, NumberTypeOption); + +impl NumberTypeOptionBuilder { + pub fn name(mut self, name: &str) -> Self { + self.0.name = name.to_string(); + self + } + + pub fn set_format(mut self, format: NumberFormat) -> Self { + self.0.set_format(format); + self + } + + pub fn scale(mut self, scale: u32) -> Self { + self.0.scale = scale; + self + } + + pub fn positive(mut self, positive: bool) -> Self { + self.0.sign_positive = positive; + self + } +} + +impl TypeOptionBuilder for NumberTypeOptionBuilder { + fn field_type(&self) -> FieldType { + self.0.field_type() + } + + fn entry(&self) -> &dyn TypeOptionDataEntry { + &self.0 + } +} + +// Number +#[derive(Clone, Debug, Serialize, Deserialize, ProtoBuf)] +pub struct NumberTypeOption { + #[pb(index = 1)] + pub format: NumberFormat, + + #[pb(index = 2)] + pub scale: u32, + + #[pb(index = 3)] + pub symbol: String, + + #[pb(index = 4)] + pub sign_positive: bool, + + #[pb(index = 5)] + pub name: String, +} +impl_type_option!(NumberTypeOption, FieldType::Number); + +impl CellDataOperation for NumberTypeOption { + fn decode_cell_data( + &self, + encoded_data: T, + decoded_field_type: &FieldType, + _field_meta: &FieldMeta, + ) -> FlowyResult + where + T: Into, + { + if decoded_field_type.is_date() { + return Ok(DecodedCellData::default()); + } + + let cell_data = encoded_data.into(); + match self.format { + NumberFormat::Number => { + if let Ok(v) = cell_data.parse::() { + return Ok(DecodedCellData::new(v.to_string())); + } + + if let Ok(v) = cell_data.parse::() { + return Ok(DecodedCellData::new(v.to_string())); + } + + Ok(DecodedCellData::default()) + } + NumberFormat::Percent => { + let content = cell_data.parse::().map_or(String::new(), |v| v.to_string()); + Ok(DecodedCellData::new(content)) + } + _ => { + let content = self.number_from_str(&cell_data); + Ok(DecodedCellData::new(content)) + } + } + } + + fn apply_changeset(&self, changeset: C, _cell_meta: Option) -> Result + where + C: Into, + { + let changeset = changeset.into(); + let mut data = changeset.trim().to_string(); + + if self.format != NumberFormat::Number { + data = self.strip_symbol(data); + if !data.chars().all(char::is_numeric) { + return Err(FlowyError::invalid_data().context("Should only contain numbers")); + } + } + + Ok(data) + } +} + +impl std::default::Default for NumberTypeOption { + fn default() -> Self { + let format = NumberFormat::default(); + let symbol = format.symbol(); + NumberTypeOption { + format, + scale: 0, + symbol, + sign_positive: true, + name: "Number".to_string(), + } + } +} + +impl NumberTypeOption { + pub fn set_format(&mut self, format: NumberFormat) { + self.format = format; + self.symbol = format.symbol(); + } + + fn number_from_str(&self, s: &str) -> String { + match Decimal::from_str(s) { + Ok(mut decimal) => { + match decimal.set_scale(self.scale) { + Ok(_) => {} + Err(e) => { + tracing::error!("Set decimal scale failed: {:?}", e); + } + } + + decimal.set_sign_positive(self.sign_positive); + let money = rusty_money::Money::from_decimal(decimal, self.format.currency()); + money.to_string() + } + Err(_) => { + let s = self.strip_symbol(s); + if !s.is_empty() && s.chars().all(char::is_numeric) { + self.number_from_str(&s) + } else { + "".to_owned() + } + } + } + } + + fn strip_symbol(&self, s: T) -> String { + let mut s = s.to_string(); + + for symbol in CURRENCY_SYMBOL.iter() { + if s.starts_with(symbol) { + s = s.strip_prefix(symbol).unwrap_or("").to_string(); + break; + } + } + + if !s.chars().all(char::is_numeric) { + s.retain(|c| !STRIP_SYMBOL.contains(&c.to_string())); + } + s + } +} + +#[cfg(test)] +mod tests { + use crate::services::field::FieldBuilder; + use crate::services::field::{NumberFormat, NumberTypeOption}; + use crate::services::row::CellDataOperation; + use flowy_grid_data_model::entities::{FieldMeta, FieldType}; + use strum::IntoEnumIterator; + + #[test] + fn number_type_option_invalid_input_test() { + let type_option = NumberTypeOption::default(); + let field_type = FieldType::Number; + let field_meta = FieldBuilder::from_field_type(&field_type).build(); + assert_equal(&type_option, "", "", &field_type, &field_meta); + assert_equal(&type_option, "abc", "", &field_type, &field_meta); + } + + #[test] + fn number_type_option_format_number_test() { + let mut type_option = NumberTypeOption::default(); + let field_type = FieldType::Number; + let field_meta = FieldBuilder::from_field_type(&field_type).build(); + assert_eq!(type_option.strip_symbol("¥18,443"), "18443".to_owned()); + assert_eq!(type_option.strip_symbol("$18,443"), "18443".to_owned()); + assert_eq!(type_option.strip_symbol("€18.443"), "18443".to_owned()); + + for format in NumberFormat::iter() { + type_option.format = format; + match format { + NumberFormat::Number => { + assert_equal(&type_option, "18443", "18443", &field_type, &field_meta); + } + NumberFormat::USD => { + assert_equal(&type_option, "18443", "$18,443", &field_type, &field_meta); + } + NumberFormat::Yen => { + assert_equal(&type_option, "18443", "¥18,443", &field_type, &field_meta); + } + NumberFormat::Yuan => { + assert_equal(&type_option, "18443", "CN¥18,443", &field_type, &field_meta); + } + NumberFormat::EUR => { + assert_equal(&type_option, "18443", "€18.443", &field_type, &field_meta); + } + _ => {} + } + } + } + + #[test] + fn number_type_option_format_str_test() { + let mut type_option = NumberTypeOption::default(); + let field_type = FieldType::Number; + let field_meta = FieldBuilder::from_field_type(&field_type).build(); + + for format in NumberFormat::iter() { + type_option.format = format; + match format { + NumberFormat::Number => { + // assert_equal(&type_option, "18443", "18443", &field_type, &field_meta); + } + NumberFormat::USD => { + assert_equal(&type_option, "$18,44", "$1,844", &field_type, &field_meta); + assert_equal(&type_option, "", "", &field_type, &field_meta); + assert_equal(&type_option, "abc", "", &field_type, &field_meta); + } + NumberFormat::Yen => { + assert_equal(&type_option, "¥18,44", "¥1,844", &field_type, &field_meta); + assert_equal(&type_option, "¥1844", "¥1,844", &field_type, &field_meta); + } + NumberFormat::Yuan => { + assert_equal(&type_option, "CN¥18,44", "CN¥1,844", &field_type, &field_meta); + assert_equal(&type_option, "CN¥1844", "CN¥1,844", &field_type, &field_meta); + } + NumberFormat::EUR => { + assert_equal(&type_option, "€18.44", "€1.844", &field_type, &field_meta); + assert_equal(&type_option, "€1844", "€1.844", &field_type, &field_meta); + } + _ => {} + } + } + } + + #[test] + fn number_type_option_scale_test() { + let mut type_option = NumberTypeOption { + scale: 1, + ..Default::default() + }; + let field_type = FieldType::Number; + let field_meta = FieldBuilder::from_field_type(&field_type).build(); + + for format in NumberFormat::iter() { + type_option.format = format; + match format { + NumberFormat::Number => { + assert_equal(&type_option, "18443", "18443", &field_type, &field_meta); + } + NumberFormat::USD => { + assert_equal(&type_option, "18443", "$1,844.3", &field_type, &field_meta); + } + NumberFormat::Yen => { + assert_equal(&type_option, "18443", "¥1,844.3", &field_type, &field_meta); + } + NumberFormat::EUR => { + assert_equal(&type_option, "18443", "€1.844,3", &field_type, &field_meta); + } + _ => {} + } + } + } + + #[test] + fn number_description_sign_test() { + let mut type_option = NumberTypeOption { + sign_positive: false, + ..Default::default() + }; + let field_type = FieldType::Number; + let field_meta = FieldBuilder::from_field_type(&field_type).build(); + + for format in NumberFormat::iter() { + type_option.format = format; + match format { + NumberFormat::Number => { + assert_equal(&type_option, "18443", "18443", &field_type, &field_meta); + } + NumberFormat::USD => { + assert_equal(&type_option, "18443", "-$18,443", &field_type, &field_meta); + } + NumberFormat::Yen => { + assert_equal(&type_option, "18443", "-¥18,443", &field_type, &field_meta); + } + NumberFormat::EUR => { + assert_equal(&type_option, "18443", "-€18.443", &field_type, &field_meta); + } + _ => {} + } + } + } + + fn assert_equal( + type_option: &NumberTypeOption, + cell_data: &str, + expected_str: &str, + field_type: &FieldType, + field_meta: &FieldMeta, + ) { + assert_eq!( + type_option + .decode_cell_data(cell_data, field_type, field_meta) + .unwrap() + .to_string(), + expected_str.to_owned() + ); + } +} From 76da44999c3a8220de05cb2ba64b66ca3dcfbded Mon Sep 17 00:00:00 2001 From: appflowy Date: Mon, 30 May 2022 20:43:38 +0800 Subject: [PATCH 4/4] chore: reset content when number is not valid --- .../grid/cell/cell_service/data_loader.dart | 18 ++++--- .../grid/cell/number_cell_bloc.dart | 30 +++++++----- .../grid/src/widgets/cell/number_cell.dart | 47 ++++++++++--------- 3 files changed, 56 insertions(+), 39 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_loader.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_loader.dart index 92caedc4e9..676e3f66d0 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_loader.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_loader.dart @@ -58,11 +58,7 @@ class GridCellDataLoader extends IGridCellDataLoader { 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 { @override String? parserData(List data) { - return utf8.decode(data); + final s = utf8.decode(data); + return s; } } class DateCellDataParser implements ICellDataParser { @override DateCellData? parserData(List data) { + if (data.isEmpty) { + return null; + } return DateCellData.fromBuffer(data); } } @@ -116,6 +116,9 @@ class DateCellDataParser implements ICellDataParser { class SelectOptionCellDataParser implements ICellDataParser { @override SelectOptionCellData? parserData(List data) { + if (data.isEmpty) { + return null; + } return SelectOptionCellData.fromBuffer(data); } } @@ -123,6 +126,9 @@ class SelectOptionCellDataParser implements ICellDataParser { @override URLCellData? parserData(List data) { + if (data.isEmpty) { + return null; + } return URLCellData.fromBuffer(data); } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart index b694ac5059..adcfee71e6 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell/number_cell_bloc.dart +++ b/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 { }) : super(NumberCellState.initial(cellContext)) { on( (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 { _onCellChangedFn = cellContext.startListening( onCellChanged: ((cellContent) { if (!isClosed) { - add(NumberCellEvent.didReceiveCellUpdate(cellContent)); + add(NumberCellEvent.didReceiveCellUpdate(left(cellContent ?? ""))); } }), ); @@ -57,17 +63,19 @@ class NumberCellBloc extends Bloc { 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 cellContent) = _DidReceiveCellUpdate; } @freezed class NumberCellState with _$NumberCellState { const factory NumberCellState({ - required String content, + required Either content, }) = _NumberCellState; factory NumberCellState.initial(GridCellContext context) { final cellContent = context.getCellData() ?? ""; - return NumberCellState(content: cellContent); + return NumberCellState( + content: left(cellContent), + ); } } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart index da0b222d25..d11229c4cb 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/number_cell.dart @@ -29,7 +29,7 @@ class _NumberCellState extends State { void initState() { final cellContext = widget.cellContextBuilder.build(); _cellBloc = getIt(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 { _listenCellRequestFocus(context); return BlocProvider.value( value: _cellBloc, - child: BlocConsumer( - 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( + 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 { 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 { } }); } + + String contentFromState(NumberCellState state) { + return state.content.fold((l) => l, (r) => ""); + } }