mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: toggle notifications on/off (#3672)
This commit is contained in:
parent
bc8f35d7db
commit
ebe112581d
@ -1,4 +1,4 @@
|
|||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart';
|
import 'package:appflowy/workspace/presentation/settings/settings_dialog.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu_element.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_menu_element.dart';
|
||||||
|
@ -7,7 +7,7 @@ import 'package:appflowy/plugins/inline_actions/handlers/inline_page_reference.d
|
|||||||
import 'package:appflowy/plugins/inline_actions/handlers/reminder_reference.dart';
|
import 'package:appflowy/plugins/inline_actions/handlers/reminder_reference.dart';
|
||||||
import 'package:appflowy/plugins/inline_actions/inline_actions_command.dart';
|
import 'package:appflowy/plugins/inline_actions/inline_actions_command.dart';
|
||||||
import 'package:appflowy/plugins/inline_actions/inline_actions_service.dart';
|
import 'package:appflowy/plugins/inline_actions/inline_actions_service.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_service.dart';
|
import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_service.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_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
@ -2,7 +2,7 @@ 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/document/presentation/editor_plugins/actions/block_action_button.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/block_action_button.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/option_action.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/actions/option_action.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
import 'package:appflowy/workspace/presentation/widgets/pop_up_action.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
|
@ -2,7 +2,7 @@ import 'package:appflowy/generated/flowy_svgs.g.dart';
|
|||||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart';
|
import 'package:appflowy/plugins/document/presentation/editor_plugins/mention/mention_block.dart';
|
||||||
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
||||||
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
|
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.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/workspace/application/settings/date_time/date_format_ext.dart';
|
||||||
import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/date_picker_dialog.dart';
|
import 'package:appflowy/workspace/presentation/widgets/date_picker/widgets/date_picker_dialog.dart';
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||||
|
@ -24,6 +24,7 @@ import 'package:appflowy/user/presentation/router.dart';
|
|||||||
import 'package:appflowy/workspace/application/edit_panel/edit_panel_bloc.dart';
|
import 'package:appflowy/workspace/application/edit_panel/edit_panel_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
import 'package:appflowy/workspace/application/favorite/favorite_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/local_notifications/notification_action_bloc.dart';
|
import 'package:appflowy/workspace/application/local_notifications/notification_action_bloc.dart';
|
||||||
|
import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
import 'package:appflowy/workspace/application/settings/prelude.dart';
|
||||||
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/user/prelude.dart';
|
import 'package:appflowy/workspace/application/user/prelude.dart';
|
||||||
@ -168,14 +169,22 @@ void _resolveHomeDeps(GetIt getIt) {
|
|||||||
|
|
||||||
getIt.registerLazySingleton<TabsBloc>(() => TabsBloc());
|
getIt.registerLazySingleton<TabsBloc>(() => TabsBloc());
|
||||||
|
|
||||||
getIt.registerSingleton<ReminderBloc>(ReminderBloc());
|
getIt.registerSingleton<NotificationSettingsCubit>(
|
||||||
|
NotificationSettingsCubit(),
|
||||||
|
);
|
||||||
|
|
||||||
|
getIt.registerSingleton<ReminderBloc>(
|
||||||
|
ReminderBloc(notificationSettings: getIt<NotificationSettingsCubit>()),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _resolveFolderDeps(GetIt getIt) {
|
void _resolveFolderDeps(GetIt getIt) {
|
||||||
//workspace
|
//workspace
|
||||||
getIt.registerFactoryParam<WorkspaceListener, UserProfilePB, String>(
|
getIt.registerFactoryParam<WorkspaceListener, UserProfilePB, String>(
|
||||||
(user, workspaceId) =>
|
(user, workspaceId) => WorkspaceListener(
|
||||||
WorkspaceListener(user: user, workspaceId: workspaceId),
|
user: user,
|
||||||
|
workspaceId: workspaceId,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactoryParam<ViewBloc, ViewPB, void>(
|
getIt.registerFactoryParam<ViewBloc, ViewPB, void>(
|
||||||
|
@ -1,19 +1,23 @@
|
|||||||
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/local_notifications/notification_service.dart';
|
|
||||||
import 'package:appflowy/startup/tasks/prelude.dart';
|
import 'prelude.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
|
||||||
import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
|
||||||
import 'package:flowy_infra/theme.dart';
|
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
|
|
||||||
import '../../user/application/user_settings_service.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import '../../workspace/application/appearance.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import '../startup.dart';
|
import 'package:appflowy_editor/appflowy_editor.dart' hide Log;
|
||||||
|
import 'package:appflowy_backend/log.dart';
|
||||||
|
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||||
|
import 'package:flowy_infra/theme.dart';
|
||||||
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
|
||||||
|
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
||||||
|
import 'package:appflowy/workspace/application/local_notifications/notification_service.dart';
|
||||||
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
|
import 'package:appflowy/user/application/user_settings_service.dart';
|
||||||
|
import 'package:appflowy/startup/startup.dart';
|
||||||
|
|
||||||
class InitAppWidgetTask extends LaunchTask {
|
class InitAppWidgetTask extends LaunchTask {
|
||||||
const InitAppWidgetTask();
|
const InitAppWidgetTask();
|
||||||
@ -95,8 +99,8 @@ class ApplicationWidget extends StatefulWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final AppearanceSettingsPB appearanceSetting;
|
|
||||||
final AppTheme appTheme;
|
final AppTheme appTheme;
|
||||||
|
final AppearanceSettingsPB appearanceSetting;
|
||||||
final DateTimeSettingsPB dateTimeSettings;
|
final DateTimeSettingsPB dateTimeSettings;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -125,6 +129,9 @@ class _ApplicationWidgetState extends State<ApplicationWidget> {
|
|||||||
widget.appTheme,
|
widget.appTheme,
|
||||||
)..readLocaleWhenAppLaunch(context),
|
)..readLocaleWhenAppLaunch(context),
|
||||||
),
|
),
|
||||||
|
BlocProvider<NotificationSettingsCubit>(
|
||||||
|
create: (_) => getIt<NotificationSettingsCubit>(),
|
||||||
|
),
|
||||||
BlocProvider<DocumentAppearanceCubit>(
|
BlocProvider<DocumentAppearanceCubit>(
|
||||||
create: (_) => DocumentAppearanceCubit()..fetch(),
|
create: (_) => DocumentAppearanceCubit()..fetch(),
|
||||||
),
|
),
|
||||||
|
@ -6,6 +6,7 @@ import 'package:appflowy/user/application/reminder/reminder_service.dart';
|
|||||||
import 'package:appflowy/workspace/application/local_notifications/notification_action.dart';
|
import 'package:appflowy/workspace/application/local_notifications/notification_action.dart';
|
||||||
import 'package:appflowy/workspace/application/local_notifications/notification_action_bloc.dart';
|
import 'package:appflowy/workspace/application/local_notifications/notification_action_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/local_notifications/notification_service.dart';
|
import 'package:appflowy/workspace/application/local_notifications/notification_service.dart';
|
||||||
|
import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart';
|
||||||
import 'package:appflowy_backend/log.dart';
|
import 'package:appflowy_backend/log.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
@ -18,11 +19,16 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||||||
part 'reminder_bloc.freezed.dart';
|
part 'reminder_bloc.freezed.dart';
|
||||||
|
|
||||||
class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
|
class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
|
||||||
|
final NotificationSettingsCubit _notificationSettings;
|
||||||
|
|
||||||
late final NotificationActionBloc actionBloc;
|
late final NotificationActionBloc actionBloc;
|
||||||
late final ReminderService reminderService;
|
late final ReminderService reminderService;
|
||||||
late final Timer timer;
|
late final Timer timer;
|
||||||
|
|
||||||
ReminderBloc() : super(ReminderState()) {
|
ReminderBloc({
|
||||||
|
required NotificationSettingsCubit notificationSettings,
|
||||||
|
}) : _notificationSettings = notificationSettings,
|
||||||
|
super(ReminderState()) {
|
||||||
actionBloc = getIt<NotificationActionBloc>();
|
actionBloc = getIt<NotificationActionBloc>();
|
||||||
reminderService = const ReminderService();
|
reminderService = const ReminderService();
|
||||||
timer = _periodicCheck();
|
timer = _periodicCheck();
|
||||||
@ -124,16 +130,18 @@ class ReminderBloc extends Bloc<ReminderEvent, ReminderState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (scheduledAt.isBefore(now)) {
|
if (scheduledAt.isBefore(now)) {
|
||||||
NotificationMessage(
|
if (_notificationSettings.state.isNotificationsEnabled) {
|
||||||
identifier: reminder.id,
|
NotificationMessage(
|
||||||
title: LocaleKeys.reminderNotification_title.tr(),
|
identifier: reminder.id,
|
||||||
body: LocaleKeys.reminderNotification_message.tr(),
|
title: LocaleKeys.reminderNotification_title.tr(),
|
||||||
onClick: () => actionBloc.add(
|
body: LocaleKeys.reminderNotification_message.tr(),
|
||||||
NotificationActionEvent.performAction(
|
onClick: () => actionBloc.add(
|
||||||
action: NotificationAction(objectId: reminder.objectId),
|
NotificationActionEvent.performAction(
|
||||||
|
action: NotificationAction(objectId: reminder.objectId),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
}
|
||||||
|
|
||||||
add(
|
add(
|
||||||
ReminderEvent.update(
|
ReminderEvent.update(
|
||||||
|
@ -41,4 +41,20 @@ class UserSettingsBackendService {
|
|||||||
) async {
|
) async {
|
||||||
return (await UserEventSetDateTimeSettings(settings).send()).swap();
|
return (await UserEventSetDateTimeSettings(settings).send()).swap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Either<FlowyError, Unit>> setNotificationSettings(
|
||||||
|
NotificationSettingsPB settings,
|
||||||
|
) async {
|
||||||
|
return (await UserEventSetNotificationSettings(settings).send()).swap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<NotificationSettingsPB> getNotificationSettings() async {
|
||||||
|
final result = await UserEventGetNotificationSettings().send();
|
||||||
|
|
||||||
|
return result.fold(
|
||||||
|
(NotificationSettingsPB setting) => setting,
|
||||||
|
(error) =>
|
||||||
|
throw FlowySDKException(ExceptionType.AppearanceSettingsIsEmpty),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import 'package:appflowy/startup/startup.dart';
|
|||||||
import 'package:appflowy/user/application/sign_in_bloc.dart';
|
import 'package:appflowy/user/application/sign_in_bloc.dart';
|
||||||
import 'package:appflowy/user/presentation/presentation.dart';
|
import 'package:appflowy/user/presentation/presentation.dart';
|
||||||
import 'package:appflowy/util/platform_extension.dart';
|
import 'package:appflowy/util/platform_extension.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/size.dart';
|
import 'package:flowy_infra/size.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
|
@ -8,7 +8,7 @@ import 'package:appflowy/user/application/auth/auth_service.dart';
|
|||||||
import 'package:appflowy/user/application/historical_user_bloc.dart';
|
import 'package:appflowy/user/application/historical_user_bloc.dart';
|
||||||
import 'package:appflowy/user/presentation/router.dart';
|
import 'package:appflowy/user/presentation/router.dart';
|
||||||
import 'package:appflowy/user/presentation/widgets/widgets.dart';
|
import 'package:appflowy/user/presentation/widgets/widgets.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_language_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_language_view.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';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:appflowy/user/application/user_listener.dart';
|
import 'package:appflowy/user/application/user_listener.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/edit_panel/edit_context.dart';
|
import 'package:appflowy/workspace/application/edit_panel/edit_context.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-folder2/workspace.pb.dart'
|
import 'package:appflowy_backend/protobuf/flowy-folder2/workspace.pb.dart'
|
||||||
show WorkspaceSettingPB;
|
show WorkspaceSettingPB;
|
||||||
|
@ -16,33 +16,40 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
part 'appearance.freezed.dart';
|
part 'appearance_cubit.freezed.dart';
|
||||||
|
|
||||||
const _white = Color(0xFFFFFFFF);
|
const _white = Color(0xFFFFFFFF);
|
||||||
|
|
||||||
/// [AppearanceSettingsCubit] is used to modify the appearance of AppFlowy.
|
/// [AppearanceSettingsCubit] is used to modify the appearance of AppFlowy.
|
||||||
/// It includes the [AppTheme], [ThemeMode], [TextStyles] and [Locale].
|
/// It includes:
|
||||||
|
/// - [AppTheme]
|
||||||
|
/// - [ThemeMode]
|
||||||
|
/// - [TextStyle]'s
|
||||||
|
/// - [Locale]
|
||||||
|
/// - [UserDateFormatPB]
|
||||||
|
/// - [UserTimeFormatPB]
|
||||||
|
///
|
||||||
class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
||||||
final AppearanceSettingsPB _setting;
|
final AppearanceSettingsPB _appearanceSettings;
|
||||||
final DateTimeSettingsPB _dateTimeSettings;
|
final DateTimeSettingsPB _dateTimeSettings;
|
||||||
|
|
||||||
AppearanceSettingsCubit(
|
AppearanceSettingsCubit(
|
||||||
AppearanceSettingsPB setting,
|
AppearanceSettingsPB appearanceSettings,
|
||||||
DateTimeSettingsPB dateTimeSettings,
|
DateTimeSettingsPB dateTimeSettings,
|
||||||
AppTheme appTheme,
|
AppTheme appTheme,
|
||||||
) : _setting = setting,
|
) : _appearanceSettings = appearanceSettings,
|
||||||
_dateTimeSettings = dateTimeSettings,
|
_dateTimeSettings = dateTimeSettings,
|
||||||
super(
|
super(
|
||||||
AppearanceSettingsState.initial(
|
AppearanceSettingsState.initial(
|
||||||
appTheme,
|
appTheme,
|
||||||
setting.themeMode,
|
appearanceSettings.themeMode,
|
||||||
setting.font,
|
appearanceSettings.font,
|
||||||
setting.monospaceFont,
|
appearanceSettings.monospaceFont,
|
||||||
setting.layoutDirection,
|
appearanceSettings.layoutDirection,
|
||||||
setting.textDirection,
|
appearanceSettings.textDirection,
|
||||||
setting.locale,
|
appearanceSettings.locale,
|
||||||
setting.isMenuCollapsed,
|
appearanceSettings.isMenuCollapsed,
|
||||||
setting.menuOffset,
|
appearanceSettings.menuOffset,
|
||||||
dateTimeSettings.dateFormat,
|
dateTimeSettings.dateFormat,
|
||||||
dateTimeSettings.timeFormat,
|
dateTimeSettings.timeFormat,
|
||||||
dateTimeSettings.timezoneId,
|
dateTimeSettings.timezoneId,
|
||||||
@ -52,7 +59,7 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
/// Update selected theme in the user's settings and emit an updated state
|
/// Update selected theme in the user's settings and emit an updated state
|
||||||
/// with the AppTheme named [themeName].
|
/// with the AppTheme named [themeName].
|
||||||
Future<void> setTheme(String themeName) async {
|
Future<void> setTheme(String themeName) async {
|
||||||
_setting.theme = themeName;
|
_appearanceSettings.theme = themeName;
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
emit(state.copyWith(appTheme: await AppTheme.fromName(themeName)));
|
emit(state.copyWith(appTheme: await AppTheme.fromName(themeName)));
|
||||||
}
|
}
|
||||||
@ -63,7 +70,7 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
|
|
||||||
/// Update the theme mode in the user's settings and emit an updated state.
|
/// Update the theme mode in the user's settings and emit an updated state.
|
||||||
void setThemeMode(ThemeMode themeMode) {
|
void setThemeMode(ThemeMode themeMode) {
|
||||||
_setting.themeMode = _themeModeToPB(themeMode);
|
_appearanceSettings.themeMode = _themeModeToPB(themeMode);
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
emit(state.copyWith(themeMode: themeMode));
|
emit(state.copyWith(themeMode: themeMode));
|
||||||
}
|
}
|
||||||
@ -81,13 +88,13 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setLayoutDirection(LayoutDirection layoutDirection) {
|
void setLayoutDirection(LayoutDirection layoutDirection) {
|
||||||
_setting.layoutDirection = layoutDirection.toLayoutDirectionPB();
|
_appearanceSettings.layoutDirection = layoutDirection.toLayoutDirectionPB();
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
emit(state.copyWith(layoutDirection: layoutDirection));
|
emit(state.copyWith(layoutDirection: layoutDirection));
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTextDirection(AppFlowyTextDirection? textDirection) {
|
void setTextDirection(AppFlowyTextDirection? textDirection) {
|
||||||
_setting.textDirection =
|
_appearanceSettings.textDirection =
|
||||||
textDirection?.toTextDirectionPB() ?? TextDirectionPB.FALLBACK;
|
textDirection?.toTextDirectionPB() ?? TextDirectionPB.FALLBACK;
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
emit(state.copyWith(textDirection: textDirection));
|
emit(state.copyWith(textDirection: textDirection));
|
||||||
@ -96,7 +103,7 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
/// Update selected font in the user's settings and emit an updated state
|
/// Update selected font in the user's settings and emit an updated state
|
||||||
/// with the font name.
|
/// with the font name.
|
||||||
void setFontFamily(String fontFamilyName) {
|
void setFontFamily(String fontFamilyName) {
|
||||||
_setting.font = fontFamilyName;
|
_appearanceSettings.font = fontFamilyName;
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
emit(state.copyWith(font: fontFamilyName));
|
emit(state.copyWith(font: fontFamilyName));
|
||||||
}
|
}
|
||||||
@ -118,8 +125,8 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (state.locale != newLocale) {
|
if (state.locale != newLocale) {
|
||||||
_setting.locale.languageCode = newLocale.languageCode;
|
_appearanceSettings.locale.languageCode = newLocale.languageCode;
|
||||||
_setting.locale.countryCode = newLocale.countryCode ?? "";
|
_appearanceSettings.locale.countryCode = newLocale.countryCode ?? "";
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
emit(state.copyWith(locale: newLocale));
|
emit(state.copyWith(locale: newLocale));
|
||||||
}
|
}
|
||||||
@ -127,13 +134,13 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
|
|
||||||
// Saves the menus current visibility
|
// Saves the menus current visibility
|
||||||
void saveIsMenuCollapsed(bool collapsed) {
|
void saveIsMenuCollapsed(bool collapsed) {
|
||||||
_setting.isMenuCollapsed = collapsed;
|
_appearanceSettings.isMenuCollapsed = collapsed;
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saves the current resize offset of the menu
|
// Saves the current resize offset of the menu
|
||||||
void saveMenuOffset(double offset) {
|
void saveMenuOffset(double offset) {
|
||||||
_setting.menuOffset = offset;
|
_appearanceSettings.menuOffset = offset;
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,14 +153,14 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
_setting.settingKeyValue.remove(key);
|
_appearanceSettings.settingKeyValue.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_setting.settingKeyValue[key] != value) {
|
if (_appearanceSettings.settingKeyValue[key] != value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
_setting.settingKeyValue.remove(key);
|
_appearanceSettings.settingKeyValue.remove(key);
|
||||||
} else {
|
} else {
|
||||||
_setting.settingKeyValue[key] = value;
|
_appearanceSettings.settingKeyValue[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
@ -164,14 +171,14 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
Log.warn("The key should not be empty");
|
Log.warn("The key should not be empty");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return _setting.settingKeyValue[key];
|
return _appearanceSettings.settingKeyValue[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when the application launches.
|
/// Called when the application launches.
|
||||||
/// Uses the device locale when the application is opened for the first time.
|
/// Uses the device locale when the application is opened for the first time.
|
||||||
void readLocaleWhenAppLaunch(BuildContext context) {
|
void readLocaleWhenAppLaunch(BuildContext context) {
|
||||||
if (_setting.resetToDefault) {
|
if (_appearanceSettings.resetToDefault) {
|
||||||
_setting.resetToDefault = false;
|
_appearanceSettings.resetToDefault = false;
|
||||||
_saveAppearanceSettings();
|
_saveAppearanceSettings();
|
||||||
setLocale(context, context.deviceLocale);
|
setLocale(context, context.deviceLocale);
|
||||||
return;
|
return;
|
||||||
@ -204,7 +211,9 @@ class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _saveAppearanceSettings() async {
|
Future<void> _saveAppearanceSettings() async {
|
||||||
UserSettingsBackendService().setAppearanceSetting(_setting).then((result) {
|
UserSettingsBackendService()
|
||||||
|
.setAppearanceSetting(_appearanceSettings)
|
||||||
|
.then((result) {
|
||||||
result.fold(
|
result.fold(
|
||||||
(l) => null,
|
(l) => null,
|
||||||
(error) => Log.error(error),
|
(error) => Log.error(error),
|
@ -0,0 +1,62 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:appflowy/user/application/user_settings_service.dart';
|
||||||
|
import 'package:appflowy_backend/log.dart';
|
||||||
|
import 'package:appflowy_backend/protobuf/flowy-user/user_setting.pb.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'notification_settings_cubit.freezed.dart';
|
||||||
|
|
||||||
|
class NotificationSettingsCubit extends Cubit<NotificationSettingsState> {
|
||||||
|
final Completer<void> _initCompleter = Completer();
|
||||||
|
|
||||||
|
late final NotificationSettingsPB _notificationSettings;
|
||||||
|
|
||||||
|
NotificationSettingsCubit() : super(NotificationSettingsState.initial()) {
|
||||||
|
UserSettingsBackendService()
|
||||||
|
.getNotificationSettings()
|
||||||
|
.then((notificationSettings) {
|
||||||
|
_notificationSettings = notificationSettings;
|
||||||
|
_initCompleter.complete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> toggleNotificationsEnabled() async {
|
||||||
|
await _initCompleter.future;
|
||||||
|
|
||||||
|
_notificationSettings.notificationsEnabled = !state.isNotificationsEnabled;
|
||||||
|
_saveNotificationSettings();
|
||||||
|
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
isNotificationsEnabled: _notificationSettings.notificationsEnabled,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _saveNotificationSettings() async {
|
||||||
|
await _initCompleter.future;
|
||||||
|
|
||||||
|
UserSettingsBackendService()
|
||||||
|
.setNotificationSettings(_notificationSettings)
|
||||||
|
.then((result) {
|
||||||
|
result.fold(
|
||||||
|
(error) => Log.error(error),
|
||||||
|
(r) => null,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class NotificationSettingsState with _$NotificationSettingsState {
|
||||||
|
const NotificationSettingsState._();
|
||||||
|
|
||||||
|
const factory NotificationSettingsState({
|
||||||
|
required bool isNotificationsEnabled,
|
||||||
|
}) = _NotificationSettingsState;
|
||||||
|
|
||||||
|
factory NotificationSettingsState.initial() =>
|
||||||
|
const NotificationSettingsState(isNotificationsEnabled: true);
|
||||||
|
}
|
@ -13,6 +13,7 @@ enum SettingsPage {
|
|||||||
language,
|
language,
|
||||||
files,
|
files,
|
||||||
user,
|
user,
|
||||||
|
notifications,
|
||||||
syncSetting,
|
syncSetting,
|
||||||
shortcuts,
|
shortcuts,
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import 'package:appflowy/startup/plugin/plugin.dart';
|
|||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.dart';
|
||||||
import 'package:appflowy/user/application/auth/auth_service.dart';
|
import 'package:appflowy/user/application/auth/auth_service.dart';
|
||||||
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
|
import 'package:appflowy/user/application/reminder/reminder_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/home/home_bloc.dart';
|
import 'package:appflowy/workspace/application/home/home_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/home/home_service.dart';
|
import 'package:appflowy/workspace/application/home/home_service.dart';
|
||||||
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
import 'package:appflowy/workspace/application/home/home_setting_bloc.dart';
|
||||||
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
import 'package:appflowy/workspace/application/tabs/tabs_bloc.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'package:appflowy/startup/startup.dart';
|
import 'package:appflowy/startup/startup.dart';
|
||||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_notifications_view.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/sync_setting_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/sync_setting_view.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance_view.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_customize_shortcuts_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_customize_shortcuts_view.dart';
|
||||||
@ -101,6 +102,8 @@ class SettingsDialog extends StatelessWidget {
|
|||||||
didLogout: didLogout,
|
didLogout: didLogout,
|
||||||
didOpenUser: didOpenUser,
|
didOpenUser: didOpenUser,
|
||||||
);
|
);
|
||||||
|
case SettingsPage.notifications:
|
||||||
|
return const SettingsNotificationsView();
|
||||||
case SettingsPage.syncSetting:
|
case SettingsPage.syncSetting:
|
||||||
return SyncSettingView(userId: user.id.toString());
|
return SyncSettingView(userId: user.id.toString());
|
||||||
case SettingsPage.shortcuts:
|
case SettingsPage.shortcuts:
|
||||||
|
@ -2,7 +2,7 @@ import 'dart:io';
|
|||||||
|
|
||||||
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/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.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';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
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/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/presentation/home/toast.dart';
|
import 'package:appflowy/workspace/presentation/home/toast.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/theme_setting_entry_template.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/theme_setting_entry_template.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/theme_upload/theme_upload_view.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/theme_upload/theme_upload_view.dart';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
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/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/date_time.pbenum.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/date_time.pbenum.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';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
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/document/presentation/more/cubit/document_appearance_cubit.dart';
|
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.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';
|
||||||
|
@ -2,7 +2,7 @@ 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/document/presentation/more/cubit/document_appearance_cubit.dart';
|
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
||||||
import 'package:appflowy/util/google_font_family_extension.dart';
|
import 'package:appflowy/util/google_font_family_extension.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance_defaults.dart';
|
import 'package:appflowy/workspace/application/appearance_defaults.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
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/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/date_time.pbenum.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/date_time.pbenum.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';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/create_file_setting.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/create_file_setting.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/date_format_setting.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/date_format_setting.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/time_format_setting.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/time_format_setting.dart';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
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/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.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';
|
||||||
|
@ -61,6 +61,13 @@ class SettingsMenu extends StatelessWidget {
|
|||||||
icon: Icons.account_box_outlined,
|
icon: Icons.account_box_outlined,
|
||||||
changeSelectedPage: changeSelectedPage,
|
changeSelectedPage: changeSelectedPage,
|
||||||
),
|
),
|
||||||
|
SettingsMenuElement(
|
||||||
|
page: SettingsPage.notifications,
|
||||||
|
selectedPage: currentPage,
|
||||||
|
label: LocaleKeys.settings_menu_notifications.tr(),
|
||||||
|
icon: Icons.notifications_outlined,
|
||||||
|
changeSelectedPage: changeSelectedPage,
|
||||||
|
),
|
||||||
if (showSyncSetting)
|
if (showSyncSetting)
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 10,
|
height: 10,
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||||
|
import 'package:appflowy/workspace/application/settings/notifications/notification_settings_cubit.dart';
|
||||||
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/theme_setting_entry_template.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
|
class SettingsNotificationsView extends StatelessWidget {
|
||||||
|
const SettingsNotificationsView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<NotificationSettingsCubit, NotificationSettingsState>(
|
||||||
|
builder: (context, state) {
|
||||||
|
return SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ThemeSettingEntryTemplateWidget(
|
||||||
|
label: LocaleKeys
|
||||||
|
.settings_notifications_enableNotifications_label
|
||||||
|
.tr(),
|
||||||
|
hint: LocaleKeys.settings_notifications_enableNotifications_hint
|
||||||
|
.tr(),
|
||||||
|
trailing: [
|
||||||
|
Switch(
|
||||||
|
value: state.isNotificationsEnabled,
|
||||||
|
splashRadius: 0,
|
||||||
|
activeColor: Theme.of(context).colorScheme.primary,
|
||||||
|
onChanged: (value) {
|
||||||
|
context
|
||||||
|
.read<NotificationSettingsCubit>()
|
||||||
|
.toggleNotificationsEnabled();
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:appflowy/user/application/user_settings_service.dart';
|
import 'package:appflowy/user/application/user_settings_service.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:bloc_test/bloc_test.dart';
|
import 'package:bloc_test/bloc_test.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-user/user_setting.pb.dart';
|
import 'package:appflowy_backend/protobuf/flowy-user/user_setting.pb.dart';
|
||||||
import 'package:flowy_infra/theme.dart';
|
import 'package:flowy_infra/theme.dart';
|
||||||
@ -18,6 +18,7 @@ void main() {
|
|||||||
group('$AppearanceSettingsCubit', () {
|
group('$AppearanceSettingsCubit', () {
|
||||||
late AppearanceSettingsPB appearanceSetting;
|
late AppearanceSettingsPB appearanceSetting;
|
||||||
late DateTimeSettingsPB dateTimeSettings;
|
late DateTimeSettingsPB dateTimeSettings;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
appearanceSetting =
|
appearanceSetting =
|
||||||
await UserSettingsBackendService().getAppearanceSetting();
|
await UserSettingsBackendService().getAppearanceSetting();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
import 'package:appflowy/plugins/document/presentation/more/cubit/document_appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/application/appearance.dart';
|
import 'package:appflowy/workspace/application/settings/appearance/appearance_cubit.dart';
|
||||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/font_family_setting.dart';
|
import 'package:appflowy/workspace/presentation/settings/widgets/settings_appearance/font_family_setting.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/material.dart';
|
||||||
|
@ -241,6 +241,7 @@
|
|||||||
"language": "Language",
|
"language": "Language",
|
||||||
"user": "User",
|
"user": "User",
|
||||||
"files": "Files",
|
"files": "Files",
|
||||||
|
"notifications": "Notifications",
|
||||||
"open": "Open Settings",
|
"open": "Open Settings",
|
||||||
"logout": "Logout",
|
"logout": "Logout",
|
||||||
"logoutPrompt": "Are you sure to logout?",
|
"logoutPrompt": "Are you sure to logout?",
|
||||||
@ -256,6 +257,12 @@
|
|||||||
"historicalUserListTooltip": "This list displays your anonymous accounts. You can click on an account to view its details. Anonymous accounts are created by clicking the 'Get Started' button",
|
"historicalUserListTooltip": "This list displays your anonymous accounts. You can click on an account to view its details. Anonymous accounts are created by clicking the 'Get Started' button",
|
||||||
"openHistoricalUser": "Click to open the anonymous account"
|
"openHistoricalUser": "Click to open the anonymous account"
|
||||||
},
|
},
|
||||||
|
"notifications": {
|
||||||
|
"enableNotifications": {
|
||||||
|
"label": "Enable notifications",
|
||||||
|
"hint": "Turn off to stop local notifications from appearing."
|
||||||
|
}
|
||||||
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"resetSetting": "Reset this setting",
|
"resetSetting": "Reset this setting",
|
||||||
"fontFamily": {
|
"fontFamily": {
|
||||||
|
@ -237,3 +237,17 @@ impl std::default::Default for DateTimeSettingsPB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(ProtoBuf, Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub struct NotificationSettingsPB {
|
||||||
|
#[pb(index = 1)]
|
||||||
|
pub notifications_enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::default::Default for NotificationSettingsPB {
|
||||||
|
fn default() -> Self {
|
||||||
|
NotificationSettingsPB {
|
||||||
|
notifications_enabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -195,7 +195,7 @@ pub async fn get_date_time_settings(
|
|||||||
Ok(setting) => setting,
|
Ok(setting) => setting,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
"Deserialize AppearanceSettings failed: {:?}, fallback to default",
|
"Deserialize DateTimeSettings failed: {:?}, fallback to default",
|
||||||
e
|
e
|
||||||
);
|
);
|
||||||
DateTimeSettingsPB::default()
|
DateTimeSettingsPB::default()
|
||||||
@ -206,6 +206,42 @@ pub async fn get_date_time_settings(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const NOTIFICATION_SETTINGS_CACHE_KEY: &str = "notification_settings";
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
|
pub async fn set_notification_settings(
|
||||||
|
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
||||||
|
data: AFPluginData<NotificationSettingsPB>,
|
||||||
|
) -> Result<(), FlowyError> {
|
||||||
|
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
||||||
|
let setting = data.into_inner();
|
||||||
|
store_preferences.set_object(NOTIFICATION_SETTINGS_CACHE_KEY, setting)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
|
pub async fn get_notification_settings(
|
||||||
|
store_preferences: AFPluginState<Weak<StorePreferences>>,
|
||||||
|
) -> DataResult<NotificationSettingsPB, FlowyError> {
|
||||||
|
let store_preferences = upgrade_store_preferences(store_preferences)?;
|
||||||
|
match store_preferences.get_str(NOTIFICATION_SETTINGS_CACHE_KEY) {
|
||||||
|
None => data_result_ok(NotificationSettingsPB::default()),
|
||||||
|
Some(s) => {
|
||||||
|
let setting = match serde_json::from_str(&s) {
|
||||||
|
Ok(setting) => setting,
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!(
|
||||||
|
"Deserialize NotificationSettings failed: {:?}, fallback to default",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
NotificationSettingsPB::default()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
data_result_ok(setting)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip_all, err)]
|
#[tracing::instrument(level = "debug", skip_all, err)]
|
||||||
pub async fn get_user_setting(
|
pub async fn get_user_setting(
|
||||||
manager: AFPluginState<Weak<UserManager>>,
|
manager: AFPluginState<Weak<UserManager>>,
|
||||||
|
@ -65,6 +65,14 @@ pub fn init(user_session: Weak<UserManager>) -> AFPlugin {
|
|||||||
.event(UserEvent::ResetWorkspace, reset_workspace_handler)
|
.event(UserEvent::ResetWorkspace, reset_workspace_handler)
|
||||||
.event(UserEvent::SetDateTimeSettings, set_date_time_settings)
|
.event(UserEvent::SetDateTimeSettings, set_date_time_settings)
|
||||||
.event(UserEvent::GetDateTimeSettings, get_date_time_settings)
|
.event(UserEvent::GetDateTimeSettings, get_date_time_settings)
|
||||||
|
.event(
|
||||||
|
UserEvent::SetNotificationSettings,
|
||||||
|
set_notification_settings,
|
||||||
|
)
|
||||||
|
.event(
|
||||||
|
UserEvent::GetNotificationSettings,
|
||||||
|
get_notification_settings,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SignUpContext {
|
pub struct SignUpContext {
|
||||||
@ -317,4 +325,10 @@ pub enum UserEvent {
|
|||||||
/// Retrieve the Date/Time formats
|
/// Retrieve the Date/Time formats
|
||||||
#[event(output = "DateTimeSettingsPB")]
|
#[event(output = "DateTimeSettingsPB")]
|
||||||
GetDateTimeSettings = 34,
|
GetDateTimeSettings = 34,
|
||||||
|
|
||||||
|
#[event(input = "NotificationSettingsPB")]
|
||||||
|
SetNotificationSettings = 35,
|
||||||
|
|
||||||
|
#[event(output = "NotificationSettingsPB")]
|
||||||
|
GetNotificationSettings = 36,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user