Last active
August 28, 2024 16:40
-
-
Save PlugFox/320d051c5a393f56f60c3cf080d6171a to your computer and use it in GitHub Desktop.
SettingsScope with InheritedModel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* https://gist.github.com/PlugFox/320d051c5a393f56f60c3cf080d6171a | |
* https://dartpad.dev/320d051c5a393f56f60c3cf080d6171a?null_safety=true | |
*/ | |
import 'package:flutter/widgets.dart'; | |
@immutable | |
class SettingsScope extends StatefulWidget { | |
final Widget child; | |
const SettingsScope({ | |
required this.child, | |
Key? key, | |
}) : super(key: key); | |
static SettingsBLoC _blocOf(BuildContext context) => _InheritedSettings.stateOf(context).settingsBLoC; | |
/// Обновить настройки приложения | |
static void updateOf(BuildContext context, {required UserSettings settings}) => _blocOf(context).add( | |
SettingsEvent.update( | |
Provider.of<UserEntity>( | |
context, | |
listen: false, | |
), | |
settings, | |
), | |
); | |
/// Получить текущие настройки приложения | |
static UserSettings settingsOf(BuildContext context, {bool listen = false}) => | |
_InheritedSettings.of(context, listen: listen).settings; | |
/// Получить и подписаться на текущую локаль приложения | |
static String localeOf(BuildContext context) => _InheritedSettings.aspectOf(context, 'locale').locale; | |
/// Получить и подписаться на текущую тему приложения | |
static String themeOf(BuildContext context) => _InheritedSettings.aspectOf(context, 'theme').theme; | |
@override | |
State<StatefulWidget> createState() => _SettingsScopeState(); | |
} | |
class _SettingsScopeState extends State<SettingsScope> { | |
UserEntity? _lastUserSettings; | |
late SettingsBLoC settingsBLoC; | |
@override | |
void initState() { | |
super.initState(); | |
settingsBLoC = SettingsBLoC( | |
repository: Provider.of<RepositoryStore>(context, listen: false).settingsRepository, | |
); | |
} | |
@override | |
void didChangeDependencies() { | |
super.didChangeDependencies(); | |
final user = Provider.of<UserEntity>(context, listen: true); | |
if (_lastUserSettings != user) { | |
_lastUserSettings = user; | |
settingsBLoC.add(SettingsEvent.getFromServer(user)); | |
} | |
} | |
@override | |
void dispose() { | |
settingsBLoC.close(); | |
super.dispose(); | |
} | |
@override | |
Widget build(BuildContext context) => BlocBuilder<SettingsBLoC, SettingsState>( | |
bloc: settingsBLoC, | |
builder: (context, state) => _InheritedSettings( | |
state: this, | |
settings: state.settings, | |
child: widget.child, | |
), | |
); | |
} | |
class _InheritedSettings extends InheritedModel<String> { | |
final _SettingsScopeState state; | |
final UserSettings settings; | |
const _InheritedSettings({ | |
required this.state, | |
required this.settings, | |
required Widget child, | |
Key? key, | |
}) : super(child: child, key: key); | |
@override | |
bool updateShouldNotify(covariant _InheritedSettings oldWidget) => oldWidget.settings != settings; | |
@override | |
bool updateShouldNotifyDependent(covariant _InheritedSettings oldWidget, Set<String> dependencies) => | |
oldWidget.settings != settings && | |
((dependencies.contains('locale') && oldWidget.settings.locale != settings.locale) || | |
(dependencies.contains('theme') && oldWidget.settings.theme != settings.theme)); | |
static _InheritedSettings of(BuildContext context, {bool listen = false}) => listen | |
? context.dependOnInheritedWidgetOfExactType<_InheritedSettings>()! | |
: (context.getElementForInheritedWidgetOfExactType<_InheritedSettings>()!.widget as _InheritedSettings); | |
static UserSettings aspectOf(BuildContext context, String aspect) => | |
InheritedModel.inheritFrom<_InheritedSettings>(context, aspect: aspect)!.settings; | |
static _SettingsScopeState stateOf(BuildContext context) => of(context, listen: false).state; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment