mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-24 00:10:47 +00:00
Compare commits
5 commits
1f88c7d9a4
...
c50baa4802
Author | SHA1 | Date | |
---|---|---|---|
|
c50baa4802 | ||
|
205255b916 | ||
|
e165b53ef2 | ||
|
6ee662d79d | ||
|
cdaf0905da |
15 changed files with 113 additions and 104 deletions
|
@ -12,9 +12,7 @@ import 'package:lightmeter/utils/inherited_generics.dart';
|
|||
class Application extends StatelessWidget {
|
||||
final Environment env;
|
||||
|
||||
Application(this.env, {super.key});
|
||||
|
||||
final RouteObserver<ModalRoute> routeObserver = RouteObserver<ModalRoute>();
|
||||
const Application(this.env, {super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -32,19 +30,15 @@ class Application extends StatelessWidget {
|
|||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
builder: (context, child) => InheritedWidgetBase<RouteObserver<ModalRoute>>(
|
||||
data: routeObserver,
|
||||
child: MediaQuery(
|
||||
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
|
||||
child: child!,
|
||||
),
|
||||
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(),
|
||||
},
|
||||
navigatorObservers: [routeObserver],
|
||||
),
|
||||
)
|
||||
: const SizedBox(),
|
||||
|
|
|
@ -4,5 +4,5 @@ import 'package:lightmeter/environment.dart';
|
|||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
runApp(Application(const Environment.dev()));
|
||||
runApp(const Application(Environment.dev()));
|
||||
}
|
||||
|
|
|
@ -6,5 +6,5 @@ import 'package:lightmeter/firebase.dart';
|
|||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
await initializeFirebase();
|
||||
runApp(Application(const Environment.prod()));
|
||||
runApp(const Application(Environment.prod()));
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
|
|||
on<MeasureEvent>(_onMeasure, transformer: droppable());
|
||||
on<MeasuredEvent>(_onMeasured);
|
||||
on<MeasureErrorEvent>(_onMeasureError);
|
||||
on<SettingsOpenedEvent>(_onSettingsOpened);
|
||||
on<SettingsClosedEvent>(_onSettingsClosed);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -233,4 +235,12 @@ class MeteringBloc extends Bloc<MeteringEvent, MeteringState> {
|
|||
add(const MeasureEvent());
|
||||
}
|
||||
}
|
||||
|
||||
void _onSettingsOpened(SettingsOpenedEvent _, Emitter __) {
|
||||
_communicationBloc.add(const communication_events.SettingsOpenedEvent());
|
||||
}
|
||||
|
||||
void _onSettingsClosed(SettingsClosedEvent _, Emitter __) {
|
||||
_communicationBloc.add(const communication_events.SettingsClosedEvent());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,5 +11,7 @@ class MeteringCommunicationBloc
|
|||
on<MeasureEvent>((_, emit) => emit(MeasureState()));
|
||||
on<MeteringInProgressEvent>((event, emit) => emit(MeteringInProgressState(event.ev100)));
|
||||
on<MeteringEndedEvent>((event, emit) => emit(MeteringEndedState(event.ev100)));
|
||||
on<SettingsOpenedEvent>((_, emit) => emit(const SettingsOpenedState()));
|
||||
on<SettingsClosedEvent>((_, emit) => emit(const SettingsClosedState()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,3 +47,11 @@ class MeteringEndedEvent extends MeasuredEvent {
|
|||
@override
|
||||
int get hashCode => Object.hash(ev100, runtimeType);
|
||||
}
|
||||
|
||||
class SettingsOpenedEvent extends ScreenEvent {
|
||||
const SettingsOpenedEvent();
|
||||
}
|
||||
|
||||
class SettingsClosedEvent extends ScreenEvent {
|
||||
const SettingsClosedEvent();
|
||||
}
|
||||
|
|
|
@ -51,3 +51,11 @@ class MeteringEndedState extends MeasuredState {
|
|||
@override
|
||||
int get hashCode => Object.hash(ev100, runtimeType);
|
||||
}
|
||||
|
||||
class SettingsOpenedState extends SourceState {
|
||||
const SettingsOpenedState();
|
||||
}
|
||||
|
||||
class SettingsClosedState extends SourceState {
|
||||
const SettingsClosedState();
|
||||
}
|
||||
|
|
|
@ -40,6 +40,8 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
|||
|
||||
double? _ev100 = 0.0;
|
||||
|
||||
bool _settingsOpened = false;
|
||||
|
||||
CameraContainerBloc(
|
||||
this._meteringInteractor,
|
||||
this._volumeKeysNotifier,
|
||||
|
@ -72,18 +74,26 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
|||
|
||||
@override
|
||||
void onCommunicationState(communication_states.SourceState communicationState) {
|
||||
if (communicationState is communication_states.MeasureState) {
|
||||
if (_canTakePhoto) {
|
||||
_takePhoto().then((ev100Raw) {
|
||||
if (ev100Raw != null) {
|
||||
_ev100 = ev100Raw + _meteringInteractor.cameraEvCalibration;
|
||||
communicationBloc.add(communication_event.MeteringEndedEvent(_ev100));
|
||||
} else {
|
||||
_ev100 = null;
|
||||
communicationBloc.add(const communication_event.MeteringEndedEvent(null));
|
||||
}
|
||||
});
|
||||
}
|
||||
switch (communicationState) {
|
||||
case communication_states.MeasureState():
|
||||
if (_canTakePhoto) {
|
||||
_takePhoto().then((ev100Raw) {
|
||||
if (ev100Raw != null) {
|
||||
_ev100 = ev100Raw + _meteringInteractor.cameraEvCalibration;
|
||||
communicationBloc.add(communication_event.MeteringEndedEvent(_ev100));
|
||||
} else {
|
||||
_ev100 = null;
|
||||
communicationBloc.add(const communication_event.MeteringEndedEvent(null));
|
||||
}
|
||||
});
|
||||
}
|
||||
case communication_states.SettingsOpenedState():
|
||||
_settingsOpened = true;
|
||||
add(const DeinitializeEvent());
|
||||
case communication_states.SettingsClosedState():
|
||||
_settingsOpened = false;
|
||||
add(const InitializeEvent());
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +166,7 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
|||
|
||||
Future<void> _onDeinitialize(DeinitializeEvent _, Emitter emit) async {
|
||||
emit(const CameraLoadingState());
|
||||
unawaited(_cameraController?.dispose().then((_) => _cameraController = null));
|
||||
await _cameraController?.dispose().then((_) => _cameraController = null);
|
||||
}
|
||||
|
||||
Future<void> _onZoomChanged(ZoomChangedEvent event, Emitter emit) async {
|
||||
|
@ -224,13 +234,15 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
|
|||
}
|
||||
|
||||
Future<void> _appLifecycleStateObserver(AppLifecycleState state) async {
|
||||
switch (state) {
|
||||
case AppLifecycleState.resumed:
|
||||
add(const InitializeEvent());
|
||||
case AppLifecycleState.paused:
|
||||
case AppLifecycleState.detached:
|
||||
add(const DeinitializeEvent());
|
||||
default:
|
||||
if (!_settingsOpened) {
|
||||
switch (state) {
|
||||
case AppLifecycleState.resumed:
|
||||
add(const InitializeEvent());
|
||||
case AppLifecycleState.paused:
|
||||
case AppLifecycleState.detached:
|
||||
add(const DeinitializeEvent());
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,9 @@ import 'package:lightmeter/screens/metering/components/camera_container/state_co
|
|||
import 'package:lightmeter/screens/metering/components/shared/exposure_pairs_list/widget_list_exposure_pairs.dart';
|
||||
import 'package:lightmeter/screens/metering/components/shared/metering_top_bar/widget_top_bar_metering.dart';
|
||||
import 'package:lightmeter/screens/metering/components/shared/readings_container/widget_container_readings.dart';
|
||||
import 'package:lightmeter/utils/inherited_generics.dart';
|
||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
|
||||
class CameraContainer extends StatefulWidget {
|
||||
class CameraContainer extends StatelessWidget {
|
||||
final ExposurePair? fastest;
|
||||
final ExposurePair? slowest;
|
||||
final Film film;
|
||||
|
@ -45,29 +44,6 @@ class CameraContainer extends StatefulWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<CameraContainer> createState() => _CameraContainerState();
|
||||
}
|
||||
|
||||
class _CameraContainerState extends State<CameraContainer> with RouteAware {
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
context.get<RouteObserver<ModalRoute>>().subscribe(this, ModalRoute.of(context)!);
|
||||
}
|
||||
|
||||
@override
|
||||
void didPushNext() {
|
||||
super.didPushNext();
|
||||
context.read<CameraContainerBloc>().add(const DeinitializeEvent());
|
||||
}
|
||||
|
||||
@override
|
||||
void didPopNext() {
|
||||
super.didPopNext();
|
||||
context.read<CameraContainerBloc>().add(const InitializeEvent());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final double cameraViewHeight =
|
||||
|
@ -99,14 +75,14 @@ class _CameraContainerState extends State<CameraContainer> with RouteAware {
|
|||
children: [
|
||||
MeteringTopBar(
|
||||
readingsContainer: ReadingsContainer(
|
||||
fastest: widget.fastest,
|
||||
slowest: widget.slowest,
|
||||
film: widget.film,
|
||||
iso: widget.iso,
|
||||
nd: widget.nd,
|
||||
onFilmChanged: widget.onFilmChanged,
|
||||
onIsoChanged: widget.onIsoChanged,
|
||||
onNdChanged: widget.onNdChanged,
|
||||
fastest: fastest,
|
||||
slowest: slowest,
|
||||
film: film,
|
||||
iso: iso,
|
||||
nd: nd,
|
||||
onFilmChanged: onFilmChanged,
|
||||
onIsoChanged: onIsoChanged,
|
||||
onNdChanged: onNdChanged,
|
||||
),
|
||||
appendixHeight: topBarOverflow,
|
||||
preview: const _CameraViewBuilder(),
|
||||
|
@ -116,7 +92,7 @@ class _CameraContainerState extends State<CameraContainer> with RouteAware {
|
|||
padding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM),
|
||||
child: _MiddleContentWrapper(
|
||||
topBarOverflow: topBarOverflow,
|
||||
leftContent: ExposurePairsList(widget.exposurePairs),
|
||||
leftContent: ExposurePairsList(exposurePairs),
|
||||
rightContent: const _CameraControlsBuilder(),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -31,12 +31,16 @@ class LightSensorContainerBloc
|
|||
|
||||
@override
|
||||
void onCommunicationState(communication_states.SourceState communicationState) {
|
||||
if (communicationState is communication_states.MeasureState) {
|
||||
if (_luxSubscriptions == null) {
|
||||
_startMetering();
|
||||
} else {
|
||||
switch (communicationState) {
|
||||
case communication_states.MeasureState():
|
||||
if (_luxSubscriptions == null) {
|
||||
_startMetering();
|
||||
} else {
|
||||
_cancelMetering();
|
||||
}
|
||||
case communication_states.SettingsOpenedState():
|
||||
_cancelMetering();
|
||||
}
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/data/models/exposure_pair.dart';
|
||||
import 'package:lightmeter/data/models/film.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/screens/metering/components/light_sensor_container/bloc_container_light_sensor.dart';
|
||||
import 'package:lightmeter/screens/metering/components/light_sensor_container/event_container_light_sensor.dart';
|
||||
import 'package:lightmeter/screens/metering/components/shared/exposure_pairs_list/widget_list_exposure_pairs.dart';
|
||||
import 'package:lightmeter/screens/metering/components/shared/metering_top_bar/widget_top_bar_metering.dart';
|
||||
import 'package:lightmeter/screens/metering/components/shared/readings_container/widget_container_readings.dart';
|
||||
import 'package:lightmeter/utils/inherited_generics.dart';
|
||||
import 'package:m3_lightmeter_resources/m3_lightmeter_resources.dart';
|
||||
|
||||
class LightSensorContainer extends StatefulWidget {
|
||||
class LightSensorContainer extends StatelessWidget {
|
||||
final ExposurePair? fastest;
|
||||
final ExposurePair? slowest;
|
||||
final Film film;
|
||||
|
@ -35,43 +31,26 @@ class LightSensorContainer extends StatefulWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<LightSensorContainer> createState() => _LightSensorContainerState();
|
||||
}
|
||||
|
||||
class _LightSensorContainerState extends State<LightSensorContainer> with RouteAware {
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
context.get<RouteObserver<ModalRoute>>().subscribe(this, ModalRoute.of(context)!);
|
||||
}
|
||||
|
||||
@override
|
||||
void didPushNext() {
|
||||
super.didPushNext();
|
||||
context.read<LightSensorContainerBloc>().add(const CancelLuxMeteringEvent());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
MeteringTopBar(
|
||||
readingsContainer: ReadingsContainer(
|
||||
fastest: widget.fastest,
|
||||
slowest: widget.slowest,
|
||||
film: widget.film,
|
||||
iso: widget.iso,
|
||||
nd: widget.nd,
|
||||
onFilmChanged: widget.onFilmChanged,
|
||||
onIsoChanged: widget.onIsoChanged,
|
||||
onNdChanged: widget.onNdChanged,
|
||||
fastest: fastest,
|
||||
slowest: slowest,
|
||||
film: film,
|
||||
iso: iso,
|
||||
nd: nd,
|
||||
onFilmChanged: onFilmChanged,
|
||||
onIsoChanged: onIsoChanged,
|
||||
onNdChanged: onNdChanged,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: Dimens.paddingM),
|
||||
child: Center(child: ExposurePairsList(widget.exposurePairs)),
|
||||
child: Center(child: ExposurePairsList(exposurePairs)),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -10,7 +10,6 @@ class VolumeKeysNotifier extends ChangeNotifier with RouteAware {
|
|||
VolumeKey _value = VolumeKey.up;
|
||||
|
||||
VolumeKeysNotifier(this.volumeEventsService) {
|
||||
// TODO: add RouteObserver and disable overriden action if SettingScreen is opened
|
||||
_volumeKeysSubscription = volumeEventsService
|
||||
.volumeButtonsEventStream()
|
||||
.map((event) => event == 24 ? VolumeKey.up : VolumeKey.down)
|
||||
|
|
|
@ -45,3 +45,11 @@ class MeasureErrorEvent extends MeteringEvent {
|
|||
|
||||
const MeasureErrorEvent({required this.isMetering});
|
||||
}
|
||||
|
||||
class SettingsOpenedEvent extends MeteringEvent {
|
||||
const SettingsOpenedEvent();
|
||||
}
|
||||
|
||||
class SettingsClosedEvent extends MeteringEvent {
|
||||
const SettingsClosedEvent();
|
||||
}
|
||||
|
|
|
@ -50,7 +50,12 @@ class MeteringScreen extends StatelessWidget {
|
|||
? EvSourceTypeProvider.of(context).toggleType
|
||||
: null,
|
||||
onMeasure: () => context.read<MeteringBloc>().add(const MeasureEvent()),
|
||||
onSettings: () => Navigator.pushNamed(context, 'settings'),
|
||||
onSettings: () {
|
||||
context.read<MeteringBloc>().add(const SettingsOpenedEvent());
|
||||
Navigator.pushNamed(context, 'settings').then((value) {
|
||||
context.read<MeteringBloc>().add(const SettingsClosedEvent());
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -11,6 +11,10 @@ class VolumeActionsListTileBloc extends Cubit<VolumeAction> {
|
|||
|
||||
void onVolumeActionChanged(VolumeAction value) {
|
||||
_settingsInteractor.setVolumeAction(value);
|
||||
|
||||
// while in settings we allow system to handle volume
|
||||
// so that volume keys action works only when necessary - on the metering screen
|
||||
_settingsInteractor.disableVolumeHandling();
|
||||
emit(value);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue