mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-01-11 07:39:32 -05:00
settings / preferences upate
This commit is contained in:
parent
1455aabe6c
commit
d962f98786
@ -219,7 +219,26 @@
|
|||||||
"settings_page": {
|
"settings_page": {
|
||||||
"titlebar": "Settings",
|
"titlebar": "Settings",
|
||||||
"color_theme": "Color Theme",
|
"color_theme": "Color Theme",
|
||||||
"brightness_mode": "Brightness Mode"
|
"brightness_mode": "Brightness Mode",
|
||||||
|
"display_beta_warning": "Display beta warning on startup",
|
||||||
|
"none": "None",
|
||||||
|
"in_app": "In-app",
|
||||||
|
"push": "Push",
|
||||||
|
"in_app_or_push": "In-app or Push",
|
||||||
|
"enable_badge": "Enable icon 'badge' bubble",
|
||||||
|
"enable_notifications": "Enable notifications",
|
||||||
|
"message_notification_content": "Message notification content",
|
||||||
|
"invitation_accepted": "On invitation accept/reject",
|
||||||
|
"message_received": "On message received",
|
||||||
|
"message_sent": "On message sent",
|
||||||
|
"name_and_content": "Name and content",
|
||||||
|
"name_only": "Name only",
|
||||||
|
"nothing": "Nothing",
|
||||||
|
"bonk": "Bonk",
|
||||||
|
"boop": "Boop",
|
||||||
|
"badeep": "Badeep",
|
||||||
|
"beep_badeep": "Beep-Badeep",
|
||||||
|
"custom": "Custom"
|
||||||
},
|
},
|
||||||
"developer": {
|
"developer": {
|
||||||
"title": "Developer Logs",
|
"title": "Developer Logs",
|
||||||
|
BIN
assets/sounds/badeep.wav
Normal file
BIN
assets/sounds/badeep.wav
Normal file
Binary file not shown.
BIN
assets/sounds/beepbadeep.wav
Normal file
BIN
assets/sounds/beepbadeep.wav
Normal file
Binary file not shown.
BIN
assets/sounds/bonk.wav
Normal file
BIN
assets/sounds/bonk.wav
Normal file
Binary file not shown.
BIN
assets/sounds/boop.wav
Normal file
BIN
assets/sounds/boop.wav
Normal file
Binary file not shown.
@ -43,7 +43,7 @@ class VeilidChatApp extends StatelessWidget {
|
|||||||
void _reloadTheme(BuildContext context) {
|
void _reloadTheme(BuildContext context) {
|
||||||
log.info('Reloading theme');
|
log.info('Reloading theme');
|
||||||
final theme =
|
final theme =
|
||||||
PreferencesRepository.instance.value.themePreferences.themeData();
|
PreferencesRepository.instance.value.themePreference.themeData();
|
||||||
ThemeSwitcher.of(context).changeTheme(theme: theme);
|
ThemeSwitcher.of(context).changeTheme(theme: theme);
|
||||||
|
|
||||||
// Hack to reload translations
|
// Hack to reload translations
|
||||||
|
@ -12,6 +12,7 @@ import 'package:url_launcher/url_launcher_string.dart';
|
|||||||
import 'package:veilid_support/veilid_support.dart';
|
import 'package:veilid_support/veilid_support.dart';
|
||||||
|
|
||||||
import '../../account_manager/account_manager.dart';
|
import '../../account_manager/account_manager.dart';
|
||||||
|
import '../../settings/settings.dart';
|
||||||
import '../../theme/theme.dart';
|
import '../../theme/theme.dart';
|
||||||
import 'drawer_menu/drawer_menu.dart';
|
import 'drawer_menu/drawer_menu.dart';
|
||||||
import 'home_account_invalid.dart';
|
import 'home_account_invalid.dart';
|
||||||
@ -41,7 +42,17 @@ class HomeScreenState extends State<HomeScreen>
|
|||||||
.indexWhere((x) => x.superIdentity.recordKey == activeLocalAccount);
|
.indexWhere((x) => x.superIdentity.recordKey == activeLocalAccount);
|
||||||
final canClose = activeIndex != -1;
|
final canClose = activeIndex != -1;
|
||||||
|
|
||||||
unawaited(_doBetaDialog(context));
|
final displayBetaWarning = context
|
||||||
|
.read<PreferencesCubit>()
|
||||||
|
.state
|
||||||
|
.asData
|
||||||
|
?.value
|
||||||
|
.notificationsPreference
|
||||||
|
.displayBetaWarning ??
|
||||||
|
true;
|
||||||
|
if (displayBetaWarning) {
|
||||||
|
await _doBetaDialog(context);
|
||||||
|
}
|
||||||
|
|
||||||
if (!canClose) {
|
if (!canClose) {
|
||||||
await _zoomDrawerController.open!();
|
await _zoomDrawerController.open!();
|
||||||
@ -51,10 +62,13 @@ class HomeScreenState extends State<HomeScreen>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _doBetaDialog(BuildContext context) async {
|
Future<void> _doBetaDialog(BuildContext context) async {
|
||||||
|
var displayBetaWarning = true;
|
||||||
|
|
||||||
await QuickAlert.show(
|
await QuickAlert.show(
|
||||||
context: context,
|
context: context,
|
||||||
title: translate('splash.beta_title'),
|
title: translate('splash.beta_title'),
|
||||||
widget: RichText(
|
widget: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||||
|
RichText(
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
children: <TextSpan>[
|
children: <TextSpan>[
|
||||||
@ -77,7 +91,28 @@ class HomeScreenState extends State<HomeScreen>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
type: QuickAlertType.warning);
|
Row(mainAxisSize: MainAxisSize.min, children: [
|
||||||
|
StatefulBuilder(
|
||||||
|
builder: (context, setState) => Checkbox.adaptive(
|
||||||
|
value: displayBetaWarning,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
displayBetaWarning = value ?? true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
)),
|
||||||
|
Text(translate('settings_page.display_beta_warning'),
|
||||||
|
style: const TextStyle(color: Colors.black)),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
type: QuickAlertType.warning,
|
||||||
|
);
|
||||||
|
|
||||||
|
final preferencesInstance = PreferencesRepository.instance;
|
||||||
|
await preferencesInstance.set(preferencesInstance.value.copyWith(
|
||||||
|
notificationsPreference: preferencesInstance
|
||||||
|
.value.notificationsPreference
|
||||||
|
.copyWith(displayBetaWarning: displayBetaWarning)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAccountPage(
|
Widget _buildAccountPage(
|
||||||
|
@ -36,7 +36,7 @@ void main() async {
|
|||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await PreferencesRepository.instance.init();
|
await PreferencesRepository.instance.init();
|
||||||
final initialThemeData =
|
final initialThemeData =
|
||||||
PreferencesRepository.instance.value.themePreferences.themeData();
|
PreferencesRepository.instance.value.themePreference.themeData();
|
||||||
|
|
||||||
// Manage window on desktop platforms
|
// Manage window on desktop platforms
|
||||||
await initializeWindowControl();
|
await initializeWindowControl();
|
||||||
|
2
lib/notifications/models/models.dart
Normal file
2
lib/notifications/models/models.dart
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export 'notifications_preference.dart';
|
||||||
|
export 'notifications_state.dart';
|
69
lib/notifications/models/notifications_preference.dart
Normal file
69
lib/notifications/models/notifications_preference.dart
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import 'package:change_case/change_case.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'notifications_preference.freezed.dart';
|
||||||
|
part 'notifications_preference.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
class NotificationsPreference with _$NotificationsPreference {
|
||||||
|
const factory NotificationsPreference({
|
||||||
|
@Default(true) bool displayBetaWarning,
|
||||||
|
@Default(true) bool enableBadge,
|
||||||
|
@Default(true) bool enableNotifications,
|
||||||
|
@Default(MessageNotificationContent.nameAndContent)
|
||||||
|
MessageNotificationContent messageNotificationContent,
|
||||||
|
@Default(NotificationMode.inAppOrPush)
|
||||||
|
NotificationMode onInvitationAcceptedMode,
|
||||||
|
@Default(SoundEffect.beepBaDeep) SoundEffect onInvitationAcceptedSound,
|
||||||
|
@Default(NotificationMode.inAppOrPush)
|
||||||
|
NotificationMode onMessageReceivedMode,
|
||||||
|
@Default(SoundEffect.boop) SoundEffect onMessageReceivedSound,
|
||||||
|
@Default(SoundEffect.bonk) SoundEffect onMessageSentSound,
|
||||||
|
}) = _NotificationsPreference;
|
||||||
|
|
||||||
|
factory NotificationsPreference.fromJson(dynamic json) =>
|
||||||
|
_$NotificationsPreferenceFromJson(json as Map<String, dynamic>);
|
||||||
|
|
||||||
|
static const NotificationsPreference defaults = NotificationsPreference();
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NotificationMode {
|
||||||
|
none,
|
||||||
|
inApp,
|
||||||
|
push,
|
||||||
|
inAppOrPush;
|
||||||
|
|
||||||
|
factory NotificationMode.fromJson(dynamic j) =>
|
||||||
|
NotificationMode.values.byName((j as String).toCamelCase());
|
||||||
|
String toJson() => name.toPascalCase();
|
||||||
|
|
||||||
|
static const NotificationMode defaults = NotificationMode.none;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum MessageNotificationContent {
|
||||||
|
nothing,
|
||||||
|
nameOnly,
|
||||||
|
nameAndContent;
|
||||||
|
|
||||||
|
factory MessageNotificationContent.fromJson(dynamic j) =>
|
||||||
|
MessageNotificationContent.values.byName((j as String).toCamelCase());
|
||||||
|
String toJson() => name.toPascalCase();
|
||||||
|
|
||||||
|
static const MessageNotificationContent defaults =
|
||||||
|
MessageNotificationContent.nothing;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SoundEffect {
|
||||||
|
none,
|
||||||
|
bonk,
|
||||||
|
boop,
|
||||||
|
baDeep,
|
||||||
|
beepBaDeep,
|
||||||
|
custom;
|
||||||
|
|
||||||
|
factory SoundEffect.fromJson(dynamic j) =>
|
||||||
|
SoundEffect.values.byName((j as String).toCamelCase());
|
||||||
|
String toJson() => name.toPascalCase();
|
||||||
|
|
||||||
|
static const SoundEffect defaults = SoundEffect.none;
|
||||||
|
}
|
358
lib/notifications/models/notifications_preference.freezed.dart
Normal file
358
lib/notifications/models/notifications_preference.freezed.dart
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'notifications_preference.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||||
|
|
||||||
|
NotificationsPreference _$NotificationsPreferenceFromJson(
|
||||||
|
Map<String, dynamic> json) {
|
||||||
|
return _NotificationsPreference.fromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$NotificationsPreference {
|
||||||
|
bool get displayBetaWarning => throw _privateConstructorUsedError;
|
||||||
|
bool get enableBadge => throw _privateConstructorUsedError;
|
||||||
|
bool get enableNotifications => throw _privateConstructorUsedError;
|
||||||
|
MessageNotificationContent get messageNotificationContent =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
NotificationMode get onInvitationAcceptedMode =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
SoundEffect get onInvitationAcceptedSound =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
NotificationMode get onMessageReceivedMode =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
SoundEffect get onMessageReceivedSound => throw _privateConstructorUsedError;
|
||||||
|
SoundEffect get onMessageSentSound => throw _privateConstructorUsedError;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
$NotificationsPreferenceCopyWith<NotificationsPreference> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $NotificationsPreferenceCopyWith<$Res> {
|
||||||
|
factory $NotificationsPreferenceCopyWith(NotificationsPreference value,
|
||||||
|
$Res Function(NotificationsPreference) then) =
|
||||||
|
_$NotificationsPreferenceCopyWithImpl<$Res, NotificationsPreference>;
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{bool displayBetaWarning,
|
||||||
|
bool enableBadge,
|
||||||
|
bool enableNotifications,
|
||||||
|
MessageNotificationContent messageNotificationContent,
|
||||||
|
NotificationMode onInvitationAcceptedMode,
|
||||||
|
SoundEffect onInvitationAcceptedSound,
|
||||||
|
NotificationMode onMessageReceivedMode,
|
||||||
|
SoundEffect onMessageReceivedSound,
|
||||||
|
SoundEffect onMessageSentSound});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$NotificationsPreferenceCopyWithImpl<$Res,
|
||||||
|
$Val extends NotificationsPreference>
|
||||||
|
implements $NotificationsPreferenceCopyWith<$Res> {
|
||||||
|
_$NotificationsPreferenceCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? displayBetaWarning = null,
|
||||||
|
Object? enableBadge = null,
|
||||||
|
Object? enableNotifications = null,
|
||||||
|
Object? messageNotificationContent = null,
|
||||||
|
Object? onInvitationAcceptedMode = null,
|
||||||
|
Object? onInvitationAcceptedSound = null,
|
||||||
|
Object? onMessageReceivedMode = null,
|
||||||
|
Object? onMessageReceivedSound = null,
|
||||||
|
Object? onMessageSentSound = null,
|
||||||
|
}) {
|
||||||
|
return _then(_value.copyWith(
|
||||||
|
displayBetaWarning: null == displayBetaWarning
|
||||||
|
? _value.displayBetaWarning
|
||||||
|
: displayBetaWarning // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
enableBadge: null == enableBadge
|
||||||
|
? _value.enableBadge
|
||||||
|
: enableBadge // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
enableNotifications: null == enableNotifications
|
||||||
|
? _value.enableNotifications
|
||||||
|
: enableNotifications // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
messageNotificationContent: null == messageNotificationContent
|
||||||
|
? _value.messageNotificationContent
|
||||||
|
: messageNotificationContent // ignore: cast_nullable_to_non_nullable
|
||||||
|
as MessageNotificationContent,
|
||||||
|
onInvitationAcceptedMode: null == onInvitationAcceptedMode
|
||||||
|
? _value.onInvitationAcceptedMode
|
||||||
|
: onInvitationAcceptedMode // ignore: cast_nullable_to_non_nullable
|
||||||
|
as NotificationMode,
|
||||||
|
onInvitationAcceptedSound: null == onInvitationAcceptedSound
|
||||||
|
? _value.onInvitationAcceptedSound
|
||||||
|
: onInvitationAcceptedSound // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SoundEffect,
|
||||||
|
onMessageReceivedMode: null == onMessageReceivedMode
|
||||||
|
? _value.onMessageReceivedMode
|
||||||
|
: onMessageReceivedMode // ignore: cast_nullable_to_non_nullable
|
||||||
|
as NotificationMode,
|
||||||
|
onMessageReceivedSound: null == onMessageReceivedSound
|
||||||
|
? _value.onMessageReceivedSound
|
||||||
|
: onMessageReceivedSound // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SoundEffect,
|
||||||
|
onMessageSentSound: null == onMessageSentSound
|
||||||
|
? _value.onMessageSentSound
|
||||||
|
: onMessageSentSound // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SoundEffect,
|
||||||
|
) as $Val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$NotificationsPreferenceImplCopyWith<$Res>
|
||||||
|
implements $NotificationsPreferenceCopyWith<$Res> {
|
||||||
|
factory _$$NotificationsPreferenceImplCopyWith(
|
||||||
|
_$NotificationsPreferenceImpl value,
|
||||||
|
$Res Function(_$NotificationsPreferenceImpl) then) =
|
||||||
|
__$$NotificationsPreferenceImplCopyWithImpl<$Res>;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call(
|
||||||
|
{bool displayBetaWarning,
|
||||||
|
bool enableBadge,
|
||||||
|
bool enableNotifications,
|
||||||
|
MessageNotificationContent messageNotificationContent,
|
||||||
|
NotificationMode onInvitationAcceptedMode,
|
||||||
|
SoundEffect onInvitationAcceptedSound,
|
||||||
|
NotificationMode onMessageReceivedMode,
|
||||||
|
SoundEffect onMessageReceivedSound,
|
||||||
|
SoundEffect onMessageSentSound});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$NotificationsPreferenceImplCopyWithImpl<$Res>
|
||||||
|
extends _$NotificationsPreferenceCopyWithImpl<$Res,
|
||||||
|
_$NotificationsPreferenceImpl>
|
||||||
|
implements _$$NotificationsPreferenceImplCopyWith<$Res> {
|
||||||
|
__$$NotificationsPreferenceImplCopyWithImpl(
|
||||||
|
_$NotificationsPreferenceImpl _value,
|
||||||
|
$Res Function(_$NotificationsPreferenceImpl) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? displayBetaWarning = null,
|
||||||
|
Object? enableBadge = null,
|
||||||
|
Object? enableNotifications = null,
|
||||||
|
Object? messageNotificationContent = null,
|
||||||
|
Object? onInvitationAcceptedMode = null,
|
||||||
|
Object? onInvitationAcceptedSound = null,
|
||||||
|
Object? onMessageReceivedMode = null,
|
||||||
|
Object? onMessageReceivedSound = null,
|
||||||
|
Object? onMessageSentSound = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$NotificationsPreferenceImpl(
|
||||||
|
displayBetaWarning: null == displayBetaWarning
|
||||||
|
? _value.displayBetaWarning
|
||||||
|
: displayBetaWarning // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
enableBadge: null == enableBadge
|
||||||
|
? _value.enableBadge
|
||||||
|
: enableBadge // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
enableNotifications: null == enableNotifications
|
||||||
|
? _value.enableNotifications
|
||||||
|
: enableNotifications // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
messageNotificationContent: null == messageNotificationContent
|
||||||
|
? _value.messageNotificationContent
|
||||||
|
: messageNotificationContent // ignore: cast_nullable_to_non_nullable
|
||||||
|
as MessageNotificationContent,
|
||||||
|
onInvitationAcceptedMode: null == onInvitationAcceptedMode
|
||||||
|
? _value.onInvitationAcceptedMode
|
||||||
|
: onInvitationAcceptedMode // ignore: cast_nullable_to_non_nullable
|
||||||
|
as NotificationMode,
|
||||||
|
onInvitationAcceptedSound: null == onInvitationAcceptedSound
|
||||||
|
? _value.onInvitationAcceptedSound
|
||||||
|
: onInvitationAcceptedSound // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SoundEffect,
|
||||||
|
onMessageReceivedMode: null == onMessageReceivedMode
|
||||||
|
? _value.onMessageReceivedMode
|
||||||
|
: onMessageReceivedMode // ignore: cast_nullable_to_non_nullable
|
||||||
|
as NotificationMode,
|
||||||
|
onMessageReceivedSound: null == onMessageReceivedSound
|
||||||
|
? _value.onMessageReceivedSound
|
||||||
|
: onMessageReceivedSound // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SoundEffect,
|
||||||
|
onMessageSentSound: null == onMessageSentSound
|
||||||
|
? _value.onMessageSentSound
|
||||||
|
: onMessageSentSound // ignore: cast_nullable_to_non_nullable
|
||||||
|
as SoundEffect,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _$NotificationsPreferenceImpl implements _NotificationsPreference {
|
||||||
|
const _$NotificationsPreferenceImpl(
|
||||||
|
{this.displayBetaWarning = true,
|
||||||
|
this.enableBadge = true,
|
||||||
|
this.enableNotifications = true,
|
||||||
|
this.messageNotificationContent =
|
||||||
|
MessageNotificationContent.nameAndContent,
|
||||||
|
this.onInvitationAcceptedMode = NotificationMode.inAppOrPush,
|
||||||
|
this.onInvitationAcceptedSound = SoundEffect.beepBaDeep,
|
||||||
|
this.onMessageReceivedMode = NotificationMode.inAppOrPush,
|
||||||
|
this.onMessageReceivedSound = SoundEffect.boop,
|
||||||
|
this.onMessageSentSound = SoundEffect.bonk});
|
||||||
|
|
||||||
|
factory _$NotificationsPreferenceImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$NotificationsPreferenceImplFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool displayBetaWarning;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool enableBadge;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final bool enableNotifications;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final MessageNotificationContent messageNotificationContent;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final NotificationMode onInvitationAcceptedMode;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final SoundEffect onInvitationAcceptedSound;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final NotificationMode onMessageReceivedMode;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final SoundEffect onMessageReceivedSound;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final SoundEffect onMessageSentSound;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'NotificationsPreference(displayBetaWarning: $displayBetaWarning, enableBadge: $enableBadge, enableNotifications: $enableNotifications, messageNotificationContent: $messageNotificationContent, onInvitationAcceptedMode: $onInvitationAcceptedMode, onInvitationAcceptedSound: $onInvitationAcceptedSound, onMessageReceivedMode: $onMessageReceivedMode, onMessageReceivedSound: $onMessageReceivedSound, onMessageSentSound: $onMessageSentSound)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$NotificationsPreferenceImpl &&
|
||||||
|
(identical(other.displayBetaWarning, displayBetaWarning) ||
|
||||||
|
other.displayBetaWarning == displayBetaWarning) &&
|
||||||
|
(identical(other.enableBadge, enableBadge) ||
|
||||||
|
other.enableBadge == enableBadge) &&
|
||||||
|
(identical(other.enableNotifications, enableNotifications) ||
|
||||||
|
other.enableNotifications == enableNotifications) &&
|
||||||
|
(identical(other.messageNotificationContent,
|
||||||
|
messageNotificationContent) ||
|
||||||
|
other.messageNotificationContent ==
|
||||||
|
messageNotificationContent) &&
|
||||||
|
(identical(
|
||||||
|
other.onInvitationAcceptedMode, onInvitationAcceptedMode) ||
|
||||||
|
other.onInvitationAcceptedMode == onInvitationAcceptedMode) &&
|
||||||
|
(identical(other.onInvitationAcceptedSound,
|
||||||
|
onInvitationAcceptedSound) ||
|
||||||
|
other.onInvitationAcceptedSound == onInvitationAcceptedSound) &&
|
||||||
|
(identical(other.onMessageReceivedMode, onMessageReceivedMode) ||
|
||||||
|
other.onMessageReceivedMode == onMessageReceivedMode) &&
|
||||||
|
(identical(other.onMessageReceivedSound, onMessageReceivedSound) ||
|
||||||
|
other.onMessageReceivedSound == onMessageReceivedSound) &&
|
||||||
|
(identical(other.onMessageSentSound, onMessageSentSound) ||
|
||||||
|
other.onMessageSentSound == onMessageSentSound));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
displayBetaWarning,
|
||||||
|
enableBadge,
|
||||||
|
enableNotifications,
|
||||||
|
messageNotificationContent,
|
||||||
|
onInvitationAcceptedMode,
|
||||||
|
onInvitationAcceptedSound,
|
||||||
|
onMessageReceivedMode,
|
||||||
|
onMessageReceivedSound,
|
||||||
|
onMessageSentSound);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$NotificationsPreferenceImplCopyWith<_$NotificationsPreferenceImpl>
|
||||||
|
get copyWith => __$$NotificationsPreferenceImplCopyWithImpl<
|
||||||
|
_$NotificationsPreferenceImpl>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$NotificationsPreferenceImplToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class _NotificationsPreference implements NotificationsPreference {
|
||||||
|
const factory _NotificationsPreference(
|
||||||
|
{final bool displayBetaWarning,
|
||||||
|
final bool enableBadge,
|
||||||
|
final bool enableNotifications,
|
||||||
|
final MessageNotificationContent messageNotificationContent,
|
||||||
|
final NotificationMode onInvitationAcceptedMode,
|
||||||
|
final SoundEffect onInvitationAcceptedSound,
|
||||||
|
final NotificationMode onMessageReceivedMode,
|
||||||
|
final SoundEffect onMessageReceivedSound,
|
||||||
|
final SoundEffect onMessageSentSound}) = _$NotificationsPreferenceImpl;
|
||||||
|
|
||||||
|
factory _NotificationsPreference.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$NotificationsPreferenceImpl.fromJson;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get displayBetaWarning;
|
||||||
|
@override
|
||||||
|
bool get enableBadge;
|
||||||
|
@override
|
||||||
|
bool get enableNotifications;
|
||||||
|
@override
|
||||||
|
MessageNotificationContent get messageNotificationContent;
|
||||||
|
@override
|
||||||
|
NotificationMode get onInvitationAcceptedMode;
|
||||||
|
@override
|
||||||
|
SoundEffect get onInvitationAcceptedSound;
|
||||||
|
@override
|
||||||
|
NotificationMode get onMessageReceivedMode;
|
||||||
|
@override
|
||||||
|
SoundEffect get onMessageReceivedSound;
|
||||||
|
@override
|
||||||
|
SoundEffect get onMessageSentSound;
|
||||||
|
@override
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$NotificationsPreferenceImplCopyWith<_$NotificationsPreferenceImpl>
|
||||||
|
get copyWith => throw _privateConstructorUsedError;
|
||||||
|
}
|
50
lib/notifications/models/notifications_preference.g.dart
Normal file
50
lib/notifications/models/notifications_preference.g.dart
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'notifications_preference.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$NotificationsPreferenceImpl _$$NotificationsPreferenceImplFromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
_$NotificationsPreferenceImpl(
|
||||||
|
displayBetaWarning: json['display_beta_warning'] as bool? ?? true,
|
||||||
|
enableBadge: json['enable_badge'] as bool? ?? true,
|
||||||
|
enableNotifications: json['enable_notifications'] as bool? ?? true,
|
||||||
|
messageNotificationContent: json['message_notification_content'] == null
|
||||||
|
? MessageNotificationContent.nameAndContent
|
||||||
|
: MessageNotificationContent.fromJson(
|
||||||
|
json['message_notification_content']),
|
||||||
|
onInvitationAcceptedMode: json['on_invitation_accepted_mode'] == null
|
||||||
|
? NotificationMode.inAppOrPush
|
||||||
|
: NotificationMode.fromJson(json['on_invitation_accepted_mode']),
|
||||||
|
onInvitationAcceptedSound: json['on_invitation_accepted_sound'] == null
|
||||||
|
? SoundEffect.beepBaDeep
|
||||||
|
: SoundEffect.fromJson(json['on_invitation_accepted_sound']),
|
||||||
|
onMessageReceivedMode: json['on_message_received_mode'] == null
|
||||||
|
? NotificationMode.inAppOrPush
|
||||||
|
: NotificationMode.fromJson(json['on_message_received_mode']),
|
||||||
|
onMessageReceivedSound: json['on_message_received_sound'] == null
|
||||||
|
? SoundEffect.boop
|
||||||
|
: SoundEffect.fromJson(json['on_message_received_sound']),
|
||||||
|
onMessageSentSound: json['on_message_sent_sound'] == null
|
||||||
|
? SoundEffect.bonk
|
||||||
|
: SoundEffect.fromJson(json['on_message_sent_sound']),
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$NotificationsPreferenceImplToJson(
|
||||||
|
_$NotificationsPreferenceImpl instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'display_beta_warning': instance.displayBetaWarning,
|
||||||
|
'enable_badge': instance.enableBadge,
|
||||||
|
'enable_notifications': instance.enableNotifications,
|
||||||
|
'message_notification_content':
|
||||||
|
instance.messageNotificationContent.toJson(),
|
||||||
|
'on_invitation_accepted_mode': instance.onInvitationAcceptedMode.toJson(),
|
||||||
|
'on_invitation_accepted_sound':
|
||||||
|
instance.onInvitationAcceptedSound.toJson(),
|
||||||
|
'on_message_received_mode': instance.onMessageReceivedMode.toJson(),
|
||||||
|
'on_message_received_sound': instance.onMessageReceivedSound.toJson(),
|
||||||
|
'on_message_sent_sound': instance.onMessageSentSound.toJson(),
|
||||||
|
};
|
@ -1,3 +1,3 @@
|
|||||||
export 'cubits/notifications_cubit.dart';
|
export 'cubits/notifications_cubit.dart';
|
||||||
export 'models/notifications_state.dart';
|
export 'models/models.dart';
|
||||||
export 'views/notifications_widget.dart';
|
export 'views/views.dart';
|
||||||
|
285
lib/notifications/views/notifications_preferences.dart
Normal file
285
lib/notifications/views/notifications_preferences.dart
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
import 'package:awesome_extensions/awesome_extensions.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
|
import 'package:flutter_translate/flutter_translate.dart';
|
||||||
|
|
||||||
|
import '../../settings/settings.dart';
|
||||||
|
import '../../theme/theme.dart';
|
||||||
|
import '../notifications.dart';
|
||||||
|
|
||||||
|
const String formFieldDisplayBetaWarning = 'displayBetaWarning';
|
||||||
|
const String formFieldEnableBadge = 'enableBadge';
|
||||||
|
const String formFieldEnableNotifications = 'enableNotifications';
|
||||||
|
const String formFieldMessageNotificationContent = 'messageNotificationContent';
|
||||||
|
const String formFieldInvitationAcceptMode = 'invitationAcceptMode';
|
||||||
|
const String formFieldInvitationAcceptSound = 'invitationAcceptSound';
|
||||||
|
const String formFieldMessageReceivedMode = 'messageReceivedMode';
|
||||||
|
const String formFieldMessageReceivedSound = 'messageReceivedSound';
|
||||||
|
const String formFieldMessageSentSound = 'messageSentSound';
|
||||||
|
|
||||||
|
Widget buildSettingsPageNotificationPreferences(
|
||||||
|
{required BuildContext context, required void Function() onChanged}) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
final scale = theme.extension<ScaleScheme>()!;
|
||||||
|
final scaleConfig = theme.extension<ScaleConfig>()!;
|
||||||
|
final textTheme = theme.textTheme;
|
||||||
|
|
||||||
|
final preferencesRepository = PreferencesRepository.instance;
|
||||||
|
final notificationsPreference =
|
||||||
|
preferencesRepository.value.notificationsPreference;
|
||||||
|
|
||||||
|
Future<void> updatePreferences(
|
||||||
|
NotificationsPreference newNotificationsPreference) async {
|
||||||
|
final newPrefs = preferencesRepository.value
|
||||||
|
.copyWith(notificationsPreference: newNotificationsPreference);
|
||||||
|
await preferencesRepository.set(newPrefs);
|
||||||
|
onChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DropdownMenuItem<NotificationMode>> notificationModeItems() {
|
||||||
|
final out = <DropdownMenuItem<NotificationMode>>[];
|
||||||
|
final items = [
|
||||||
|
(NotificationMode.none, true, translate('settings_page.none')),
|
||||||
|
(NotificationMode.inApp, true, translate('settings_page.in_app')),
|
||||||
|
(NotificationMode.push, false, translate('settings_page.push')),
|
||||||
|
(
|
||||||
|
NotificationMode.inAppOrPush,
|
||||||
|
true,
|
||||||
|
translate('settings_page.in_app_or_push')
|
||||||
|
),
|
||||||
|
];
|
||||||
|
for (final x in items) {
|
||||||
|
out.add(DropdownMenuItem(
|
||||||
|
value: x.$1,
|
||||||
|
enabled: x.$2,
|
||||||
|
child: Text(x.$3, style: textTheme.labelSmall)));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DropdownMenuItem<SoundEffect>> soundEffectItems() {
|
||||||
|
final out = <DropdownMenuItem<SoundEffect>>[];
|
||||||
|
final items = [
|
||||||
|
(SoundEffect.none, true, translate('settings_page.none')),
|
||||||
|
(SoundEffect.bonk, true, translate('settings_page.bonk')),
|
||||||
|
(SoundEffect.boop, true, translate('settings_page.boop')),
|
||||||
|
(SoundEffect.baDeep, true, translate('settings_page.badeep')),
|
||||||
|
(SoundEffect.beepBaDeep, true, translate('settings_page.beep_badeep')),
|
||||||
|
(SoundEffect.custom, false, translate('settings_page.custom')),
|
||||||
|
];
|
||||||
|
for (final x in items) {
|
||||||
|
out.add(DropdownMenuItem(
|
||||||
|
value: x.$1,
|
||||||
|
enabled: x.$2,
|
||||||
|
child: Text(x.$3, style: textTheme.labelSmall)));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DropdownMenuItem<MessageNotificationContent>>
|
||||||
|
messageNotificationContentItems() {
|
||||||
|
final out = <DropdownMenuItem<MessageNotificationContent>>[];
|
||||||
|
final items = [
|
||||||
|
(
|
||||||
|
MessageNotificationContent.nameAndContent,
|
||||||
|
true,
|
||||||
|
translate('settings_page.name_and_content')
|
||||||
|
),
|
||||||
|
(
|
||||||
|
MessageNotificationContent.nameOnly,
|
||||||
|
true,
|
||||||
|
translate('settings_page.name_only')
|
||||||
|
),
|
||||||
|
(
|
||||||
|
MessageNotificationContent.nothing,
|
||||||
|
true,
|
||||||
|
translate('settings_page.nothing')
|
||||||
|
),
|
||||||
|
];
|
||||||
|
for (final x in items) {
|
||||||
|
out.add(DropdownMenuItem(
|
||||||
|
value: x.$1,
|
||||||
|
enabled: x.$2,
|
||||||
|
child: Text(x.$3, style: textTheme.labelSmall)));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DecoratedBox(
|
||||||
|
decoration: ShapeDecoration(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
side: BorderSide(width: 2, color: scale.primaryScale.border),
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius.circular(8 * scaleConfig.borderRadiusScale))),
|
||||||
|
child: Column(mainAxisSize: MainAxisSize.min, children: [
|
||||||
|
// Display Beta Warning
|
||||||
|
FormBuilderCheckbox(
|
||||||
|
name: formFieldDisplayBetaWarning,
|
||||||
|
side: BorderSide(color: scale.primaryScale.border, width: 2),
|
||||||
|
title: Text(translate('settings_page.display_beta_warning'),
|
||||||
|
style: textTheme.labelMedium),
|
||||||
|
initialValue: notificationsPreference.displayBetaWarning,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final newNotificationsPreference =
|
||||||
|
notificationsPreference.copyWith(displayBetaWarning: value);
|
||||||
|
|
||||||
|
await updatePreferences(newNotificationsPreference);
|
||||||
|
}),
|
||||||
|
// Enable Badge
|
||||||
|
FormBuilderCheckbox(
|
||||||
|
name: formFieldEnableBadge,
|
||||||
|
side: BorderSide(color: scale.primaryScale.border, width: 2),
|
||||||
|
title: Text(translate('settings_page.enable_badge'),
|
||||||
|
style: textTheme.labelMedium),
|
||||||
|
initialValue: notificationsPreference.enableBadge,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final newNotificationsPreference =
|
||||||
|
notificationsPreference.copyWith(enableBadge: value);
|
||||||
|
await updatePreferences(newNotificationsPreference);
|
||||||
|
}),
|
||||||
|
// Enable Notifications
|
||||||
|
FormBuilderCheckbox(
|
||||||
|
name: formFieldEnableNotifications,
|
||||||
|
side: BorderSide(color: scale.primaryScale.border, width: 2),
|
||||||
|
title: Text(translate('settings_page.enable_notifications'),
|
||||||
|
style: textTheme.labelMedium),
|
||||||
|
initialValue: notificationsPreference.enableNotifications,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final newNotificationsPreference =
|
||||||
|
notificationsPreference.copyWith(enableNotifications: value);
|
||||||
|
await updatePreferences(newNotificationsPreference);
|
||||||
|
}),
|
||||||
|
|
||||||
|
FormBuilderDropdown(
|
||||||
|
name: formFieldMessageNotificationContent,
|
||||||
|
isDense: false,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: translate('settings_page.message_notification_content')),
|
||||||
|
enabled: notificationsPreference.enableNotifications,
|
||||||
|
initialValue: notificationsPreference.messageNotificationContent,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final newNotificationsPreference = notificationsPreference.copyWith(
|
||||||
|
messageNotificationContent: value);
|
||||||
|
await updatePreferences(newNotificationsPreference);
|
||||||
|
},
|
||||||
|
items: messageNotificationContentItems(),
|
||||||
|
).paddingAll(8),
|
||||||
|
|
||||||
|
// Notifications
|
||||||
|
Table(
|
||||||
|
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||||
|
children: [
|
||||||
|
TableRow(children: [
|
||||||
|
// Invitation accepted
|
||||||
|
Text(
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
translate('settings_page.invitation_accepted'))
|
||||||
|
.paddingAll(8),
|
||||||
|
FormBuilderDropdown(
|
||||||
|
name: formFieldInvitationAcceptMode,
|
||||||
|
isDense: false,
|
||||||
|
enabled: notificationsPreference.enableNotifications,
|
||||||
|
initialValue: notificationsPreference.onInvitationAcceptedMode,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final newNotificationsPreference = notificationsPreference
|
||||||
|
.copyWith(onInvitationAcceptedMode: value);
|
||||||
|
await updatePreferences(newNotificationsPreference);
|
||||||
|
},
|
||||||
|
items: notificationModeItems(),
|
||||||
|
).paddingAll(4),
|
||||||
|
FormBuilderDropdown(
|
||||||
|
name: formFieldInvitationAcceptSound,
|
||||||
|
isDense: false,
|
||||||
|
enabled: notificationsPreference.enableNotifications,
|
||||||
|
initialValue: notificationsPreference.onInvitationAcceptedSound,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final newNotificationsPreference = notificationsPreference
|
||||||
|
.copyWith(onInvitationAcceptedSound: value);
|
||||||
|
await updatePreferences(newNotificationsPreference);
|
||||||
|
},
|
||||||
|
items: soundEffectItems(),
|
||||||
|
).paddingAll(4)
|
||||||
|
]),
|
||||||
|
// Message received
|
||||||
|
TableRow(children: [
|
||||||
|
Text(
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
translate('settings_page.message_received'))
|
||||||
|
.paddingAll(8),
|
||||||
|
FormBuilderDropdown(
|
||||||
|
name: formFieldMessageReceivedMode,
|
||||||
|
isDense: false,
|
||||||
|
enabled: notificationsPreference.enableNotifications,
|
||||||
|
initialValue: notificationsPreference.onMessageReceivedMode,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final newNotificationsPreference = notificationsPreference
|
||||||
|
.copyWith(onMessageReceivedMode: value);
|
||||||
|
await updatePreferences(newNotificationsPreference);
|
||||||
|
},
|
||||||
|
items: notificationModeItems(),
|
||||||
|
).paddingAll(4),
|
||||||
|
FormBuilderDropdown(
|
||||||
|
name: formFieldMessageReceivedSound,
|
||||||
|
isDense: false,
|
||||||
|
enabled: notificationsPreference.enableNotifications,
|
||||||
|
initialValue: notificationsPreference.onMessageReceivedSound,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final newNotificationsPreference = notificationsPreference
|
||||||
|
.copyWith(onMessageReceivedSound: value);
|
||||||
|
await updatePreferences(newNotificationsPreference);
|
||||||
|
},
|
||||||
|
items: soundEffectItems(),
|
||||||
|
).paddingAll(4)
|
||||||
|
]),
|
||||||
|
|
||||||
|
// Message sent
|
||||||
|
TableRow(children: [
|
||||||
|
Text(
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
translate('settings_page.message_sent'))
|
||||||
|
.paddingAll(8),
|
||||||
|
const SizedBox.shrink(),
|
||||||
|
FormBuilderDropdown(
|
||||||
|
name: formFieldMessageSentSound,
|
||||||
|
isDense: false,
|
||||||
|
enabled: notificationsPreference.enableNotifications,
|
||||||
|
initialValue: notificationsPreference.onMessageSentSound,
|
||||||
|
onChanged: (value) async {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final newNotificationsPreference = notificationsPreference
|
||||||
|
.copyWith(onMessageSentSound: value);
|
||||||
|
await updatePreferences(newNotificationsPreference);
|
||||||
|
},
|
||||||
|
items: soundEffectItems(),
|
||||||
|
).paddingAll(4)
|
||||||
|
]),
|
||||||
|
]).paddingAll(8)
|
||||||
|
]).paddingAll(8),
|
||||||
|
);
|
||||||
|
}
|
2
lib/notifications/views/views.dart
Normal file
2
lib/notifications/views/views.dart
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export 'notifications_preferences.dart';
|
||||||
|
export 'notifications_widget.dart';
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:change_case/change_case.dart';
|
import 'package:change_case/change_case.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
import '../../notifications/notifications.dart';
|
||||||
import '../../theme/theme.dart';
|
import '../../theme/theme.dart';
|
||||||
|
|
||||||
part 'preferences.freezed.dart';
|
part 'preferences.freezed.dart';
|
||||||
@ -11,19 +12,15 @@ part 'preferences.g.dart';
|
|||||||
@freezed
|
@freezed
|
||||||
class LockPreference with _$LockPreference {
|
class LockPreference with _$LockPreference {
|
||||||
const factory LockPreference({
|
const factory LockPreference({
|
||||||
required int inactivityLockSecs,
|
@Default(0) int inactivityLockSecs,
|
||||||
required bool lockWhenSwitching,
|
@Default(false) bool lockWhenSwitching,
|
||||||
required bool lockWithSystemLock,
|
@Default(false) bool lockWithSystemLock,
|
||||||
}) = _LockPreference;
|
}) = _LockPreference;
|
||||||
|
|
||||||
factory LockPreference.fromJson(dynamic json) =>
|
factory LockPreference.fromJson(dynamic json) =>
|
||||||
_$LockPreferenceFromJson(json as Map<String, dynamic>);
|
_$LockPreferenceFromJson(json as Map<String, dynamic>);
|
||||||
|
|
||||||
static const LockPreference defaults = LockPreference(
|
static const LockPreference defaults = LockPreference();
|
||||||
inactivityLockSecs: 0,
|
|
||||||
lockWhenSwitching: false,
|
|
||||||
lockWithSystemLock: false,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Theme supports multiple translations
|
// Theme supports multiple translations
|
||||||
@ -42,16 +39,15 @@ enum LanguagePreference {
|
|||||||
@freezed
|
@freezed
|
||||||
class Preferences with _$Preferences {
|
class Preferences with _$Preferences {
|
||||||
const factory Preferences({
|
const factory Preferences({
|
||||||
required ThemePreferences themePreferences,
|
@Default(ThemePreferences.defaults) ThemePreferences themePreference,
|
||||||
required LanguagePreference language,
|
@Default(LanguagePreference.defaults) LanguagePreference languagePreference,
|
||||||
required LockPreference locking,
|
@Default(LockPreference.defaults) LockPreference lockPreference,
|
||||||
|
@Default(NotificationsPreference.defaults)
|
||||||
|
NotificationsPreference notificationsPreference,
|
||||||
}) = _Preferences;
|
}) = _Preferences;
|
||||||
|
|
||||||
factory Preferences.fromJson(dynamic json) =>
|
factory Preferences.fromJson(dynamic json) =>
|
||||||
_$PreferencesFromJson(json as Map<String, dynamic>);
|
_$PreferencesFromJson(json as Map<String, dynamic>);
|
||||||
|
|
||||||
static const Preferences defaults = Preferences(
|
static const Preferences defaults = Preferences();
|
||||||
themePreferences: ThemePreferences.defaults,
|
|
||||||
language: LanguagePreference.defaults,
|
|
||||||
locking: LockPreference.defaults);
|
|
||||||
}
|
}
|
||||||
|
@ -126,18 +126,21 @@ class __$$LockPreferenceImplCopyWithImpl<$Res>
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$LockPreferenceImpl implements _LockPreference {
|
class _$LockPreferenceImpl implements _LockPreference {
|
||||||
const _$LockPreferenceImpl(
|
const _$LockPreferenceImpl(
|
||||||
{required this.inactivityLockSecs,
|
{this.inactivityLockSecs = 0,
|
||||||
required this.lockWhenSwitching,
|
this.lockWhenSwitching = false,
|
||||||
required this.lockWithSystemLock});
|
this.lockWithSystemLock = false});
|
||||||
|
|
||||||
factory _$LockPreferenceImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$LockPreferenceImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$LockPreferenceImplFromJson(json);
|
_$$LockPreferenceImplFromJson(json);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@JsonKey()
|
||||||
final int inactivityLockSecs;
|
final int inactivityLockSecs;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey()
|
||||||
final bool lockWhenSwitching;
|
final bool lockWhenSwitching;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey()
|
||||||
final bool lockWithSystemLock;
|
final bool lockWithSystemLock;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -180,9 +183,9 @@ class _$LockPreferenceImpl implements _LockPreference {
|
|||||||
|
|
||||||
abstract class _LockPreference implements LockPreference {
|
abstract class _LockPreference implements LockPreference {
|
||||||
const factory _LockPreference(
|
const factory _LockPreference(
|
||||||
{required final int inactivityLockSecs,
|
{final int inactivityLockSecs,
|
||||||
required final bool lockWhenSwitching,
|
final bool lockWhenSwitching,
|
||||||
required final bool lockWithSystemLock}) = _$LockPreferenceImpl;
|
final bool lockWithSystemLock}) = _$LockPreferenceImpl;
|
||||||
|
|
||||||
factory _LockPreference.fromJson(Map<String, dynamic> json) =
|
factory _LockPreference.fromJson(Map<String, dynamic> json) =
|
||||||
_$LockPreferenceImpl.fromJson;
|
_$LockPreferenceImpl.fromJson;
|
||||||
@ -205,9 +208,12 @@ Preferences _$PreferencesFromJson(Map<String, dynamic> json) {
|
|||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$Preferences {
|
mixin _$Preferences {
|
||||||
ThemePreferences get themePreferences => throw _privateConstructorUsedError;
|
ThemePreferences get themePreference => throw _privateConstructorUsedError;
|
||||||
LanguagePreference get language => throw _privateConstructorUsedError;
|
LanguagePreference get languagePreference =>
|
||||||
LockPreference get locking => throw _privateConstructorUsedError;
|
throw _privateConstructorUsedError;
|
||||||
|
LockPreference get lockPreference => throw _privateConstructorUsedError;
|
||||||
|
NotificationsPreference get notificationsPreference =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@ -222,12 +228,14 @@ abstract class $PreferencesCopyWith<$Res> {
|
|||||||
_$PreferencesCopyWithImpl<$Res, Preferences>;
|
_$PreferencesCopyWithImpl<$Res, Preferences>;
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{ThemePreferences themePreferences,
|
{ThemePreferences themePreference,
|
||||||
LanguagePreference language,
|
LanguagePreference languagePreference,
|
||||||
LockPreference locking});
|
LockPreference lockPreference,
|
||||||
|
NotificationsPreference notificationsPreference});
|
||||||
|
|
||||||
$ThemePreferencesCopyWith<$Res> get themePreferences;
|
$ThemePreferencesCopyWith<$Res> get themePreference;
|
||||||
$LockPreferenceCopyWith<$Res> get locking;
|
$LockPreferenceCopyWith<$Res> get lockPreference;
|
||||||
|
$NotificationsPreferenceCopyWith<$Res> get notificationsPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -243,39 +251,53 @@ class _$PreferencesCopyWithImpl<$Res, $Val extends Preferences>
|
|||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? themePreferences = null,
|
Object? themePreference = null,
|
||||||
Object? language = null,
|
Object? languagePreference = null,
|
||||||
Object? locking = null,
|
Object? lockPreference = null,
|
||||||
|
Object? notificationsPreference = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_value.copyWith(
|
return _then(_value.copyWith(
|
||||||
themePreferences: null == themePreferences
|
themePreference: null == themePreference
|
||||||
? _value.themePreferences
|
? _value.themePreference
|
||||||
: themePreferences // ignore: cast_nullable_to_non_nullable
|
: themePreference // ignore: cast_nullable_to_non_nullable
|
||||||
as ThemePreferences,
|
as ThemePreferences,
|
||||||
language: null == language
|
languagePreference: null == languagePreference
|
||||||
? _value.language
|
? _value.languagePreference
|
||||||
: language // ignore: cast_nullable_to_non_nullable
|
: languagePreference // ignore: cast_nullable_to_non_nullable
|
||||||
as LanguagePreference,
|
as LanguagePreference,
|
||||||
locking: null == locking
|
lockPreference: null == lockPreference
|
||||||
? _value.locking
|
? _value.lockPreference
|
||||||
: locking // ignore: cast_nullable_to_non_nullable
|
: lockPreference // ignore: cast_nullable_to_non_nullable
|
||||||
as LockPreference,
|
as LockPreference,
|
||||||
|
notificationsPreference: null == notificationsPreference
|
||||||
|
? _value.notificationsPreference
|
||||||
|
: notificationsPreference // ignore: cast_nullable_to_non_nullable
|
||||||
|
as NotificationsPreference,
|
||||||
) as $Val);
|
) as $Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$ThemePreferencesCopyWith<$Res> get themePreferences {
|
$ThemePreferencesCopyWith<$Res> get themePreference {
|
||||||
return $ThemePreferencesCopyWith<$Res>(_value.themePreferences, (value) {
|
return $ThemePreferencesCopyWith<$Res>(_value.themePreference, (value) {
|
||||||
return _then(_value.copyWith(themePreferences: value) as $Val);
|
return _then(_value.copyWith(themePreference: value) as $Val);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
$LockPreferenceCopyWith<$Res> get locking {
|
$LockPreferenceCopyWith<$Res> get lockPreference {
|
||||||
return $LockPreferenceCopyWith<$Res>(_value.locking, (value) {
|
return $LockPreferenceCopyWith<$Res>(_value.lockPreference, (value) {
|
||||||
return _then(_value.copyWith(locking: value) as $Val);
|
return _then(_value.copyWith(lockPreference: value) as $Val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$NotificationsPreferenceCopyWith<$Res> get notificationsPreference {
|
||||||
|
return $NotificationsPreferenceCopyWith<$Res>(
|
||||||
|
_value.notificationsPreference, (value) {
|
||||||
|
return _then(_value.copyWith(notificationsPreference: value) as $Val);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,14 +311,17 @@ abstract class _$$PreferencesImplCopyWith<$Res>
|
|||||||
@override
|
@override
|
||||||
@useResult
|
@useResult
|
||||||
$Res call(
|
$Res call(
|
||||||
{ThemePreferences themePreferences,
|
{ThemePreferences themePreference,
|
||||||
LanguagePreference language,
|
LanguagePreference languagePreference,
|
||||||
LockPreference locking});
|
LockPreference lockPreference,
|
||||||
|
NotificationsPreference notificationsPreference});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
$ThemePreferencesCopyWith<$Res> get themePreferences;
|
$ThemePreferencesCopyWith<$Res> get themePreference;
|
||||||
@override
|
@override
|
||||||
$LockPreferenceCopyWith<$Res> get locking;
|
$LockPreferenceCopyWith<$Res> get lockPreference;
|
||||||
|
@override
|
||||||
|
$NotificationsPreferenceCopyWith<$Res> get notificationsPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
@ -310,23 +335,28 @@ class __$$PreferencesImplCopyWithImpl<$Res>
|
|||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline')
|
||||||
@override
|
@override
|
||||||
$Res call({
|
$Res call({
|
||||||
Object? themePreferences = null,
|
Object? themePreference = null,
|
||||||
Object? language = null,
|
Object? languagePreference = null,
|
||||||
Object? locking = null,
|
Object? lockPreference = null,
|
||||||
|
Object? notificationsPreference = null,
|
||||||
}) {
|
}) {
|
||||||
return _then(_$PreferencesImpl(
|
return _then(_$PreferencesImpl(
|
||||||
themePreferences: null == themePreferences
|
themePreference: null == themePreference
|
||||||
? _value.themePreferences
|
? _value.themePreference
|
||||||
: themePreferences // ignore: cast_nullable_to_non_nullable
|
: themePreference // ignore: cast_nullable_to_non_nullable
|
||||||
as ThemePreferences,
|
as ThemePreferences,
|
||||||
language: null == language
|
languagePreference: null == languagePreference
|
||||||
? _value.language
|
? _value.languagePreference
|
||||||
: language // ignore: cast_nullable_to_non_nullable
|
: languagePreference // ignore: cast_nullable_to_non_nullable
|
||||||
as LanguagePreference,
|
as LanguagePreference,
|
||||||
locking: null == locking
|
lockPreference: null == lockPreference
|
||||||
? _value.locking
|
? _value.lockPreference
|
||||||
: locking // ignore: cast_nullable_to_non_nullable
|
: lockPreference // ignore: cast_nullable_to_non_nullable
|
||||||
as LockPreference,
|
as LockPreference,
|
||||||
|
notificationsPreference: null == notificationsPreference
|
||||||
|
? _value.notificationsPreference
|
||||||
|
: notificationsPreference // ignore: cast_nullable_to_non_nullable
|
||||||
|
as NotificationsPreference,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,23 +365,30 @@ class __$$PreferencesImplCopyWithImpl<$Res>
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$PreferencesImpl implements _Preferences {
|
class _$PreferencesImpl implements _Preferences {
|
||||||
const _$PreferencesImpl(
|
const _$PreferencesImpl(
|
||||||
{required this.themePreferences,
|
{this.themePreference = ThemePreferences.defaults,
|
||||||
required this.language,
|
this.languagePreference = LanguagePreference.defaults,
|
||||||
required this.locking});
|
this.lockPreference = LockPreference.defaults,
|
||||||
|
this.notificationsPreference = NotificationsPreference.defaults});
|
||||||
|
|
||||||
factory _$PreferencesImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$PreferencesImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$PreferencesImplFromJson(json);
|
_$$PreferencesImplFromJson(json);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final ThemePreferences themePreferences;
|
@JsonKey()
|
||||||
|
final ThemePreferences themePreference;
|
||||||
@override
|
@override
|
||||||
final LanguagePreference language;
|
@JsonKey()
|
||||||
|
final LanguagePreference languagePreference;
|
||||||
@override
|
@override
|
||||||
final LockPreference locking;
|
@JsonKey()
|
||||||
|
final LockPreference lockPreference;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final NotificationsPreference notificationsPreference;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'Preferences(themePreferences: $themePreferences, language: $language, locking: $locking)';
|
return 'Preferences(themePreference: $themePreference, languagePreference: $languagePreference, lockPreference: $lockPreference, notificationsPreference: $notificationsPreference)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -359,17 +396,21 @@ class _$PreferencesImpl implements _Preferences {
|
|||||||
return identical(this, other) ||
|
return identical(this, other) ||
|
||||||
(other.runtimeType == runtimeType &&
|
(other.runtimeType == runtimeType &&
|
||||||
other is _$PreferencesImpl &&
|
other is _$PreferencesImpl &&
|
||||||
(identical(other.themePreferences, themePreferences) ||
|
(identical(other.themePreference, themePreference) ||
|
||||||
other.themePreferences == themePreferences) &&
|
other.themePreference == themePreference) &&
|
||||||
(identical(other.language, language) ||
|
(identical(other.languagePreference, languagePreference) ||
|
||||||
other.language == language) &&
|
other.languagePreference == languagePreference) &&
|
||||||
(identical(other.locking, locking) || other.locking == locking));
|
(identical(other.lockPreference, lockPreference) ||
|
||||||
|
other.lockPreference == lockPreference) &&
|
||||||
|
(identical(
|
||||||
|
other.notificationsPreference, notificationsPreference) ||
|
||||||
|
other.notificationsPreference == notificationsPreference));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
int get hashCode =>
|
int get hashCode => Object.hash(runtimeType, themePreference,
|
||||||
Object.hash(runtimeType, themePreferences, language, locking);
|
languagePreference, lockPreference, notificationsPreference);
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
@override
|
@override
|
||||||
@ -387,19 +428,23 @@ class _$PreferencesImpl implements _Preferences {
|
|||||||
|
|
||||||
abstract class _Preferences implements Preferences {
|
abstract class _Preferences implements Preferences {
|
||||||
const factory _Preferences(
|
const factory _Preferences(
|
||||||
{required final ThemePreferences themePreferences,
|
{final ThemePreferences themePreference,
|
||||||
required final LanguagePreference language,
|
final LanguagePreference languagePreference,
|
||||||
required final LockPreference locking}) = _$PreferencesImpl;
|
final LockPreference lockPreference,
|
||||||
|
final NotificationsPreference notificationsPreference}) =
|
||||||
|
_$PreferencesImpl;
|
||||||
|
|
||||||
factory _Preferences.fromJson(Map<String, dynamic> json) =
|
factory _Preferences.fromJson(Map<String, dynamic> json) =
|
||||||
_$PreferencesImpl.fromJson;
|
_$PreferencesImpl.fromJson;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ThemePreferences get themePreferences;
|
ThemePreferences get themePreference;
|
||||||
@override
|
@override
|
||||||
LanguagePreference get language;
|
LanguagePreference get languagePreference;
|
||||||
@override
|
@override
|
||||||
LockPreference get locking;
|
LockPreference get lockPreference;
|
||||||
|
@override
|
||||||
|
NotificationsPreference get notificationsPreference;
|
||||||
@override
|
@override
|
||||||
@JsonKey(ignore: true)
|
@JsonKey(ignore: true)
|
||||||
_$$PreferencesImplCopyWith<_$PreferencesImpl> get copyWith =>
|
_$$PreferencesImplCopyWith<_$PreferencesImpl> get copyWith =>
|
||||||
|
@ -8,9 +8,9 @@ part of 'preferences.dart';
|
|||||||
|
|
||||||
_$LockPreferenceImpl _$$LockPreferenceImplFromJson(Map<String, dynamic> json) =>
|
_$LockPreferenceImpl _$$LockPreferenceImplFromJson(Map<String, dynamic> json) =>
|
||||||
_$LockPreferenceImpl(
|
_$LockPreferenceImpl(
|
||||||
inactivityLockSecs: (json['inactivity_lock_secs'] as num).toInt(),
|
inactivityLockSecs: (json['inactivity_lock_secs'] as num?)?.toInt() ?? 0,
|
||||||
lockWhenSwitching: json['lock_when_switching'] as bool,
|
lockWhenSwitching: json['lock_when_switching'] as bool? ?? false,
|
||||||
lockWithSystemLock: json['lock_with_system_lock'] as bool,
|
lockWithSystemLock: json['lock_with_system_lock'] as bool? ?? false,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$LockPreferenceImplToJson(
|
Map<String, dynamic> _$$LockPreferenceImplToJson(
|
||||||
@ -23,14 +23,24 @@ Map<String, dynamic> _$$LockPreferenceImplToJson(
|
|||||||
|
|
||||||
_$PreferencesImpl _$$PreferencesImplFromJson(Map<String, dynamic> json) =>
|
_$PreferencesImpl _$$PreferencesImplFromJson(Map<String, dynamic> json) =>
|
||||||
_$PreferencesImpl(
|
_$PreferencesImpl(
|
||||||
themePreferences: ThemePreferences.fromJson(json['theme_preferences']),
|
themePreference: json['theme_preference'] == null
|
||||||
language: LanguagePreference.fromJson(json['language']),
|
? ThemePreferences.defaults
|
||||||
locking: LockPreference.fromJson(json['locking']),
|
: ThemePreferences.fromJson(json['theme_preference']),
|
||||||
|
languagePreference: json['language_preference'] == null
|
||||||
|
? LanguagePreference.defaults
|
||||||
|
: LanguagePreference.fromJson(json['language_preference']),
|
||||||
|
lockPreference: json['lock_preference'] == null
|
||||||
|
? LockPreference.defaults
|
||||||
|
: LockPreference.fromJson(json['lock_preference']),
|
||||||
|
notificationsPreference: json['notifications_preference'] == null
|
||||||
|
? NotificationsPreference.defaults
|
||||||
|
: NotificationsPreference.fromJson(json['notifications_preference']),
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$PreferencesImplToJson(_$PreferencesImpl instance) =>
|
Map<String, dynamic> _$$PreferencesImplToJson(_$PreferencesImpl instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'theme_preferences': instance.themePreferences.toJson(),
|
'theme_preference': instance.themePreference.toJson(),
|
||||||
'language': instance.language.toJson(),
|
'language_preference': instance.languagePreference.toJson(),
|
||||||
'locking': instance.locking.toJson(),
|
'lock_preference': instance.lockPreference.toJson(),
|
||||||
|
'notifications_preference': instance.notificationsPreference.toJson(),
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,7 @@ import 'package:flutter_translate/flutter_translate.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
import '../layout/default_app_bar.dart';
|
import '../layout/default_app_bar.dart';
|
||||||
|
import '../notifications/notifications.dart';
|
||||||
import '../theme/theme.dart';
|
import '../theme/theme.dart';
|
||||||
import '../veilid_processor/veilid_processor.dart';
|
import '../veilid_processor/veilid_processor.dart';
|
||||||
import 'settings.dart';
|
import 'settings.dart';
|
||||||
@ -49,6 +50,8 @@ class SettingsPageState extends State<SettingsPage> {
|
|||||||
context: context, onChanged: () => setState(() {})),
|
context: context, onChanged: () => setState(() {})),
|
||||||
buildSettingsPageBrightnessPreferences(
|
buildSettingsPageBrightnessPreferences(
|
||||||
context: context, onChanged: () => setState(() {})),
|
context: context, onChanged: () => setState(() {})),
|
||||||
|
buildSettingsPageNotificationPreferences(
|
||||||
|
context: context, onChanged: () => setState(() {})),
|
||||||
].map((x) => x.paddingLTRB(0, 0, 0, 8)).toList(),
|
].map((x) => x.paddingLTRB(0, 0, 0, 8)).toList(),
|
||||||
),
|
),
|
||||||
).paddingSymmetric(horizontal: 24, vertical: 16),
|
).paddingSymmetric(horizontal: 24, vertical: 16),
|
||||||
|
@ -49,19 +49,16 @@ enum ColorPreference {
|
|||||||
@freezed
|
@freezed
|
||||||
class ThemePreferences with _$ThemePreferences {
|
class ThemePreferences with _$ThemePreferences {
|
||||||
const factory ThemePreferences({
|
const factory ThemePreferences({
|
||||||
required BrightnessPreference brightnessPreference,
|
@Default(BrightnessPreference.system)
|
||||||
required ColorPreference colorPreference,
|
BrightnessPreference brightnessPreference,
|
||||||
required double displayScale,
|
@Default(ColorPreference.vapor) ColorPreference colorPreference,
|
||||||
|
@Default(1) double displayScale,
|
||||||
}) = _ThemePreferences;
|
}) = _ThemePreferences;
|
||||||
|
|
||||||
factory ThemePreferences.fromJson(dynamic json) =>
|
factory ThemePreferences.fromJson(dynamic json) =>
|
||||||
_$ThemePreferencesFromJson(json as Map<String, dynamic>);
|
_$ThemePreferencesFromJson(json as Map<String, dynamic>);
|
||||||
|
|
||||||
static const ThemePreferences defaults = ThemePreferences(
|
static const ThemePreferences defaults = ThemePreferences();
|
||||||
colorPreference: ColorPreference.vapor,
|
|
||||||
brightnessPreference: BrightnessPreference.system,
|
|
||||||
displayScale: 1,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ThemePreferencesExt on ThemePreferences {
|
extension ThemePreferencesExt on ThemePreferences {
|
||||||
|
@ -127,18 +127,21 @@ class __$$ThemePreferencesImplCopyWithImpl<$Res>
|
|||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class _$ThemePreferencesImpl implements _ThemePreferences {
|
class _$ThemePreferencesImpl implements _ThemePreferences {
|
||||||
const _$ThemePreferencesImpl(
|
const _$ThemePreferencesImpl(
|
||||||
{required this.brightnessPreference,
|
{this.brightnessPreference = BrightnessPreference.system,
|
||||||
required this.colorPreference,
|
this.colorPreference = ColorPreference.vapor,
|
||||||
required this.displayScale});
|
this.displayScale = 1});
|
||||||
|
|
||||||
factory _$ThemePreferencesImpl.fromJson(Map<String, dynamic> json) =>
|
factory _$ThemePreferencesImpl.fromJson(Map<String, dynamic> json) =>
|
||||||
_$$ThemePreferencesImplFromJson(json);
|
_$$ThemePreferencesImplFromJson(json);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@JsonKey()
|
||||||
final BrightnessPreference brightnessPreference;
|
final BrightnessPreference brightnessPreference;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey()
|
||||||
final ColorPreference colorPreference;
|
final ColorPreference colorPreference;
|
||||||
@override
|
@override
|
||||||
|
@JsonKey()
|
||||||
final double displayScale;
|
final double displayScale;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -181,9 +184,9 @@ class _$ThemePreferencesImpl implements _ThemePreferences {
|
|||||||
|
|
||||||
abstract class _ThemePreferences implements ThemePreferences {
|
abstract class _ThemePreferences implements ThemePreferences {
|
||||||
const factory _ThemePreferences(
|
const factory _ThemePreferences(
|
||||||
{required final BrightnessPreference brightnessPreference,
|
{final BrightnessPreference brightnessPreference,
|
||||||
required final ColorPreference colorPreference,
|
final ColorPreference colorPreference,
|
||||||
required final double displayScale}) = _$ThemePreferencesImpl;
|
final double displayScale}) = _$ThemePreferencesImpl;
|
||||||
|
|
||||||
factory _ThemePreferences.fromJson(Map<String, dynamic> json) =
|
factory _ThemePreferences.fromJson(Map<String, dynamic> json) =
|
||||||
_$ThemePreferencesImpl.fromJson;
|
_$ThemePreferencesImpl.fromJson;
|
||||||
|
@ -9,10 +9,13 @@ part of 'theme_preference.dart';
|
|||||||
_$ThemePreferencesImpl _$$ThemePreferencesImplFromJson(
|
_$ThemePreferencesImpl _$$ThemePreferencesImplFromJson(
|
||||||
Map<String, dynamic> json) =>
|
Map<String, dynamic> json) =>
|
||||||
_$ThemePreferencesImpl(
|
_$ThemePreferencesImpl(
|
||||||
brightnessPreference:
|
brightnessPreference: json['brightness_preference'] == null
|
||||||
BrightnessPreference.fromJson(json['brightness_preference']),
|
? BrightnessPreference.system
|
||||||
colorPreference: ColorPreference.fromJson(json['color_preference']),
|
: BrightnessPreference.fromJson(json['brightness_preference']),
|
||||||
displayScale: (json['display_scale'] as num).toDouble(),
|
colorPreference: json['color_preference'] == null
|
||||||
|
? ColorPreference.vapor
|
||||||
|
: ColorPreference.fromJson(json['color_preference']),
|
||||||
|
displayScale: (json['display_scale'] as num?)?.toDouble() ?? 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$$ThemePreferencesImplToJson(
|
Map<String, dynamic> _$$ThemePreferencesImplToJson(
|
||||||
|
@ -24,7 +24,7 @@ List<DropdownMenuItem<dynamic>> _getBrightnessDropdownItems() {
|
|||||||
Widget buildSettingsPageBrightnessPreferences(
|
Widget buildSettingsPageBrightnessPreferences(
|
||||||
{required BuildContext context, required void Function() onChanged}) {
|
{required BuildContext context, required void Function() onChanged}) {
|
||||||
final preferencesRepository = PreferencesRepository.instance;
|
final preferencesRepository = PreferencesRepository.instance;
|
||||||
final themePreferences = preferencesRepository.value.themePreferences;
|
final themePreferences = preferencesRepository.value.themePreference;
|
||||||
return ThemeSwitcher.withTheme(
|
return ThemeSwitcher.withTheme(
|
||||||
builder: (_, switcher, theme) => FormBuilderDropdown(
|
builder: (_, switcher, theme) => FormBuilderDropdown(
|
||||||
name: formFieldBrightness,
|
name: formFieldBrightness,
|
||||||
@ -36,7 +36,7 @@ Widget buildSettingsPageBrightnessPreferences(
|
|||||||
final newThemePrefs = themePreferences.copyWith(
|
final newThemePrefs = themePreferences.copyWith(
|
||||||
brightnessPreference: value as BrightnessPreference);
|
brightnessPreference: value as BrightnessPreference);
|
||||||
final newPrefs = preferencesRepository.value
|
final newPrefs = preferencesRepository.value
|
||||||
.copyWith(themePreferences: newThemePrefs);
|
.copyWith(themePreference: newThemePrefs);
|
||||||
|
|
||||||
await preferencesRepository.set(newPrefs);
|
await preferencesRepository.set(newPrefs);
|
||||||
switcher.changeTheme(theme: newThemePrefs.themeData());
|
switcher.changeTheme(theme: newThemePrefs.themeData());
|
||||||
|
@ -34,7 +34,7 @@ List<DropdownMenuItem<dynamic>> _getThemeDropdownItems() {
|
|||||||
Widget buildSettingsPageColorPreferences(
|
Widget buildSettingsPageColorPreferences(
|
||||||
{required BuildContext context, required void Function() onChanged}) {
|
{required BuildContext context, required void Function() onChanged}) {
|
||||||
final preferencesRepository = PreferencesRepository.instance;
|
final preferencesRepository = PreferencesRepository.instance;
|
||||||
final themePreferences = preferencesRepository.value.themePreferences;
|
final themePreferences = preferencesRepository.value.themePreference;
|
||||||
return ThemeSwitcher.withTheme(
|
return ThemeSwitcher.withTheme(
|
||||||
builder: (_, switcher, theme) => FormBuilderDropdown(
|
builder: (_, switcher, theme) => FormBuilderDropdown(
|
||||||
name: formFieldTheme,
|
name: formFieldTheme,
|
||||||
@ -46,7 +46,7 @@ Widget buildSettingsPageColorPreferences(
|
|||||||
final newThemePrefs = themePreferences.copyWith(
|
final newThemePrefs = themePreferences.copyWith(
|
||||||
colorPreference: value as ColorPreference);
|
colorPreference: value as ColorPreference);
|
||||||
final newPrefs = preferencesRepository.value
|
final newPrefs = preferencesRepository.value
|
||||||
.copyWith(themePreferences: newThemePrefs);
|
.copyWith(themePreference: newThemePrefs);
|
||||||
|
|
||||||
await preferencesRepository.set(newPrefs);
|
await preferencesRepository.set(newPrefs);
|
||||||
switcher.changeTheme(theme: newThemePrefs.themeData());
|
switcher.changeTheme(theme: newThemePrefs.themeData());
|
||||||
|
@ -19,6 +19,14 @@ extension BorderExt on Widget {
|
|||||||
child: this);
|
child: this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension SizeToFixExt on Widget {
|
||||||
|
FittedBox fit({BoxFit? fit, Key? key}) => FittedBox(
|
||||||
|
key: key,
|
||||||
|
fit: fit ?? BoxFit.scaleDown,
|
||||||
|
child: this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
extension ModalProgressExt on Widget {
|
extension ModalProgressExt on Widget {
|
||||||
BlurryModalProgressHUD withModalHUD(BuildContext context, bool isLoading) {
|
BlurryModalProgressHUD withModalHUD(BuildContext context, bool isLoading) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
|
@ -160,6 +160,11 @@ flutter:
|
|||||||
- assets/images/ellet.png
|
- assets/images/ellet.png
|
||||||
# Printing
|
# Printing
|
||||||
- assets/js/pdf/3.2.146/pdf.min.js
|
- assets/js/pdf/3.2.146/pdf.min.js
|
||||||
|
# Sounds
|
||||||
|
- assets/sounds/bonk.wav
|
||||||
|
- assets/sounds/boop.wav
|
||||||
|
- assets/sounds/badeep.wav
|
||||||
|
- assets/sounds/beepbadeep.wav
|
||||||
# Fonts
|
# Fonts
|
||||||
fonts:
|
fonts:
|
||||||
- family: Source Code Pro
|
- family: Source Code Pro
|
||||||
|
Loading…
Reference in New Issue
Block a user