From 7769034467eb1c8b07911fc1fd8b68778ba5ac72 Mon Sep 17 00:00:00 2001 From: "Lucas.Xu" Date: Thu, 8 Aug 2024 13:35:22 +0800 Subject: [PATCH] chore: add more logs in reminder bloc (#5860) * chore: add more logs in reminder bloc * Revert "chore: add more logs in reminder bloc" This reverts commit 9d0bb8fb2963d24cc572754c2f9411cebfa69f98. * chore: add more logs in reminder bloc * fix: unable to view reminders on Desktop * fix: force refresh reminders * chore: fix flutter analyze * feat: support database reminder on Mobile * chore: remove referenced database padding --- .../notification_reminder_bloc.dart | 35 ++++++-- .../presentation/base/mobile_view_page.dart | 11 ++- .../presentation/home/mobile_home_page.dart | 1 + .../notifications/widgets/shared.dart | 60 +++++++++++--- .../widgets/board_hidden_groups.dart | 6 +- .../calendar/presentation/calendar_page.dart | 18 ++-- .../calculations/calculations_row.dart | 12 +-- .../widgets/footer/grid_footer.dart | 9 +- .../grid/presentation/widgets/row/row.dart | 2 +- .../widgets/database_view_widget.dart | 3 +- .../lib/shared/google_fonts_extension.dart | 7 +- .../application/reminder/reminder_bloc.dart | 83 ++++++++++++++----- .../home/desktop_home_screen.dart | 3 +- .../notifications/notification_dialog.dart | 15 ++-- .../widgets/notification_button.dart | 15 +++- .../widgets/notification_item.dart | 38 +++------ .../widgets/notification_view.dart | 2 +- 17 files changed, 216 insertions(+), 104 deletions(-) diff --git a/frontend/appflowy_flutter/lib/mobile/application/notification/notification_reminder_bloc.dart b/frontend/appflowy_flutter/lib/mobile/application/notification/notification_reminder_bloc.dart index 8adfa58d0f..193634b2d5 100644 --- a/frontend/appflowy_flutter/lib/mobile/application/notification/notification_reminder_bloc.dart +++ b/frontend/appflowy_flutter/lib/mobile/application/notification/notification_reminder_bloc.dart @@ -5,6 +5,7 @@ import 'package:appflowy/user/application/reminder/reminder_extension.dart'; import 'package:appflowy/workspace/application/settings/date_time/date_format_ext.dart'; import 'package:appflowy/workspace/application/settings/date_time/time_format_ext.dart'; import 'package:appflowy/workspace/application/view/prelude.dart'; +import 'package:appflowy/workspace/application/view/view_ext.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; @@ -23,16 +24,20 @@ class NotificationReminderBloc await event.when( initial: (reminder, dateFormat, timeFormat) async { this.reminder = reminder; + this.dateFormat = dateFormat; + this.timeFormat = timeFormat; + add(const NotificationReminderEvent.reset()); + }, + reset: () async { final createdAt = await _getCreatedAt( reminder, dateFormat, timeFormat, ); final view = await _getView(reminder); - final node = await _getContent(reminder); - if (view == null || node == null) { + if (view == null) { emit( NotificationReminderState( createdAt: createdAt, @@ -41,25 +46,43 @@ class NotificationReminderBloc status: NotificationReminderStatus.error, ), ); - } else { + } + + final layout = view!.layout; + + if (layout.isDocumentView) { + final node = await _getContent(reminder); + if (node != null) { + emit( + NotificationReminderState( + createdAt: createdAt, + pageTitle: view.name, + view: view, + reminderContent: node.delta?.toPlainText() ?? '', + nodes: [node], + status: NotificationReminderStatus.loaded, + ), + ); + } + } else if (layout.isDatabaseView) { emit( NotificationReminderState( createdAt: createdAt, pageTitle: view.name, view: view, - reminderContent: node.delta?.toPlainText() ?? '', - nodes: [node], + reminderContent: reminder.message, status: NotificationReminderStatus.loaded, ), ); } }, - reset: () {}, ); }); } late final ReminderPB reminder; + late final UserDateFormatPB dateFormat; + late final UserTimeFormatPB timeFormat; Future _getCreatedAt( ReminderPB reminder, diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart index 216624340e..603005fc38 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/base/mobile_view_page.dart @@ -46,10 +46,18 @@ class _MobileViewPageState extends State { // control the app bar opacity when in immersive mode final ValueNotifier _appBarOpacity = ValueNotifier(1.0); + @override + void initState() { + super.initState(); + + getIt().add(const ReminderEvent.started()); + } + @override void dispose() { _appBarOpacity.dispose(); _scrollNotificationObserver = null; + super.dispose(); } @@ -78,8 +86,7 @@ class _MobileViewPageState extends State { ViewBloc(view: view)..add(const ViewEvent.initial()), ), BlocProvider.value( - value: getIt() - ..add(const ReminderEvent.started()), + value: getIt(), ), if (view.layout.isDocumentView) BlocProvider( diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart index 99c24bb05e..215c9433b5 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/home/mobile_home_page.dart @@ -99,6 +99,7 @@ class _MobileHomePageState extends State { super.initState(); getIt().addLatestViewListener(_onLatestViewChange); + getIt().add(const ReminderEvent.started()); } @override diff --git a/frontend/appflowy_flutter/lib/mobile/presentation/notifications/widgets/shared.dart b/frontend/appflowy_flutter/lib/mobile/presentation/notifications/widgets/shared.dart index 10b5a03222..4f1a7d2db0 100644 --- a/frontend/appflowy_flutter/lib/mobile/presentation/notifications/widgets/shared.dart +++ b/frontend/appflowy_flutter/lib/mobile/presentation/notifications/widgets/shared.dart @@ -6,6 +6,8 @@ import 'package:appflowy/mobile/presentation/notifications/widgets/color.dart'; import 'package:appflowy/plugins/document/presentation/editor_configuration.dart'; import 'package:appflowy/plugins/document/presentation/editor_style.dart'; import 'package:appflowy/user/application/reminder/reminder_extension.dart'; +import 'package:appflowy/workspace/application/view/view_ext.dart'; +import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -76,7 +78,7 @@ class UnreadRedDot extends StatelessWidget { } } -class NotificationContent extends StatelessWidget { +class NotificationContent extends StatefulWidget { const NotificationContent({ super.key, required this.reminder, @@ -84,10 +86,29 @@ class NotificationContent extends StatelessWidget { final ReminderPB reminder; + @override + State createState() => _NotificationContentState(); +} + +class _NotificationContentState extends State { + @override + void didUpdateWidget(covariant NotificationContent oldWidget) { + super.didUpdateWidget(oldWidget); + + context.read().add( + const NotificationReminderEvent.reset(), + ); + } + @override Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { + final view = state.view; + if (view == null) { + return const SizedBox.shrink(); + } + return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, @@ -105,15 +126,7 @@ class NotificationContent extends StatelessWidget { // content Padding( padding: const EdgeInsets.only(right: 16.0), - child: IntrinsicHeight( - child: BlocProvider( - create: (context) => DocumentPageStyleBloc(view: state.view!), - child: NotificationDocumentContent( - reminder: reminder, - nodes: state.nodes, - ), - ), - ), + child: _buildContent(view, nodes: state.nodes), ), ], ); @@ -121,6 +134,33 @@ class NotificationContent extends StatelessWidget { ); } + Widget _buildContent(ViewPB view, {List? nodes}) { + if (view.layout.isDocumentView && nodes != null) { + return IntrinsicHeight( + child: BlocProvider( + create: (context) => DocumentPageStyleBloc(view: view), + child: NotificationDocumentContent( + reminder: widget.reminder, + nodes: nodes, + ), + ), + ); + } else if (view.layout.isDatabaseView) { + final opacity = widget.reminder.type == ReminderType.past ? 0.3 : 1.0; + return Opacity( + opacity: opacity, + child: FlowyText( + widget.reminder.message, + fontSize: 14, + figmaLineHeight: 22, + color: context.notificationItemTextColor, + ), + ); + } + + return const SizedBox.shrink(); + } + Widget _buildHeader() { return FlowyText.semibold( LocaleKeys.settings_notifications_titles_reminder.tr(), diff --git a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart index 6bba024eb0..98dd7a8eaf 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/board/presentation/widgets/board_hidden_groups.dart @@ -8,6 +8,7 @@ import 'package:appflowy/plugins/database/application/row/row_cache.dart'; import 'package:appflowy/plugins/database/application/row/row_controller.dart'; import 'package:appflowy/plugins/database/board/application/board_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; +import 'package:appflowy/plugins/database/tab_bar/tab_bar_view.dart'; import 'package:appflowy/plugins/database/widgets/cell/card_cell_builder.dart'; import 'package:appflowy/plugins/database/widgets/cell/card_cell_skeleton/text_card_cell.dart'; import 'package:appflowy/plugins/database/widgets/row/row_detail.dart'; @@ -64,7 +65,10 @@ class HiddenGroupsColumn extends StatelessWidget { height: 50, child: Padding( padding: EdgeInsets.only( - left: 80 + margin.left, + left: margin.left + + context + .read() + .horizontalPadding, right: margin.right + 4, ), child: Row( diff --git a/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_page.dart b/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_page.dart index 746305264b..65b4613204 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_page.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/calendar/presentation/calendar_page.dart @@ -1,5 +1,3 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/mobile/presentation/bottom_sheet/bottom_sheet.dart'; @@ -20,12 +18,12 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/size.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import '../../application/row/row_controller.dart'; import '../../widgets/row/row_detail.dart'; - import 'calendar_day.dart'; import 'layout/sizes.dart'; import 'toolbar/calendar_setting_bar.dart'; @@ -185,11 +183,17 @@ class _CalendarPageState extends State { return LayoutBuilder( // must specify MonthView width for useAvailableVerticalSpace to work properly builder: (context, constraints) { + EdgeInsets padding = PlatformExtension.isMobile + ? CalendarSize.contentInsetsMobile + : CalendarSize.contentInsets + + const EdgeInsets.symmetric(horizontal: 40); + final double horizontalPadding = + context.read().horizontalPadding; + if (horizontalPadding == 0) { + padding = padding.copyWith(left: 0, right: 0); + } return Padding( - padding: PlatformExtension.isMobile - ? CalendarSize.contentInsetsMobile - : CalendarSize.contentInsets + - const EdgeInsets.symmetric(horizontal: 40), + padding: padding, child: ScrollConfiguration( behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false), diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculations_row.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculations_row.dart index 7899d5f56d..5524633a46 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculations_row.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/calculations/calculations_row.dart @@ -1,9 +1,8 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/plugins/database/grid/application/calculations/calculations_bloc.dart'; import 'package:appflowy/plugins/database/grid/application/grid_bloc.dart'; -import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; import 'package:appflowy/plugins/database/grid/presentation/widgets/calculations/calculate_cell.dart'; +import 'package:appflowy/plugins/database/tab_bar/tab_bar_view.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class GridCalculationsRow extends StatelessWidget { @@ -27,9 +26,12 @@ class GridCalculationsRow extends StatelessWidget { )..add(const CalculationsEvent.started()), child: BlocBuilder( builder: (context, state) { + final padding = + context.read().horizontalPadding; return Padding( - padding: - includeDefaultInsets ? GridSize.contentInsets : EdgeInsets.zero, + padding: includeDefaultInsets + ? EdgeInsets.symmetric(horizontal: padding) + : EdgeInsets.zero, child: Row( children: [ ...state.fields.map( diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/footer/grid_footer.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/footer/grid_footer.dart index fa78dd629e..31ff0e8469 100755 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/footer/grid_footer.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/footer/grid_footer.dart @@ -1,13 +1,13 @@ -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/grid/application/grid_bloc.dart'; import 'package:appflowy/plugins/database/grid/presentation/layout/sizes.dart'; +import 'package:appflowy/plugins/database/tab_bar/tab_bar_view.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/style_widget/button.dart'; import 'package:flowy_infra_ui/style_widget/text.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class GridAddRowButton extends StatelessWidget { @@ -41,8 +41,11 @@ class GridRowBottomBar extends StatelessWidget { @override Widget build(BuildContext context) { + final padding = + context.read().horizontalPadding; return Container( - padding: GridSize.footerContentInsets + const EdgeInsets.only(left: 40), + padding: GridSize.footerContentInsets.copyWith(left: 0) + + EdgeInsets.only(left: padding), height: GridSize.footerHeight, child: const GridAddRowButton(), ); diff --git a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/row/row.dart b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/row/row.dart index 337aab4a70..fd52ec727e 100755 --- a/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/row/row.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/grid/presentation/widgets/row/row.dart @@ -98,7 +98,7 @@ class _RowLeadingState extends State<_RowLeading> { return AppFlowyPopover( controller: popoverController, triggerActions: PopoverTriggerFlags.none, - constraints: BoxConstraints.loose(const Size(176, 200)), + constraints: BoxConstraints.loose(const Size(200, 200)), direction: PopoverDirection.rightWithCenterAligned, margin: const EdgeInsets.symmetric(horizontal: 6, vertical: 8), popupBuilder: (_) { diff --git a/frontend/appflowy_flutter/lib/plugins/database/widgets/database_view_widget.dart b/frontend/appflowy_flutter/lib/plugins/database/widgets/database_view_widget.dart index 35169550f1..c979ee0829 100644 --- a/frontend/appflowy_flutter/lib/plugins/database/widgets/database_view_widget.dart +++ b/frontend/appflowy_flutter/lib/plugins/database/widgets/database_view_widget.dart @@ -56,7 +56,8 @@ class _DatabaseViewWidgetState extends State { shrinkWrap: widget.shrinkWrap, context: PluginContext(), data: { - kDatabasePluginWidgetBuilderHorizontalPadding: 40.0, + kDatabasePluginWidgetBuilderHorizontalPadding: + view.layout == ViewLayoutPB.Grid ? 40.0 : 0.0, }, ), ); diff --git a/frontend/appflowy_flutter/lib/shared/google_fonts_extension.dart b/frontend/appflowy_flutter/lib/shared/google_fonts_extension.dart index c5cb5df786..3e6a69153a 100644 --- a/frontend/appflowy_flutter/lib/shared/google_fonts_extension.dart +++ b/frontend/appflowy_flutter/lib/shared/google_fonts_extension.dart @@ -1,5 +1,4 @@ import 'package:appflowy/workspace/application/settings/appearance/base_appearance.dart'; -import 'package:appflowy_backend/log.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -38,11 +37,7 @@ TextStyle getGoogleFontSafely( letterSpacing: letterSpacing, height: lineHeight, ); - } catch (e) { - Log.error( - 'Font family $fontFamily is not available, using default font family instead', - ); - } + } catch (_) {} } return TextStyle( diff --git a/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart b/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart index 07024b2668..c5e9d7e132 100644 --- a/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart +++ b/frontend/appflowy_flutter/lib/user/application/reminder/reminder_bloc.dart @@ -24,6 +24,8 @@ part 'reminder_bloc.freezed.dart'; class ReminderBloc extends Bloc { ReminderBloc() : super(ReminderState()) { + Log.info('ReminderBloc created'); + _actionBloc = getIt(); _reminderService = const ReminderService(); timer = _periodicCheck(); @@ -40,36 +42,58 @@ class ReminderBloc extends Bloc { (event, emit) async { await event.when( started: () async { - final remindersOrFailure = await _reminderService.fetchReminders(); + Log.info('Start fetching reminders'); - remindersOrFailure.fold( - (reminders) => emit(state.copyWith(reminders: reminders)), - (error) => Log.error(error), + final result = await _reminderService.fetchReminders(); + + result.fold( + (reminders) { + Log.info('Fetched reminders on startup: ${reminders.length}'); + emit(state.copyWith(reminders: reminders)); + }, + (error) => Log.error('Failed to fetch reminders: $error'), ); }, remove: (reminderId) async { - final unitOrFailure = - await _reminderService.removeReminder(reminderId: reminderId); + final result = await _reminderService.removeReminder( + reminderId: reminderId, + ); - unitOrFailure.fold( + result.fold( (_) { + Log.info('Removed reminder: $reminderId'); final reminders = [...state.reminders]; reminders.removeWhere((e) => e.id == reminderId); emit(state.copyWith(reminders: reminders)); }, - (error) => Log.error(error), + (error) => Log.error( + 'Failed to remove reminder($reminderId): $error', + ), ); }, add: (reminder) async { - final unitOrFailure = - await _reminderService.addReminder(reminder: reminder); + // check the timestamp in the reminder + if (reminder.createdAt == null) { + reminder.freeze(); + reminder = reminder.rebuild((update) { + update.meta[ReminderMetaKeys.createdAt] = + DateTime.now().millisecondsSinceEpoch.toString(); + }); + } - return unitOrFailure.fold( + final result = await _reminderService.addReminder( + reminder: reminder, + ); + + return result.fold( (_) { + Log.info('Added reminder: ${reminder.id}'); + Log.info('Before adding reminder: ${state.reminders.length}'); final reminders = [...state.reminders, reminder]; + Log.info('After adding reminder: ${reminders.length}'); emit(state.copyWith(reminders: reminders)); }, - (error) => Log.error(error), + (error) => Log.error('Failed to add reminder: $error'), ); }, addById: (reminderId, objectId, scheduledAt, meta) async => add( @@ -86,8 +110,9 @@ class ReminderBloc extends Bloc { ), ), update: (updateObject) async { - final reminder = state.reminders - .firstWhereOrNull((r) => r.id == updateObject.id); + final reminder = state.reminders.firstWhereOrNull( + (r) => r.id == updateObject.id, + ); if (reminder == null) { return; @@ -98,15 +123,20 @@ class ReminderBloc extends Bloc { reminder: newReminder, ); + Log.info('Updating reminder: ${reminder.id}'); + failureOrUnit.fold( (_) { + Log.info('Updated reminder: ${reminder.id}'); final index = state.reminders.indexWhere((r) => r.id == reminder.id); final reminders = [...state.reminders]; reminders.replaceRange(index, index + 1, [newReminder]); emit(state.copyWith(reminders: reminders)); }, - (error) => Log.error(error), + (error) => Log.error( + 'Failed to update reminder(${reminder.id}): $error', + ), ); }, pressReminder: (reminderId, path, view) { @@ -157,6 +187,9 @@ class ReminderBloc extends Bloc { }, markAsRead: (reminderIds) async { final reminders = await _onMarkAsRead(reminderIds: reminderIds); + + Log.info('Marked reminders as read: $reminderIds'); + emit( state.copyWith( reminders: reminders, @@ -168,6 +201,9 @@ class ReminderBloc extends Bloc { isArchived: true, reminderIds: reminderIds, ); + + Log.info('Archived reminders: $reminderIds'); + emit( state.copyWith( reminders: reminders, @@ -176,6 +212,9 @@ class ReminderBloc extends Bloc { }, markAllRead: () async { final reminders = await _onMarkAsRead(); + + Log.info('Marked all reminders as read'); + emit( state.copyWith( reminders: reminders, @@ -184,6 +223,9 @@ class ReminderBloc extends Bloc { }, archiveAll: () async { final reminders = await _onArchived(isArchived: true); + + Log.info('Archived all reminders'); + emit( state.copyWith( reminders: reminders, @@ -199,11 +241,14 @@ class ReminderBloc extends Bloc { ); }, refresh: () async { - final remindersOrFailure = await _reminderService.fetchReminders(); + final result = await _reminderService.fetchReminders(); - remindersOrFailure.fold( - (reminders) => emit(state.copyWith(reminders: reminders)), - (error) => emit(state), + result.fold( + (reminders) { + Log.info('Fetched reminders on refresh: ${reminders.length}'); + emit(state.copyWith(reminders: reminders)); + }, + (error) => Log.error('Failed to fetch reminders: $error'), ); }, ); diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart b/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart index f2e1515112..b2f9c89889 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/home/desktop_home_screen.dart @@ -71,8 +71,7 @@ class DesktopHomeScreen extends StatelessWidget { key: ValueKey(userProfile.id), providers: [ BlocProvider.value( - value: getIt() - ..add(const ReminderEvent.started()), + value: getIt(), ), BlocProvider.value(value: getIt()), BlocProvider( diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart index 022e6b3876..d0392efb55 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/notification_dialog.dart @@ -1,5 +1,3 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/startup/startup.dart'; import 'package:appflowy/user/application/notification_filter/notification_filter_bloc.dart'; import 'package:appflowy/user/application/reminder/reminder_bloc.dart'; @@ -11,6 +9,7 @@ import 'package:appflowy/workspace/presentation/notifications/widgets/notificati import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; import 'package:appflowy_backend/protobuf/flowy-user/reminder.pb.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NotificationDialog extends StatefulWidget { @@ -64,12 +63,10 @@ class _NotificationDialogState extends State builder: (context, filterState) => BlocBuilder( builder: (context, state) { - final List pastReminders = state.pastReminders - .where((r) => filterState.showUnreadsOnly ? !r.isRead : true) - .sortByScheduledAt(); - - final List upcomingReminders = + final reminders = state.reminders.sortByScheduledAt(); + final upcomingReminders = state.upcomingReminders.sortByScheduledAt(); + final hasUnreads = reminders.any((r) => !r.isRead); return Column( mainAxisSize: MainAxisSize.min, @@ -82,14 +79,14 @@ class _NotificationDialogState extends State controller: _controller, children: [ NotificationsView( - shownReminders: pastReminders, + shownReminders: reminders, reminderBloc: _reminderBloc, views: widget.views, onDelete: _onDelete, onAction: _onAction, onReadChanged: _onReadChanged, actionBar: InboxActionBar( - hasUnreads: state.hasUnreads, + hasUnreads: hasUnreads, showUnreadsOnly: filterState.showUnreadsOnly, ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart index 0fe3fdf75c..433511929f 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_button.dart @@ -1,5 +1,3 @@ -import 'package:flutter/material.dart'; - import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; import 'package:appflowy/startup/startup.dart'; @@ -11,6 +9,7 @@ import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flowy_infra/theme_extension.dart'; import 'package:flowy_infra_ui/flowy_infra_ui.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NotificationButton extends StatefulWidget { @@ -23,6 +22,12 @@ class NotificationButton extends StatefulWidget { class _NotificationButtonState extends State { final mutex = PopoverMutex(); + @override + void initState() { + super.initState(); + getIt().add(const ReminderEvent.started()); + } + @override void dispose() { mutex.dispose(); @@ -56,8 +61,10 @@ class _NotificationButtonState extends State { child: FlowyButton( useIntrinsicWidth: true, margin: EdgeInsets.zero, - text: - _buildNotificationIcon(context, state.hasUnreads), + text: _buildNotificationIcon( + context, + state.hasUnreads, + ), ), ), ), diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_item.dart b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_item.dart index fed0bf4390..029f6e1145 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_item.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_item.dart @@ -1,10 +1,10 @@ import 'package:appflowy/generated/flowy_svgs.g.dart'; import 'package:appflowy/generated/locale_keys.g.dart'; -import 'package:appflowy/plugins/document/presentation/editor_configuration.dart'; -import 'package:appflowy/plugins/document/presentation/editor_style.dart'; +import 'package:appflowy/mobile/presentation/notifications/widgets/widgets.dart'; import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart'; import 'package:appflowy/workspace/application/settings/date_time/date_format_ext.dart'; import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart'; +import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; import 'package:appflowy_editor/appflowy_editor.dart'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:easy_localization/easy_localization.dart'; @@ -18,7 +18,7 @@ import 'package:provider/provider.dart'; class NotificationItem extends StatefulWidget { const NotificationItem({ super.key, - required this.reminderId, + required this.reminder, required this.title, required this.scheduled, required this.body, @@ -32,7 +32,7 @@ class NotificationItem extends StatefulWidget { this.view, }); - final String reminderId; + final ReminderPB reminder; final String title; final Int64 scheduled; final String body; @@ -169,6 +169,7 @@ class _NotificationItemState extends State { ), child: _NotificationContent( block: widget.block, + reminder: widget.reminder, body: widget.body, ), ), @@ -214,10 +215,12 @@ class _NotificationItemState extends State { class _NotificationContent extends StatelessWidget { const _NotificationContent({ required this.body, + required this.reminder, required this.block, }); final String body; + final ReminderPB reminder; final Future? block; @override @@ -229,29 +232,10 @@ class _NotificationContent extends StatelessWidget { return FlowyText.regular(body, maxLines: 4); } - final editorState = EditorState( - document: Document(root: snapshot.data!), - ); - - final styleCustomizer = EditorStyleCustomizer( - context: context, - padding: EdgeInsets.zero, - ); - - return Transform.scale( - scale: .9, - alignment: Alignment.centerLeft, - child: AppFlowyEditor( - editorState: editorState, - editorStyle: styleCustomizer.style(), - editable: false, - shrinkWrap: true, - blockComponentBuilders: getEditorBuilderMap( - context: context, - editorState: editorState, - styleCustomizer: styleCustomizer, - editable: false, - ), + return IntrinsicHeight( + child: NotificationDocumentContent( + nodes: [snapshot.data!], + reminder: reminder, ), ); }, diff --git a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_view.dart b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_view.dart index 42e5d50bfd..645be8b055 100644 --- a/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_view.dart +++ b/frontend/appflowy_flutter/lib/workspace/presentation/notifications/widgets/notification_view.dart @@ -76,7 +76,7 @@ class NotificationsView extends StatelessWidget { final view = views.findView(reminder.objectId); return NotificationItem( - reminderId: reminder.id, + reminder: reminder, key: ValueKey(reminder.id), title: reminder.title, scheduled: reminder.scheduledAt,