mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2025-03-12 05:10:41 +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) {
|
when (call.method) {
|
||||||
"setVolumeHandling" -> {
|
"setVolumeHandling" -> {
|
||||||
handleVolume = call.arguments as Boolean
|
handleVolume = call.arguments as Boolean
|
||||||
result.success(true)
|
result.success(handleVolume)
|
||||||
}
|
}
|
||||||
else -> result.notImplemented()
|
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/metering_screen_layout_config.dart';
|
||||||
import 'package:lightmeter/data/models/supported_locale.dart';
|
import 'package:lightmeter/data/models/supported_locale.dart';
|
||||||
import 'package:lightmeter/data/models/theme_type.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:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@ class UserPreferencesService {
|
||||||
|
|
||||||
static const caffeineKey = "caffeine";
|
static const caffeineKey = "caffeine";
|
||||||
static const hapticsKey = "haptics";
|
static const hapticsKey = "haptics";
|
||||||
|
static const volumeActionKey = "volumeAction";
|
||||||
static const localeKey = "locale";
|
static const localeKey = "locale";
|
||||||
|
|
||||||
static const themeTypeKey = "themeType";
|
static const themeTypeKey = "themeType";
|
||||||
|
@ -82,9 +84,6 @@ class UserPreferencesService {
|
||||||
EvSourceType.values[_sharedPreferences.getInt(evSourceTypeKey) ?? 0];
|
EvSourceType.values[_sharedPreferences.getInt(evSourceTypeKey) ?? 0];
|
||||||
set evSourceType(EvSourceType value) => _sharedPreferences.setInt(evSourceTypeKey, value.index);
|
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];
|
StopType get stopType => StopType.values[_sharedPreferences.getInt(stopTypeKey) ?? 2];
|
||||||
set stopType(StopType value) => _sharedPreferences.setInt(stopTypeKey, value.index);
|
set stopType(StopType value) => _sharedPreferences.setInt(stopTypeKey, value.index);
|
||||||
|
|
||||||
|
@ -105,9 +104,19 @@ class UserPreferencesService {
|
||||||
set meteringScreenLayout(MeteringScreenLayoutConfig value) =>
|
set meteringScreenLayout(MeteringScreenLayoutConfig value) =>
|
||||||
_sharedPreferences.setString(meteringScreenLayoutKey, json.encode(value.toJson()));
|
_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;
|
bool get haptics => _sharedPreferences.getBool(hapticsKey) ?? true;
|
||||||
set haptics(bool value) => _sharedPreferences.setBool(hapticsKey, value);
|
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(
|
SupportedLocale get locale => SupportedLocale.values.firstWhere(
|
||||||
(e) => e.toString() == _sharedPreferences.getString(localeKey),
|
(e) => e.toString() == _sharedPreferences.getString(localeKey),
|
||||||
orElse: () => SupportedLocale.en,
|
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/haptics_service.dart';
|
||||||
import 'package:lightmeter/data/light_sensor_service.dart';
|
import 'package:lightmeter/data/light_sensor_service.dart';
|
||||||
import 'package:lightmeter/data/models/film.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/permissions_service.dart';
|
||||||
import 'package:lightmeter/data/shared_prefs_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:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
import 'package:permission_handler/permission_handler.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
|
@ -16,6 +18,7 @@ class MeteringInteractor {
|
||||||
final HapticsService _hapticsService;
|
final HapticsService _hapticsService;
|
||||||
final PermissionsService _permissionsService;
|
final PermissionsService _permissionsService;
|
||||||
final LightSensorService _lightSensorService;
|
final LightSensorService _lightSensorService;
|
||||||
|
final VolumeEventsService _volumeEventsService;
|
||||||
|
|
||||||
MeteringInteractor(
|
MeteringInteractor(
|
||||||
this._userPreferencesService,
|
this._userPreferencesService,
|
||||||
|
@ -23,10 +26,13 @@ class MeteringInteractor {
|
||||||
this._hapticsService,
|
this._hapticsService,
|
||||||
this._permissionsService,
|
this._permissionsService,
|
||||||
this._lightSensorService,
|
this._lightSensorService,
|
||||||
|
this._volumeEventsService,
|
||||||
) {
|
) {
|
||||||
if (_userPreferencesService.caffeine) {
|
if (_userPreferencesService.caffeine) {
|
||||||
_caffeineService.keepScreenOn(true);
|
_caffeineService.keepScreenOn(true);
|
||||||
}
|
}
|
||||||
|
_volumeEventsService
|
||||||
|
.setVolumeHandling(_userPreferencesService.volumeAction != VolumeAction.none);
|
||||||
}
|
}
|
||||||
|
|
||||||
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
||||||
|
@ -42,6 +48,12 @@ class MeteringInteractor {
|
||||||
Film get film => _userPreferencesService.film;
|
Film get film => _userPreferencesService.film;
|
||||||
set film(Film value) => _userPreferencesService.film = value;
|
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
|
/// Executes vibration if haptics are enabled in settings
|
||||||
Future<void> quickVibration() async {
|
Future<void> quickVibration() async {
|
||||||
if (_userPreferencesService.haptics) await _hapticsService.quickVibration();
|
if (_userPreferencesService.haptics) await _hapticsService.quickVibration();
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
import 'package:lightmeter/data/caffeine_service.dart';
|
import 'package:lightmeter/data/caffeine_service.dart';
|
||||||
import 'package:lightmeter/data/haptics_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/shared_prefs_service.dart';
|
||||||
|
import 'package:lightmeter/data/volume_events_service.dart';
|
||||||
|
|
||||||
class SettingsInteractor {
|
class SettingsInteractor {
|
||||||
final UserPreferencesService _userPreferencesService;
|
final UserPreferencesService _userPreferencesService;
|
||||||
final CaffeineService _caffeineService;
|
final CaffeineService _caffeineService;
|
||||||
final HapticsService _hapticsService;
|
final HapticsService _hapticsService;
|
||||||
|
final VolumeEventsService _volumeEventsService;
|
||||||
|
|
||||||
const SettingsInteractor(
|
const SettingsInteractor(
|
||||||
this._userPreferencesService,
|
this._userPreferencesService,
|
||||||
this._caffeineService,
|
this._caffeineService,
|
||||||
this._hapticsService,
|
this._hapticsService,
|
||||||
|
this._volumeEventsService,
|
||||||
);
|
);
|
||||||
|
|
||||||
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
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;
|
bool get isHapticsEnabled => _userPreferencesService.haptics;
|
||||||
void enableHaptics(bool enable) {
|
void enableHaptics(bool enable) {
|
||||||
_userPreferencesService.haptics = enable;
|
_userPreferencesService.haptics = enable;
|
||||||
|
|
|
@ -56,6 +56,9 @@
|
||||||
"general": "General",
|
"general": "General",
|
||||||
"keepScreenOn": "Keep screen on",
|
"keepScreenOn": "Keep screen on",
|
||||||
"haptics": "Haptics",
|
"haptics": "Haptics",
|
||||||
|
"volumeKeysAction": "Volume keys action",
|
||||||
|
"shutter": "Shutter",
|
||||||
|
"zoom": "Zoom",
|
||||||
"language": "Language",
|
"language": "Language",
|
||||||
"chooseLanguage": "Choose language",
|
"chooseLanguage": "Choose language",
|
||||||
"theme": "Theme",
|
"theme": "Theme",
|
||||||
|
|
|
@ -56,6 +56,9 @@
|
||||||
"general": "Général",
|
"general": "Général",
|
||||||
"keepScreenOn": "Garder l'écran allumé",
|
"keepScreenOn": "Garder l'écran allumé",
|
||||||
"haptics": "Haptiques",
|
"haptics": "Haptiques",
|
||||||
|
"volumeKeysAction": "Action des touches de volume",
|
||||||
|
"shutter": "Obturateur",
|
||||||
|
"zoom": "Zoom",
|
||||||
"language": "Langue",
|
"language": "Langue",
|
||||||
"chooseLanguage": "Choisissez la langue",
|
"chooseLanguage": "Choisissez la langue",
|
||||||
"theme": "Thème",
|
"theme": "Thème",
|
||||||
|
|
|
@ -56,6 +56,9 @@
|
||||||
"general": "Общие",
|
"general": "Общие",
|
||||||
"keepScreenOn": "Запрет блокировки",
|
"keepScreenOn": "Запрет блокировки",
|
||||||
"haptics": "Вибрация",
|
"haptics": "Вибрация",
|
||||||
|
"volumeKeysAction": "Кнопки регулировки громкости",
|
||||||
|
"shutter": "Затвор",
|
||||||
|
"zoom": "Зум",
|
||||||
"language": "Язык",
|
"language": "Язык",
|
||||||
"chooseLanguage": "Выберите язык",
|
"chooseLanguage": "Выберите язык",
|
||||||
"theme": "Тема",
|
"theme": "Тема",
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:lightmeter/data/haptics_service.dart';
|
||||||
import 'package:lightmeter/data/light_sensor_service.dart';
|
import 'package:lightmeter/data/light_sensor_service.dart';
|
||||||
import 'package:lightmeter/data/permissions_service.dart';
|
import 'package:lightmeter/data/permissions_service.dart';
|
||||||
import 'package:lightmeter/data/shared_prefs_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/environment.dart';
|
||||||
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
import 'package:lightmeter/providers/equipment_profile_provider.dart';
|
||||||
import 'package:lightmeter/providers/ev_source_type_provider.dart';
|
import 'package:lightmeter/providers/ev_source_type_provider.dart';
|
||||||
|
@ -41,16 +42,19 @@ class LightmeterProviders extends StatelessWidget {
|
||||||
data: const CaffeineService(),
|
data: const CaffeineService(),
|
||||||
child: InheritedWidgetBase<HapticsService>(
|
child: InheritedWidgetBase<HapticsService>(
|
||||||
data: const HapticsService(),
|
data: const HapticsService(),
|
||||||
child: InheritedWidgetBase<PermissionsService>(
|
child: InheritedWidgetBase<VolumeEventsService>(
|
||||||
data: const PermissionsService(),
|
data: const VolumeEventsService(),
|
||||||
child: MeteringScreenLayoutProvider(
|
child: InheritedWidgetBase<PermissionsService>(
|
||||||
child: StopTypeProvider(
|
data: const PermissionsService(),
|
||||||
child: EquipmentProfileProvider(
|
child: MeteringScreenLayoutProvider(
|
||||||
child: EvSourceTypeProvider(
|
child: StopTypeProvider(
|
||||||
child: SupportedLocaleProvider(
|
child: EquipmentProfileProvider(
|
||||||
child: ThemeProvider(
|
child: EvSourceTypeProvider(
|
||||||
child: Builder(
|
child: SupportedLocaleProvider(
|
||||||
builder: (context) => builder(context, true),
|
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/foundation.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:lightmeter/data/models/film.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/interactors/metering_interactor.dart';
|
||||||
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
||||||
import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart'
|
import 'package:lightmeter/screens/metering/communication/event_communication_metering.dart'
|
||||||
as communication_events;
|
as communication_events;
|
||||||
import 'package:lightmeter/screens/metering/communication/state_communication_metering.dart'
|
import 'package:lightmeter/screens/metering/communication/state_communication_metering.dart'
|
||||||
as communication_states;
|
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/event_metering.dart';
|
||||||
import 'package:lightmeter/screens/metering/state_metering.dart';
|
import 'package:lightmeter/screens/metering/state_metering.dart';
|
||||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||||
|
@ -19,6 +21,12 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
|
||||||
final MeteringCommunicationBloc _communicationBloc;
|
final MeteringCommunicationBloc _communicationBloc;
|
||||||
late final StreamSubscription<communication_states.ScreenState> _communicationSubscription;
|
late final StreamSubscription<communication_states.ScreenState> _communicationSubscription;
|
||||||
|
|
||||||
|
late final VolumeKeysListener _volumeKeysListener = VolumeKeysListener(
|
||||||
|
_meteringInteractor,
|
||||||
|
action: VolumeAction.shutter,
|
||||||
|
onKey: (value) => add(const MeasureEvent()),
|
||||||
|
);
|
||||||
|
|
||||||
MeteringBloc(
|
MeteringBloc(
|
||||||
this._meteringInteractor,
|
this._meteringInteractor,
|
||||||
this._communicationBloc,
|
this._communicationBloc,
|
||||||
|
@ -64,6 +72,7 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
|
await _volumeKeysListener.dispose();
|
||||||
await _communicationSubscription.cancel();
|
await _communicationSubscription.cancel();
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import 'package:camera/camera.dart';
|
||||||
import 'package:exif/exif.dart';
|
import 'package:exif/exif.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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/interactors/metering_interactor.dart';
|
||||||
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
import 'package:lightmeter/screens/metering/communication/bloc_communication_metering.dart';
|
||||||
import 'package:lightmeter/screens/metering/communication/event_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/models/camera_error_type.dart';
|
||||||
import 'package:lightmeter/screens/metering/components/camera_container/state_container_camera.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/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';
|
import 'package:lightmeter/utils/log_2.dart';
|
||||||
|
|
||||||
class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraContainerState> {
|
class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraContainerState> {
|
||||||
|
@ -36,6 +38,19 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
||||||
|
|
||||||
double? _ev100 = 0.0;
|
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(
|
CameraContainerBloc(
|
||||||
this._meteringInteractor,
|
this._meteringInteractor,
|
||||||
MeteringCommunicationBloc communicationBloc,
|
MeteringCommunicationBloc communicationBloc,
|
||||||
|
@ -58,6 +73,7 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
WidgetsBinding.instance.removeObserver(_observer);
|
WidgetsBinding.instance.removeObserver(_observer);
|
||||||
|
_volumeKeysListener.dispose();
|
||||||
unawaited(_cameraController?.dispose().then((_) => _cameraController = null));
|
unawaited(_cameraController?.dispose().then((_) => _cameraController = null));
|
||||||
communicationBloc.add(communication_event.MeteringEndedEvent(_ev100));
|
communicationBloc.add(communication_event.MeteringEndedEvent(_ev100));
|
||||||
return super.close();
|
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/light_sensor_service.dart';
|
||||||
import 'package:lightmeter/data/permissions_service.dart';
|
import 'package:lightmeter/data/permissions_service.dart';
|
||||||
import 'package:lightmeter/data/shared_prefs_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/interactors/metering_interactor.dart';
|
||||||
import 'package:lightmeter/screens/metering/bloc_metering.dart';
|
import 'package:lightmeter/screens/metering/bloc_metering.dart';
|
||||||
import 'package:lightmeter/screens/metering/communication/bloc_communication_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<HapticsService>(),
|
||||||
context.get<PermissionsService>(),
|
context.get<PermissionsService>(),
|
||||||
context.get<LightSensorService>(),
|
context.get<LightSensorService>(),
|
||||||
|
context.get<VolumeEventsService>(),
|
||||||
),
|
),
|
||||||
child: MultiBlocProvider(
|
child: MultiBlocProvider(
|
||||||
providers: [
|
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:flutter/material.dart';
|
||||||
import 'package:lightmeter/generated/l10n.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/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/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/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';
|
import 'package:lightmeter/screens/settings/components/shared/settings_section/widget_settings_section.dart';
|
||||||
|
|
||||||
class GeneralSettingsSection extends StatelessWidget {
|
class GeneralSettingsSection extends StatelessWidget {
|
||||||
|
@ -12,10 +15,11 @@ class GeneralSettingsSection extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SettingsSection(
|
return SettingsSection(
|
||||||
title: S.of(context).general,
|
title: S.of(context).general,
|
||||||
children: const [
|
children: [
|
||||||
CaffeineListTileProvider(),
|
const CaffeineListTileProvider(),
|
||||||
HapticsListTileProvider(),
|
const HapticsListTileProvider(),
|
||||||
LanguageListTile(),
|
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/caffeine_service.dart';
|
||||||
import 'package:lightmeter/data/haptics_service.dart';
|
import 'package:lightmeter/data/haptics_service.dart';
|
||||||
import 'package:lightmeter/data/shared_prefs_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/interactors/settings_interactor.dart';
|
||||||
import 'package:lightmeter/screens/settings/screen_settings.dart';
|
import 'package:lightmeter/screens/settings/screen_settings.dart';
|
||||||
import 'package:lightmeter/utils/inherited_generics.dart';
|
import 'package:lightmeter/utils/inherited_generics.dart';
|
||||||
|
@ -16,6 +17,7 @@ class SettingsFlow extends StatelessWidget {
|
||||||
context.get<UserPreferencesService>(),
|
context.get<UserPreferencesService>(),
|
||||||
context.get<CaffeineService>(),
|
context.get<CaffeineService>(),
|
||||||
context.get<HapticsService>(),
|
context.get<HapticsService>(),
|
||||||
|
context.get<VolumeEventsService>(),
|
||||||
),
|
),
|
||||||
child: const SettingsScreen(),
|
child: const SettingsScreen(),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue