appearance.dart 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import 'dart:async';
  2. import 'package:app_flowy/user/application/user_settings_service.dart';
  3. import 'package:flowy_infra/theme.dart';
  4. import 'package:flowy_sdk/log.dart';
  5. import 'package:flowy_sdk/protobuf/flowy-user/user_setting.pb.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:easy_localization/easy_localization.dart';
  8. import 'package:flutter_bloc/flutter_bloc.dart';
  9. import 'package:freezed_annotation/freezed_annotation.dart';
  10. part 'appearance.freezed.dart';
  11. /// [AppearanceSettingsCubit] is used to modify the appear setting of AppFlowy application. Includes the [Locale] and [AppTheme].
  12. class AppearanceSettingsCubit extends Cubit<AppearanceSettingsState> {
  13. final AppearanceSettingsPB _setting;
  14. AppearanceSettingsCubit(AppearanceSettingsPB setting)
  15. : _setting = setting,
  16. super(AppearanceSettingsState.initial(
  17. setting.theme,
  18. setting.font,
  19. setting.monospaceFont,
  20. setting.locale,
  21. ));
  22. /// Updates the current theme and notify the listeners the theme was changed.
  23. /// Do nothing if the passed in themeType equal to the current theme type.
  24. void setTheme(Brightness brightness) {
  25. if (state.theme.brightness == brightness) {
  26. return;
  27. }
  28. _setting.theme = themeTypeToString(brightness);
  29. _saveAppearanceSettings();
  30. emit(state.copyWith(
  31. theme: AppTheme.fromName(
  32. themeName: _setting.theme,
  33. font: state.theme.font,
  34. monospaceFont: state.theme.monospaceFont,
  35. ),
  36. ));
  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. void setLocale(BuildContext context, Locale newLocale) {
  41. if (!context.supportedLocales.contains(newLocale)) {
  42. Log.warn("Unsupported locale: $newLocale, Fallback to locale: en");
  43. newLocale = const Locale('en');
  44. }
  45. context.setLocale(newLocale);
  46. if (state.locale != newLocale) {
  47. _setting.locale.languageCode = newLocale.languageCode;
  48. _setting.locale.countryCode = newLocale.countryCode ?? "";
  49. _saveAppearanceSettings();
  50. emit(state.copyWith(locale: newLocale));
  51. }
  52. }
  53. /// Saves key/value setting to disk.
  54. /// Removes the key if the passed in value is null
  55. void setKeyValue(String key, String? value) {
  56. if (key.isEmpty) {
  57. Log.warn("The key should not be empty");
  58. return;
  59. }
  60. if (value == null) {
  61. _setting.settingKeyValue.remove(key);
  62. }
  63. if (_setting.settingKeyValue[key] != value) {
  64. if (value == null) {
  65. _setting.settingKeyValue.remove(key);
  66. } else {
  67. _setting.settingKeyValue[key] = value;
  68. }
  69. }
  70. _saveAppearanceSettings();
  71. }
  72. String? getValue(String key) {
  73. if (key.isEmpty) {
  74. Log.warn("The key should not be empty");
  75. return null;
  76. }
  77. return _setting.settingKeyValue[key];
  78. }
  79. /// Called when the application launch.
  80. /// Uses the device locale when open the application for the first time
  81. void readLocaleWhenAppLaunch(BuildContext context) {
  82. if (_setting.resetToDefault) {
  83. _setting.resetToDefault = false;
  84. _saveAppearanceSettings();
  85. setLocale(context, context.deviceLocale);
  86. return;
  87. }
  88. setLocale(context, state.locale);
  89. }
  90. Future<void> _saveAppearanceSettings() async {
  91. SettingsFFIService().setAppearanceSetting(_setting).then((result) {
  92. result.fold(
  93. (l) => null,
  94. (error) => Log.error(error),
  95. );
  96. });
  97. }
  98. }
  99. @freezed
  100. class AppearanceSettingsState with _$AppearanceSettingsState {
  101. const factory AppearanceSettingsState({
  102. required AppTheme theme,
  103. required Locale locale,
  104. }) = _AppearanceSettingsState;
  105. factory AppearanceSettingsState.initial(
  106. String themeName,
  107. String font,
  108. String monospaceFont,
  109. LocaleSettingsPB locale,
  110. ) =>
  111. AppearanceSettingsState(
  112. theme: AppTheme.fromName(
  113. themeName: themeName,
  114. font: font,
  115. monospaceFont: monospaceFont,
  116. ),
  117. locale: Locale(locale.languageCode, locale.countryCode),
  118. );
  119. }