Skip to content

Instantly share code, notes, and snippets.

@proteye
Forked from PlugFox/inherited_model_sample.dart
Created August 28, 2024 16:40
Show Gist options
  • Save proteye/9b0bff9aa569666ea356b6469bd3d7e4 to your computer and use it in GitHub Desktop.
Save proteye/9b0bff9aa569666ea356b6469bd3d7e4 to your computer and use it in GitHub Desktop.
SettingsScope with InheritedModel
/*
* 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