feat: remove reminder in the same event (#7869)

This commit is contained in:
Lucas 2025-04-30 19:34:43 +08:00 committed by GitHub
parent 86872c462f
commit 8441a8c7f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 65 additions and 50 deletions

View File

@ -3,9 +3,9 @@ import 'dart:async';
import 'package:appflowy/generated/locale_keys.g.dart';
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database/application/field/field_info.dart';
import 'package:appflowy/plugins/database/application/field/type_option/type_option_data_parser.dart';
import 'package:appflowy/plugins/database/domain/date_cell_service.dart';
import 'package:appflowy/plugins/database/domain/field_service.dart';
import 'package:appflowy/plugins/database/application/field/type_option/type_option_data_parser.dart';
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
import 'package:appflowy/user/application/reminder/reminder_extension.dart';
import 'package:appflowy/util/int64_extension.dart';
@ -113,8 +113,9 @@ class DateCellEditorBloc
clearDate: () async {
// Remove reminder if neccessary
if (state.reminderId.isNotEmpty) {
_reminderBloc
.add(ReminderEvent.remove(reminderId: state.reminderId));
_reminderBloc.add(
ReminderEvent.removeReminder(reminderId: state.reminderId),
);
}
await _clearDate();
@ -218,7 +219,7 @@ class DateCellEditorBloc
} else {
if (option == ReminderOption.none) {
// remove reminder from reminder bloc and cell data
_reminderBloc.add(ReminderEvent.remove(reminderId: state.reminderId));
_reminderBloc.add(ReminderEvent.removeReminder(reminderId: state.reminderId));
await _updateCellReminderId("");
} else {
// Update reminder

View File

@ -95,7 +95,7 @@ class DateTransactionHandler extends MentionTransactionHandler {
final reminderId = data.$2[MentionBlockKeys.reminderId];
if (reminderId case String _ when reminderId.isNotEmpty) {
getIt<ReminderBloc>().add(ReminderEvent.remove(reminderId: reminderId));
getIt<ReminderBloc>().add(ReminderEvent.removeReminder(reminderId: reminderId));
}
}

View File

@ -148,7 +148,7 @@ class _MentionDateBlockState extends State<MentionDateBlock> {
if (rootContext != null && _reminderId != null) {
rootContext
.read<ReminderBloc?>()
?.add(ReminderEvent.remove(reminderId: _reminderId!));
?.add(ReminderEvent.removeReminder(reminderId: _reminderId!));
}
_updateBlock(selectedDay, includeTime: _includeTime);
}
@ -266,7 +266,7 @@ class _MentionDateBlockState extends State<MentionDateBlock> {
// Delete existing reminder
return rootContext
.read<ReminderBloc>()
.add(ReminderEvent.remove(reminderId: reminder.id));
.add(ReminderEvent.removeReminder(reminderId: reminder.id));
}
// Update existing reminder

View File

@ -204,9 +204,12 @@ class PasswordHttpService {
final errorBody =
response.body.isNotEmpty ? jsonDecode(response.body) : {};
Log.info(
'${endpoint.name} request failed: ${response.statusCode}, $errorBody ',
);
// the checkHasPassword endpoint will return 403, which is not an error
if (endpoint != PasswordEndpoint.checkHasPassword) {
Log.info(
'${endpoint.name} request failed: ${response.statusCode}, $errorBody ',
);
}
ErrorCode errorCode = ErrorCode.Internal;

View File

@ -54,21 +54,29 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
bool hasReminder(String reminderId) =>
state.allReminders.where((e) => e.id == reminderId).firstOrNull != null;
final List<ViewPB> _allViews = [];
void _dispatch() {
on<ReminderEvent>(
(event, emit) async {
await event.when(
started: () async {
Log.info('Start fetching reminders');
add(const ReminderEvent.refresh());
},
refresh: () async {
final result = await _reminderService.fetchReminders();
final views = await ViewBackendService.getAllViews();
views.onSuccess((views) {
_allViews.clear();
_allViews.addAll(views.items);
});
await result.fold(
(reminders) async {
final availableReminders = await filterAvailableReminders(
reminders,
removeUnavailableReminder: true,
);
final availableReminders =
await filterAvailableReminders(reminders);
Log.info(
'Fetched reminders on startup: ${availableReminders.length}',
'Fetched reminders on refresh: ${availableReminders.length}',
);
if (!isClosed && !emit.isDone) {
emit(
@ -79,12 +87,12 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
);
}
},
(error) async {
(error) {
Log.error('Failed to fetch reminders: $error');
},
);
},
remove: (reminderId) async {
removeReminder: (reminderId) async {
final result = await _reminderService.removeReminder(
reminderId: reminderId,
);
@ -105,6 +113,28 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
),
);
},
removeReminders: (reminderIds) async {
Log.info('Remove reminders: $reminderIds');
final removedIds = <String>{};
for (final reminderId in reminderIds) {
final result = await _reminderService.removeReminder(
reminderId: reminderId,
);
if (result.isSuccess) {
Log.info('Removed reminder: $reminderId');
removedIds.add(reminderId);
} else {
Log.error('Failed to remove reminder: $reminderId');
}
}
emit(
state.copyWith(
reminders: state.reminders
.where((reminder) => !removedIds.contains(reminder.id))
.toList(),
),
);
},
add: (reminder) async {
// check the timestamp in the reminder
if (reminder.createdAt == null) {
@ -305,30 +335,6 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
),
);
},
refresh: () async {
final result = await _reminderService.fetchReminders();
await result.fold(
(reminders) async {
final availableReminders =
await filterAvailableReminders(reminders);
Log.info(
'Fetched reminders on refresh: ${availableReminders.length}',
);
if (!isClosed && !emit.isDone) {
emit(
state.copyWith(
reminders: availableReminders,
serverReminders: reminders,
),
);
}
},
(error) {
Log.error('Failed to fetch reminders: $error');
},
);
},
resetTimer: () {
timer?.cancel();
timer = _periodicCheck();
@ -450,7 +456,7 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
Set<String> reminderIds, {
Set<String> removeIds = const {},
}) async {
/// check if schedule time is comming
/// check if schedule time is coming
final scheduledAt = reminder.scheduledAt.toDateTime();
if (!DateTime.now().isAfter(scheduledAt) && !reminder.isRead) {
return false;
@ -458,8 +464,7 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
/// check if view is not null
final viewId = reminder.objectId;
final view =
await ViewBackendService.getView(viewId).fold((s) => s, (_) => null);
final view = _allViews.firstWhereOrNull((e) => e.id == viewId);
if (view == null) {
removeIds.add(reminder.id);
return false;
@ -527,17 +532,18 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
final List<ReminderPB> availableReminders = [];
final reminderIds = reminders.map((e) => e.id).toSet();
final removeIds = <String>{};
for (final r in reminders) {
if (await checkReminderAvailable(r, reminderIds, removeIds: removeIds)) {
availableReminders.add(r);
}
}
if (removeUnavailableReminder) {
for (final id in removeIds) {
Log.warn('Remove unavailable reminder: $id');
if (!isClosed) add(ReminderEvent.remove(reminderId: id));
}
Log.info('Remove unavailable reminder: $removeIds');
add(ReminderEvent.removeReminders(removeIds));
}
return availableReminders;
}
}
@ -548,7 +554,12 @@ class ReminderEvent with _$ReminderEvent {
const factory ReminderEvent.started() = _Started;
// Remove a reminder
const factory ReminderEvent.remove({required String reminderId}) = _Remove;
const factory ReminderEvent.removeReminder({required String reminderId}) =
_RemoveReminder;
// Remove reminders
const factory ReminderEvent.removeReminders(Set<String> reminderIds) =
_RemoveReminders;
// Add a reminder
const factory ReminderEvent.add({required ReminderPB reminder}) = _Add;