mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-11-02 02:53:59 +00:00
fix: reminder improvements (#6680)
This commit is contained in:
parent
07e34609e7
commit
0ea2da424f
@ -28,8 +28,8 @@ class MobileNotificationsScreen extends StatefulWidget {
|
||||
|
||||
class _MobileNotificationsScreenState extends State<MobileNotificationsScreen>
|
||||
with SingleTickerProviderStateMixin {
|
||||
final ReminderBloc _reminderBloc = getIt<ReminderBloc>();
|
||||
late final TabController _controller = TabController(length: 2, vsync: this);
|
||||
final ReminderBloc reminderBloc = getIt<ReminderBloc>();
|
||||
late final TabController controller = TabController(length: 2, vsync: this);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -39,7 +39,7 @@ class _MobileNotificationsScreenState extends State<MobileNotificationsScreen>
|
||||
create: (context) =>
|
||||
UserProfileBloc()..add(const UserProfileEvent.started()),
|
||||
),
|
||||
BlocProvider<ReminderBloc>.value(value: _reminderBloc),
|
||||
BlocProvider<ReminderBloc>.value(value: reminderBloc),
|
||||
BlocProvider<NotificationFilterBloc>(
|
||||
create: (_) => NotificationFilterBloc(),
|
||||
),
|
||||
@ -54,8 +54,8 @@ class _MobileNotificationsScreenState extends State<MobileNotificationsScreen>
|
||||
_NotificationScreenContent(
|
||||
workspaceSetting: workspaceSetting,
|
||||
userProfile: userProfile,
|
||||
controller: _controller,
|
||||
reminderBloc: _reminderBloc,
|
||||
controller: controller,
|
||||
reminderBloc: reminderBloc,
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -124,7 +124,6 @@ class _NotificationScreenContent extends StatelessWidget {
|
||||
reminderBloc: reminderBloc,
|
||||
views: sectionState.section.publicViews,
|
||||
onAction: _onAction,
|
||||
onDelete: _onDelete,
|
||||
onReadChanged: _onReadChanged,
|
||||
actionBar: InboxActionBar(
|
||||
hasUnreads: state.hasUnreads,
|
||||
@ -161,9 +160,6 @@ class _NotificationScreenContent extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
|
||||
void _onDelete(ReminderPB reminder) =>
|
||||
reminderBloc.add(ReminderEvent.remove(reminderId: reminder.id));
|
||||
|
||||
void _onReadChanged(ReminderPB reminder, bool isRead) => reminderBloc.add(
|
||||
ReminderEvent.update(ReminderUpdate(id: reminder.id, isRead: isRead)),
|
||||
);
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/transaction_handler/editor_transaction_handler.dart';
|
||||
import 'package:appflowy/plugins/trash/application/trash_service.dart';
|
||||
import 'package:appflowy/shared/clipboard_state.dart';
|
||||
import 'package:appflowy/workspace/application/view/view_service.dart';
|
||||
@ -12,20 +11,12 @@ import 'package:flowy_infra_ui/style_widget/snap_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
/// The data used to handle transactions for mentions.
|
||||
///
|
||||
/// [Node] is the block node.
|
||||
/// [Map] is the data of the mention block.
|
||||
/// [int] is the index of the mention block in the list of deltas (after transaction apply).
|
||||
///
|
||||
typedef MentionBlockData = (Node, Map<String, dynamic>, int);
|
||||
import '../transaction_handler/mention_transaction_handler.dart';
|
||||
|
||||
const _pasteIdentifier = 'child_page_transaction';
|
||||
|
||||
class ChildPageTransactionHandler
|
||||
extends EditorTransactionHandler<MentionBlockData> {
|
||||
ChildPageTransactionHandler()
|
||||
: super(type: MentionBlockKeys.mention, livesInDelta: true);
|
||||
class ChildPageTransactionHandler extends MentionTransactionHandler {
|
||||
ChildPageTransactionHandler() : super(subType: MentionType.childPage.name);
|
||||
|
||||
@override
|
||||
Future<void> onTransaction(
|
||||
|
||||
@ -4,6 +4,7 @@ import 'package:appflowy/plugins/document/presentation/editor_notification.dart'
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/child_page_transaction_handler.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/sub_page/sub_page_transaction_handler.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/transaction_handler/editor_transaction_handler.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/transaction_handler/mention_transaction_handler.dart';
|
||||
import 'package:appflowy/shared/clipboard_state.dart';
|
||||
import 'package:appflowy/shared/feature_flags.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/transaction_handler/editor_transaction_handler.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
|
||||
/// The data used to handle transactions for mentions.
|
||||
///
|
||||
/// [Node] is the block node.
|
||||
/// [Map] is the data of the mention block.
|
||||
/// [int] is the index of the mention block in the list of deltas (after transaction apply).
|
||||
///
|
||||
typedef MentionBlockData = (Node, Map<String, dynamic>, int);
|
||||
|
||||
abstract class MentionTransactionHandler
|
||||
extends EditorTransactionHandler<MentionBlockData> {
|
||||
const MentionTransactionHandler({
|
||||
required this.subType,
|
||||
})
|
||||
: super(type: MentionBlockKeys.mention, livesInDelta: true);
|
||||
|
||||
final String subType;
|
||||
|
||||
MentionType get mentionType => MentionType.fromString(subType);
|
||||
}
|
||||
@ -301,12 +301,6 @@ extension ViewLayoutExtension on ViewLayoutPB {
|
||||
_ => throw Exception('Unknown layout type'),
|
||||
};
|
||||
|
||||
FlowySvgData mentionIcon({bool isChildPage = false}) => switch (this) {
|
||||
ViewLayoutPB.Document =>
|
||||
isChildPage ? FlowySvgs.child_page_s : FlowySvgs.link_to_page_s,
|
||||
_ => icon,
|
||||
};
|
||||
|
||||
bool get isDocumentView => switch (this) {
|
||||
ViewLayoutPB.Document => true,
|
||||
ViewLayoutPB.Chat ||
|
||||
|
||||
@ -28,25 +28,25 @@ class NotificationDialog extends StatefulWidget {
|
||||
|
||||
class _NotificationDialogState extends State<NotificationDialog>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late final TabController _controller = TabController(length: 2, vsync: this);
|
||||
final PopoverMutex _mutex = PopoverMutex();
|
||||
final ReminderBloc _reminderBloc = getIt<ReminderBloc>();
|
||||
late final TabController controller = TabController(length: 2, vsync: this);
|
||||
final PopoverMutex mutex = PopoverMutex();
|
||||
final ReminderBloc reminderBloc = getIt<ReminderBloc>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// Get all the past and upcoming reminders
|
||||
_reminderBloc.add(const ReminderEvent.started());
|
||||
_controller.addListener(_updateState);
|
||||
reminderBloc.add(const ReminderEvent.started());
|
||||
controller.addListener(updateState);
|
||||
}
|
||||
|
||||
void _updateState() => setState(() {});
|
||||
void updateState() => setState(() {});
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_mutex.dispose();
|
||||
_controller.removeListener(_updateState);
|
||||
_controller.dispose();
|
||||
mutex.dispose();
|
||||
controller.removeListener(updateState);
|
||||
controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ class _NotificationDialogState extends State<NotificationDialog>
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider<ReminderBloc>.value(value: _reminderBloc),
|
||||
BlocProvider<ReminderBloc>.value(value: reminderBloc),
|
||||
BlocProvider<NotificationFilterBloc>(
|
||||
create: (_) => NotificationFilterBloc(),
|
||||
),
|
||||
@ -63,27 +63,26 @@ class _NotificationDialogState extends State<NotificationDialog>
|
||||
builder: (context, filterState) =>
|
||||
BlocBuilder<ReminderBloc, ReminderState>(
|
||||
builder: (context, state) {
|
||||
final reminders = state.reminders.sortByScheduledAt();
|
||||
final pastReminders = state.pastReminders.sortByScheduledAt();
|
||||
final upcomingReminders =
|
||||
state.upcomingReminders.sortByScheduledAt();
|
||||
final hasUnreads = reminders.any((r) => !r.isRead);
|
||||
final hasUnreads = pastReminders.any((r) => !r.isRead);
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const NotificationHubTitle(),
|
||||
NotificationTabBar(tabController: _controller),
|
||||
NotificationTabBar(tabController: controller),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
controller: _controller,
|
||||
controller: controller,
|
||||
children: [
|
||||
NotificationsView(
|
||||
shownReminders: reminders,
|
||||
reminderBloc: _reminderBloc,
|
||||
shownReminders: pastReminders,
|
||||
reminderBloc: reminderBloc,
|
||||
views: widget.views,
|
||||
onDelete: _onDelete,
|
||||
onAction: _onAction,
|
||||
onAction: onAction,
|
||||
onReadChanged: _onReadChanged,
|
||||
actionBar: InboxActionBar(
|
||||
hasUnreads: hasUnreads,
|
||||
@ -92,10 +91,10 @@ class _NotificationDialogState extends State<NotificationDialog>
|
||||
),
|
||||
NotificationsView(
|
||||
shownReminders: upcomingReminders,
|
||||
reminderBloc: _reminderBloc,
|
||||
reminderBloc: reminderBloc,
|
||||
views: widget.views,
|
||||
isUpcoming: true,
|
||||
onAction: _onAction,
|
||||
onAction: onAction,
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -108,20 +107,16 @@ class _NotificationDialogState extends State<NotificationDialog>
|
||||
);
|
||||
}
|
||||
|
||||
void _onAction(ReminderPB reminder, int? path, ViewPB? view) {
|
||||
_reminderBloc.add(
|
||||
void onAction(ReminderPB reminder, int? path, ViewPB? view) {
|
||||
reminderBloc.add(
|
||||
ReminderEvent.pressReminder(reminderId: reminder.id, path: path),
|
||||
);
|
||||
|
||||
widget.mutex.close();
|
||||
}
|
||||
|
||||
void _onDelete(ReminderPB reminder) {
|
||||
_reminderBloc.add(ReminderEvent.remove(reminderId: reminder.id));
|
||||
}
|
||||
|
||||
void _onReadChanged(ReminderPB reminder, bool isRead) {
|
||||
_reminderBloc.add(
|
||||
reminderBloc.add(
|
||||
ReminderEvent.update(ReminderUpdate(id: reminder.id, isRead: isRead)),
|
||||
);
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ class _NotificationButtonState extends State<NotificationButton> {
|
||||
builder: (notificationSettingsContext, notificationSettingsState) {
|
||||
return BlocBuilder<ReminderBloc, ReminderState>(
|
||||
builder: (context, state) {
|
||||
final hasUnreads = state.reminders.any((r) => !r.isRead);
|
||||
final hasUnreads = state.pastReminders.any((r) => !r.isRead);
|
||||
return notificationSettingsState.isShowNotificationsIconEnabled
|
||||
? FlowyTooltip(
|
||||
message: LocaleKeys.notificationHub_title.tr(),
|
||||
|
||||
@ -27,7 +27,6 @@ class NotificationItem extends StatefulWidget {
|
||||
this.includeTime = false,
|
||||
this.readOnly = false,
|
||||
this.onAction,
|
||||
this.onDelete,
|
||||
this.onReadChanged,
|
||||
this.view,
|
||||
});
|
||||
@ -50,7 +49,6 @@ class NotificationItem extends StatefulWidget {
|
||||
final bool readOnly;
|
||||
|
||||
final void Function(int? path)? onAction;
|
||||
final VoidCallback? onDelete;
|
||||
final void Function(bool isRead)? onReadChanged;
|
||||
|
||||
@override
|
||||
@ -153,7 +151,6 @@ class _NotificationItemState extends State<NotificationItem> {
|
||||
UniversalPlatform.isMobile ? 16 : 14,
|
||||
color: AFThemeExtension.of(context).textColor,
|
||||
),
|
||||
// TODO(Xazin): Relative time
|
||||
FlowyText.regular(
|
||||
infoString,
|
||||
fontSize:
|
||||
@ -191,7 +188,6 @@ class _NotificationItemState extends State<NotificationItem> {
|
||||
top: UniversalPlatform.isMobile ? 8 : 4,
|
||||
child: NotificationItemActions(
|
||||
isRead: widget.isRead,
|
||||
onDelete: widget.onDelete,
|
||||
onReadChanged: widget.onReadChanged,
|
||||
),
|
||||
),
|
||||
@ -247,12 +243,10 @@ class NotificationItemActions extends StatelessWidget {
|
||||
const NotificationItemActions({
|
||||
super.key,
|
||||
required this.isRead,
|
||||
this.onDelete,
|
||||
this.onReadChanged,
|
||||
});
|
||||
|
||||
final bool isRead;
|
||||
final VoidCallback? onDelete;
|
||||
final void Function(bool isRead)? onReadChanged;
|
||||
|
||||
@override
|
||||
@ -292,23 +286,6 @@ class NotificationItemActions extends StatelessWidget {
|
||||
onPressed: () => onReadChanged?.call(true),
|
||||
),
|
||||
],
|
||||
VerticalDivider(
|
||||
width: 3,
|
||||
thickness: 1,
|
||||
indent: 2,
|
||||
endIndent: 2,
|
||||
color: UniversalPlatform.isMobile
|
||||
? Theme.of(context).colorScheme.outline
|
||||
: Theme.of(context).dividerColor,
|
||||
),
|
||||
FlowyIconButton(
|
||||
height: size,
|
||||
width: size,
|
||||
tooltipText: LocaleKeys.reminderNotification_tooltipDelete.tr(),
|
||||
icon: const FlowySvg(FlowySvgs.delete_s),
|
||||
iconColorOnHover: Theme.of(context).colorScheme.onSurface,
|
||||
onPressed: onDelete,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -26,7 +26,6 @@ class NotificationsView extends StatelessWidget {
|
||||
required this.views,
|
||||
this.isUpcoming = false,
|
||||
this.onAction,
|
||||
this.onDelete,
|
||||
this.onReadChanged,
|
||||
this.actionBar,
|
||||
});
|
||||
@ -36,7 +35,6 @@ class NotificationsView extends StatelessWidget {
|
||||
final List<ViewPB> views;
|
||||
final bool isUpcoming;
|
||||
final Function(ReminderPB reminder, int? path, ViewPB? view)? onAction;
|
||||
final Function(ReminderPB reminder)? onDelete;
|
||||
final Function(ReminderPB reminder, bool isRead)? onReadChanged;
|
||||
final Widget? actionBar;
|
||||
|
||||
@ -87,7 +85,6 @@ class NotificationsView extends StatelessWidget {
|
||||
readOnly: isUpcoming,
|
||||
onReadChanged: (isRead) =>
|
||||
onReadChanged?.call(reminder, isRead),
|
||||
onDelete: () => onDelete?.call(reminder),
|
||||
onAction: (path) => onAction?.call(reminder, path, view),
|
||||
view: view,
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user