mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
fix: open row as full page launch review issues (#5254)
* perf: improve getting database speed * fix: navigate to incorrect origin database view from full-width row * fix: import row detail page action placement
This commit is contained in:
@ -68,9 +68,8 @@ class DatabaseCallbacks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DatabaseController {
|
class DatabaseController {
|
||||||
DatabaseController({required ViewPB view})
|
DatabaseController({required this.view})
|
||||||
: viewId = view.id,
|
: _databaseViewBackendSvc = DatabaseViewBackendService(viewId: view.id),
|
||||||
_databaseViewBackendSvc = DatabaseViewBackendService(viewId: view.id),
|
|
||||||
fieldController = FieldController(viewId: view.id),
|
fieldController = FieldController(viewId: view.id),
|
||||||
_groupListener = DatabaseGroupListener(view.id),
|
_groupListener = DatabaseGroupListener(view.id),
|
||||||
databaseLayout = databaseLayoutFromViewLayout(view.layout),
|
databaseLayout = databaseLayoutFromViewLayout(view.layout),
|
||||||
@ -86,7 +85,7 @@ class DatabaseController {
|
|||||||
_listenOnLayoutChanged();
|
_listenOnLayoutChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
final String viewId;
|
final ViewPB view;
|
||||||
final DatabaseViewBackendService _databaseViewBackendSvc;
|
final DatabaseViewBackendService _databaseViewBackendSvc;
|
||||||
final FieldController fieldController;
|
final FieldController fieldController;
|
||||||
DatabaseLayoutPB databaseLayout;
|
DatabaseLayoutPB databaseLayout;
|
||||||
@ -100,6 +99,7 @@ class DatabaseController {
|
|||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
RowCache get rowCache => _viewCache.rowCache;
|
RowCache get rowCache => _viewCache.rowCache;
|
||||||
|
String get viewId => view.id;
|
||||||
|
|
||||||
// Listener
|
// Listener
|
||||||
final DatabaseGroupListener _groupListener;
|
final DatabaseGroupListener _groupListener;
|
||||||
|
@ -3,7 +3,6 @@ import 'package:appflowy_backend/dispatch/dispatch.dart';
|
|||||||
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database2/protobuf.dart';
|
||||||
import 'package:appflowy_result/appflowy_result.dart';
|
import 'package:appflowy_result/appflowy_result.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
import '../database_controller.dart';
|
import '../database_controller.dart';
|
||||||
@ -67,13 +66,10 @@ class RelatedRowDetailPageBloc
|
|||||||
/// 2. use the `inline_view_id` to instantiate a `DatabaseController`.
|
/// 2. use the `inline_view_id` to instantiate a `DatabaseController`.
|
||||||
/// 3. use the `row_id` with the DatabaseController` to create `RowController`
|
/// 3. use the `row_id` with the DatabaseController` to create `RowController`
|
||||||
void _init(String databaseId, String initialRowId) async {
|
void _init(String databaseId, String initialRowId) async {
|
||||||
final databaseMeta = await DatabaseEventGetDatabases()
|
final databaseMeta =
|
||||||
.send()
|
await DatabaseEventGetDatabaseMeta(DatabaseIdPB(value: databaseId))
|
||||||
.fold<DatabaseMetaPB?>(
|
.send()
|
||||||
(s) => s.items
|
.fold<DatabaseMetaPB?>((s) => s, (f) => null);
|
||||||
.firstWhereOrNull((metaPB) => metaPB.databaseId == databaseId),
|
|
||||||
(f) => null,
|
|
||||||
);
|
|
||||||
if (databaseMeta == null) {
|
if (databaseMeta == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,19 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
import 'package:appflowy/generated/flowy_svgs.g.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.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/bloc/text_cell_bloc.dart';
|
||||||
import 'package:appflowy/plugins/database/application/cell/cell_controller.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_banner_bloc.dart';
|
||||||
import 'package:appflowy/plugins/database/application/row/row_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/widgets/cell/editable_cell_builder.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/cell/editable_cell_skeleton/text.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/row/cells/cell_container.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/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/workspace/presentation/settings/widgets/emoji_picker/emoji_picker.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
const _kBannerActionHeight = 40.0;
|
const _kBannerActionHeight = 40.0;
|
||||||
@ -28,13 +21,13 @@ const _kBannerActionHeight = 40.0;
|
|||||||
class RowBanner extends StatefulWidget {
|
class RowBanner extends StatefulWidget {
|
||||||
const RowBanner({
|
const RowBanner({
|
||||||
super.key,
|
super.key,
|
||||||
required this.fieldController,
|
required this.databaseController,
|
||||||
required this.rowController,
|
required this.rowController,
|
||||||
required this.cellBuilder,
|
required this.cellBuilder,
|
||||||
this.allowOpenAsFullPage = true,
|
this.allowOpenAsFullPage = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
final FieldController fieldController;
|
final DatabaseController databaseController;
|
||||||
final RowController rowController;
|
final RowController rowController;
|
||||||
final EditableCellBuilder cellBuilder;
|
final EditableCellBuilder cellBuilder;
|
||||||
final bool allowOpenAsFullPage;
|
final bool allowOpenAsFullPage;
|
||||||
@ -58,77 +51,32 @@ class _RowBannerState extends State<RowBanner> {
|
|||||||
return BlocProvider<RowBannerBloc>(
|
return BlocProvider<RowBannerBloc>(
|
||||||
create: (context) => RowBannerBloc(
|
create: (context) => RowBannerBloc(
|
||||||
viewId: widget.rowController.viewId,
|
viewId: widget.rowController.viewId,
|
||||||
fieldController: widget.fieldController,
|
fieldController: widget.databaseController.fieldController,
|
||||||
rowMeta: widget.rowController.rowMeta,
|
rowMeta: widget.rowController.rowMeta,
|
||||||
)..add(const RowBannerEvent.initial()),
|
)..add(const RowBannerEvent.initial()),
|
||||||
child: MouseRegion(
|
child: MouseRegion(
|
||||||
onEnter: (event) => _isHovering.value = true,
|
onEnter: (event) => _isHovering.value = true,
|
||||||
onExit: (event) => _isHovering.value = false,
|
onExit: (event) => _isHovering.value = false,
|
||||||
child: Stack(
|
child: Padding(
|
||||||
children: [
|
padding: const EdgeInsets.fromLTRB(60, 34, 60, 0),
|
||||||
Padding(
|
child: Column(
|
||||||
padding: const EdgeInsets.fromLTRB(60, 34, 60, 0),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
child: Column(
|
children: [
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
SizedBox(
|
||||||
children: [
|
height: 30,
|
||||||
SizedBox(
|
child: _BannerAction(
|
||||||
height: 30,
|
isHovering: _isHovering,
|
||||||
child: _BannerAction(
|
popoverController: popoverController,
|
||||||
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<ViewBloc>();
|
|
||||||
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<TabsBloc>().add(
|
|
||||||
TabsEvent.openPlugin(
|
|
||||||
plugin: DatabaseDocumentPlugin(
|
|
||||||
data: DatabaseDocumentContext(
|
|
||||||
view: viewBloc.state.view,
|
|
||||||
databaseId: databaseId,
|
|
||||||
rowId: widget.rowController.rowId,
|
|
||||||
documentId: documentId,
|
|
||||||
),
|
|
||||||
pluginType: PluginType.databaseDocument,
|
|
||||||
),
|
|
||||||
setLatest: false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
const VSpace(4),
|
||||||
|
_BannerTitle(
|
||||||
|
cellBuilder: widget.cellBuilder,
|
||||||
|
popoverController: popoverController,
|
||||||
|
rowController: widget.rowController,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -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/database_controller.dart';
|
||||||
import 'package:appflowy/plugins/database/application/row/row_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/grid/application/row/row_detail_bloc.dart';
|
||||||
import 'package:appflowy/plugins/database/widgets/row/row_document.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/startup/startup.dart';
|
||||||
import 'package:appflowy/user/application/reminder/reminder_bloc.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:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
import '../cell/editable_cell_builder.dart';
|
import '../cell/editable_cell_builder.dart';
|
||||||
@ -55,37 +59,87 @@ class _RowDetailPageState extends State<RowDetailPage> {
|
|||||||
),
|
),
|
||||||
BlocProvider.value(value: getIt<ReminderBloc>()),
|
BlocProvider.value(value: getIt<ReminderBloc>()),
|
||||||
],
|
],
|
||||||
child: ListView(
|
child: Stack(
|
||||||
controller: scrollController,
|
|
||||||
children: [
|
children: [
|
||||||
RowBanner(
|
ListView(
|
||||||
fieldController: widget.databaseController.fieldController,
|
controller: scrollController,
|
||||||
rowController: widget.rowController,
|
children: [
|
||||||
cellBuilder: cellBuilder,
|
RowBanner(
|
||||||
allowOpenAsFullPage: widget.allowOpenAsFullPage,
|
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),
|
Positioned(
|
||||||
Padding(
|
top: 12,
|
||||||
padding: const EdgeInsets.only(left: 40, right: 60),
|
right: 12,
|
||||||
child: RowPropertyList(
|
child: Row(
|
||||||
cellBuilder: cellBuilder,
|
children: _actions(context),
|
||||||
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,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Widget> _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<TabsBloc>().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),
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -738,6 +738,22 @@ pub(crate) async fn delete_group_handler(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip(manager), err)]
|
||||||
|
pub(crate) async fn get_database_meta_handler(
|
||||||
|
data: AFPluginData<DatabaseIdPB>,
|
||||||
|
manager: AFPluginState<Weak<DatabaseManager>>,
|
||||||
|
) -> DataResult<DatabaseMetaPB, FlowyError> {
|
||||||
|
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)]
|
#[tracing::instrument(level = "debug", skip(manager), err)]
|
||||||
pub(crate) async fn get_databases_handler(
|
pub(crate) async fn get_databases_handler(
|
||||||
manager: AFPluginState<Weak<DatabaseManager>>,
|
manager: AFPluginState<Weak<DatabaseManager>>,
|
||||||
|
@ -62,6 +62,7 @@ pub fn init(database_manager: Weak<DatabaseManager>) -> AFPlugin {
|
|||||||
.event(DatabaseEvent::CreateGroup, create_group_handler)
|
.event(DatabaseEvent::CreateGroup, create_group_handler)
|
||||||
.event(DatabaseEvent::DeleteGroup, delete_group_handler)
|
.event(DatabaseEvent::DeleteGroup, delete_group_handler)
|
||||||
// Database
|
// Database
|
||||||
|
.event(DatabaseEvent::GetDatabaseMeta, get_database_meta_handler)
|
||||||
.event(DatabaseEvent::GetDatabases, get_databases_handler)
|
.event(DatabaseEvent::GetDatabases, get_databases_handler)
|
||||||
// Calendar
|
// Calendar
|
||||||
.event(DatabaseEvent::GetAllCalendarEvents, get_calendar_events_handler)
|
.event(DatabaseEvent::GetAllCalendarEvents, get_calendar_events_handler)
|
||||||
@ -292,6 +293,9 @@ pub enum DatabaseEvent {
|
|||||||
#[event(input = "DeleteGroupPayloadPB")]
|
#[event(input = "DeleteGroupPayloadPB")]
|
||||||
DeleteGroup = 115,
|
DeleteGroup = 115,
|
||||||
|
|
||||||
|
#[event(input = "DatabaseIdPB", output = "DatabaseMetaPB")]
|
||||||
|
GetDatabaseMeta = 119,
|
||||||
|
|
||||||
/// Returns all the databases
|
/// Returns all the databases
|
||||||
#[event(output = "RepeatedDatabaseDescriptionPB")]
|
#[event(output = "RepeatedDatabaseDescriptionPB")]
|
||||||
GetDatabases = 120,
|
GetDatabases = 120,
|
||||||
|
Reference in New Issue
Block a user