diff --git a/assets/i18n/en-US.json b/assets/i18n/en-US.json index 4c714e37..a70c0f6b 100644 --- a/assets/i18n/en-US.json +++ b/assets/i18n/en-US.json @@ -326,7 +326,7 @@ "settingsAutoTranslate": "Auto Translate", "settingsHideBottomNav": "Hide Bottom Navigation", "settingsSoundEffects": "Sound Effects", - "settingsAprilFoolFeatures": "April Fool Features", + "settingsFestivalFeatures": "Festival Limited Features", "settingsEnterToSend": "Enter to Send", "settingsTransparentAppBar": "Transparent App Bar", "settingsCustomFonts": "Custom Fonts", diff --git a/lib/pods/config.dart b/lib/pods/config.dart index 8efca68f..a32f3669 100644 --- a/lib/pods/config.dart +++ b/lib/pods/config.dart @@ -22,10 +22,9 @@ const kAppColorSchemeStoreKey = 'app_color_scheme'; const kAppCustomColorsStoreKey = 'app_custom_colors'; const kAppNotifyWithHaptic = 'app_notify_with_haptic'; const kAppCustomFonts = 'app_custom_fonts'; -const kAppAutoTranslate = 'app_auto_translate'; const kAppDataSavingMode = 'app_data_saving_mode'; const kAppSoundEffects = 'app_sound_effects'; -const kAppAprilFoolFeatures = 'app_april_fool_features'; +const kAppFestivalFeatures = 'app_feastival_features'; const kAppWindowSize = 'app_window_size'; const kAppWindowOpacity = 'app_window_opacity'; const kAppCardTransparent = 'app_card_transparent'; @@ -82,10 +81,9 @@ sealed class ThemeColors with _$ThemeColors { @freezed sealed class AppSettings with _$AppSettings { const factory AppSettings({ - required bool autoTranslate, required bool dataSavingMode, required bool soundEffects, - required bool aprilFoolFeatures, + required bool festivalFeatures, required bool enterToSend, required bool appBarTransparent, required bool showBackgroundImage, @@ -111,10 +109,9 @@ class AppSettingsNotifier extends _$AppSettingsNotifier { AppSettings build() { final prefs = ref.watch(sharedPreferencesProvider); return AppSettings( - autoTranslate: prefs.getBool(kAppAutoTranslate) ?? false, dataSavingMode: prefs.getBool(kAppDataSavingMode) ?? false, soundEffects: prefs.getBool(kAppSoundEffects) ?? true, - aprilFoolFeatures: prefs.getBool(kAppAprilFoolFeatures) ?? true, + festivalFeatures: prefs.getBool(kAppFestivalFeatures) ?? true, enterToSend: prefs.getBool(kAppEnterToSend) ?? true, appBarTransparent: prefs.getBool(kAppbarTransparentStoreKey) ?? false, showBackgroundImage: prefs.getBool(kAppShowBackgroundImage) ?? true, @@ -173,12 +170,6 @@ class AppSettingsNotifier extends _$AppSettingsNotifier { state = state.copyWith(defaultPoolId: value); } - void setAutoTranslate(bool value) { - final prefs = ref.read(sharedPreferencesProvider); - prefs.setBool(kAppAutoTranslate, value); - state = state.copyWith(autoTranslate: value); - } - void setDataSavingMode(bool value) { final prefs = ref.read(sharedPreferencesProvider); prefs.setBool(kAppDataSavingMode, value); @@ -191,10 +182,10 @@ class AppSettingsNotifier extends _$AppSettingsNotifier { state = state.copyWith(soundEffects: value); } - void setAprilFoolFeatures(bool value) { + void setFeativalFeatures(bool value) { final prefs = ref.read(sharedPreferencesProvider); - prefs.setBool(kAppAprilFoolFeatures, value); - state = state.copyWith(aprilFoolFeatures: value); + prefs.setBool(kAppFestivalFeatures, value); + state = state.copyWith(festivalFeatures: value); } void setEnterToSend(bool value) { diff --git a/lib/pods/config.freezed.dart b/lib/pods/config.freezed.dart index 03289830..2adbedc8 100644 --- a/lib/pods/config.freezed.dart +++ b/lib/pods/config.freezed.dart @@ -286,7 +286,7 @@ as int?, /// @nodoc mixin _$AppSettings { - bool get autoTranslate; bool get dataSavingMode; bool get soundEffects; bool get aprilFoolFeatures; bool get enterToSend; bool get appBarTransparent; bool get showBackgroundImage; String? get customFonts; int? get appColorScheme;// The color stored via the int type + bool get dataSavingMode; bool get soundEffects; bool get festivalFeatures; bool get enterToSend; bool get appBarTransparent; bool get showBackgroundImage; String? get customFonts; int? get appColorScheme;// The color stored via the int type ThemeColors? get customColors; Size? get windowSize;// The window size for desktop platforms double get windowOpacity;// The window opacity for desktop platforms double get cardTransparency;// The card background opacity @@ -301,16 +301,16 @@ $AppSettingsCopyWith get copyWith => _$AppSettingsCopyWithImpl Object.hashAll([runtimeType,autoTranslate,dataSavingMode,soundEffects,aprilFoolFeatures,enterToSend,appBarTransparent,showBackgroundImage,customFonts,appColorScheme,customColors,windowSize,windowOpacity,cardTransparency,defaultPoolId,messageDisplayStyle,themeMode,useMaterial3,disableAnimation,fabPosition,groupedChatList]); +int get hashCode => Object.hashAll([runtimeType,dataSavingMode,soundEffects,festivalFeatures,enterToSend,appBarTransparent,showBackgroundImage,customFonts,appColorScheme,customColors,windowSize,windowOpacity,cardTransparency,defaultPoolId,messageDisplayStyle,themeMode,useMaterial3,disableAnimation,fabPosition,groupedChatList]); @override String toString() { - return 'AppSettings(autoTranslate: $autoTranslate, dataSavingMode: $dataSavingMode, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, showBackgroundImage: $showBackgroundImage, customFonts: $customFonts, appColorScheme: $appColorScheme, customColors: $customColors, windowSize: $windowSize, windowOpacity: $windowOpacity, cardTransparency: $cardTransparency, defaultPoolId: $defaultPoolId, messageDisplayStyle: $messageDisplayStyle, themeMode: $themeMode, useMaterial3: $useMaterial3, disableAnimation: $disableAnimation, fabPosition: $fabPosition, groupedChatList: $groupedChatList)'; + return 'AppSettings(dataSavingMode: $dataSavingMode, soundEffects: $soundEffects, festivalFeatures: $festivalFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, showBackgroundImage: $showBackgroundImage, customFonts: $customFonts, appColorScheme: $appColorScheme, customColors: $customColors, windowSize: $windowSize, windowOpacity: $windowOpacity, cardTransparency: $cardTransparency, defaultPoolId: $defaultPoolId, messageDisplayStyle: $messageDisplayStyle, themeMode: $themeMode, useMaterial3: $useMaterial3, disableAnimation: $disableAnimation, fabPosition: $fabPosition, groupedChatList: $groupedChatList)'; } @@ -321,7 +321,7 @@ abstract mixin class $AppSettingsCopyWith<$Res> { factory $AppSettingsCopyWith(AppSettings value, $Res Function(AppSettings) _then) = _$AppSettingsCopyWithImpl; @useResult $Res call({ - bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation, String fabPosition, bool groupedChatList + bool dataSavingMode, bool soundEffects, bool festivalFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation, String fabPosition, bool groupedChatList }); @@ -338,12 +338,11 @@ class _$AppSettingsCopyWithImpl<$Res> /// Create a copy of AppSettings /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? autoTranslate = null,Object? dataSavingMode = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? showBackgroundImage = null,Object? customFonts = freezed,Object? appColorScheme = freezed,Object? customColors = freezed,Object? windowSize = freezed,Object? windowOpacity = null,Object? cardTransparency = null,Object? defaultPoolId = freezed,Object? messageDisplayStyle = null,Object? themeMode = freezed,Object? useMaterial3 = null,Object? disableAnimation = null,Object? fabPosition = null,Object? groupedChatList = null,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? dataSavingMode = null,Object? soundEffects = null,Object? festivalFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? showBackgroundImage = null,Object? customFonts = freezed,Object? appColorScheme = freezed,Object? customColors = freezed,Object? windowSize = freezed,Object? windowOpacity = null,Object? cardTransparency = null,Object? defaultPoolId = freezed,Object? messageDisplayStyle = null,Object? themeMode = freezed,Object? useMaterial3 = null,Object? disableAnimation = null,Object? fabPosition = null,Object? groupedChatList = null,}) { return _then(_self.copyWith( -autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable -as bool,dataSavingMode: null == dataSavingMode ? _self.dataSavingMode : dataSavingMode // ignore: cast_nullable_to_non_nullable +dataSavingMode: null == dataSavingMode ? _self.dataSavingMode : dataSavingMode // ignore: cast_nullable_to_non_nullable as bool,soundEffects: null == soundEffects ? _self.soundEffects : soundEffects // ignore: cast_nullable_to_non_nullable -as bool,aprilFoolFeatures: null == aprilFoolFeatures ? _self.aprilFoolFeatures : aprilFoolFeatures // ignore: cast_nullable_to_non_nullable +as bool,festivalFeatures: null == festivalFeatures ? _self.festivalFeatures : festivalFeatures // ignore: cast_nullable_to_non_nullable as bool,enterToSend: null == enterToSend ? _self.enterToSend : enterToSend // ignore: cast_nullable_to_non_nullable as bool,appBarTransparent: null == appBarTransparent ? _self.appBarTransparent : appBarTransparent // ignore: cast_nullable_to_non_nullable as bool,showBackgroundImage: null == showBackgroundImage ? _self.showBackgroundImage : showBackgroundImage // ignore: cast_nullable_to_non_nullable @@ -454,10 +453,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation, String fabPosition, bool groupedChatList)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( bool dataSavingMode, bool soundEffects, bool festivalFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation, String fabPosition, bool groupedChatList)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _AppSettings() when $default != null: -return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_that.customFonts,_that.appColorScheme,_that.customColors,_that.windowSize,_that.windowOpacity,_that.cardTransparency,_that.defaultPoolId,_that.messageDisplayStyle,_that.themeMode,_that.useMaterial3,_that.disableAnimation,_that.fabPosition,_that.groupedChatList);case _: +return $default(_that.dataSavingMode,_that.soundEffects,_that.festivalFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_that.customFonts,_that.appColorScheme,_that.customColors,_that.windowSize,_that.windowOpacity,_that.cardTransparency,_that.defaultPoolId,_that.messageDisplayStyle,_that.themeMode,_that.useMaterial3,_that.disableAnimation,_that.fabPosition,_that.groupedChatList);case _: return orElse(); } @@ -475,10 +474,10 @@ return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_tha /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation, String fabPosition, bool groupedChatList) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( bool dataSavingMode, bool soundEffects, bool festivalFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation, String fabPosition, bool groupedChatList) $default,) {final _that = this; switch (_that) { case _AppSettings(): -return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_that.customFonts,_that.appColorScheme,_that.customColors,_that.windowSize,_that.windowOpacity,_that.cardTransparency,_that.defaultPoolId,_that.messageDisplayStyle,_that.themeMode,_that.useMaterial3,_that.disableAnimation,_that.fabPosition,_that.groupedChatList);} +return $default(_that.dataSavingMode,_that.soundEffects,_that.festivalFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_that.customFonts,_that.appColorScheme,_that.customColors,_that.windowSize,_that.windowOpacity,_that.cardTransparency,_that.defaultPoolId,_that.messageDisplayStyle,_that.themeMode,_that.useMaterial3,_that.disableAnimation,_that.fabPosition,_that.groupedChatList);} } /// A variant of `when` that fallback to returning `null` /// @@ -492,10 +491,10 @@ return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_tha /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation, String fabPosition, bool groupedChatList)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( bool dataSavingMode, bool soundEffects, bool festivalFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation, String fabPosition, bool groupedChatList)? $default,) {final _that = this; switch (_that) { case _AppSettings() when $default != null: -return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_that.aprilFoolFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_that.customFonts,_that.appColorScheme,_that.customColors,_that.windowSize,_that.windowOpacity,_that.cardTransparency,_that.defaultPoolId,_that.messageDisplayStyle,_that.themeMode,_that.useMaterial3,_that.disableAnimation,_that.fabPosition,_that.groupedChatList);case _: +return $default(_that.dataSavingMode,_that.soundEffects,_that.festivalFeatures,_that.enterToSend,_that.appBarTransparent,_that.showBackgroundImage,_that.customFonts,_that.appColorScheme,_that.customColors,_that.windowSize,_that.windowOpacity,_that.cardTransparency,_that.defaultPoolId,_that.messageDisplayStyle,_that.themeMode,_that.useMaterial3,_that.disableAnimation,_that.fabPosition,_that.groupedChatList);case _: return null; } @@ -507,13 +506,12 @@ return $default(_that.autoTranslate,_that.dataSavingMode,_that.soundEffects,_tha class _AppSettings implements AppSettings { - const _AppSettings({required this.autoTranslate, required this.dataSavingMode, required this.soundEffects, required this.aprilFoolFeatures, required this.enterToSend, required this.appBarTransparent, required this.showBackgroundImage, required this.customFonts, required this.appColorScheme, required this.customColors, required this.windowSize, required this.windowOpacity, required this.cardTransparency, required this.defaultPoolId, required this.messageDisplayStyle, required this.themeMode, required this.useMaterial3, required this.disableAnimation, required this.fabPosition, required this.groupedChatList}); + const _AppSettings({required this.dataSavingMode, required this.soundEffects, required this.festivalFeatures, required this.enterToSend, required this.appBarTransparent, required this.showBackgroundImage, required this.customFonts, required this.appColorScheme, required this.customColors, required this.windowSize, required this.windowOpacity, required this.cardTransparency, required this.defaultPoolId, required this.messageDisplayStyle, required this.themeMode, required this.useMaterial3, required this.disableAnimation, required this.fabPosition, required this.groupedChatList}); -@override final bool autoTranslate; @override final bool dataSavingMode; @override final bool soundEffects; -@override final bool aprilFoolFeatures; +@override final bool festivalFeatures; @override final bool enterToSend; @override final bool appBarTransparent; @override final bool showBackgroundImage; @@ -545,16 +543,16 @@ _$AppSettingsCopyWith<_AppSettings> get copyWith => __$AppSettingsCopyWithImpl<_ @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppSettings&&(identical(other.autoTranslate, autoTranslate) || other.autoTranslate == autoTranslate)&&(identical(other.dataSavingMode, dataSavingMode) || other.dataSavingMode == dataSavingMode)&&(identical(other.soundEffects, soundEffects) || other.soundEffects == soundEffects)&&(identical(other.aprilFoolFeatures, aprilFoolFeatures) || other.aprilFoolFeatures == aprilFoolFeatures)&&(identical(other.enterToSend, enterToSend) || other.enterToSend == enterToSend)&&(identical(other.appBarTransparent, appBarTransparent) || other.appBarTransparent == appBarTransparent)&&(identical(other.showBackgroundImage, showBackgroundImage) || other.showBackgroundImage == showBackgroundImage)&&(identical(other.customFonts, customFonts) || other.customFonts == customFonts)&&(identical(other.appColorScheme, appColorScheme) || other.appColorScheme == appColorScheme)&&(identical(other.customColors, customColors) || other.customColors == customColors)&&(identical(other.windowSize, windowSize) || other.windowSize == windowSize)&&(identical(other.windowOpacity, windowOpacity) || other.windowOpacity == windowOpacity)&&(identical(other.cardTransparency, cardTransparency) || other.cardTransparency == cardTransparency)&&(identical(other.defaultPoolId, defaultPoolId) || other.defaultPoolId == defaultPoolId)&&(identical(other.messageDisplayStyle, messageDisplayStyle) || other.messageDisplayStyle == messageDisplayStyle)&&(identical(other.themeMode, themeMode) || other.themeMode == themeMode)&&(identical(other.useMaterial3, useMaterial3) || other.useMaterial3 == useMaterial3)&&(identical(other.disableAnimation, disableAnimation) || other.disableAnimation == disableAnimation)&&(identical(other.fabPosition, fabPosition) || other.fabPosition == fabPosition)&&(identical(other.groupedChatList, groupedChatList) || other.groupedChatList == groupedChatList)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppSettings&&(identical(other.dataSavingMode, dataSavingMode) || other.dataSavingMode == dataSavingMode)&&(identical(other.soundEffects, soundEffects) || other.soundEffects == soundEffects)&&(identical(other.festivalFeatures, festivalFeatures) || other.festivalFeatures == festivalFeatures)&&(identical(other.enterToSend, enterToSend) || other.enterToSend == enterToSend)&&(identical(other.appBarTransparent, appBarTransparent) || other.appBarTransparent == appBarTransparent)&&(identical(other.showBackgroundImage, showBackgroundImage) || other.showBackgroundImage == showBackgroundImage)&&(identical(other.customFonts, customFonts) || other.customFonts == customFonts)&&(identical(other.appColorScheme, appColorScheme) || other.appColorScheme == appColorScheme)&&(identical(other.customColors, customColors) || other.customColors == customColors)&&(identical(other.windowSize, windowSize) || other.windowSize == windowSize)&&(identical(other.windowOpacity, windowOpacity) || other.windowOpacity == windowOpacity)&&(identical(other.cardTransparency, cardTransparency) || other.cardTransparency == cardTransparency)&&(identical(other.defaultPoolId, defaultPoolId) || other.defaultPoolId == defaultPoolId)&&(identical(other.messageDisplayStyle, messageDisplayStyle) || other.messageDisplayStyle == messageDisplayStyle)&&(identical(other.themeMode, themeMode) || other.themeMode == themeMode)&&(identical(other.useMaterial3, useMaterial3) || other.useMaterial3 == useMaterial3)&&(identical(other.disableAnimation, disableAnimation) || other.disableAnimation == disableAnimation)&&(identical(other.fabPosition, fabPosition) || other.fabPosition == fabPosition)&&(identical(other.groupedChatList, groupedChatList) || other.groupedChatList == groupedChatList)); } @override -int get hashCode => Object.hashAll([runtimeType,autoTranslate,dataSavingMode,soundEffects,aprilFoolFeatures,enterToSend,appBarTransparent,showBackgroundImage,customFonts,appColorScheme,customColors,windowSize,windowOpacity,cardTransparency,defaultPoolId,messageDisplayStyle,themeMode,useMaterial3,disableAnimation,fabPosition,groupedChatList]); +int get hashCode => Object.hashAll([runtimeType,dataSavingMode,soundEffects,festivalFeatures,enterToSend,appBarTransparent,showBackgroundImage,customFonts,appColorScheme,customColors,windowSize,windowOpacity,cardTransparency,defaultPoolId,messageDisplayStyle,themeMode,useMaterial3,disableAnimation,fabPosition,groupedChatList]); @override String toString() { - return 'AppSettings(autoTranslate: $autoTranslate, dataSavingMode: $dataSavingMode, soundEffects: $soundEffects, aprilFoolFeatures: $aprilFoolFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, showBackgroundImage: $showBackgroundImage, customFonts: $customFonts, appColorScheme: $appColorScheme, customColors: $customColors, windowSize: $windowSize, windowOpacity: $windowOpacity, cardTransparency: $cardTransparency, defaultPoolId: $defaultPoolId, messageDisplayStyle: $messageDisplayStyle, themeMode: $themeMode, useMaterial3: $useMaterial3, disableAnimation: $disableAnimation, fabPosition: $fabPosition, groupedChatList: $groupedChatList)'; + return 'AppSettings(dataSavingMode: $dataSavingMode, soundEffects: $soundEffects, festivalFeatures: $festivalFeatures, enterToSend: $enterToSend, appBarTransparent: $appBarTransparent, showBackgroundImage: $showBackgroundImage, customFonts: $customFonts, appColorScheme: $appColorScheme, customColors: $customColors, windowSize: $windowSize, windowOpacity: $windowOpacity, cardTransparency: $cardTransparency, defaultPoolId: $defaultPoolId, messageDisplayStyle: $messageDisplayStyle, themeMode: $themeMode, useMaterial3: $useMaterial3, disableAnimation: $disableAnimation, fabPosition: $fabPosition, groupedChatList: $groupedChatList)'; } @@ -565,7 +563,7 @@ abstract mixin class _$AppSettingsCopyWith<$Res> implements $AppSettingsCopyWith factory _$AppSettingsCopyWith(_AppSettings value, $Res Function(_AppSettings) _then) = __$AppSettingsCopyWithImpl; @override @useResult $Res call({ - bool autoTranslate, bool dataSavingMode, bool soundEffects, bool aprilFoolFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation, String fabPosition, bool groupedChatList + bool dataSavingMode, bool soundEffects, bool festivalFeatures, bool enterToSend, bool appBarTransparent, bool showBackgroundImage, String? customFonts, int? appColorScheme, ThemeColors? customColors, Size? windowSize, double windowOpacity, double cardTransparency, String? defaultPoolId, String messageDisplayStyle, String? themeMode, bool useMaterial3, bool disableAnimation, String fabPosition, bool groupedChatList }); @@ -582,12 +580,11 @@ class __$AppSettingsCopyWithImpl<$Res> /// Create a copy of AppSettings /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? autoTranslate = null,Object? dataSavingMode = null,Object? soundEffects = null,Object? aprilFoolFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? showBackgroundImage = null,Object? customFonts = freezed,Object? appColorScheme = freezed,Object? customColors = freezed,Object? windowSize = freezed,Object? windowOpacity = null,Object? cardTransparency = null,Object? defaultPoolId = freezed,Object? messageDisplayStyle = null,Object? themeMode = freezed,Object? useMaterial3 = null,Object? disableAnimation = null,Object? fabPosition = null,Object? groupedChatList = null,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? dataSavingMode = null,Object? soundEffects = null,Object? festivalFeatures = null,Object? enterToSend = null,Object? appBarTransparent = null,Object? showBackgroundImage = null,Object? customFonts = freezed,Object? appColorScheme = freezed,Object? customColors = freezed,Object? windowSize = freezed,Object? windowOpacity = null,Object? cardTransparency = null,Object? defaultPoolId = freezed,Object? messageDisplayStyle = null,Object? themeMode = freezed,Object? useMaterial3 = null,Object? disableAnimation = null,Object? fabPosition = null,Object? groupedChatList = null,}) { return _then(_AppSettings( -autoTranslate: null == autoTranslate ? _self.autoTranslate : autoTranslate // ignore: cast_nullable_to_non_nullable -as bool,dataSavingMode: null == dataSavingMode ? _self.dataSavingMode : dataSavingMode // ignore: cast_nullable_to_non_nullable +dataSavingMode: null == dataSavingMode ? _self.dataSavingMode : dataSavingMode // ignore: cast_nullable_to_non_nullable as bool,soundEffects: null == soundEffects ? _self.soundEffects : soundEffects // ignore: cast_nullable_to_non_nullable -as bool,aprilFoolFeatures: null == aprilFoolFeatures ? _self.aprilFoolFeatures : aprilFoolFeatures // ignore: cast_nullable_to_non_nullable +as bool,festivalFeatures: null == festivalFeatures ? _self.festivalFeatures : festivalFeatures // ignore: cast_nullable_to_non_nullable as bool,enterToSend: null == enterToSend ? _self.enterToSend : enterToSend // ignore: cast_nullable_to_non_nullable as bool,appBarTransparent: null == appBarTransparent ? _self.appBarTransparent : appBarTransparent // ignore: cast_nullable_to_non_nullable as bool,showBackgroundImage: null == showBackgroundImage ? _self.showBackgroundImage : showBackgroundImage // ignore: cast_nullable_to_non_nullable diff --git a/lib/pods/config.g.dart b/lib/pods/config.g.dart index 8e4a153f..f562a5e7 100644 --- a/lib/pods/config.g.dart +++ b/lib/pods/config.g.dart @@ -65,7 +65,7 @@ final class AppSettingsNotifierProvider } String _$appSettingsNotifierHash() => - r'46ac63d6febb9a13f414faa17feb1ac4c1e22c60'; + r'bc9ce5dffe89be2333267e920a6d85c8b45aaeef'; abstract class _$AppSettingsNotifier extends $Notifier { AppSettings build(); diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 11a41898..9b95cd18 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -722,20 +722,6 @@ class SettingsScreen extends HookConsumerWidget { ]; final behaviorSettings = [ - ListTile( - minLeadingWidth: 48, - title: Text('settingsAutoTranslate').tr(), - contentPadding: const EdgeInsets.only(left: 24, right: 17), - leading: const Icon(Symbols.translate), - trailing: Switch( - value: settings.autoTranslate, - onChanged: (value) { - ref.read(appSettingsProvider.notifier).setAutoTranslate(value); - }, - ), - ), - - // Sound effects settings ListTile( minLeadingWidth: 48, title: Text('settingsSoundEffects').tr(), @@ -752,13 +738,13 @@ class SettingsScreen extends HookConsumerWidget { // April Fool features settings ListTile( minLeadingWidth: 48, - title: Text('settingsAprilFoolFeatures').tr(), + title: Text('settingsFestivalFeatures').tr(), contentPadding: const EdgeInsets.only(left: 24, right: 17), leading: const Icon(Symbols.celebration), trailing: Switch( - value: settings.aprilFoolFeatures, + value: settings.festivalFeatures, onChanged: (value) { - ref.read(appSettingsProvider.notifier).setAprilFoolFeatures(value); + ref.read(appSettingsProvider.notifier).setFeativalFeatures(value); }, ), ), diff --git a/lib/widgets/app_wrapper.dart b/lib/widgets/app_wrapper.dart index a793a602..6d782906 100644 --- a/lib/widgets/app_wrapper.dart +++ b/lib/widgets/app_wrapper.dart @@ -1,8 +1,8 @@ -import 'dart:async'; import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:protocol_handler/protocol_handler.dart'; import 'package:island/pods/activity/activity_rpc.dart'; import 'package:island/pods/config.dart'; @@ -21,140 +21,145 @@ import 'package:island/widgets/post/compose_sheet.dart'; import 'package:island/screens/notification.dart'; import 'package:island/screens/thought/think_sheet.dart'; import 'package:island/services/event_bus.dart'; +import 'package:snow_fall_animation/snow_fall_animation.dart'; import 'package:tray_manager/tray_manager.dart'; import 'package:window_manager/window_manager.dart'; -class AppWrapper extends ConsumerStatefulWidget { +class AppWrapper extends HookConsumerWidget { final Widget child; const AppWrapper({super.key, required this.child}); @override - ConsumerState createState() => _AppWrapperState(); -} + Widget build(BuildContext context, WidgetRef ref) { + final networkStateShowing = useState(false); + final wsNotifier = ref.watch(websocketStateProvider.notifier); + final websocketState = ref.watch(websocketStateProvider); + final showSnow = useState(false); + final isSnowGone = useState(false); -class _AppWrapperState extends ConsumerState - with ProtocolListener, TrayListener { - StreamSubscription? ntySubs; - bool networkStateShowing = false; - - StreamSubscription? composeSheetSubs; - StreamSubscription? notificationSheetSubs; - StreamSubscription? thoughtSheetSubs; - - @override - void initState() { - super.initState(); - protocolHandler.addListener(this); - Future(() async { - if (mounted) ntySubs = setupNotificationListener(context, ref); + // Handle network status modal + if (websocketState == WebSocketState.duplicateDevice() && + !networkStateShowing.value) { + networkStateShowing.value = true; + WidgetsBinding.instance.addPostFrameCallback((_) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + isDismissible: false, + builder: (context) => + NetworkStatusSheet(onReconnect: () => wsNotifier.connect()), + ).then((_) => networkStateShowing.value = false); + }); + } + // Initialize services and listeners + useEffect(() { + final ntySubs = setupNotificationListener(context, ref); final sharingService = SharingIntentService(); - if (mounted) sharingService.initialize(context); - if (mounted) UpdateService().checkForUpdates(context); + sharingService.initialize(context); + UpdateService().checkForUpdates(context); - TrayService.instance.initialize(this); + final trayService = TrayService.instance; + trayService.initialize( + _TrayListenerImpl( + onTrayIconMouseDown: () => windowManager.show(), + onTrayIconRightMouseUp: () => trayManager.popUpContextMenu(), + onTrayMenuItemClick: (menuItem) => trayService.handleAction(menuItem), + ), + ); ref.read(rpcServerStateProvider.notifier).start(); ref.read(webAuthServerStateProvider.notifier).start(); // Listen to special action events - composeSheetSubs = eventBus.on().listen((event) { - if (mounted) { - _showComposeSheet(); - } - }); - - notificationSheetSubs = eventBus.on().listen(( + final composeSheetSubs = eventBus.on().listen(( event, ) { - if (mounted) { - _showNotificationSheet(); + if (context.mounted) _showComposeSheet(context); + }); + + final notificationSheetSubs = eventBus + .on() + .listen((event) { + if (context.mounted) _showNotificationSheet(context); + }); + + final thoughtSheetSubs = eventBus.on().listen(( + event, + ) { + if (context.mounted) _showThoughtSheet(context, event); + }); + + // Protocol handler listener + final protocolListener = _ProtocolListenerImpl( + onProtocolUrlReceived: (url) => + _handleDeepLink(Uri.parse(url), ref, context), + ); + protocolHandler.addListener(protocolListener); + + // Handle initial URL + protocolHandler.getInitialUrl().then((initialUrl) { + if (initialUrl != null) { + WidgetsBinding.instance.addPostFrameCallback((_) { + _handleDeepLink(Uri.parse(initialUrl), ref, context); + }); } }); - thoughtSheetSubs = eventBus.on().listen((event) { - if (mounted) { - _showThoughtSheet(event); - } + return () { + protocolHandler.removeListener(protocolListener); + ref.read(rpcServerProvider).stop(); + trayService.dispose( + _TrayListenerImpl( + onTrayIconMouseDown: () => {}, + onTrayIconRightMouseUp: () => {}, + onTrayMenuItemClick: (menuItem) => {}, + ), + ); + ntySubs?.cancel(); + composeSheetSubs.cancel(); + notificationSheetSubs.cancel(); + thoughtSheetSubs.cancel(); + }; + }, []); + + final settings = ref.watch(appSettingsProvider); + + final now = DateTime.now(); + final doesShowSnow = + settings.festivalFeatures && + now.month == 12 && + (now.day >= 22 && now.day <= 28); + if (doesShowSnow && !isSnowGone.value) { + showSnow.value = true; + isSnowGone.value = true; + Future.delayed(const Duration(seconds: 10), () { + showSnow.value = false; }); - - final initialUrl = await protocolHandler.getInitialUrl(); - if (initialUrl != null && mounted) { - WidgetsBinding.instance.addPostFrameCallback((_) { - _handleDeepLink(Uri.parse(initialUrl), ref); - }); - } - }); - } - - @override - void dispose() { - protocolHandler.removeListener(this); - ref.read(rpcServerProvider).stop(); - TrayService.instance.dispose(this); - ntySubs?.cancel(); - composeSheetSubs?.cancel(); - notificationSheetSubs?.cancel(); - thoughtSheetSubs?.cancel(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - final wsNotifier = ref.watch(websocketStateProvider.notifier); - final websocketState = ref.watch(websocketStateProvider); - - if (websocketState == WebSocketState.duplicateDevice()) { - if (!networkStateShowing) { - WidgetsBinding.instance.addPostFrameCallback((_) { - setState(() => networkStateShowing = true); - showModalBottomSheet( - context: context, - isScrollControlled: true, - isDismissible: false, - builder: (context) => - NetworkStatusSheet(onReconnect: () => wsNotifier.connect()), - ).then((_) => setState(() => networkStateShowing = false)); - }); - } } - return TourTriggerWidget(key: UniqueKey(), child: widget.child); + return TourTriggerWidget( + key: UniqueKey(), + child: Stack( + children: [ + child, + if (showSnow.value) + IgnorePointer( + child: SnowFallAnimation( + key: const Key("app_snow_animation"), + config: SnowfallConfig(numberOfSnowflakes: 50, speed: 1.0), + ), + ), + ], + ), + ); } - @override - void onProtocolUrlReceived(String url) { - _handleDeepLink(Uri.parse(url), ref); - } - - void _trayIconPrimaryAction() { - windowManager.show(); - } - - void _trayIconSecondaryAction() { - trayManager.popUpContextMenu(); - } - - @override - void onTrayIconMouseUp() { - _trayIconPrimaryAction(); - } - - @override - void onTrayIconRightMouseDown() { - _trayIconSecondaryAction(); - } - - @override - void onTrayMenuItemClick(MenuItem menuItem) { - TrayService.instance.handleAction(menuItem); - } - - void _showComposeSheet() { + void _showComposeSheet(BuildContext context) { PostComposeSheet.show(context); } - void _showNotificationSheet() { + void _showNotificationSheet(BuildContext context) { showModalBottomSheet( context: context, isScrollControlled: true, @@ -163,7 +168,7 @@ class _AppWrapperState extends ConsumerState ); } - void _showThoughtSheet(ShowThoughtSheetEvent event) { + void _showThoughtSheet(BuildContext context, ShowThoughtSheetEvent event) { ThoughtSheet.show( context, initialMessage: event.initialMessage, @@ -172,7 +177,7 @@ class _AppWrapperState extends ConsumerState ); } - void _handleDeepLink(Uri uri, WidgetRef ref) async { + void _handleDeepLink(Uri uri, WidgetRef ref, BuildContext context) async { String path = '/${uri.host}${uri.path}'; // Special handling for OIDC auth callback @@ -182,9 +187,7 @@ class _AppWrapperState extends ConsumerState ref.invalidate(tokenProvider); // Do post login tasks - if (mounted) { - await performPostLogin(context, ref); - } + await performPostLogin(context, ref); if (!kIsWeb && (Platform.isWindows || Platform.isLinux || Platform.isMacOS)) { @@ -217,3 +220,42 @@ class _AppWrapperState extends ConsumerState } } } + +class _TrayListenerImpl implements TrayListener { + final VoidCallback _primaryAction; + final VoidCallback _secondaryAction; + final void Function(MenuItem) _onTrayMenuItemClick; + + _TrayListenerImpl({ + required VoidCallback onTrayIconMouseDown, + required VoidCallback onTrayIconRightMouseUp, + required void Function(MenuItem) onTrayMenuItemClick, + }) : _primaryAction = onTrayIconMouseDown, + _secondaryAction = onTrayIconRightMouseUp, + _onTrayMenuItemClick = onTrayMenuItemClick; + + @override + void onTrayIconMouseDown() => _primaryAction(); + + @override + void onTrayIconRightMouseUp() => _secondaryAction(); + + @override + void onTrayIconMouseUp() => _primaryAction(); + + @override + void onTrayIconRightMouseDown() => _secondaryAction(); + + @override + void onTrayMenuItemClick(MenuItem menuItem) => _onTrayMenuItemClick(menuItem); +} + +class _ProtocolListenerImpl implements ProtocolListener { + final void Function(String) _onProtocolUrlReceived; + + _ProtocolListenerImpl({required void Function(String) onProtocolUrlReceived}) + : _onProtocolUrlReceived = onProtocolUrlReceived; + + @override + void onProtocolUrlReceived(String url) => _onProtocolUrlReceived(url); +}