| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 | import 'dart:async';import 'package:app_flowy/user/application/user_settings_service.dart';import 'package:equatable/equatable.dart';import 'package:flowy_infra/theme.dart';import 'package:flowy_sdk/log.dart';import 'package:flowy_sdk/protobuf/flowy-user/user_setting.pb.dart';import 'package:flutter/material.dart';import 'package:easy_localization/easy_localization.dart';/// [AppearanceSetting] is used to modify the appear setting of AppFlowy application. Including the [Locale], [AppTheme], etc.class AppearanceSetting extends ChangeNotifier with EquatableMixin {  final AppearanceSettingsPB _setting;  AppTheme _theme;  Locale _locale;  Timer? _debounceSaveOperation;  AppearanceSetting(AppearanceSettingsPB setting)      : _setting = setting,        _theme = AppTheme.fromName(name: setting.theme),        _locale = Locale(          setting.locale.languageCode,          setting.locale.countryCode,        );  /// Returns the current [AppTheme]  AppTheme get theme => _theme;  /// Returns the current [Locale]  Locale get locale => _locale;  /// Updates the current theme and notify the listeners the theme was changed.  /// Do nothing if the passed in themeType equal to the current theme type.  ///  void setTheme(ThemeType themeType) {    if (_theme.ty == themeType) {      return;    }    _theme = AppTheme.fromType(themeType);    _setting.theme = themeTypeToString(themeType);    _saveAppearSetting();    notifyListeners();  }  /// Updates the current locale and notify the listeners the locale was changed  /// Fallback to [en] locale If the newLocale is not supported.  ///  void setLocale(BuildContext context, Locale newLocale) {    if (!context.supportedLocales.contains(newLocale)) {      Log.warn("Unsupported locale: $newLocale, Fallback to locale: en");      newLocale = const Locale('en');    }    context.setLocale(newLocale);    if (_locale != newLocale) {      _locale = newLocale;      _setting.locale.languageCode = _locale.languageCode;      _setting.locale.countryCode = _locale.countryCode ?? "";      _saveAppearSetting();      notifyListeners();    }  }  /// Saves key/value setting to disk.  /// Removes the key if the passed in value is null  void setKeyValue(String key, String? value) {    if (key.isEmpty) {      Log.warn("The key should not be empty");      return;    }    if (value == null) {      _setting.settingKeyValue.remove(key);    }    if (_setting.settingKeyValue[key] != value) {      if (value == null) {        _setting.settingKeyValue.remove(key);      } else {        _setting.settingKeyValue[key] = value;      }      _saveAppearSetting();      notifyListeners();    }  }  /// Called when the application launch.  /// Uses the device locale when open the application for the first time  void readLocaleWhenAppLaunch(BuildContext context) {    if (_setting.resetToDefault) {      _setting.resetToDefault = false;      _saveAppearSetting();      setLocale(context, context.deviceLocale);      return;    }    setLocale(context, _locale);  }  Future<void> _saveAppearSetting() async {    _debounceSaveOperation?.cancel();    _debounceSaveOperation = Timer(      const Duration(seconds: 1),      () {        SettingsFFIService().setAppearanceSetting(_setting).then((result) {          result.fold((l) => null, (error) => Log.error(error));        });      },    );  }  @override  List<Object> get props {    return [_setting.hashCode];  }}
 |