Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ML-77 Redundant vibrations #76

Merged
merged 11 commits into from
Jun 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 27 additions & 73 deletions lib/application.dart
Original file line number Diff line number Diff line change
@@ -1,26 +1,13 @@
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.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/models/supported_locale.dart';
import 'package:lightmeter/data/permissions_service.dart';
import 'package:lightmeter/data/shared_prefs_service.dart';
import 'package:lightmeter/environment.dart';
import 'package:lightmeter/generated/l10n.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/stop_type_provider.dart';
import 'package:lightmeter/providers/supported_locale_provider.dart';
import 'package:lightmeter/providers/theme_provider.dart';
import 'package:lightmeter/providers.dart';
import 'package:lightmeter/screens/metering/flow_metering.dart';
import 'package:lightmeter/screens/settings/flow_settings.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:lightmeter/utils/inherited_generics.dart';

class Application extends StatelessWidget {
final Environment env;
Expand All @@ -29,65 +16,32 @@ class Application extends StatelessWidget {

@override
Widget build(BuildContext context) {
return FutureBuilder(
future: Future.wait([
SharedPreferences.getInstance(),
if (Platform.isAndroid) const LightSensorService().hasSensor() else Future.value(false),
]),
builder: (_, snapshot) {
if (snapshot.data != null) {
return MultiProvider(
providers: [
Provider.value(value: env.copyWith(hasLightSensor: snapshot.data![1] as bool)),
Provider(
create: (_) => UserPreferencesService(snapshot.data![0] as SharedPreferences),
),
Provider(create: (_) => const CaffeineService()),
Provider(create: (_) => const HapticsService()),
Provider(create: (_) => PermissionsService()),
Provider(create: (_) => const LightSensorService()),
],
child: MeteringScreenLayoutProvider(
child: StopTypeProvider(
child: EquipmentProfileProvider(
child: EvSourceTypeProvider(
child: SupportedLocaleProvider(
child: ThemeProvider(
builder: (context, _) => _AnnotatedRegionWrapper(
child: MaterialApp(
theme: context.watch<ThemeData>(),
locale: Locale(context.watch<SupportedLocale>().intlName),
localizationsDelegates: const [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
builder: (context, child) => MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
child: child!,
),
initialRoute: "metering",
routes: {
"metering": (context) => const MeteringFlow(),
"settings": (context) => const SettingsFlow(),
},
),
),
),
),
),
return LightmeterProviders(
env: env,
builder: (context, ready) => ready
? _AnnotatedRegionWrapper(
child: MaterialApp(
theme: context.listen<ThemeData>(),
locale: Locale(context.listen<SupportedLocale>().intlName),
localizationsDelegates: const [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
builder: (context, child) => MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
child: child!,
),
initialRoute: "metering",
routes: {
"metering": (context) => const MeteringFlow(),
"settings": (context) => const SettingsFlow(),
},
),
),
);
} else if (snapshot.error != null) {
return Center(child: Text(snapshot.error!.toString()));
} else {
return const SizedBox.shrink();
}
},
)
: const SizedBox(),
);
}
}
Expand All @@ -100,7 +54,7 @@ class _AnnotatedRegionWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
final systemIconsBrightness = ThemeData.estimateBrightnessForColor(
context.watch<ThemeData>().colorScheme.onSurface,
context.listen<ThemeData>().colorScheme.onSurface,
);
return AnnotatedRegion(
value: SystemUiOverlayStyle(
Expand Down
2 changes: 2 additions & 0 deletions lib/data/permissions_service.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:permission_handler/permission_handler.dart';

class PermissionsService {
const PermissionsService();

Future<PermissionStatus> checkCameraPermission() async => Permission.camera.status;

Future<PermissionStatus> requestCameraPermission() async => Permission.camera.request();
Expand Down
74 changes: 74 additions & 0 deletions lib/providers.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import 'dart:io';

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/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/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:shared_preferences/shared_preferences.dart';

class LightmeterProviders extends StatelessWidget {
final Environment env;
final Widget Function(BuildContext context, bool ready) builder;

const LightmeterProviders({required this.env, required this.builder, super.key});

@override
Widget build(BuildContext context) {
return FutureBuilder(
future: Future.wait([
SharedPreferences.getInstance(),
if (Platform.isAndroid) const LightSensorService().hasSensor() else Future.value(false),
]),
builder: (_, snapshot) {
if (snapshot.data != null) {
return InheritedWidgetBase<Environment>(
data: env.copyWith(hasLightSensor: snapshot.data![1] as bool),
child: InheritedWidgetBase<UserPreferencesService>(
data: UserPreferencesService(snapshot.data![0] as SharedPreferences),
child: InheritedWidgetBase<LightSensorService>(
data: const LightSensorService(),
child: InheritedWidgetBase<CaffeineService>(
data: const CaffeineService(),
child: InheritedWidgetBase<HapticsService>(
data: const HapticsService(),
child: InheritedWidgetBase<PermissionsService>(
data: const PermissionsService(),
child: MeteringScreenLayoutProvider(
child: StopTypeProvider(
child: EquipmentProfileProvider(
child: EvSourceTypeProvider(
child: SupportedLocaleProvider(
child: ThemeProvider(
child: Builder(
builder: (context) => builder(context, true),
),
),
),
),
),
),
),
),
),
),
),
),
);
} else if (snapshot.error != null) {
return Center(child: Text(snapshot.error!.toString()));
}
return builder(context, false);
},
);
}
}
63 changes: 12 additions & 51 deletions lib/providers/equipment_profile_provider.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import 'package:flutter/material.dart';
import 'package:lightmeter/data/shared_prefs_service.dart';
import 'package:lightmeter/utils/inherited_generics.dart';
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
import 'package:provider/provider.dart';
import 'package:uuid/uuid.dart';

typedef EquipmentProfiles = List<EquipmentProfileData>;
typedef EquipmentProfile = EquipmentProfileData;

class EquipmentProfileProvider extends StatefulWidget {
final Widget child;

Expand Down Expand Up @@ -33,23 +36,23 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
EquipmentProfileData get _selectedProfile => _customProfiles.firstWhere(
(e) => e.id == _selectedId,
orElse: () {
context.read<UserPreferencesService>().selectedEquipmentProfileId = _defaultProfile.id;
context.get<UserPreferencesService>().selectedEquipmentProfileId = _defaultProfile.id;
return _defaultProfile;
},
);

@override
void initState() {
super.initState();
_selectedId = context.read<UserPreferencesService>().selectedEquipmentProfileId;
_customProfiles = context.read<UserPreferencesService>().equipmentProfiles;
_selectedId = context.get<UserPreferencesService>().selectedEquipmentProfileId;
_customProfiles = context.get<UserPreferencesService>().equipmentProfiles;
}

@override
Widget build(BuildContext context) {
return EquipmentProfiles(
profiles: [_defaultProfile] + _customProfiles,
child: EquipmentProfile(
return InheritedWidgetBase<List<EquipmentProfileData>>(
data: [_defaultProfile] + _customProfiles,
child: InheritedWidgetBase<EquipmentProfileData>(
data: _selectedProfile,
child: widget.child,
),
Expand All @@ -60,7 +63,7 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
setState(() {
_selectedId = data.id;
});
context.read<UserPreferencesService>().selectedEquipmentProfileId = _selectedProfile.id;
context.get<UserPreferencesService>().selectedEquipmentProfileId = _selectedProfile.id;
}

/// Creates a default equipment profile
Expand Down Expand Up @@ -92,49 +95,7 @@ class EquipmentProfileProviderState extends State<EquipmentProfileProvider> {
}

void _refreshSavedProfiles() {
context.read<UserPreferencesService>().equipmentProfiles = _customProfiles;
context.get<UserPreferencesService>().equipmentProfiles = _customProfiles;
setState(() {});
}
}

class EquipmentProfiles extends InheritedWidget {
final List<EquipmentProfileData> profiles;

const EquipmentProfiles({
required this.profiles,
required super.child,
super.key,
});

static List<EquipmentProfileData> of(BuildContext context, {bool listen = true}) {
if (listen) {
return context.dependOnInheritedWidgetOfExactType<EquipmentProfiles>()!.profiles;
} else {
return context.findAncestorWidgetOfExactType<EquipmentProfiles>()!.profiles;
}
}

@override
bool updateShouldNotify(EquipmentProfiles oldWidget) => true;
}

class EquipmentProfile extends InheritedWidget {
final EquipmentProfileData data;

const EquipmentProfile({
required this.data,
required super.child,
super.key,
});

static EquipmentProfileData of(BuildContext context, {bool listen = true}) {
if (listen) {
return context.dependOnInheritedWidgetOfExactType<EquipmentProfile>()!.data;
} else {
return context.findAncestorWidgetOfExactType<EquipmentProfile>()!.data;
}
}

@override
bool updateShouldNotify(EquipmentProfile oldWidget) => true;
}
16 changes: 8 additions & 8 deletions lib/providers/ev_source_type_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ 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:provider/provider.dart';
import 'package:lightmeter/utils/inherited_generics.dart';

class EvSourceTypeProvider extends StatefulWidget {
final Widget child;
Expand All @@ -23,9 +23,9 @@ class EvSourceTypeProviderState extends State<EvSourceTypeProvider> {
@override
void initState() {
super.initState();
final evSourceType = context.read<UserPreferencesService>().evSourceType;
final evSourceType = context.get<UserPreferencesService>().evSourceType;
valueListenable = ValueNotifier(
evSourceType == EvSourceType.sensor && !context.read<Environment>().hasLightSensor
evSourceType == EvSourceType.sensor && !context.get<Environment>().hasLightSensor
? EvSourceType.camera
: evSourceType,
);
Expand All @@ -41,9 +41,9 @@ class EvSourceTypeProviderState extends State<EvSourceTypeProvider> {
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: valueListenable,
builder: (_, value, child) => Provider.value(
value: value,
child: child,
builder: (_, value, child) => InheritedWidgetBase<EvSourceType>(
data: value,
child: child!,
),
child: widget.child,
);
Expand All @@ -52,12 +52,12 @@ class EvSourceTypeProviderState extends State<EvSourceTypeProvider> {
void toggleType() {
switch (valueListenable.value) {
case EvSourceType.camera:
if (context.read<Environment>().hasLightSensor) {
if (context.get<Environment>().hasLightSensor) {
valueListenable.value = EvSourceType.sensor;
}
case EvSourceType.sensor:
valueListenable.value = EvSourceType.camera;
}
context.read<UserPreferencesService>().evSourceType = valueListenable.value;
context.get<UserPreferencesService>().evSourceType = valueListenable.value;
}
}
Loading