mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-03-12 05:10:41 +00:00
Removed InheritedModelAspectListener
This commit is contained in:
parent
c01cdc9dce
commit
cc10ed26bd
3 changed files with 55 additions and 100 deletions
|
@ -14,6 +14,7 @@ import 'package:lightmeter/screens/metering/components/camera_container/provider
|
|||
import 'package:lightmeter/screens/metering/components/light_sensor_container/provider_container_light_sensor.dart';
|
||||
import 'package:lightmeter/screens/metering/event_metering.dart';
|
||||
import 'package:lightmeter/screens/metering/state_metering.dart';
|
||||
import 'package:lightmeter/screens/metering/utils/listener_metering_layout_feature.dart';
|
||||
import 'package:lightmeter/utils/inherited_generics.dart';
|
||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
|
||||
|
@ -75,8 +76,8 @@ class _InheritedListeners extends StatelessWidget {
|
|||
onDidChangeDependencies: (value) {
|
||||
context.read<MeteringBloc>().add(EquipmentProfileChangedEvent(value));
|
||||
},
|
||||
child: InheritedModelAspectListener<MeteringScreenLayoutFeature, bool>(
|
||||
aspect: MeteringScreenLayoutFeature.filmPicker,
|
||||
child: MeteringScreenLayoutFeatureListener(
|
||||
feature: MeteringScreenLayoutFeature.filmPicker,
|
||||
onDidChangeDependencies: (value) {
|
||||
if (!value) context.read<MeteringBloc>().add(const FilmChangedEvent(Film.other()));
|
||||
},
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
|
||||
import 'package:lightmeter/providers/user_preferences_provider.dart';
|
||||
|
||||
/// Listening to multiple dependencies at the same time causes firing an event for all dependencies
|
||||
/// even though some of them didn't change:
|
||||
/// ```dart
|
||||
/// @override
|
||||
/// void didChangeDependencies() {
|
||||
/// super.didChangeDependencies();
|
||||
/// _bloc.add(EquipmentProfileChangedEvent(EquipmentProfile.of(context)));
|
||||
/// if (!MeteringScreenLayout.featureStatusOf(context, MeteringScreenLayoutFeature.filmPicker)) {
|
||||
/// _bloc.add(const FilmChangedEvent(Film.other()));
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// To overcome this issue I've decided to create a generic listener,
|
||||
/// that will listen to each dependency separately.
|
||||
class MeteringScreenLayoutFeatureListener extends StatefulWidget {
|
||||
final MeteringScreenLayoutFeature feature;
|
||||
final ValueChanged<bool> onDidChangeDependencies;
|
||||
final Widget child;
|
||||
|
||||
const MeteringScreenLayoutFeatureListener({
|
||||
required this.feature,
|
||||
required this.onDidChangeDependencies,
|
||||
required this.child,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<MeteringScreenLayoutFeatureListener> createState() =>
|
||||
_MeteringScreenLayoutFeatureListenerState();
|
||||
}
|
||||
|
||||
class _MeteringScreenLayoutFeatureListenerState extends State<MeteringScreenLayoutFeatureListener> {
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
widget.onDidChangeDependencies(
|
||||
UserPreferencesProvider.meteringScreenFeatureOf(
|
||||
context,
|
||||
widget.feature,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return widget.child;
|
||||
}
|
||||
}
|
|
@ -71,101 +71,3 @@ extension InheritedWidgetBaseContext on BuildContext {
|
|||
return InheritedWidgetBase.of<T>(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// Listening to multiple dependencies at the same time causes firing an event for all dependencies
|
||||
/// even though some of them didn't change:
|
||||
/// ```dart
|
||||
/// @override
|
||||
/// void didChangeDependencies() {
|
||||
/// super.didChangeDependencies();
|
||||
/// _bloc.add(EquipmentProfileChangedEvent(EquipmentProfile.of(context)));
|
||||
/// if (!MeteringScreenLayout.featureStatusOf(context, MeteringScreenLayoutFeature.filmPicker)) {
|
||||
/// _bloc.add(const FilmChangedEvent(Film.other()));
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
/// To overcome this issue I've decided to create a generic listener,
|
||||
/// that will listen to each dependency separately.
|
||||
class InheritedModelAspectListener<A extends Object, T> extends StatefulWidget {
|
||||
final A aspect;
|
||||
final ValueChanged<T> onDidChangeDependencies;
|
||||
final Widget child;
|
||||
|
||||
const InheritedModelAspectListener({
|
||||
required this.aspect,
|
||||
required this.onDidChangeDependencies,
|
||||
required this.child,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<InheritedModelAspectListener<A, T>> createState() =>
|
||||
_InheritedModelAspectListenerState<A, T>();
|
||||
}
|
||||
|
||||
class _InheritedModelAspectListenerState<A extends Object, T>
|
||||
extends State<InheritedModelAspectListener<A, T>> {
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
widget.onDidChangeDependencies(context.listenModelFeature<A, T>(widget.aspect));
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return widget.child;
|
||||
}
|
||||
}
|
||||
|
||||
class InheritedModelBase<A, T> extends InheritedModel<A> {
|
||||
final Map<A, T> data;
|
||||
|
||||
const InheritedModelBase({
|
||||
required this.data,
|
||||
required super.child,
|
||||
super.key,
|
||||
});
|
||||
|
||||
static Map<A, T> of<A, T>(BuildContext context, {bool listen = true}) {
|
||||
if (listen) {
|
||||
return context.dependOnInheritedWidgetOfExactType<InheritedModelBase<A, T>>()!.data;
|
||||
} else {
|
||||
return context.findAncestorWidgetOfExactType<InheritedModelBase<A, T>>()!.data;
|
||||
}
|
||||
}
|
||||
|
||||
static T featureOf<A extends Object, T>(BuildContext context, A aspect) {
|
||||
return InheritedModel.inheritFrom<InheritedModelBase<A, T>>(context, aspect: aspect)!
|
||||
.data[aspect]!;
|
||||
}
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(InheritedModelBase oldWidget) => true;
|
||||
|
||||
@override
|
||||
bool updateShouldNotifyDependent(
|
||||
InheritedModelBase<A, T> oldWidget,
|
||||
Set<A> dependencies,
|
||||
) {
|
||||
for (final dependecy in dependencies) {
|
||||
if (oldWidget.data[dependecy] != data[dependecy]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
extension InheritedModelBaseContext on BuildContext {
|
||||
Map<A, T> getModel<A, T>() {
|
||||
return InheritedModelBase.of<A, T>(this, listen: false);
|
||||
}
|
||||
|
||||
Map<A, T> listenModel<A, T>() {
|
||||
return InheritedModelBase.of<A, T>(this);
|
||||
}
|
||||
|
||||
T listenModelFeature<A extends Object, T>(A aspect) {
|
||||
return InheritedModelBase.featureOf<A, T>(this, aspect);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue