mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-03-11 12:50:39 +00:00
implemented VolumeKeysListener
(wip)
This commit is contained in:
parent
933a0e30cc
commit
e20b9f76b9
18 changed files with 210 additions and 18 deletions
|
@ -52,7 +52,7 @@ class MainActivity : FlutterActivity() {
|
|||
when (call.method) {
|
||||
"setVolumeHandling" -> {
|
||||
handleVolume = call.arguments as Boolean
|
||||
result.success(true)
|
||||
result.success(handleVolume)
|
||||
}
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
|
|
3
lib/data/models/volume_action.dart
Normal file
3
lib/data/models/volume_action.dart
Normal file
|
@ -0,0 +1,3 @@
|
|||
enum VolumeAction { shutter, zoom, none }
|
||||
|
||||
enum VolumeKey { up, down }
|
|
@ -6,6 +6,7 @@ import 'package:lightmeter/data/models/film.dart';
|
|||
import 'package:lightmeter/data/models/metering_screen_layout_config.dart';
|
||||
import 'package:lightmeter/data/models/supported_locale.dart';
|
||||
import 'package:lightmeter/data/models/theme_type.dart';
|
||||
import 'package:lightmeter/data/models/volume_action.dart';
|
||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
|
@ -22,6 +23,7 @@ class UserPreferencesService {
|
|||
|
||||
static const caffeineKey = "caffeine";
|
||||
static const hapticsKey = "haptics";
|
||||
static const volumeActionKey = "volumeAction";
|
||||
static const localeKey = "locale";
|
||||
|
||||
static const themeTypeKey = "themeType";
|
||||
|
@ -82,9 +84,6 @@ class UserPreferencesService {
|
|||
EvSourceType.values[_sharedPreferences.getInt(evSourceTypeKey) ?? 0];
|
||||
set evSourceType(EvSourceType value) => _sharedPreferences.setInt(evSourceTypeKey, value.index);
|
||||
|
||||
bool get caffeine => _sharedPreferences.getBool(caffeineKey) ?? false;
|
||||
set caffeine(bool value) => _sharedPreferences.setBool(caffeineKey, value);
|
||||
|
||||
StopType get stopType => StopType.values[_sharedPreferences.getInt(stopTypeKey) ?? 2];
|
||||
set stopType(StopType value) => _sharedPreferences.setInt(stopTypeKey, value.index);
|
||||
|
||||
|
@ -105,9 +104,19 @@ class UserPreferencesService {
|
|||
set meteringScreenLayout(MeteringScreenLayoutConfig value) =>
|
||||
_sharedPreferences.setString(meteringScreenLayoutKey, json.encode(value.toJson()));
|
||||
|
||||
bool get caffeine => _sharedPreferences.getBool(caffeineKey) ?? false;
|
||||
set caffeine(bool value) => _sharedPreferences.setBool(caffeineKey, value);
|
||||
|
||||
bool get haptics => _sharedPreferences.getBool(hapticsKey) ?? true;
|
||||
set haptics(bool value) => _sharedPreferences.setBool(hapticsKey, value);
|
||||
|
||||
VolumeAction get volumeAction => VolumeAction.values.firstWhere(
|
||||
(e) => e.toString() == _sharedPreferences.getString(volumeActionKey),
|
||||
orElse: () => VolumeAction.shutter,
|
||||
);
|
||||
set volumeAction(VolumeAction value) =>
|
||||
_sharedPreferences.setString(volumeActionKey, value.toString());
|
||||
|
||||
SupportedLocale get locale => SupportedLocale.values.firstWhere(
|
||||
(e) => e.toString() == _sharedPreferences.getString(localeKey),
|
||||
orElse: () => SupportedLocale.en,
|
||||
|
|
|
@ -5,8 +5,10 @@ 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/film.dart';
|
||||
import 'package:lightmeter/data/models/volume_action.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:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
|
@ -16,6 +18,7 @@ class MeteringInteractor {
|
|||
final HapticsService _hapticsService;
|
||||
final PermissionsService _permissionsService;
|
||||
final LightSensorService _lightSensorService;
|
||||
final VolumeEventsService _volumeEventsService;
|
||||
|
||||
MeteringInteractor(
|
||||
this._userPreferencesService,
|
||||
|
@ -23,10 +26,13 @@ class MeteringInteractor {
|
|||
this._hapticsService,
|
||||
this._permissionsService,
|
||||
this._lightSensorService,
|
||||
this._volumeEventsService,
|
||||
) {
|
||||
if (_userPreferencesService.caffeine) {
|
||||
_caffeineService.keepScreenOn(true);
|
||||
}
|
||||
_volumeEventsService
|
||||
.setVolumeHandling(_userPreferencesService.volumeAction != VolumeAction.none);
|
||||
}
|
||||
|
||||
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
||||
|
@ -42,6 +48,12 @@ class MeteringInteractor {
|
|||
Film get film => _userPreferencesService.film;
|
||||
set film(Film value) => _userPreferencesService.film = value;
|
||||
|
||||
VolumeAction get volumeAction => _userPreferencesService.volumeAction;
|
||||
Stream<VolumeKey> volumeKeysStream() => _volumeEventsService
|
||||
.volumeButtonsEventStream()
|
||||
.where((event) => event == 24 || event == 25)
|
||||
.map((event) => event == 24 ? VolumeKey.up : VolumeKey.down);
|
||||
|
||||
/// Executes vibration if haptics are enabled in settings
|
||||
Future<void> quickVibration() async {
|
||||
if (_userPreferencesService.haptics) await _hapticsService.quickVibration();
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
import 'package:lightmeter/data/caffeine_service.dart';
|
||||
import 'package:lightmeter/data/haptics_service.dart';
|
||||
import 'package:lightmeter/data/models/volume_action.dart';
|
||||
import 'package:lightmeter/data/shared_prefs_service.dart';
|
||||
import 'package:lightmeter/data/volume_events_service.dart';
|
||||
|
||||
class SettingsInteractor {
|
||||
final UserPreferencesService _userPreferencesService;
|
||||
final CaffeineService _caffeineService;
|
||||
final HapticsService _hapticsService;
|
||||
final VolumeEventsService _volumeEventsService;
|
||||
|
||||
const SettingsInteractor(
|
||||
this._userPreferencesService,
|
||||
this._caffeineService,
|
||||
this._hapticsService,
|
||||
this._volumeEventsService,
|
||||
);
|
||||
|
||||
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
||||
|
@ -27,6 +31,13 @@ class SettingsInteractor {
|
|||
});
|
||||
}
|
||||
|
||||
VolumeAction get volumeAction => _userPreferencesService.volumeAction;
|
||||
Future<void> setVolumeAction(VolumeAction value) async {
|
||||
/// If user selects `VolumeAction.volume` we allow system to handle key events
|
||||
await _volumeEventsService.setVolumeHandling(value != VolumeAction.none);
|
||||
_userPreferencesService.volumeAction = value;
|
||||
}
|
||||
|
||||
bool get isHapticsEnabled => _userPreferencesService.haptics;
|
||||
void enableHaptics(bool enable) {
|
||||
_userPreferencesService.haptics = enable;
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
"general": "General",
|
||||
"keepScreenOn": "Keep screen on",
|
||||
"haptics": "Haptics",
|
||||
"volumeKeysAction": "Volume keys action",
|
||||
"shutter": "Shutter",
|
||||
"zoom": "Zoom",
|
||||
"language": "Language",
|
||||
"chooseLanguage": "Choose language",
|
||||
"theme": "Theme",
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
"general": "Général",
|
||||
"keepScreenOn": "Garder l'écran allumé",
|
||||
"haptics": "Haptiques",
|
||||
"volumeKeysAction": "Action des touches de volume",
|
||||
"shutter": "Obturateur",
|
||||
"zoom": "Zoom",
|
||||
"language": "Langue",
|
||||
"chooseLanguage": "Choisissez la langue",
|
||||
"theme": "Thème",
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
"general": "Общие",
|
||||
"keepScreenOn": "Запрет блокировки",
|
||||
"haptics": "Вибрация",
|
||||
"volumeKeysAction": "Кнопки регулировки громкости",
|
||||
"shutter": "Затвор",
|
||||
"zoom": "Зум",
|
||||
"language": "Язык",
|
||||
"chooseLanguage": "Выберите язык",
|
||||
"theme": "Тема",
|
||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
||||
import 'package:lightmeter/providers/ev_source_type_provider.dart';
|
||||
|
@ -41,16 +42,19 @@ class LightmeterProviders extends StatelessWidget {
|
|||
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),
|
||||
child: InheritedWidgetBase<VolumeEventsService>(
|
||||
data: const VolumeEventsService(),
|
||||
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),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -4,12 +4,14 @@ import 'package:bloc_concurrency/bloc_concurrency.dart';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/data/models/film.dart';
|
||||
import 'package:lightmeter/data/models/volume_action.dart';
|
||||
import 'package:lightmeter/interactors/metering_interactor.dart';
|
||||
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
||||
import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart'
|
||||
as communication_events;
|
||||
import 'package:lightmeter/screens/metering/communication/state_communication_metering.dart'
|
||||
as communication_states;
|
||||
import 'package:lightmeter/screens/metering/components/shared/volume_keys_listener/listener_volume_keys.dart';
|
||||
import 'package:lightmeter/screens/metering/event_metering.dart';
|
||||
import 'package:lightmeter/screens/metering/state_metering.dart';
|
||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
|
@ -19,6 +21,12 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
|
|||
final MeteringCommunicationBloc _communicationBloc;
|
||||
late final StreamSubscription<communication_states.ScreenState> _communicationSubscription;
|
||||
|
||||
late final VolumeKeysListener _volumeKeysListener = VolumeKeysListener(
|
||||
_meteringInteractor,
|
||||
action: VolumeAction.shutter,
|
||||
onKey: (value) => add(const MeasureEvent()),
|
||||
);
|
||||
|
||||
MeteringBloc(
|
||||
this._meteringInteractor,
|
||||
this._communicationBloc,
|
||||
|
@ -64,6 +72,7 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
|
|||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
await _volumeKeysListener.dispose();
|
||||
await _communicationSubscription.cancel();
|
||||
return super.close();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import 'package:camera/camera.dart';
|
|||
import 'package:exif/exif.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/data/models/volume_action.dart';
|
||||
import 'package:lightmeter/interactors/metering_interactor.dart';
|
||||
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
||||
import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart'
|
||||
|
@ -18,6 +19,7 @@ import 'package:lightmeter/screens/metering/components/camera_container/event_co
|
|||
import 'package:lightmeter/screens/metering/components/camera_container/models/camera_error_type.dart';
|
||||
import 'package:lightmeter/screens/metering/components/camera_container/state_container_camera.dart';
|
||||
import 'package:lightmeter/screens/metering/components/shared/ev_source_base/bloc_base_ev_source.dart';
|
||||
import 'package:lightmeter/screens/metering/components/shared/volume_keys_listener/listener_volume_keys.dart';
|
||||
import 'package:lightmeter/utils/log_2.dart';
|
||||
|
||||
class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraContainerState> {
|
||||
|
@ -36,6 +38,19 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
|||
|
||||
double? _ev100 = 0.0;
|
||||
|
||||
late final VolumeKeysListener _volumeKeysListener = VolumeKeysListener(
|
||||
_meteringInteractor,
|
||||
action: VolumeAction.zoom,
|
||||
onKey: (key) {
|
||||
switch (key) {
|
||||
case VolumeKey.up:
|
||||
add(ZoomChangedEvent(_currentZoom + 0.5));
|
||||
case VolumeKey.down:
|
||||
add(ZoomChangedEvent(_currentZoom - 0.5));
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
CameraContainerBloc(
|
||||
this._meteringInteractor,
|
||||
MeteringCommunicationBloc communicationBloc,
|
||||
|
@ -58,6 +73,7 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
|||
@override
|
||||
Future<void> close() async {
|
||||
WidgetsBinding.instance.removeObserver(_observer);
|
||||
_volumeKeysListener.dispose();
|
||||
unawaited(_cameraController?.dispose().then((_) => _cameraController = null));
|
||||
communicationBloc.add(communication_event.MeteringEndedEvent(_ev100));
|
||||
return super.close();
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/data/models/volume_action.dart';
|
||||
import 'package:lightmeter/interactors/metering_interactor.dart';
|
||||
|
||||
class VolumeKeysListener {
|
||||
final MeteringInteractor _meteringInteractor;
|
||||
late final StreamSubscription<VolumeKey> _volumeKeysSubscription;
|
||||
|
||||
VolumeKeysListener(
|
||||
this._meteringInteractor, {
|
||||
required VolumeAction action,
|
||||
required ValueChanged<VolumeKey> onKey,
|
||||
}) {
|
||||
_volumeKeysSubscription = _meteringInteractor.volumeKeysStream().listen((event) {
|
||||
if (_meteringInteractor.volumeAction == action) {
|
||||
onKey(event);
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: add RouteObserver and disable overriden action if SettingScreen is opened
|
||||
}
|
||||
|
||||
Future<void> dispose() async {
|
||||
await _volumeKeysSubscription.cancel();
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ 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/screens/metering/bloc_metering.dart';
|
||||
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
||||
|
@ -28,6 +29,7 @@ class _MeteringFlowState extends State<MeteringFlow> {
|
|||
context.get<HapticsService>(),
|
||||
context.get<PermissionsService>(),
|
||||
context.get<LightSensorService>(),
|
||||
context.get<VolumeEventsService>(),
|
||||
),
|
||||
child: MultiBlocProvider(
|
||||
providers: [
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/data/models/volume_action.dart';
|
||||
import 'package:lightmeter/interactors/settings_interactor.dart';
|
||||
|
||||
class VolumeActionsListTileBloc extends Cubit<VolumeAction> {
|
||||
final SettingsInteractor _settingsInteractor;
|
||||
|
||||
VolumeActionsListTileBloc(
|
||||
this._settingsInteractor,
|
||||
) : super(_settingsInteractor.volumeAction);
|
||||
|
||||
void onVolumeActionChanged(VolumeAction value) {
|
||||
_settingsInteractor.setVolumeAction(value);
|
||||
emit(value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/interactors/settings_interactor.dart';
|
||||
|
||||
import 'package:lightmeter/screens/settings/components/general/components/volume_actions/bloc_list_tile_volume_actions.dart';
|
||||
import 'package:lightmeter/screens/settings/components/general/components/volume_actions/widget_list_tile_volume_actions.dart';
|
||||
import 'package:lightmeter/utils/inherited_generics.dart';
|
||||
|
||||
class VolumeActionsListTileProvider extends StatelessWidget {
|
||||
const VolumeActionsListTileProvider({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => VolumeActionsListTileBloc(context.get<SettingsInteractor>()),
|
||||
child: const VolumeActionsListTile(),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/data/models/volume_action.dart';
|
||||
import 'package:lightmeter/generated/l10n.dart';
|
||||
import 'package:lightmeter/screens/settings/components/general/components/volume_actions/bloc_list_tile_volume_actions.dart';
|
||||
import 'package:lightmeter/screens/settings/components/shared/dialog_picker.dart/widget_dialog_picker.dart';
|
||||
|
||||
class VolumeActionsListTile extends StatelessWidget {
|
||||
const VolumeActionsListTile({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<VolumeActionsListTileBloc, VolumeAction>(
|
||||
builder: (context, state) => ListTile(
|
||||
leading: const Icon(Icons.volume_up),
|
||||
title: Text(S.of(context).volumeKeysAction),
|
||||
trailing: Text(actionToString(context, state)),
|
||||
onTap: () {
|
||||
showDialog<VolumeAction>(
|
||||
context: context,
|
||||
builder: (_) => DialogPicker<VolumeAction>(
|
||||
icon: Icons.volume_up,
|
||||
title: S.of(context).volumeKeysAction,
|
||||
selectedValue: state,
|
||||
values: VolumeAction.values,
|
||||
titleAdapter: (context, value) => actionToString(context, value),
|
||||
),
|
||||
).then((value) {
|
||||
if (value != null) {
|
||||
context.read<VolumeActionsListTileBloc>().onVolumeActionChanged(value);
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String actionToString(BuildContext context, VolumeAction themeType) {
|
||||
switch (themeType) {
|
||||
case VolumeAction.shutter:
|
||||
return S.of(context).shutter;
|
||||
case VolumeAction.zoom:
|
||||
return S.of(context).zoom;
|
||||
case VolumeAction.none:
|
||||
return S.of(context).none;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/generated/l10n.dart';
|
||||
import 'package:lightmeter/screens/settings/components/general/components/caffeine/provider_list_tile_caffeine.dart';
|
||||
import 'package:lightmeter/screens/settings/components/general/components/haptics/provider_list_tile_haptics.dart';
|
||||
import 'package:lightmeter/screens/settings/components/general/components/language/widget_list_tile_language.dart';
|
||||
import 'package:lightmeter/screens/settings/components/general/components/volume_actions/provider_list_tile_volume_actions.dart';
|
||||
import 'package:lightmeter/screens/settings/components/shared/settings_section/widget_settings_section.dart';
|
||||
|
||||
class GeneralSettingsSection extends StatelessWidget {
|
||||
|
@ -12,10 +15,11 @@ class GeneralSettingsSection extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return SettingsSection(
|
||||
title: S.of(context).general,
|
||||
children: const [
|
||||
CaffeineListTileProvider(),
|
||||
HapticsListTileProvider(),
|
||||
LanguageListTile(),
|
||||
children: [
|
||||
const CaffeineListTileProvider(),
|
||||
const HapticsListTileProvider(),
|
||||
if (Platform.isAndroid) const VolumeActionsListTileProvider(),
|
||||
const LanguageListTile(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ 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/screens/settings/screen_settings.dart';
|
||||
import 'package:lightmeter/utils/inherited_generics.dart';
|
||||
|
@ -16,6 +17,7 @@ class SettingsFlow extends StatelessWidget {
|
|||
context.get<UserPreferencesService>(),
|
||||
context.get<CaffeineService>(),
|
||||
context.get<HapticsService>(),
|
||||
context.get<VolumeEventsService>(),
|
||||
),
|
||||
child: const SettingsScreen(),
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue