Line data Source code
1 : import 'dart:async';
2 :
3 : import 'package:app_pym/core/permission_handler/permission_handler.dart';
4 : import 'package:app_pym/data/devices/compass_device.dart';
5 : import 'package:bloc/bloc.dart';
6 : import 'package:flutter/foundation.dart';
7 : import 'package:freezed_annotation/freezed_annotation.dart';
8 : import 'package:injectable/injectable.dart';
9 : import 'package:permission_handler/permission_handler.dart';
10 :
11 : part 'compass_bloc.freezed.dart';
12 : part 'compass_event.dart';
13 : part 'compass_state.dart';
14 :
15 : @prod
16 : @injectable
17 : class CompassBloc extends Bloc<CompassEvent, CompassState> {
18 : final PermissionHandler permissionHandler;
19 : final CompassDevice compassDevice;
20 : StreamSubscription<double> subscription;
21 : final ValueNotifier<double> progress = ValueNotifier<double>(0.0);
22 :
23 1 : CompassBloc({
24 : @required this.permissionHandler,
25 : @required this.compassDevice,
26 : });
27 :
28 1 : @override
29 : CompassState get initialState => const CompassState.initial();
30 :
31 : @override
32 0 : Future<void> close() async {
33 0 : await subscription?.cancel();
34 0 : progress.dispose();
35 0 : return super.close();
36 : }
37 :
38 : @override
39 1 : Stream<CompassState> mapEventToState(
40 : CompassEvent event,
41 : ) async* {
42 1 : yield const CompassState.loading();
43 :
44 3 : final statuses = await permissionHandler.requestPermissions;
45 2 : final locationIsEnabled = permissionHandler.locationIsEnabled;
46 :
47 2 : if (statuses[Permission.camera] == PermissionStatus.granted &&
48 2 : statuses[Permission.locationWhenInUse] == PermissionStatus.granted &&
49 1 : await locationIsEnabled) {
50 : int index = 0;
51 2 : progress.value = 0.0;
52 2 : await subscription?.cancel();
53 3 : final stream = compassDevice.heading.asBroadcastStream();
54 3 : subscription = stream.listen((data) {
55 1 : index++;
56 3 : progress.value = index / 100;
57 : });
58 1 : yield const CompassState.movingLoading();
59 2 : await stream.elementAt(100);
60 1 : yield const CompassState.stopMovingLoading();
61 :
62 2 : final bearing = await Future<double>.delayed(
63 : const Duration(seconds: 2),
64 2 : () => stream.first,
65 : );
66 3 : await subscription.cancel();
67 2 : yield CompassState.loaded(bearing);
68 : } else {
69 2 : yield CompassState.notPermitted(
70 : cameraIsGranted:
71 2 : statuses[Permission.camera] == PermissionStatus.granted,
72 1 : locationIsEnabled: await locationIsEnabled,
73 : locationIsGranted:
74 2 : statuses[Permission.locationWhenInUse] == PermissionStatus.granted,
75 : );
76 : }
77 : }
78 : }
|