diff --git a/frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/context_builder.dart b/frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_controller.dart similarity index 100% rename from frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/context_builder.dart rename to frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_controller.dart diff --git a/frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_service.dart b/frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_service.dart index 48e82cc906..eb64543167 100644 --- a/frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_service.dart +++ b/frontend/app_flowy/lib/plugins/grid/application/cell/cell_service/cell_service.dart @@ -21,7 +21,7 @@ import '../../field/type_option/type_option_context.dart'; import 'cell_field_notifier.dart'; part 'cell_service.freezed.dart'; part 'cell_data_loader.dart'; -part 'context_builder.dart'; +part 'cell_controller.dart'; part 'cell_cache.dart'; part 'cell_data_persistence.dart'; diff --git a/frontend/app_flowy/lib/plugins/grid/application/field/field_cache.dart b/frontend/app_flowy/lib/plugins/grid/application/field/field_cache.dart index e521f097ee..b83c261626 100644 --- a/frontend/app_flowy/lib/plugins/grid/application/field/field_cache.dart +++ b/frontend/app_flowy/lib/plugins/grid/application/field/field_cache.dart @@ -52,9 +52,6 @@ class GridFieldCache { _fieldNotifier = null; } - UnmodifiableListView get unmodifiableFields => - UnmodifiableListView(_fieldNotifier?.fields ?? []); - List get fields => [..._fieldNotifier?.fields ?? []]; set fields(List fields) { @@ -158,7 +155,8 @@ class GridRowFieldNotifierImpl extends IGridRowFieldNotifier { GridRowFieldNotifierImpl(GridFieldCache cache) : _cache = cache; @override - UnmodifiableListView get fields => _cache.unmodifiableFields; + UnmodifiableListView get fields => + UnmodifiableListView(_cache.fields); @override void onRowFieldsChanged(VoidCallback callback) { diff --git a/frontend/app_flowy/lib/plugins/grid/application/setting/group_bloc.dart b/frontend/app_flowy/lib/plugins/grid/application/setting/group_bloc.dart index 80ab7f91f2..691371bd8a 100644 --- a/frontend/app_flowy/lib/plugins/grid/application/setting/group_bloc.dart +++ b/frontend/app_flowy/lib/plugins/grid/application/setting/group_bloc.dart @@ -6,16 +6,19 @@ import 'package:freezed_annotation/freezed_annotation.dart'; import 'dart:async'; import '../field/field_cache.dart'; +import 'setting_controller.dart'; part 'group_bloc.freezed.dart'; class GridGroupBloc extends Bloc { final GridFieldCache _fieldCache; + final SettingController _settingController; Function(List)? _onFieldsFn; - GridGroupBloc({required String gridId, required GridFieldCache fieldCache}) + GridGroupBloc({required String viewId, required GridFieldCache fieldCache}) : _fieldCache = fieldCache, - super(GridGroupState.initial(gridId, fieldCache.fields)) { + _settingController = SettingController(viewId: viewId), + super(GridGroupState.initial(viewId, fieldCache.fields)) { on( (event, emit) async { await event.map( @@ -24,7 +27,7 @@ class GridGroupBloc extends Bloc { }, setFieldVisibility: (_SetFieldVisibility value) async { final fieldService = - FieldService(gridId: gridId, fieldId: value.fieldId); + FieldService(gridId: viewId, fieldId: value.fieldId); final result = await fieldService.updateField(visibility: value.visibility); result.fold( @@ -58,6 +61,11 @@ class GridGroupBloc extends Bloc { onFields: _onFieldsFn, listenWhen: () => !isClosed, ); + + _settingController.startListeing( + onSettingUpdated: (setting) {}, + onError: (err) {}, + ); } } diff --git a/frontend/app_flowy/lib/plugins/grid/application/setting/setting_controller.dart b/frontend/app_flowy/lib/plugins/grid/application/setting/setting_controller.dart new file mode 100644 index 0000000000..721e5d35f1 --- /dev/null +++ b/frontend/app_flowy/lib/plugins/grid/application/setting/setting_controller.dart @@ -0,0 +1,58 @@ +import 'package:app_flowy/plugins/grid/application/setting/setting_service.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/setting_entities.pb.dart'; +import 'setting_listener.dart'; + +typedef OnError = void Function(FlowyError); +typedef OnSettingUpdated = void Function(GridSettingPB); + +class SettingController { + final String viewId; + final SettingFFIService _ffiService; + final SettingListener _listener; + OnSettingUpdated? _onSettingUpdated; + OnError? _onError; + GridSettingPB? _setting; + GridSettingPB? get setting => _setting; + + SettingController({ + required this.viewId, + }) : _ffiService = SettingFFIService(viewId: viewId), + _listener = SettingListener(gridId: viewId) { + // Load setting + _ffiService.getSetting().then((result) { + result.fold( + (newSetting) => updateSetting(newSetting), + (err) => _onError?.call(err), + ); + }); + + // Listen on the seting changes + _listener.start(onSettingUpdated: (result) { + result.fold( + (newSetting) => updateSetting(newSetting), + (err) => _onError?.call(err), + ); + }); + } + + void startListeing({ + required OnSettingUpdated onSettingUpdated, + required OnError onError, + }) { + assert(_onSettingUpdated == null, 'Should call once'); + _onSettingUpdated = onSettingUpdated; + _onError = onError; + } + + void updateSetting(GridSettingPB newSetting) { + _setting = newSetting; + _onSettingUpdated?.call(newSetting); + } + + void dispose() { + _onSettingUpdated = null; + _onError = null; + _listener.stop(); + } +} diff --git a/frontend/app_flowy/lib/plugins/grid/application/setting/setting_listener.dart b/frontend/app_flowy/lib/plugins/grid/application/setting/setting_listener.dart new file mode 100644 index 0000000000..00de48ca78 --- /dev/null +++ b/frontend/app_flowy/lib/plugins/grid/application/setting/setting_listener.dart @@ -0,0 +1,47 @@ +import 'dart:typed_data'; + +import 'package:app_flowy/core/grid_notification.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flowy_infra/notifier.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/dart_notification.pbserver.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/setting_entities.pb.dart'; + +typedef UpdateSettingNotifiedValue = Either; + +class SettingListener { + final String gridId; + GridNotificationListener? _listener; + PublishNotifier? _updateSettingNotifier = + PublishNotifier(); + + SettingListener({required this.gridId}); + + void start({ + required void Function(UpdateSettingNotifiedValue) onSettingUpdated, + }) { + _updateSettingNotifier?.addPublishListener(onSettingUpdated); + _listener = GridNotificationListener(objectId: gridId, handler: _handler); + } + + void _handler(GridNotification ty, Either result) { + switch (ty) { + case GridNotification.DidUpdateGridSetting: + result.fold( + (payload) => _updateSettingNotifier?.value = left( + GridSettingPB.fromBuffer(payload), + ), + (error) => _updateSettingNotifier?.value = right(error), + ); + break; + default: + break; + } + } + + Future stop() async { + await _listener?.stop(); + _updateSettingNotifier?.dispose(); + _updateSettingNotifier = null; + } +} diff --git a/frontend/app_flowy/lib/plugins/grid/application/setting/setting_service.dart b/frontend/app_flowy/lib/plugins/grid/application/setting/setting_service.dart new file mode 100644 index 0000000000..8d3774ec1c --- /dev/null +++ b/frontend/app_flowy/lib/plugins/grid/application/setting/setting_service.dart @@ -0,0 +1,16 @@ +import 'package:dartz/dartz.dart'; +import 'package:flowy_sdk/dispatch/dispatch.dart'; +import 'package:flowy_sdk/protobuf/flowy-error/errors.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/grid_entities.pb.dart'; +import 'package:flowy_sdk/protobuf/flowy-grid/setting_entities.pb.dart'; + +class SettingFFIService { + final String viewId; + + const SettingFFIService({required this.viewId}); + + Future> getSetting() { + final payload = GridIdPB.create()..value = viewId; + return GridEventGetGridSetting(payload).send(); + } +} diff --git a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_group.dart b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_group.dart index 291413f096..770e16e2bf 100644 --- a/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_group.dart +++ b/frontend/app_flowy/lib/plugins/grid/presentation/widgets/toolbar/grid_group.dart @@ -1,17 +1,11 @@ import 'package:app_flowy/plugins/grid/application/field/field_cache.dart'; -<<<<<<< HEAD -======= import 'package:app_flowy/plugins/grid/presentation/layout/sizes.dart'; ->>>>>>> 0e1004785 (chore: config switch group field UI) import 'package:app_flowy/plugins/grid/presentation/widgets/header/field_type_extension.dart'; import 'package:flowy_infra/image.dart'; import 'package:flowy_infra/theme.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; -<<<<<<< HEAD -======= import 'package:flowy_infra_ui/widget/spacing.dart'; ->>>>>>> 0e1004785 (chore: config switch group field UI) import 'package:flowy_sdk/protobuf/flowy-grid/field_entities.pb.dart'; import 'package:flutter/material.dart'; import 'package:app_flowy/plugins/grid/application/setting/group_bloc.dart'; @@ -30,8 +24,10 @@ class GridGroupList extends StatelessWidget { @override Widget build(BuildContext context) { return BlocProvider( - create: (context) => GridGroupBloc(gridId: viewId, fieldCache: fieldCache) - ..add(const GridGroupEvent.initial()), + create: (context) => GridGroupBloc( + viewId: viewId, + fieldCache: fieldCache, + )..add(const GridGroupEvent.initial()), child: BlocBuilder( builder: (context, state) { final cells = state.fields.map((field) { diff --git a/frontend/rust-lib/flowy-grid/src/dart_notification.rs b/frontend/rust-lib/flowy-grid/src/dart_notification.rs index ca0f0aa681..8d7ec2ba36 100644 --- a/frontend/rust-lib/flowy-grid/src/dart_notification.rs +++ b/frontend/rust-lib/flowy-grid/src/dart_notification.rs @@ -14,6 +14,7 @@ pub enum GridNotification { DidUpdateGroupView = 60, DidUpdateGroup = 61, DidGroupByNewField = 62, + DidUpdateGridSetting = 70, } impl std::default::Default for GridNotification { diff --git a/frontend/rust-lib/flowy-grid/src/entities/filter_entities/util.rs b/frontend/rust-lib/flowy-grid/src/entities/filter_entities/util.rs index 7dff00bf56..f8588944e7 100644 --- a/frontend/rust-lib/flowy-grid/src/entities/filter_entities/util.rs +++ b/frontend/rust-lib/flowy-grid/src/entities/filter_entities/util.rs @@ -10,33 +10,33 @@ use std::convert::TryInto; use std::sync::Arc; #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] -pub struct GridFilterConfiguration { +pub struct GridFilterConfigurationPB { #[pb(index = 1)] pub id: String, } #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] -pub struct RepeatedGridConfigurationFilterPB { +pub struct RepeatedGridFilterConfigurationPB { #[pb(index = 1)] - pub items: Vec, + pub items: Vec, } -impl std::convert::From<&FilterConfigurationRevision> for GridFilterConfiguration { +impl std::convert::From<&FilterConfigurationRevision> for GridFilterConfigurationPB { fn from(rev: &FilterConfigurationRevision) -> Self { Self { id: rev.id.clone() } } } -impl std::convert::From>> for RepeatedGridConfigurationFilterPB { +impl std::convert::From>> for RepeatedGridFilterConfigurationPB { fn from(revs: Vec>) -> Self { - RepeatedGridConfigurationFilterPB { + RepeatedGridFilterConfigurationPB { items: revs.into_iter().map(|rev| rev.as_ref().into()).collect(), } } } -impl std::convert::From> for RepeatedGridConfigurationFilterPB { - fn from(items: Vec) -> Self { +impl std::convert::From> for RepeatedGridFilterConfigurationPB { + fn from(items: Vec) -> Self { Self { items } } } diff --git a/frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs b/frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs index e0397a2673..47efc11861 100644 --- a/frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs +++ b/frontend/rust-lib/flowy-grid/src/entities/setting_entities.rs @@ -1,6 +1,6 @@ use crate::entities::{ CreatGroupParams, CreateFilterParams, CreateGridFilterPayloadPB, CreateGridGroupPayloadPB, DeleteFilterParams, - DeleteFilterPayloadPB, DeleteGroupParams, DeleteGroupPayloadPB, RepeatedGridConfigurationFilterPB, + DeleteFilterPayloadPB, DeleteGroupParams, DeleteGroupPayloadPB, RepeatedGridFilterConfigurationPB, RepeatedGridGroupConfigurationPB, }; use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; @@ -19,10 +19,10 @@ pub struct GridSettingPB { pub layouts: Vec, #[pb(index = 2)] - pub current_layout_type: GridLayout, + pub layout_type: GridLayout, #[pb(index = 3)] - pub filter_configuration_by_field_id: HashMap, + pub filter_configurations: RepeatedGridFilterConfigurationPB, #[pb(index = 4)] pub group_configurations: RepeatedGridGroupConfigurationPB, 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 5b8d4e0d91..2f72f48d33 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_editor.rs @@ -532,7 +532,7 @@ impl GridRevisionEditor { self.view_manager.get_setting().await } - pub async fn get_grid_filter(&self) -> FlowyResult> { + pub async fn get_grid_filter(&self) -> FlowyResult> { self.view_manager.get_filters().await } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs b/frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs index b97e680f3a..71d2fb372a 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs @@ -1,8 +1,8 @@ use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::entities::{ - CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfiguration, GridLayout, GridLayoutPB, - GridSettingPB, GroupChangesetPB, GroupPB, GroupViewChangesetPB, InsertedGroupPB, InsertedRowPB, MoveGroupParams, - RepeatedGridConfigurationFilterPB, RepeatedGridGroupConfigurationPB, RowPB, + CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfigurationPB, GridGroupConfigurationPB, + GridLayout, GridLayoutPB, GridSettingPB, GroupChangesetPB, GroupPB, GroupViewChangesetPB, InsertedGroupPB, + InsertedRowPB, MoveGroupParams, RepeatedGridFilterConfigurationPB, RepeatedGridGroupConfigurationPB, RowPB, }; use crate::services::grid_editor_task::GridServiceTaskScheduler; use crate::services::grid_view_manager::{GridViewFieldDelegate, GridViewRowDelegate}; @@ -198,14 +198,14 @@ impl GridViewRevisionEditor { grid_setting } - pub(crate) async fn get_filters(&self) -> Vec { + pub(crate) async fn get_filters(&self) -> Vec { let field_revs = self.field_delegate.get_field_revs().await; match self.pad.read().await.get_all_filters(&field_revs) { None => vec![], Some(filters) => filters .into_values() .flatten() - .map(|filter| GridFilterConfiguration::from(filter.as_ref())) + .map(|filter| GridFilterConfigurationPB::from(filter.as_ref())) .collect(), } } @@ -463,31 +463,40 @@ impl GroupConfigurationWriter for GroupConfigurationWriterImpl { } pub fn make_grid_setting(view_pad: &GridViewRevisionPad, field_revs: &[Arc]) -> GridSettingPB { - let current_layout_type: GridLayout = view_pad.layout.clone().into(); - let filter_configuration_by_field_id = view_pad + let layout_type: GridLayout = view_pad.layout.clone().into(); + let filter_configurations = view_pad .get_all_filters(field_revs) .map(|filters_by_field_id| { filters_by_field_id .into_iter() - .map(|(k, v)| (k, v.into())) - .collect::>() + .map(|(_, v)| { + let repeated_filter: RepeatedGridFilterConfigurationPB = v.into(); + repeated_filter.items + }) + .flatten() + .collect::>() }) .unwrap_or_default(); + let group_configurations = view_pad .get_groups_by_field_revs(field_revs) .map(|groups_by_field_id| { groups_by_field_id .into_iter() - .map(|(_, v)| v.into()) - .collect::() + .map(|(_, v)| { + let repeated_group: RepeatedGridGroupConfigurationPB = v.into(); + repeated_group.items + }) + .flatten() + .collect::>() }) .unwrap_or_default(); GridSettingPB { layouts: GridLayoutPB::all(), - current_layout_type, - filter_configuration_by_field_id, - group_configurations, + layout_type, + filter_configurations: filter_configurations.into(), + group_configurations: group_configurations.into(), } } diff --git a/frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs b/frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs index 61216cc88b..460be37a44 100644 --- a/frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs +++ b/frontend/rust-lib/flowy-grid/src/services/grid_view_manager.rs @@ -1,5 +1,5 @@ use crate::entities::{ - CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfiguration, GridSettingPB, MoveGroupParams, + CreateFilterParams, CreateRowParams, DeleteFilterParams, GridFilterConfigurationPB, GridSettingPB, MoveGroupParams, RepeatedGridGroupPB, RowPB, }; use crate::manager::GridUser; @@ -105,7 +105,7 @@ impl GridViewManager { Ok(view_editor.get_setting().await) } - pub(crate) async fn get_filters(&self) -> FlowyResult> { + pub(crate) async fn get_filters(&self) -> FlowyResult> { let view_editor = self.get_default_view_editor().await?; Ok(view_editor.get_filters().await) } diff --git a/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs b/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs index 0325f6f008..2bbf5874aa 100644 --- a/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs +++ b/frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs @@ -85,7 +85,7 @@ impl GridEditorTest { .row_revs } - pub async fn grid_filters(&self) -> Vec { + pub async fn grid_filters(&self) -> Vec { self.editor.get_grid_filter().await.unwrap() }