mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-24 00:10:47 +00:00
ML-24 Implement caffeine feature (#27)
* platform-specific code * implemented caffeine flutter side * haptics revision
This commit is contained in:
parent
a183a5433e
commit
07fd61fa1e
16 changed files with 163 additions and 19 deletions
|
@ -1,6 +1,30 @@
|
||||||
package com.vodemn.lightmeter
|
package com.vodemn.lightmeter
|
||||||
|
|
||||||
|
import android.view.WindowManager
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
|
import io.flutter.plugin.common.MethodChannel
|
||||||
|
|
||||||
class MainActivity : FlutterActivity() {
|
class MainActivity : FlutterActivity() {
|
||||||
|
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||||
|
super.configureFlutterEngine(flutterEngine)
|
||||||
|
MethodChannel(
|
||||||
|
flutterEngine.dartExecutor.binaryMessenger,
|
||||||
|
"com.vodemn.lightmeter/keepScreenOn"
|
||||||
|
).setMethodCallHandler { call, result ->
|
||||||
|
when (call.method) {
|
||||||
|
"isKeepScreenOn" -> result.success((window.attributes.flags and WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) != 0)
|
||||||
|
"setKeepScreenOn" -> {
|
||||||
|
if (call.arguments !is Boolean) {
|
||||||
|
result.error("invalid args", "Argument should be of type Bool for 'setKeepScreenOn' call", null)
|
||||||
|
} else {
|
||||||
|
if (call.arguments as Boolean) window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
else window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
|
result.success(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> result.notImplemented()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,26 @@ import Flutter
|
||||||
_ application: UIApplication,
|
_ application: UIApplication,
|
||||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
|
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
|
||||||
|
let keepScreenOnChannel = FlutterMethodChannel(name: "com.vodemn.lightmeter/keepScreenOn",
|
||||||
|
binaryMessenger: controller.binaryMessenger)
|
||||||
|
keepScreenOnChannel.setMethodCallHandler({
|
||||||
|
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
|
||||||
|
switch call.method {
|
||||||
|
case "isKeepScreenOn":
|
||||||
|
result(UIApplication.shared.isIdleTimerDisabled)
|
||||||
|
case "setKeepScreenOn":
|
||||||
|
guard let keepOn = call.arguments as? Bool else {
|
||||||
|
result(FlutterError(code: "invalid arguments", message: "Argument should be of type Bool for 'setKeepScreenOn' call", details: nil))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
UIApplication.shared.isIdleTimerDisabled = keepOn
|
||||||
|
result(true)
|
||||||
|
default:
|
||||||
|
result(FlutterMethodNotImplemented)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
GeneratedPluginRegistrant.register(with: self)
|
GeneratedPluginRegistrant.register(with: self)
|
||||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:light_sensor/light_sensor.dart';
|
import 'package:light_sensor/light_sensor.dart';
|
||||||
|
import 'package:lightmeter/data/caffeine_service.dart';
|
||||||
import 'package:lightmeter/data/haptics_service.dart';
|
import 'package:lightmeter/data/haptics_service.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
@ -37,6 +38,7 @@ class Application extends StatelessWidget {
|
||||||
providers: [
|
providers: [
|
||||||
Provider.value(value: env.copyWith(hasLightSensor: snapshot.data![1] as bool)),
|
Provider.value(value: env.copyWith(hasLightSensor: snapshot.data![1] as bool)),
|
||||||
Provider(create: (_) => UserPreferencesService(snapshot.data![0] as SharedPreferences)),
|
Provider(create: (_) => UserPreferencesService(snapshot.data![0] as SharedPreferences)),
|
||||||
|
Provider(create: (_) => const CaffeineService()),
|
||||||
Provider(create: (_) => const HapticsService()),
|
Provider(create: (_) => const HapticsService()),
|
||||||
Provider(create: (_) => PermissionsService()),
|
Provider(create: (_) => PermissionsService()),
|
||||||
Provider(create: (_) => const LightSensorService()),
|
Provider(create: (_) => const LightSensorService()),
|
||||||
|
|
15
lib/data/caffeine_service.dart
Normal file
15
lib/data/caffeine_service.dart
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
class CaffeineService {
|
||||||
|
static const _methodChannel = MethodChannel("com.vodemn.lightmeter/keepScreenOn");
|
||||||
|
|
||||||
|
const CaffeineService();
|
||||||
|
|
||||||
|
Future<bool> isKeepScreenOn() async {
|
||||||
|
return await _methodChannel.invokeMethod<bool>("isKeepScreenOn").then((value) => value!);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> keepScreenOn(bool keep) async {
|
||||||
|
await _methodChannel.invokeMethod<bool>("setKeepScreenOn", keep);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,9 @@ class UserPreferencesService {
|
||||||
static const _cameraEvCalibrationKey = "cameraEvCalibration";
|
static const _cameraEvCalibrationKey = "cameraEvCalibration";
|
||||||
static const _lightSensorEvCalibrationKey = "lightSensorEvCalibration";
|
static const _lightSensorEvCalibrationKey = "lightSensorEvCalibration";
|
||||||
|
|
||||||
|
static const _caffeineKey = "caffeine";
|
||||||
static const _hapticsKey = "haptics";
|
static const _hapticsKey = "haptics";
|
||||||
|
|
||||||
static const _themeTypeKey = "themeType";
|
static const _themeTypeKey = "themeType";
|
||||||
static const _primaryColorKey = "primaryColor";
|
static const _primaryColorKey = "primaryColor";
|
||||||
static const _dynamicColorKey = "dynamicColor";
|
static const _dynamicColorKey = "dynamicColor";
|
||||||
|
@ -32,7 +34,10 @@ class UserPreferencesService {
|
||||||
EvSourceType get evSourceType => EvSourceType.values[_sharedPreferences.getInt(_evSourceTypeKey) ?? 0];
|
EvSourceType get evSourceType => 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 haptics => _sharedPreferences.getBool(_hapticsKey) ?? false;
|
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);
|
set haptics(bool value) => _sharedPreferences.setBool(_hapticsKey, value);
|
||||||
|
|
||||||
double get cameraEvCalibration => _sharedPreferences.getDouble(_cameraEvCalibrationKey) ?? 0.0;
|
double get cameraEvCalibration => _sharedPreferences.getDouble(_cameraEvCalibrationKey) ?? 0.0;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:app_settings/app_settings.dart';
|
import 'package:app_settings/app_settings.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/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';
|
||||||
|
@ -9,16 +10,22 @@ import 'package:permission_handler/permission_handler.dart';
|
||||||
|
|
||||||
class MeteringInteractor {
|
class MeteringInteractor {
|
||||||
final UserPreferencesService _userPreferencesService;
|
final UserPreferencesService _userPreferencesService;
|
||||||
|
final CaffeineService _caffeineService;
|
||||||
final HapticsService _hapticsService;
|
final HapticsService _hapticsService;
|
||||||
final PermissionsService _permissionsService;
|
final PermissionsService _permissionsService;
|
||||||
final LightSensorService _lightSensorService;
|
final LightSensorService _lightSensorService;
|
||||||
|
|
||||||
const MeteringInteractor(
|
MeteringInteractor(
|
||||||
this._userPreferencesService,
|
this._userPreferencesService,
|
||||||
|
this._caffeineService,
|
||||||
this._hapticsService,
|
this._hapticsService,
|
||||||
this._permissionsService,
|
this._permissionsService,
|
||||||
this._lightSensorService,
|
this._lightSensorService,
|
||||||
);
|
) {
|
||||||
|
if (_userPreferencesService.caffeine) {
|
||||||
|
_caffeineService.keepScreenOn(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
double get cameraEvCalibration => _userPreferencesService.cameraEvCalibration;
|
||||||
double get lightSensorEvCalibration => _userPreferencesService.lightSensorEvCalibration;
|
double get lightSensorEvCalibration => _userPreferencesService.lightSensorEvCalibration;
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
|
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';
|
||||||
|
|
||||||
class SettingsInteractor {
|
class SettingsInteractor {
|
||||||
final UserPreferencesService _userPreferencesService;
|
final UserPreferencesService _userPreferencesService;
|
||||||
|
final CaffeineService _caffeineService;
|
||||||
final HapticsService _hapticsService;
|
final HapticsService _hapticsService;
|
||||||
|
|
||||||
const SettingsInteractor(
|
const SettingsInteractor(
|
||||||
this._userPreferencesService,
|
this._userPreferencesService,
|
||||||
|
this._caffeineService,
|
||||||
this._hapticsService,
|
this._hapticsService,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -14,9 +17,21 @@ class SettingsInteractor {
|
||||||
void setCameraEvCalibration(double value) => _userPreferencesService.cameraEvCalibration = value;
|
void setCameraEvCalibration(double value) => _userPreferencesService.cameraEvCalibration = value;
|
||||||
|
|
||||||
double get lightSensorEvCalibration => _userPreferencesService.lightSensorEvCalibration;
|
double get lightSensorEvCalibration => _userPreferencesService.lightSensorEvCalibration;
|
||||||
void setLightSensorEvCalibration(double value) => _userPreferencesService.lightSensorEvCalibration = value;
|
void setLightSensorEvCalibration(double value) =>
|
||||||
|
_userPreferencesService.lightSensorEvCalibration = value;
|
||||||
|
|
||||||
|
bool get isCaffeineEnabled => _userPreferencesService.caffeine;
|
||||||
|
Future<void> enableCaffeine(bool enable) async {
|
||||||
|
await _caffeineService.keepScreenOn(enable).then((value) {
|
||||||
|
_userPreferencesService.caffeine = enable;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
bool get isHapticsEnabled => _userPreferencesService.haptics;
|
bool get isHapticsEnabled => _userPreferencesService.haptics;
|
||||||
|
void enableHaptics(bool enable) {
|
||||||
|
_userPreferencesService.haptics = enable;
|
||||||
|
quickVibration();
|
||||||
|
}
|
||||||
|
|
||||||
/// Executes vibration if haptics are enabled in settings
|
/// Executes vibration if haptics are enabled in settings
|
||||||
void quickVibration() {
|
void quickVibration() {
|
||||||
|
@ -27,6 +42,4 @@ class SettingsInteractor {
|
||||||
void responseVibration() {
|
void responseVibration() {
|
||||||
if (_userPreferencesService.haptics) _hapticsService.responseVibration();
|
if (_userPreferencesService.haptics) _hapticsService.responseVibration();
|
||||||
}
|
}
|
||||||
|
|
||||||
void enableHaptics(bool enable) => _userPreferencesService.haptics = enable;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
"camera": "Camera",
|
"camera": "Camera",
|
||||||
"lightSensor": "Light sensor",
|
"lightSensor": "Light sensor",
|
||||||
"general": "General",
|
"general": "General",
|
||||||
|
"keepScreenOn": "Keep screen on",
|
||||||
"haptics": "Haptics",
|
"haptics": "Haptics",
|
||||||
"theme": "Theme",
|
"theme": "Theme",
|
||||||
"chooseTheme": "Choose theme",
|
"chooseTheme": "Choose theme",
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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/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/photography_values/photography_value.dart';
|
import 'package:lightmeter/data/models/photography_values/photography_value.dart';
|
||||||
|
@ -25,6 +26,7 @@ class _MeteringFlowState extends State<MeteringFlow> {
|
||||||
return Provider(
|
return Provider(
|
||||||
create: (context) => MeteringInteractor(
|
create: (context) => MeteringInteractor(
|
||||||
context.read<UserPreferencesService>(),
|
context.read<UserPreferencesService>(),
|
||||||
|
context.read<CaffeineService>(),
|
||||||
context.read<HapticsService>(),
|
context.read<HapticsService>(),
|
||||||
context.read<PermissionsService>(),
|
context.read<PermissionsService>(),
|
||||||
context.read<LightSensorService>(),
|
context.read<LightSensorService>(),
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:lightmeter/interactors/settings_interactor.dart';
|
||||||
|
|
||||||
|
class CaffeineListTileBloc extends Cubit<bool> {
|
||||||
|
final SettingsInteractor _settingsInteractor;
|
||||||
|
|
||||||
|
CaffeineListTileBloc(
|
||||||
|
this._settingsInteractor,
|
||||||
|
) : super(_settingsInteractor.isCaffeineEnabled);
|
||||||
|
|
||||||
|
void onCaffeineChanged(bool value) {
|
||||||
|
_settingsInteractor.enableCaffeine(value);
|
||||||
|
emit(value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:lightmeter/interactors/settings_interactor.dart';
|
||||||
|
|
||||||
|
import 'bloc_list_tile_caffeine.dart';
|
||||||
|
import 'widget_list_tile_caffeine.dart';
|
||||||
|
|
||||||
|
class CaffeineListTileProvider extends StatelessWidget {
|
||||||
|
const CaffeineListTileProvider({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocProvider(
|
||||||
|
create: (context) => CaffeineListTileBloc(context.read<SettingsInteractor>()),
|
||||||
|
child: const CaffeineListTile(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:lightmeter/generated/l10n.dart';
|
||||||
|
|
||||||
|
import 'bloc_list_tile_caffeine.dart';
|
||||||
|
|
||||||
|
class CaffeineListTile extends StatelessWidget {
|
||||||
|
const CaffeineListTile({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return BlocBuilder<CaffeineListTileBloc, bool>(
|
||||||
|
builder: (context, state) => SwitchListTile(
|
||||||
|
secondary: const Icon(Icons.screen_lock_portrait),
|
||||||
|
title: Text(S.of(context).keepScreenOn),
|
||||||
|
value: state,
|
||||||
|
onChanged: context.read<CaffeineListTileBloc>().onCaffeineChanged,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,11 +8,8 @@ class HapticsListTileBloc extends Cubit<bool> {
|
||||||
this._settingsInteractor,
|
this._settingsInteractor,
|
||||||
) : super(_settingsInteractor.isHapticsEnabled);
|
) : super(_settingsInteractor.isHapticsEnabled);
|
||||||
|
|
||||||
void onHapticsChange(bool value) {
|
void onHapticsChanged(bool value) {
|
||||||
_settingsInteractor.enableHaptics(value);
|
_settingsInteractor.enableHaptics(value);
|
||||||
if (value) {
|
|
||||||
_settingsInteractor.quickVibration();
|
|
||||||
}
|
|
||||||
emit(value);
|
emit(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ class HapticsListTile extends StatelessWidget {
|
||||||
secondary: const Icon(Icons.vibration),
|
secondary: const Icon(Icons.vibration),
|
||||||
title: Text(S.of(context).haptics),
|
title: Text(S.of(context).haptics),
|
||||||
value: state,
|
value: state,
|
||||||
onChanged: context.read<HapticsListTileBloc>().onHapticsChange,
|
onChanged: context.read<HapticsListTileBloc>().onHapticsChanged,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.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/interactors/settings_interactor.dart';
|
import 'package:lightmeter/interactors/settings_interactor.dart';
|
||||||
|
@ -13,6 +14,7 @@ class SettingsFlow extends StatelessWidget {
|
||||||
return Provider(
|
return Provider(
|
||||||
create: (context) => SettingsInteractor(
|
create: (context) => SettingsInteractor(
|
||||||
context.read<UserPreferencesService>(),
|
context.read<UserPreferencesService>(),
|
||||||
|
context.read<CaffeineService>(),
|
||||||
context.read<HapticsService>(),
|
context.read<HapticsService>(),
|
||||||
),
|
),
|
||||||
child: const SettingsScreen(),
|
child: const SettingsScreen(),
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'package:lightmeter/generated/l10n.dart';
|
||||||
import 'package:lightmeter/res/dimens.dart';
|
import 'package:lightmeter/res/dimens.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import 'components/caffeine/provider_list_tile_caffeine.dart';
|
||||||
import 'components/calibration/widget_list_tile_calibration.dart';
|
import 'components/calibration/widget_list_tile_calibration.dart';
|
||||||
import 'components/haptics/provider_list_tile_haptics.dart';
|
import 'components/haptics/provider_list_tile_haptics.dart';
|
||||||
import 'components/primary_color/widget_list_tile_primary_color.dart';
|
import 'components/primary_color/widget_list_tile_primary_color.dart';
|
||||||
|
@ -61,6 +62,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
SettingsSection(
|
SettingsSection(
|
||||||
title: S.of(context).general,
|
title: S.of(context).general,
|
||||||
children: const [
|
children: const [
|
||||||
|
CaffeineListTileProvider(),
|
||||||
HapticsListTileProvider(),
|
HapticsListTileProvider(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue