From e15d335fed477813c7bec40f1f93b8c9254e26f4 Mon Sep 17 00:00:00 2001 From: appflowy Date: Thu, 7 Apr 2022 20:15:00 +0800 Subject: [PATCH] chore: config checkbox ui --- .../grid/cell_bloc/cell_service.dart | 14 ++++ .../grid/cell_bloc/checkbox_cell_bloc.dart | 65 ++++++++++++++++--- .../grid/src/widgets/cell/checkbox_cell.dart | 15 ++++- .../dart_event/flowy-grid/dart_event.dart | 17 +++++ .../protobuf/flowy-grid/event_map.pbenum.dart | 6 +- .../protobuf/flowy-grid/event_map.pbjson.dart | 7 +- .../rust-lib/flowy-grid/src/event_handler.rs | 13 ++++ frontend/rust-lib/flowy-grid/src/event_map.rs | 8 ++- .../src/protobuf/model/event_map.rs | 17 +++-- .../src/protobuf/proto/event_map.proto | 5 +- .../flowy-grid/src/services/grid_editor.rs | 7 ++ frontend/rust-lib/flowy-grid/src/util.rs | 8 ++- 12 files changed, 154 insertions(+), 28 deletions(-) diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart index e1af022d95..9bdd48c259 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/cell_service.dart @@ -1,7 +1,9 @@ import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; import 'package:dartz/dartz.dart'; import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; import 'package:flowy_sdk/protobuf/flowy-grid-data-model/meta.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/cell_entities.pb.dart'; class CellService { CellService(); @@ -19,4 +21,16 @@ class CellService { ..data = data; return GridEventUpdateCell(payload).send(); } + + Future> getCell({ + required String gridId, + required String fieldId, + required String rowId, + }) { + final payload = CellIdentifierPayload.create() + ..gridId = gridId + ..fieldId = fieldId + ..rowId = rowId; + return GridEventGetCell(payload).send(); + } } diff --git a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart index f5bc7e7c18..ae69176fd9 100644 --- a/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart +++ b/frontend/app_flowy/lib/workspace/application/grid/cell_bloc/checkbox_cell_bloc.dart @@ -1,5 +1,7 @@ +import 'package:app_flowy/workspace/application/grid/cell_bloc/cell_listener.dart'; import 'package:app_flowy/workspace/application/grid/row/row_service.dart'; -import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart'; +import 'package:flowy_sdk/log.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid-data-model/grid.pb.dart' show Cell; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; @@ -8,17 +10,32 @@ import 'cell_service.dart'; part 'checkbox_cell_bloc.freezed.dart'; class CheckboxCellBloc extends Bloc { - final CellService service; - // final CellData cellData; + final CellService _service; + final CellListener _listener; CheckboxCellBloc({ - required this.service, + required CellService service, required CellData cellData, - }) : super(CheckboxCellState.initial()) { + }) : _service = service, + _listener = CellListener(rowId: cellData.rowId, fieldId: cellData.field.id), + super(CheckboxCellState.initial(cellData)) { on( (event, emit) async { await event.map( - initial: (_InitialCell value) async {}, + initial: (_Initial value) { + _startListening(); + }, + select: (_Selected value) async { + service.updateCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + data: !state.isSelected ? "Yes" : "No", + ); + }, + didReceiveCellUpdate: (_DidReceiveCellUpdate value) { + emit(state.copyWith(isSelected: isSelected(value.cell))); + }, ); }, ); @@ -28,18 +45,48 @@ class CheckboxCellBloc extends Bloc { Future close() async { return super.close(); } + + void _startListening() { + _listener.updateCellNotifier.addPublishListener((result) { + result.fold( + (notificationData) async { + final result = await _service.getCell( + gridId: state.cellData.gridId, + fieldId: state.cellData.field.id, + rowId: state.cellData.rowId, + ); + result.fold( + (cell) => add(CheckboxCellEvent.didReceiveCellUpdate(cell)), + (err) => Log.error(err), + ); + }, + (err) => Log.error(err), + ); + }); + _listener.start(); + } } @freezed class CheckboxCellEvent with _$CheckboxCellEvent { - const factory CheckboxCellEvent.initial() = _InitialCell; + const factory CheckboxCellEvent.initial() = _Initial; + const factory CheckboxCellEvent.select() = _Selected; + const factory CheckboxCellEvent.didReceiveCellUpdate(Cell cell) = _DidReceiveCellUpdate; } @freezed class CheckboxCellState with _$CheckboxCellState { const factory CheckboxCellState({ - required Cell? cell, + required CellData cellData, + required bool isSelected, }) = _CheckboxCellState; - factory CheckboxCellState.initial() => const CheckboxCellState(cell: null); + factory CheckboxCellState.initial(CellData cellData) { + return CheckboxCellState(cellData: cellData, isSelected: isSelected(cellData.cell)); + } +} + +bool isSelected(Cell? cell) { + final content = cell?.content ?? ""; + return content == "Yes"; } diff --git a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart index 7e1fdf166a..b4095c71d9 100644 --- a/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart +++ b/frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/checkbox_cell.dart @@ -1,5 +1,7 @@ import 'package:app_flowy/startup/startup.dart'; import 'package:app_flowy/workspace/application/grid/prelude.dart'; +import 'package:flowy_infra/image.dart'; +import 'package:flowy_infra_ui/style_widget/icon_button.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -20,7 +22,7 @@ class _CheckboxCellState extends State { @override void initState() { - _cellBloc = getIt(param1: widget.cellData); + _cellBloc = getIt(param1: widget.cellData)..add(const CheckboxCellEvent.initial()); super.initState(); } @@ -30,7 +32,16 @@ class _CheckboxCellState extends State { value: _cellBloc, child: BlocBuilder( builder: (context, state) { - return Container(); + final icon = state.isSelected ? svgWidget('editor/editor_check') : svgWidget('editor/editor_uncheck'); + return Align( + alignment: Alignment.centerLeft, + child: FlowyIconButton( + onPressed: () => context.read().add(const CheckboxCellEvent.select()), + iconPadding: EdgeInsets.zero, + icon: icon, + width: 23, + ), + ); }, ), ); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart index 3003b4c6f8..a4871a6bef 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/dispatch/dart_event/flowy-grid/dart_event.dart @@ -239,6 +239,23 @@ class GridEventGetRow { } } +class GridEventGetCell { + CellIdentifierPayload request; + GridEventGetCell(this.request); + + Future> send() { + final request = FFIRequest.create() + ..event = GridEvent.GetCell.toString() + ..payload = requestToBytes(this.request); + + return Dispatch.asyncRequest(request) + .then((bytesResult) => bytesResult.fold( + (okBytes) => left(Cell.fromBuffer(okBytes)), + (errBytes) => right(FlowyError.fromBuffer(errBytes)), + )); + } +} + class GridEventUpdateCell { CellMetaChangeset request; GridEventUpdateCell(this.request); diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart index 7c190dcd98..37032ec41b 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbenum.dart @@ -24,8 +24,9 @@ class GridEvent extends $pb.ProtobufEnum { static const GridEvent ApplySelectOptionChangeset = GridEvent._(32, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionChangeset'); static const GridEvent CreateRow = GridEvent._(50, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CreateRow'); static const GridEvent GetRow = GridEvent._(51, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetRow'); - static const GridEvent UpdateCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); - static const GridEvent ApplySelectOptionCellChangeset = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionCellChangeset'); + static const GridEvent GetCell = GridEvent._(70, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'GetCell'); + static const GridEvent UpdateCell = GridEvent._(71, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'UpdateCell'); + static const GridEvent ApplySelectOptionCellChangeset = GridEvent._(72, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'ApplySelectOptionCellChangeset'); static const $core.List values = [ GetGridData, @@ -42,6 +43,7 @@ class GridEvent extends $pb.ProtobufEnum { ApplySelectOptionChangeset, CreateRow, GetRow, + GetCell, UpdateCell, ApplySelectOptionCellChangeset, ]; diff --git a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart index 1c07877726..bc4b838bca 100644 --- a/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart +++ b/frontend/app_flowy/packages/flowy_sdk/lib/protobuf/flowy-grid/event_map.pbjson.dart @@ -26,10 +26,11 @@ const GridEvent$json = const { const {'1': 'ApplySelectOptionChangeset', '2': 32}, const {'1': 'CreateRow', '2': 50}, const {'1': 'GetRow', '2': 51}, - const {'1': 'UpdateCell', '2': 70}, - const {'1': 'ApplySelectOptionCellChangeset', '2': 71}, + const {'1': 'GetCell', '2': 70}, + const {'1': 'UpdateCell', '2': 71}, + const {'1': 'ApplySelectOptionCellChangeset', '2': 72}, ], }; /// Descriptor for `GridEvent`. Decode as a `google.protobuf.EnumDescriptorProto`. -final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIeChpBcHBseVNlbGVjdE9wdGlvbkNoYW5nZXNldBAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEg4KClVwZGF0ZUNlbGwQRhIiCh5BcHBseVNlbGVjdE9wdGlvbkNlbGxDaGFuZ2VzZXQQRw=='); +final $typed_data.Uint8List gridEventDescriptor = $convert.base64Decode('CglHcmlkRXZlbnQSDwoLR2V0R3JpZERhdGEQABIRCg1HZXRHcmlkQmxvY2tzEAESDQoJR2V0RmllbGRzEAoSDwoLVXBkYXRlRmllbGQQCxIPCgtDcmVhdGVGaWVsZBAMEg8KC0RlbGV0ZUZpZWxkEA0SEQoNU3dpdGNoVG9GaWVsZBAOEhIKDkR1cGxpY2F0ZUZpZWxkEA8SFwoTR2V0RWRpdEZpZWxkQ29udGV4dBAQEhMKD05ld1NlbGVjdE9wdGlvbhAeEhoKFkdldFNlbGVjdE9wdGlvbkNvbnRleHQQHxIeChpBcHBseVNlbGVjdE9wdGlvbkNoYW5nZXNldBAgEg0KCUNyZWF0ZVJvdxAyEgoKBkdldFJvdxAzEgsKB0dldENlbGwQRhIOCgpVcGRhdGVDZWxsEEcSIgoeQXBwbHlTZWxlY3RPcHRpb25DZWxsQ2hhbmdlc2V0EEg='); diff --git a/frontend/rust-lib/flowy-grid/src/event_handler.rs b/frontend/rust-lib/flowy-grid/src/event_handler.rs index 3d46349240..ec6dc9659e 100644 --- a/frontend/rust-lib/flowy-grid/src/event_handler.rs +++ b/frontend/rust-lib/flowy-grid/src/event_handler.rs @@ -190,6 +190,19 @@ pub(crate) async fn create_row_handler( Ok(()) } +#[tracing::instrument(level = "debug", skip_all, err)] +pub(crate) async fn get_cell_handler( + data: Data, + manager: AppData>, +) -> DataResult { + let params: CellIdentifier = data.into_inner().try_into()?; + let editor = manager.get_grid_editor(¶ms.grid_id)?; + match editor.get_cell(¶ms).await { + None => data_result(Cell::new(¶ms.field_id, "".to_owned())), + Some(cell) => data_result(cell), + } +} + #[tracing::instrument(level = "debug", skip_all, err)] pub(crate) async fn update_cell_handler( data: Data, diff --git a/frontend/rust-lib/flowy-grid/src/event_map.rs b/frontend/rust-lib/flowy-grid/src/event_map.rs index 711ad46255..8a4c68e468 100644 --- a/frontend/rust-lib/flowy-grid/src/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/event_map.rs @@ -21,6 +21,7 @@ pub fn create(grid_manager: Arc) -> Module { .event(GridEvent::CreateRow, create_row_handler) .event(GridEvent::GetRow, get_row_handler) // Cell + .event(GridEvent::GetCell, get_cell_handler) .event(GridEvent::UpdateCell, update_cell_handler) // SelectOption .event(GridEvent::NewSelectOption, new_select_option_handler) @@ -80,9 +81,12 @@ pub enum GridEvent { #[event(input = "RowIdentifierPayload", output = "Row")] GetRow = 51, + #[event(input = "CellIdentifierPayload", output = "Cell")] + GetCell = 70, + #[event(input = "CellMetaChangeset")] - UpdateCell = 70, + UpdateCell = 71, #[event(input = "SelectOptionCellChangesetPayload")] - ApplySelectOptionCellChangeset = 71, + ApplySelectOptionCellChangeset = 72, } diff --git a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs index ef26608bf1..d9cfbac578 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs +++ b/frontend/rust-lib/flowy-grid/src/protobuf/model/event_map.rs @@ -39,8 +39,9 @@ pub enum GridEvent { ApplySelectOptionChangeset = 32, CreateRow = 50, GetRow = 51, - UpdateCell = 70, - ApplySelectOptionCellChangeset = 71, + GetCell = 70, + UpdateCell = 71, + ApplySelectOptionCellChangeset = 72, } impl ::protobuf::ProtobufEnum for GridEvent { @@ -64,8 +65,9 @@ impl ::protobuf::ProtobufEnum for GridEvent { 32 => ::std::option::Option::Some(GridEvent::ApplySelectOptionChangeset), 50 => ::std::option::Option::Some(GridEvent::CreateRow), 51 => ::std::option::Option::Some(GridEvent::GetRow), - 70 => ::std::option::Option::Some(GridEvent::UpdateCell), - 71 => ::std::option::Option::Some(GridEvent::ApplySelectOptionCellChangeset), + 70 => ::std::option::Option::Some(GridEvent::GetCell), + 71 => ::std::option::Option::Some(GridEvent::UpdateCell), + 72 => ::std::option::Option::Some(GridEvent::ApplySelectOptionCellChangeset), _ => ::std::option::Option::None } } @@ -86,6 +88,7 @@ impl ::protobuf::ProtobufEnum for GridEvent { GridEvent::ApplySelectOptionChangeset, GridEvent::CreateRow, GridEvent::GetRow, + GridEvent::GetCell, GridEvent::UpdateCell, GridEvent::ApplySelectOptionCellChangeset, ]; @@ -116,15 +119,15 @@ impl ::protobuf::reflect::ProtobufValue for GridEvent { } static file_descriptor_proto_data: &'static [u8] = b"\ - \n\x0fevent_map.proto*\xd1\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ + \n\x0fevent_map.proto*\xde\x02\n\tGridEvent\x12\x0f\n\x0bGetGridData\x10\ \0\x12\x11\n\rGetGridBlocks\x10\x01\x12\r\n\tGetFields\x10\n\x12\x0f\n\ \x0bUpdateField\x10\x0b\x12\x0f\n\x0bCreateField\x10\x0c\x12\x0f\n\x0bDe\ leteField\x10\r\x12\x11\n\rSwitchToField\x10\x0e\x12\x12\n\x0eDuplicateF\ ield\x10\x0f\x12\x17\n\x13GetEditFieldContext\x10\x10\x12\x13\n\x0fNewSe\ lectOption\x10\x1e\x12\x1a\n\x16GetSelectOptionContext\x10\x1f\x12\x1e\n\ \x1aApplySelectOptionChangeset\x10\x20\x12\r\n\tCreateRow\x102\x12\n\n\ - \x06GetRow\x103\x12\x0e\n\nUpdateCell\x10F\x12\"\n\x1eApplySelectOptionC\ - ellChangeset\x10Gb\x06proto3\ + \x06GetRow\x103\x12\x0b\n\x07GetCell\x10F\x12\x0e\n\nUpdateCell\x10G\x12\ + \"\n\x1eApplySelectOptionCellChangeset\x10Hb\x06proto3\ "; 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/event_map.proto b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto index caddf2de41..1201bd759e 100644 --- a/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto +++ b/frontend/rust-lib/flowy-grid/src/protobuf/proto/event_map.proto @@ -15,6 +15,7 @@ enum GridEvent { ApplySelectOptionChangeset = 32; CreateRow = 50; GetRow = 51; - UpdateCell = 70; - ApplySelectOptionCellChangeset = 71; + GetCell = 70; + UpdateCell = 71; + ApplySelectOptionCellChangeset = 72; } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs index cddafd3fdd..a91f0bb606 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -1,6 +1,7 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::manager::GridUser; use crate::services::block_meta_manager::GridBlockMetaEditorManager; +use crate::services::cell::CellIdentifier; use crate::services::field::{default_type_option_builder_from_type, type_option_builder_from_bytes, FieldBuilder}; use crate::services::persistence::block_index::BlockIndexPersistence; use crate::services::row::*; @@ -264,6 +265,12 @@ impl ClientGridEditor { } } + pub async fn get_cell(&self, params: &CellIdentifier) -> Option { + let field_meta = self.get_field_meta(¶ms.field_id).await?; + let row_meta = self.block_meta_manager.get_row_meta(¶ms.row_id).await.ok()??; + make_cell(¶ms.field_id, &field_meta, &row_meta) + } + pub async fn get_cell_meta(&self, row_id: &str, field_id: &str) -> FlowyResult> { let row_meta = self.block_meta_manager.get_row_meta(row_id).await?; match row_meta { diff --git a/frontend/rust-lib/flowy-grid/src/util.rs b/frontend/rust-lib/flowy-grid/src/util.rs index 9af437a40f..bbc2d1b642 100644 --- a/frontend/rust-lib/flowy-grid/src/util.rs +++ b/frontend/rust-lib/flowy-grid/src/util.rs @@ -1,5 +1,5 @@ use crate::services::field::*; -use flowy_grid_data_model::entities::BuildGridContext; +use flowy_grid_data_model::entities::{BuildGridContext, FieldType}; use flowy_sync::client_grid::GridBuilder; pub fn make_default_grid() -> BuildGridContext { @@ -25,10 +25,16 @@ pub fn make_default_grid() -> BuildGridContext { .visibility(true) .build(); + let checkbox_field = FieldBuilder::from_field_type(&FieldType::Checkbox) + .name("isReady") + .visibility(true) + .build(); + GridBuilder::default() .add_field(text_field) .add_field(single_select_field) .add_field(multi_select_field) + .add_field(checkbox_field) .add_empty_row() .add_empty_row() .add_empty_row()