appearance.dart 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import 'dart:async';
  2. import 'package:app_flowy/user/application/user_settings_service.dart';
  3. import 'package:equatable/equatable.dart';
  4. import 'package:flowy_infra/theme.dart';
  5. import 'package:flowy_sdk/log.dart';
  6. import 'package:flowy_sdk/protobuf/flowy-user/user_setting.pb.dart';
  7. import 'package:flutter/material.dart';
  8. import 'package:easy_localization/easy_localization.dart';
  9. /// [AppearanceSetting] is used to modify the appear setting of AppFlowy application. Including the [Locale], [AppTheme], etc.
  10. class AppearanceSetting extends ChangeNotifier with EquatableMixin {
  11. final AppearanceSettingsPB _setting;
  12. AppTheme _theme;
  13. Locale _locale;
  14. Timer? _debounceSaveOperation;
  15. AppearanceSetting(AppearanceSettingsPB setting)
  16. : _setting = setting,
  17. _theme = AppTheme.fromName(name: setting.theme),
  18. _locale = Locale(
  19. setting.locale.languageCode,
  20. setting.locale.countryCode,
  21. );
  22. /// Returns the current [AppTheme]
  23. AppTheme get theme => _theme;
  24. /// Returns the current [Locale]
  25. Locale get locale => _locale;
  26. /// Updates the current theme and notify the listeners the theme was changed.
  27. /// Do nothing if the passed in themeType equal to the current theme type.
  28. ///
  29. void setTheme(ThemeType themeType) {
  30. if (_theme.ty == themeType) {
  31. return;
  32. }
  33. _theme = AppTheme.fromType(themeType);
  34. _setting.theme = themeTypeToString(themeType);
  35. _saveAppearSetting();
  36. notifyListeners();
  37. }
  38. /// Updates the current locale and notify the listeners the locale was changed
  39. /// Fallback to [en] locale If the newLocale is not supported.
  40. ///
  41. void setLocale(BuildContext context, Locale newLocale) {
  42. if (!context.supportedLocales.contains(newLocale)) {
  43. Log.warn("Unsupported locale: $newLocale, Fallback to locale: en");
  44. newLocale = const Locale('en');
  45. }
  46. context.setLocale(newLocale);
  47. if (_locale != newLocale) {
  48. _locale = newLocale;
  49. _setting.locale.languageCode = _locale.languageCode;
  50. _setting.locale.countryCode = _locale.countryCode ?? "";
  51. _saveAppearSetting();
  52. notifyListeners();
  53. }
  54. }
  55. /// Saves key/value setting to disk.
  56. /// Removes the key if the passed in value is null
  57. void setKeyValue(String key, String? value) {
  58. if (key.isEmpty) {
  59. Log.warn("The key should not be empty");
  60. return;
  61. }
  62. if (value == null) {
  63. _setting.settingKeyValue.remove(key);
  64. }
  65. if (_setting.settingKeyValue[key] != value) {
  66. if (value == null) {
  67. _setting.settingKeyValue.remove(key);
  68. } else {
  69. _setting.settingKeyValue[key] = value;
  70. }
  71. _saveAppearSetting();
  72. notifyListeners();
  73. }
  74. }
  75. /// Called when the application launch.
  76. /// Uses the device locale when open the application for the first time
  77. void readLocaleWhenAppLaunch(BuildContext context) {
  78. if (_setting.resetToDefault) {
  79. _setting.resetToDefault = false;
  80. _saveAppearSetting();
  81. setLocale(context, context.deviceLocale);
  82. return;
  83. }
  84. setLocale(context, _locale);
  85. }
  86. Future<void> _saveAppearSetting() async {
  87. _debounceSaveOperation?.cancel();
  88. _debounceSaveOperation = Timer(
  89. const Duration(seconds: 1),
  90. () {
  91. SettingsFFIService().setAppearanceSetting(_setting).then((result) {
  92. result.fold((l) => null, (error) => Log.error(error));
  93. });
  94. },
  95. );
  96. }
  97. @override
  98. List<Object> get props {
  99. return [_setting.hashCode];
  100. }
  101. }