diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/database_controller.dart b/frontend/appflowy_flutter/lib/plugins/database/application/database_controller.dart index 877c470ff6..b1bc6c43a5 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/database_controller.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/database_controller.dart @@ -68,9 +68,8 @@ class DatabaseCallbacks { } class DatabaseController { - DatabaseController({required ViewPB view}) - : viewId = view.id, - _databaseViewBackendSvc = DatabaseViewBackendService(viewId: view.id), + DatabaseController({required this.view}) + : _databaseViewBackendSvc = DatabaseViewBackendService(viewId: view.id), fieldController = FieldController(viewId: view.id), _groupListener = DatabaseGroupListener(view.id), databaseLayout = databaseLayoutFromViewLayout(view.layout), @@ -86,7 +85,7 @@ class DatabaseController { _listenOnLayoutChanged(); } - final String viewId; + final ViewPB view; final DatabaseViewBackendService _databaseViewBackendSvc; final FieldController fieldController; DatabaseLayoutPB databaseLayout; @@ -100,6 +99,7 @@ class DatabaseController { // Getters RowCache get rowCache => _viewCache.rowCache; + String get viewId => view.id; // Listener final DatabaseGroupListener _groupListener; diff --git a/frontend/appflowy_flutter/lib/plugins/database/application/row/related_row_detail_bloc.dart b/frontend/appflowy_flutter/lib/plugins/database/application/row/related_row_detail_bloc.dart index 02fd79f466..06e1e2b70f 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/application/row/related_row_detail_bloc.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/application/row/related_row_detail_bloc.dart @@ -3,7 +3,6 @@ import 'package:appflowy_backend/dispatch/dispatch.dart'; import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart'; import 'package:appflowy_result/appflowy_result.dart'; import 'package:bloc/bloc.dart'; -import 'package:collection/collection.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import '../database_controller.dart'; @@ -67,13 +66,10 @@ class RelatedRowDetailPageBloc /// 2. use the `inline_view_id` to instantiate a `DatabaseController`. /// 3. use the `row_id` with the DatabaseController` to create `RowController` void _init(String databaseId, String initialRowId) async { - final databaseMeta = await DatabaseEventGetDatabases() - .send() - .fold( - (s) => s.items - .firstWhereOrNull((metaPB) => metaPB.databaseId == databaseId), - (f) => null, - ); + final databaseMeta = + await DatabaseEventGetDatabaseMeta(DatabaseIdPB(value: databaseId)) + .send() + .fold((s) => s, (f) => null); if (databaseMeta == null) { return; } diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_banner.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_banner.dart index 21ff5da21d..675b2e308a 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_banner.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_banner.dart @@ -1,26 +1,19 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/plugins/database/application/cell/bloc/text_cell_bloc.dart'; import 'package:appflowy/plugins/database/application/cell/cell_controller.dart'; -import 'package:appflowy/plugins/database/application/field/field_controller.dart'; +import 'package:appflowy/plugins/database/application/database_controller.dart'; import 'package:appflowy/plugins/database/application/row/row_banner_bloc.dart'; import 'package:appflowy/plugins/database/application/row/row_controller.dart'; -import 'package:appflowy/plugins/database/domain/database_view_service.dart'; import 'package:appflowy/plugins/database/widgets/cell/editable_cell_builder.dart'; import 'package:appflowy/plugins/database/widgets/cell/editable_cell_skeleton/text.dart'; import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.dart'; import 'package:appflowy/plugins/database/widgets/row/row_action.dart'; -import 'package:appflowy/plugins/database_document/database_document_plugin.dart'; -import 'package:appflowy/startup/plugin/plugin.dart'; -import 'package:appflowy/startup/startup.dart'; -import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; -import 'package:appflowy/workspace/application/view/view_bloc.dart'; import 'package:appflowy/workspace/presentation/settings/widgets/emoji_picker/emoji_picker.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; const _kBannerActionHeight = 40.0; @@ -28,13 +21,13 @@ const _kBannerActionHeight = 40.0; class RowBanner extends StatefulWidget { const RowBanner({ super.key, - required this.fieldController, + required this.databaseController, required this.rowController, required this.cellBuilder, this.allowOpenAsFullPage = true, }); - final FieldController fieldController; + final DatabaseController databaseController; final RowController rowController; final EditableCellBuilder cellBuilder; final bool allowOpenAsFullPage; @@ -58,77 +51,32 @@ class _RowBannerState extends State { return BlocProvider( create: (context) => RowBannerBloc( viewId: widget.rowController.viewId, - fieldController: widget.fieldController, + fieldController: widget.databaseController.fieldController, rowMeta: widget.rowController.rowMeta, )..add(const RowBannerEvent.initial()), child: MouseRegion( onEnter: (event) => _isHovering.value = true, onExit: (event) => _isHovering.value = false, - child: Stack( - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(60, 34, 60, 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 30, - child: _BannerAction( - isHovering: _isHovering, - popoverController: popoverController, - ), - ), - const VSpace(4), - _BannerTitle( - cellBuilder: widget.cellBuilder, - popoverController: popoverController, - rowController: widget.rowController, - ), - ], - ), - ), - Positioned( - top: 12, - right: 12, - child: RowActionButton(rowController: widget.rowController), - ), - if (widget.allowOpenAsFullPage) - Positioned( - top: 12, - left: 12, - child: FlowyIconButton( - width: 20, - height: 20, - icon: const FlowySvg(FlowySvgs.full_view_s), - onPressed: () async { - Navigator.of(context).pop(); - final viewBloc = context.read(); - final databaseId = await DatabaseViewBackendService( - viewId: widget.cellBuilder.databaseController.viewId, - ) - .getDatabaseId() - .then((value) => value.fold((s) => s, (f) => null)); - final documentId = widget.rowController.rowMeta.documentId; - if (databaseId != null) { - getIt().add( - TabsEvent.openPlugin( - plugin: DatabaseDocumentPlugin( - data: DatabaseDocumentContext( - view: viewBloc.state.view, - databaseId: databaseId, - rowId: widget.rowController.rowId, - documentId: documentId, - ), - pluginType: PluginType.databaseDocument, - ), - setLatest: false, - ), - ); - } - }, + child: Padding( + padding: const EdgeInsets.fromLTRB(60, 34, 60, 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 30, + child: _BannerAction( + isHovering: _isHovering, + popoverController: popoverController, ), ), - ], + const VSpace(4), + _BannerTitle( + cellBuilder: widget.cellBuilder, + popoverController: popoverController, + rowController: widget.rowController, + ), + ], + ), ), ), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_detail.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_detail.dart index 845d2966f2..605d4e5235 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_detail.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/row/row_detail.dart @@ -1,12 +1,16 @@ -import 'package:flutter/material.dart'; - +import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/plugins/database/application/database_controller.dart'; import 'package:appflowy/plugins/database/application/row/row_controller.dart'; +import 'package:appflowy/plugins/database/domain/database_view_service.dart'; import 'package:appflowy/plugins/database/grid/application/row/row_detail_bloc.dart'; import 'package:appflowy/plugins/database/widgets/row/row_document.dart'; +import 'package:appflowy/plugins/database_document/database_document_plugin.dart'; +import 'package:appflowy/startup/plugin/plugin.dart'; import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; +import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../cell/editable_cell_builder.dart'; @@ -55,37 +59,87 @@ class _RowDetailPageState extends State { ), BlocProvider.value(value: getIt()), ], - child: ListView( - controller: scrollController, + child: Stack( children: [ - RowBanner( - fieldController: widget.databaseController.fieldController, - rowController: widget.rowController, - cellBuilder: cellBuilder, - allowOpenAsFullPage: widget.allowOpenAsFullPage, + ListView( + controller: scrollController, + children: [ + RowBanner( + databaseController: widget.databaseController, + rowController: widget.rowController, + cellBuilder: cellBuilder, + allowOpenAsFullPage: widget.allowOpenAsFullPage, + ), + const VSpace(16), + Padding( + padding: const EdgeInsets.only(left: 40, right: 60), + child: RowPropertyList( + cellBuilder: cellBuilder, + viewId: widget.databaseController.viewId, + fieldController: widget.databaseController.fieldController, + ), + ), + const VSpace(20), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 60), + child: Divider(height: 1.0), + ), + const VSpace(20), + RowDocument( + viewId: widget.rowController.viewId, + rowId: widget.rowController.rowId, + ), + ], ), - const VSpace(16), - Padding( - padding: const EdgeInsets.only(left: 40, right: 60), - child: RowPropertyList( - cellBuilder: cellBuilder, - viewId: widget.databaseController.viewId, - fieldController: widget.databaseController.fieldController, + Positioned( + top: 12, + right: 12, + child: Row( + children: _actions(context), ), ), - const VSpace(20), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 60), - child: Divider(height: 1.0), - ), - const VSpace(20), - RowDocument( - viewId: widget.rowController.viewId, - rowId: widget.rowController.rowId, - ), ], ), ), ); } + + List _actions(BuildContext context) { + return [ + if (widget.allowOpenAsFullPage) ...[ + FlowyIconButton( + width: 20, + height: 20, + icon: const FlowySvg(FlowySvgs.full_view_s), + onPressed: () async { + Navigator.of(context).pop(); + final databaseId = await DatabaseViewBackendService( + viewId: widget.databaseController.viewId, + ) + .getDatabaseId() + .then((value) => value.fold((s) => s, (f) => null)); + final documentId = widget.rowController.rowMeta.documentId; + if (databaseId != null) { + getIt().add( + TabsEvent.openPlugin( + plugin: DatabaseDocumentPlugin( + data: DatabaseDocumentContext( + view: widget.databaseController.view, + databaseId: databaseId, + rowId: widget.rowController.rowId, + documentId: documentId, + ), + pluginType: PluginType.databaseDocument, + ), + setLatest: false, + ), + ); + } + }, + ), + const HSpace(4), + ], + RowActionButton(rowController: widget.rowController), + ]; + } } diff --git a/frontend/rust-lib/flowy-database2/src/event_handler.rs b/frontend/rust-lib/flowy-database2/src/event_handler.rs index c8ae34433e..92b8223593 100644 --- a/frontend/rust-lib/flowy-database2/src/event_handler.rs +++ b/frontend/rust-lib/flowy-database2/src/event_handler.rs @@ -738,6 +738,22 @@ pub(crate) async fn delete_group_handler( Ok(()) } +#[tracing::instrument(level = "debug", skip(manager), err)] +pub(crate) async fn get_database_meta_handler( + data: AFPluginData, + manager: AFPluginState>, +) -> DataResult { + let manager = upgrade_manager(manager)?; + let database_id = data.into_inner().value; + let inline_view_id = manager.get_database_inline_view_id(&database_id).await?; + + let data = DatabaseMetaPB { + database_id, + inline_view_id, + }; + data_result_ok(data) +} + #[tracing::instrument(level = "debug", skip(manager), err)] pub(crate) async fn get_databases_handler( manager: AFPluginState>, diff --git a/frontend/rust-lib/flowy-database2/src/event_map.rs b/frontend/rust-lib/flowy-database2/src/event_map.rs index 2cca51fa32..12c859fd13 100644 --- a/frontend/rust-lib/flowy-database2/src/event_map.rs +++ b/frontend/rust-lib/flowy-database2/src/event_map.rs @@ -62,6 +62,7 @@ pub fn init(database_manager: Weak) -> AFPlugin { .event(DatabaseEvent::CreateGroup, create_group_handler) .event(DatabaseEvent::DeleteGroup, delete_group_handler) // Database + .event(DatabaseEvent::GetDatabaseMeta, get_database_meta_handler) .event(DatabaseEvent::GetDatabases, get_databases_handler) // Calendar .event(DatabaseEvent::GetAllCalendarEvents, get_calendar_events_handler) @@ -292,6 +293,9 @@ pub enum DatabaseEvent { #[event(input = "DeleteGroupPayloadPB")] DeleteGroup = 115, + #[event(input = "DatabaseIdPB", output = "DatabaseMetaPB")] + GetDatabaseMeta = 119, + /// Returns all the databases #[event(output = "RepeatedDatabaseDescriptionPB")] GetDatabases = 120,