diff --git a/lib/providers.dart b/lib/providers.dart index d7907ab..72b7131 100644 --- a/lib/providers.dart +++ b/lib/providers.dart @@ -9,10 +9,10 @@ import 'package:lightmeter/environment.dart'; import 'package:lightmeter/providers/equipment_profile_provider.dart'; import 'package:lightmeter/providers/ev_source_type_provider.dart'; import 'package:lightmeter/providers/metering_screen_layout_provider.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/providers/stop_type_provider.dart'; import 'package:lightmeter/providers/supported_locale_provider.dart'; import 'package:lightmeter/providers/theme_provider.dart'; -import 'package:lightmeter/utils/inherited_generics.dart'; import 'package:platform/platform.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -31,34 +31,22 @@ class LightmeterProviders extends StatelessWidget { ]), builder: (_, snapshot) { if (snapshot.data != null) { - return InheritedWidgetBase( - data: env.copyWith(hasLightSensor: snapshot.data![1] as bool), - child: InheritedWidgetBase( - data: UserPreferencesService(snapshot.data![0] as SharedPreferences), - child: InheritedWidgetBase( - data: const LightSensorService(LocalPlatform()), - child: InheritedWidgetBase( - data: const CaffeineService(), - child: InheritedWidgetBase( - data: const HapticsService(), - child: InheritedWidgetBase( - data: const VolumeEventsService(LocalPlatform()), - child: InheritedWidgetBase( - data: const PermissionsService(), - child: MeteringScreenLayoutProvider( - child: StopTypeProvider( - child: EquipmentProfileProvider( - child: EvSourceTypeProvider( - child: SupportedLocaleProvider( - child: ThemeProvider( - child: Builder( - builder: (context) => builder(context, true), - ), - ), - ), - ), - ), - ), + return ServiceProviders( + caffeineService: const CaffeineService(), + environment: env.copyWith(hasLightSensor: snapshot.data![1] as bool), + hapticsService: const HapticsService(), + lightSensorService: const LightSensorService(LocalPlatform()), + permissionsService: const PermissionsService(), + userPreferencesService: UserPreferencesService(snapshot.data![0] as SharedPreferences), + volumeEventsService: const VolumeEventsService(LocalPlatform()), + child: MeteringScreenLayoutProvider( + child: StopTypeProvider( + child: EquipmentProfileProvider( + child: EvSourceTypeProvider( + child: SupportedLocaleProvider( + child: ThemeProvider( + child: Builder( + builder: (context) => builder(context, true), ), ), ), diff --git a/lib/providers/equipment_profile_provider.dart b/lib/providers/equipment_profile_provider.dart index 85c9377..07cacc7 100644 --- a/lib/providers/equipment_profile_provider.dart +++ b/lib/providers/equipment_profile_provider.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:lightmeter/data/shared_prefs_service.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/utils/inherited_generics.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; import 'package:uuid/uuid.dart'; @@ -35,7 +35,8 @@ class EquipmentProfileProviderState extends State { EquipmentProfile get _selectedProfile => _customProfiles.firstWhere( (e) => e.id == _selectedId, orElse: () { - context.get().selectedEquipmentProfileId = _defaultProfile.id; + ServiceProviders.userPreferencesServiceOf(context).selectedEquipmentProfileId = + _defaultProfile.id; return _defaultProfile; }, ); @@ -43,8 +44,8 @@ class EquipmentProfileProviderState extends State { @override void initState() { super.initState(); - _selectedId = context.get().selectedEquipmentProfileId; - _customProfiles = context.get().equipmentProfiles; + _selectedId = ServiceProviders.userPreferencesServiceOf(context).selectedEquipmentProfileId; + _customProfiles = ServiceProviders.userPreferencesServiceOf(context).equipmentProfiles; } @override @@ -62,7 +63,8 @@ class EquipmentProfileProviderState extends State { setState(() { _selectedId = data.id; }); - context.get().selectedEquipmentProfileId = _selectedProfile.id; + ServiceProviders.userPreferencesServiceOf(context).selectedEquipmentProfileId = + _selectedProfile.id; } /// Creates a default equipment profile @@ -94,7 +96,7 @@ class EquipmentProfileProviderState extends State { } void _refreshSavedProfiles() { - context.get().equipmentProfiles = _customProfiles; + ServiceProviders.userPreferencesServiceOf(context).equipmentProfiles = _customProfiles; setState(() {}); } } diff --git a/lib/providers/ev_source_type_provider.dart b/lib/providers/ev_source_type_provider.dart index aed873b..8042341 100644 --- a/lib/providers/ev_source_type_provider.dart +++ b/lib/providers/ev_source_type_provider.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:lightmeter/data/models/ev_source_type.dart'; -import 'package:lightmeter/data/shared_prefs_service.dart'; -import 'package:lightmeter/environment.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/utils/inherited_generics.dart'; class EvSourceTypeProvider extends StatefulWidget { @@ -23,9 +22,9 @@ class EvSourceTypeProviderState extends State { @override void initState() { super.initState(); - final evSourceType = context.get().evSourceType; + final evSourceType = ServiceProviders.userPreferencesServiceOf(context).evSourceType; valueListenable = ValueNotifier( - evSourceType == EvSourceType.sensor && !context.get().hasLightSensor + evSourceType == EvSourceType.sensor && !ServiceProviders.environmentOf(context).hasLightSensor ? EvSourceType.camera : evSourceType, ); @@ -52,12 +51,12 @@ class EvSourceTypeProviderState extends State { void toggleType() { switch (valueListenable.value) { case EvSourceType.camera: - if (context.get().hasLightSensor) { + if (ServiceProviders.environmentOf(context).hasLightSensor) { valueListenable.value = EvSourceType.sensor; } case EvSourceType.sensor: valueListenable.value = EvSourceType.camera; } - context.get().evSourceType = valueListenable.value; + ServiceProviders.userPreferencesServiceOf(context).evSourceType = valueListenable.value; } } diff --git a/lib/providers/metering_screen_layout_provider.dart b/lib/providers/metering_screen_layout_provider.dart index 405c1a7..2f8e2e4 100644 --- a/lib/providers/metering_screen_layout_provider.dart +++ b/lib/providers/metering_screen_layout_provider.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:lightmeter/data/models/metering_screen_layout_config.dart'; -import 'package:lightmeter/data/shared_prefs_service.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/utils/inherited_generics.dart'; class MeteringScreenLayoutProvider extends StatefulWidget { @@ -18,7 +18,7 @@ class MeteringScreenLayoutProvider extends StatefulWidget { class MeteringScreenLayoutProviderState extends State { late final MeteringScreenLayoutConfig _config = - context.get().meteringScreenLayout; + ServiceProviders.userPreferencesServiceOf(context).meteringScreenLayout; @override Widget build(BuildContext context) { @@ -38,7 +38,7 @@ class MeteringScreenLayoutProviderState extends State().meteringScreenLayout = _config; + ServiceProviders.userPreferencesServiceOf(context).meteringScreenLayout = _config; } } diff --git a/lib/providers/service_providers.dart b/lib/providers/service_providers.dart new file mode 100644 index 0000000..9433321 --- /dev/null +++ b/lib/providers/service_providers.dart @@ -0,0 +1,64 @@ +import 'package:flutter/material.dart'; +import 'package:lightmeter/data/caffeine_service.dart'; +import 'package:lightmeter/data/haptics_service.dart'; +import 'package:lightmeter/data/light_sensor_service.dart'; +import 'package:lightmeter/data/permissions_service.dart'; +import 'package:lightmeter/data/shared_prefs_service.dart'; +import 'package:lightmeter/data/volume_events_service.dart'; +import 'package:lightmeter/environment.dart'; + +class ServiceProviders extends InheritedWidget { + final CaffeineService caffeineService; + final Environment environment; + final HapticsService hapticsService; + final LightSensorService lightSensorService; + final PermissionsService permissionsService; + final UserPreferencesService userPreferencesService; + final VolumeEventsService volumeEventsService; + + const ServiceProviders({ + required this.caffeineService, + required this.environment, + required this.hapticsService, + required this.lightSensorService, + required this.permissionsService, + required this.userPreferencesService, + required this.volumeEventsService, + required super.child, + }); + + static CaffeineService caffeineServiceOf(BuildContext context) { + return ServiceProviders._of(context).caffeineService; + } + + static Environment environmentOf(BuildContext context) { + return ServiceProviders._of(context).environment; + } + + static HapticsService hapticsServiceOf(BuildContext context) { + return ServiceProviders._of(context).hapticsService; + } + + static LightSensorService lightSensorServiceOf(BuildContext context) { + return ServiceProviders._of(context).lightSensorService; + } + + static PermissionsService permissionsServiceOf(BuildContext context) { + return ServiceProviders._of(context).permissionsService; + } + + static UserPreferencesService userPreferencesServiceOf(BuildContext context) { + return ServiceProviders._of(context).userPreferencesService; + } + + static VolumeEventsService volumeEventsServiceOf(BuildContext context) { + return ServiceProviders._of(context).volumeEventsService; + } + + static ServiceProviders _of(BuildContext context) { + return context.findAncestorWidgetOfExactType()!; + } + + @override + bool updateShouldNotify(ServiceProviders oldWidget) => false; +} diff --git a/lib/providers/stop_type_provider.dart b/lib/providers/stop_type_provider.dart index 3b20dd5..80a7e6f 100644 --- a/lib/providers/stop_type_provider.dart +++ b/lib/providers/stop_type_provider.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:lightmeter/data/shared_prefs_service.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/utils/inherited_generics.dart'; import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart'; @@ -22,7 +22,7 @@ class StopTypeProviderState extends State { @override void initState() { super.initState(); - _stopType = context.get().stopType; + _stopType = ServiceProviders.userPreferencesServiceOf(context).stopType; } @override @@ -37,6 +37,6 @@ class StopTypeProviderState extends State { setState(() { _stopType = type; }); - context.get().stopType = type; + ServiceProviders.userPreferencesServiceOf(context).stopType = type; } } diff --git a/lib/providers/supported_locale_provider.dart b/lib/providers/supported_locale_provider.dart index caa7ced..3ca336f 100644 --- a/lib/providers/supported_locale_provider.dart +++ b/lib/providers/supported_locale_provider.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:lightmeter/data/models/supported_locale.dart'; -import 'package:lightmeter/data/shared_prefs_service.dart'; import 'package:lightmeter/generated/l10n.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/utils/inherited_generics.dart'; class SupportedLocaleProvider extends StatefulWidget { @@ -23,7 +23,7 @@ class SupportedLocaleProviderState extends State { @override void initState() { super.initState(); - valueListenable = ValueNotifier(context.get().locale); + valueListenable = ValueNotifier(ServiceProviders.userPreferencesServiceOf(context).locale); } @override @@ -47,7 +47,7 @@ class SupportedLocaleProviderState extends State { void setLocale(SupportedLocale locale) { S.load(Locale(locale.intlName)).then((value) { valueListenable.value = locale; - context.get().locale = locale; + ServiceProviders.userPreferencesServiceOf(context).locale = locale; }); } } diff --git a/lib/providers/theme_provider.dart b/lib/providers/theme_provider.dart index 9773df1..551499c 100644 --- a/lib/providers/theme_provider.dart +++ b/lib/providers/theme_provider.dart @@ -4,6 +4,7 @@ import 'package:flutter/scheduler.dart'; import 'package:lightmeter/data/models/dynamic_colors_state.dart'; import 'package:lightmeter/data/models/theme_type.dart'; import 'package:lightmeter/data/shared_prefs_service.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/utils/inherited_generics.dart'; import 'package:material_color_utilities/material_color_utilities.dart'; @@ -44,7 +45,7 @@ class ThemeProvider extends StatefulWidget { } class ThemeProviderState extends State with WidgetsBindingObserver { - UserPreferencesService get _prefs => context.get(); + UserPreferencesService get _prefs => ServiceProviders.userPreferencesServiceOf(context); late final _themeTypeNotifier = ValueNotifier(_prefs.themeType); late final _dynamicColorNotifier = ValueNotifier(_prefs.dynamicColor); diff --git a/lib/screens/metering/flow_metering.dart b/lib/screens/metering/flow_metering.dart index 1caef02..ef5d05c 100644 --- a/lib/screens/metering/flow_metering.dart +++ b/lib/screens/metering/flow_metering.dart @@ -1,12 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:lightmeter/data/caffeine_service.dart'; -import 'package:lightmeter/data/haptics_service.dart'; -import 'package:lightmeter/data/light_sensor_service.dart'; -import 'package:lightmeter/data/permissions_service.dart'; -import 'package:lightmeter/data/shared_prefs_service.dart'; -import 'package:lightmeter/data/volume_events_service.dart'; import 'package:lightmeter/interactors/metering_interactor.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/screens/metering/bloc_metering.dart'; import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart'; import 'package:lightmeter/screens/metering/components/shared/volume_keys_notifier/notifier_volume_keys.dart'; @@ -25,15 +20,15 @@ class _MeteringFlowState extends State { Widget build(BuildContext context) { return InheritedWidgetBase( data: MeteringInteractor( - context.get(), - context.get(), - context.get(), - context.get(), - context.get(), - context.get(), + ServiceProviders.userPreferencesServiceOf(context), + ServiceProviders.caffeineServiceOf(context), + ServiceProviders.hapticsServiceOf(context), + ServiceProviders.permissionsServiceOf(context), + ServiceProviders.lightSensorServiceOf(context), + ServiceProviders.volumeEventsServiceOf(context), )..initialize(), child: InheritedWidgetBase( - data: VolumeKeysNotifier(context.get()), + data: VolumeKeysNotifier(ServiceProviders.volumeEventsServiceOf(context)), child: MultiBlocProvider( providers: [ BlocProvider(create: (_) => MeteringCommunicationBloc()), diff --git a/lib/screens/metering/screen_metering.dart b/lib/screens/metering/screen_metering.dart index bbfebfc..19099e7 100644 --- a/lib/screens/metering/screen_metering.dart +++ b/lib/screens/metering/screen_metering.dart @@ -6,8 +6,8 @@ import 'package:lightmeter/data/models/ev_source_type.dart'; import 'package:lightmeter/data/models/exposure_pair.dart'; import 'package:lightmeter/data/models/film.dart'; import 'package:lightmeter/data/models/metering_screen_layout_config.dart'; -import 'package:lightmeter/environment.dart'; import 'package:lightmeter/providers/ev_source_type_provider.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/screens/metering/bloc_metering.dart'; import 'package:lightmeter/screens/metering/components/bottom_controls/provider_bottom_controls.dart'; import 'package:lightmeter/screens/metering/components/camera_container/provider_container_camera.dart'; @@ -45,7 +45,7 @@ class MeteringScreen extends StatelessWidget { builder: (context, state) => MeteringBottomControlsProvider( ev: state is MeteringDataState ? state.ev : null, isMetering: state.isMetering, - onSwitchEvSourceType: context.get().hasLightSensor + onSwitchEvSourceType: ServiceProviders.environmentOf(context).hasLightSensor ? EvSourceTypeProvider.of(context).toggleType : null, onMeasure: () => context.read().add(const MeasureEvent()), diff --git a/lib/screens/settings/components/about/components/report_issue/widget_list_tile_report_issue.dart b/lib/screens/settings/components/about/components/report_issue/widget_list_tile_report_issue.dart index 4c477f8..0d66e7b 100644 --- a/lib/screens/settings/components/about/components/report_issue/widget_list_tile_report_issue.dart +++ b/lib/screens/settings/components/about/components/report_issue/widget_list_tile_report_issue.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:lightmeter/environment.dart'; import 'package:lightmeter/generated/l10n.dart'; -import 'package:lightmeter/utils/inherited_generics.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:url_launcher/url_launcher.dart'; class ReportIssueListTile extends StatelessWidget { @@ -14,7 +13,7 @@ class ReportIssueListTile extends StatelessWidget { title: Text(S.of(context).reportIssue), onTap: () { launchUrl( - Uri.parse(context.get().issuesReportUrl), + Uri.parse(ServiceProviders.environmentOf(context).issuesReportUrl), mode: LaunchMode.externalApplication, ); }, diff --git a/lib/screens/settings/components/about/components/source_code/widget_list_tile_source_code.dart b/lib/screens/settings/components/about/components/source_code/widget_list_tile_source_code.dart index 42a73e8..1326887 100644 --- a/lib/screens/settings/components/about/components/source_code/widget_list_tile_source_code.dart +++ b/lib/screens/settings/components/about/components/source_code/widget_list_tile_source_code.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:lightmeter/environment.dart'; import 'package:lightmeter/generated/l10n.dart'; -import 'package:lightmeter/utils/inherited_generics.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:url_launcher/url_launcher.dart'; class SourceCodeListTile extends StatelessWidget { @@ -14,7 +13,7 @@ class SourceCodeListTile extends StatelessWidget { title: Text(S.of(context).sourceCode), onTap: () { launchUrl( - Uri.parse(context.get().sourceCodeUrl), + Uri.parse(ServiceProviders.environmentOf(context).sourceCodeUrl), mode: LaunchMode.externalApplication, ); }, diff --git a/lib/screens/settings/components/about/components/write_email/widget_list_tile_write_email.dart b/lib/screens/settings/components/about/components/write_email/widget_list_tile_write_email.dart index b12d0d4..624da93 100644 --- a/lib/screens/settings/components/about/components/write_email/widget_list_tile_write_email.dart +++ b/lib/screens/settings/components/about/components/write_email/widget_list_tile_write_email.dart @@ -1,8 +1,7 @@ import 'package:clipboard/clipboard.dart'; import 'package:flutter/material.dart'; -import 'package:lightmeter/environment.dart'; import 'package:lightmeter/generated/l10n.dart'; -import 'package:lightmeter/utils/inherited_generics.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:url_launcher/url_launcher.dart'; class WriteEmailListTile extends StatelessWidget { @@ -14,7 +13,7 @@ class WriteEmailListTile extends StatelessWidget { leading: const Icon(Icons.email), title: Text(S.of(context).writeEmail), onTap: () { - final email = context.get().contactEmail; + final email = ServiceProviders.environmentOf(context).contactEmail; final mailToUrl = Uri.parse('mailto:$email?subject=M3 Lightmeter'); canLaunchUrl(mailToUrl).then((canLaunch) { if (canLaunch) { diff --git a/lib/screens/settings/components/metering/components/calibration/components/calibration_dialog/widget_dialog_calibration.dart b/lib/screens/settings/components/metering/components/calibration/components/calibration_dialog/widget_dialog_calibration.dart index 4c91c87..2e5e6cb 100644 --- a/lib/screens/settings/components/metering/components/calibration/components/calibration_dialog/widget_dialog_calibration.dart +++ b/lib/screens/settings/components/metering/components/calibration/components/calibration_dialog/widget_dialog_calibration.dart @@ -1,13 +1,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:lightmeter/environment.dart'; import 'package:lightmeter/generated/l10n.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/res/dimens.dart'; import 'package:lightmeter/screens/settings/components/metering/components/calibration/components/calibration_dialog/bloc_dialog_calibration.dart'; import 'package:lightmeter/screens/settings/components/metering/components/calibration/components/calibration_dialog/event_dialog_calibration.dart'; import 'package:lightmeter/screens/settings/components/metering/components/calibration/components/calibration_dialog/state_dialog_calibration.dart'; import 'package:lightmeter/screens/shared/centered_slider/widget_slider_centered.dart'; -import 'package:lightmeter/utils/inherited_generics.dart'; import 'package:lightmeter/utils/to_string_signed.dart'; class CalibrationDialog extends StatelessWidget { @@ -15,7 +14,7 @@ class CalibrationDialog extends StatelessWidget { @override Widget build(BuildContext context) { - final bool hasLightSensor = context.get().hasLightSensor; + final bool hasLightSensor = ServiceProviders.environmentOf(context).hasLightSensor; return AlertDialog( icon: const Icon(Icons.settings_brightness), titlePadding: Dimens.dialogIconTitlePadding, diff --git a/lib/screens/settings/flow_settings.dart b/lib/screens/settings/flow_settings.dart index 3195c25..9b12ddc 100644 --- a/lib/screens/settings/flow_settings.dart +++ b/lib/screens/settings/flow_settings.dart @@ -1,9 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:lightmeter/data/caffeine_service.dart'; -import 'package:lightmeter/data/haptics_service.dart'; -import 'package:lightmeter/data/shared_prefs_service.dart'; -import 'package:lightmeter/data/volume_events_service.dart'; import 'package:lightmeter/interactors/settings_interactor.dart'; +import 'package:lightmeter/providers/service_providers.dart'; import 'package:lightmeter/screens/settings/screen_settings.dart'; import 'package:lightmeter/utils/inherited_generics.dart'; @@ -14,10 +11,10 @@ class SettingsFlow extends StatelessWidget { Widget build(BuildContext context) { return InheritedWidgetBase( data: SettingsInteractor( - context.get(), - context.get(), - context.get(), - context.get(), + ServiceProviders.userPreferencesServiceOf(context), + ServiceProviders.caffeineServiceOf(context), + ServiceProviders.hapticsServiceOf(context), + ServiceProviders.volumeEventsServiceOf(context), ), child: const SettingsScreen(), );