diff --git a/features/inspection/lib/presentation/filter/logic.dart b/features/inspection/lib/presentation/filter/logic.dart index 272f63c..949e609 100644 --- a/features/inspection/lib/presentation/filter/logic.dart +++ b/features/inspection/lib/presentation/filter/logic.dart @@ -2,16 +2,12 @@ import 'dart:async'; import 'package:flutter/animation.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_map/flutter_map.dart'; -import 'package:flutter_map_animations/flutter_map_animations.dart'; -import 'package:geolocator/geolocator.dart'; -import 'package:latlong2/latlong.dart'; -import 'package:rasadyar_core/core.dart'; import 'package:inspection/data/utils/marker_generator.dart'; +import 'package:rasadyar_core/core.dart'; enum BottomSheetStep { filter, markerSelected, markerDetails } -class SupervisionFilterLogic extends GetxController +class InspectorFilterLogic extends GetxController with GetTickerProviderStateMixin { Rx currentLocation = LatLng(35.824891, 50.948025).obs; RxList allMarkers = [].obs; @@ -23,7 +19,6 @@ class SupervisionFilterLogic extends GetxController RxInt showIndex = 0.obs; bool showSlideHint = true; - Rx bottomSheetStep = BottomSheetStep.filter.obs; late Rx slidController; @@ -33,30 +28,13 @@ class SupervisionFilterLogic extends GetxController late Rx sheetController; Future determineCurrentPosition() async { - bool serviceEnabled; - LocationPermission permission; - - serviceEnabled = await Geolocator.isLocationServiceEnabled(); - if (!serviceEnabled) { - return Future.error('Location services are disabled.'); - } - - permission = await Geolocator.checkPermission(); - if (permission == LocationPermission.denied) { - permission = await Geolocator.requestPermission(); - if (permission == LocationPermission.denied) { - return Future.error('Location permissions are denied.'); - } - } - - if (permission == LocationPermission.deniedForever) { - return Future.error('Location permissions are permanently denied.'); - } final position = await Geolocator.getCurrentPosition( locationSettings: AndroidSettings(accuracy: LocationAccuracy.best), ); final latLng = LatLng(position.latitude, position.longitude); + + currentLocation.value = latLng; markers.add(latLng); animatedMapController.animateTo( @@ -99,6 +77,7 @@ class SupervisionFilterLogic extends GetxController allMarkers.value = generatedMarkers; } + @override void onInit() { super.onInit(); @@ -154,9 +133,8 @@ class SupervisionFilterLogic extends GetxController @override void onReady() { super.onReady(); - determineCurrentPosition(); + // determineCurrentPosition(); generatedMarkers(); - } Future triggerSlidableAnimation() async { @@ -167,11 +145,8 @@ class SupervisionFilterLogic extends GetxController showSlideHint = !showSlideHint; } - - @override void onClose() { - super.onClose(); } } diff --git a/features/inspection/lib/presentation/filter/view.dart b/features/inspection/lib/presentation/filter/view.dart index e6d7cd9..2ee053c 100644 --- a/features/inspection/lib/presentation/filter/view.dart +++ b/features/inspection/lib/presentation/filter/view.dart @@ -5,7 +5,7 @@ import 'package:rasadyar_core/presentation/widget/buttons/fab.dart'; import 'logic.dart'; -class SupervisionFilterPage extends GetView { +class SupervisionFilterPage extends GetView { const SupervisionFilterPage({super.key}); @override diff --git a/features/inspection/lib/presentation/root/logic.dart b/features/inspection/lib/presentation/root/logic.dart index c7428af..bc88796 100644 --- a/features/inspection/lib/presentation/root/logic.dart +++ b/features/inspection/lib/presentation/root/logic.dart @@ -1,16 +1,83 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_core/core.dart'; import 'package:inspection/presentation/action/view.dart'; import 'package:inspection/presentation/filter/view.dart'; import 'package:inspection/presentation/profile/view.dart'; +import 'package:rasadyar_core/core.dart'; +import 'package:rasadyar_core/data/utils.dart'; + +enum ErrorLocationType { serviceDisabled, permissionDenied, none } class RootLogic extends GetxController { RxInt currentIndex = 0.obs; List pages = [SupervisionFilterPage(), ActionPage(), ProfilePage()]; + RxList errorLocationType = RxList(); + + Stream listenToLocationServiceStatus() { + return Geolocator.getServiceStatusStream().map((status) { + return status == ServiceStatus.enabled; + }); + } + + Future locationServiceEnabled() async { + bool serviceEnabled = await Geolocator.isLocationServiceEnabled(); + if (!serviceEnabled) { + return false; + } + return true; + } + + Future checkPermission({bool request = false}) async { + try { + final LocationPermission permission = await Geolocator.checkPermission(); + + switch (permission) { + case LocationPermission.denied: + final LocationPermission requestResult = await Geolocator.requestPermission(); + return requestResult != LocationPermission.denied && + requestResult != LocationPermission.deniedForever; + + case LocationPermission.deniedForever: + + return request ? await Geolocator.openAppSettings() : false; + + case LocationPermission.always: + case LocationPermission.whileInUse: + + return true; + + default: + return false; + } + } catch (e) { + + eLog(e); + return await Geolocator.openLocationSettings(); + } + } @override void onReady() { super.onReady(); + + locationServiceEnabled().then((value) { + if (!value) { + errorLocationType.add(ErrorLocationType.serviceDisabled); + } + }); + + checkPermission().then((value) { + if (!value) { + errorLocationType.add(ErrorLocationType.permissionDenied); + } + }); + + listenToLocationServiceStatus().listen((event) { + if (!event) { + errorLocationType.add(ErrorLocationType.serviceDisabled); + } else { + errorLocationType.remove(ErrorLocationType.serviceDisabled); + } + }); } void changePage(int index) { diff --git a/features/inspection/lib/presentation/root/view.dart b/features/inspection/lib/presentation/root/view.dart index 4ce262b..7693679 100644 --- a/features/inspection/lib/presentation/root/view.dart +++ b/features/inspection/lib/presentation/root/view.dart @@ -12,35 +12,135 @@ class RootPage extends GetView { return Scaffold( body: Stack( children: [ + ObxValue((errorType) { + if (errorType.isNotEmpty) { + if (errorType.contains(ErrorLocationType.serviceDisabled)) { + Future.microtask(() { + Get.defaultDialog( + title: 'خطا', + content: const Text('سرویس مکان‌یابی غیرفعال است'), + cancel: ROutlinedElevated( + text: 'بررسی مجدد', + width: 120, + textStyle: AppFonts.yekan16, + onPressed: () async { + var service = await controller.locationServiceEnabled(); + eLog(service); + if (service) { + controller.errorLocationType.remove( + ErrorLocationType.serviceDisabled, + ); + Get.back(); + } + // Don't call Get.back() if service is still disabled + }, + ), + confirm: RElevated( + text: 'روشن کردن', + textStyle: AppFonts.yekan16, + width: 120, + onPressed: () async { + var res = await Geolocator.openLocationSettings(); + if (res) { + var service = + await controller.locationServiceEnabled(); + if (service) { + controller.errorLocationType.remove( + ErrorLocationType.serviceDisabled, + ); + Get.back(); + } + } + }, + ), + + contentPadding: EdgeInsets.all(8), + onWillPop: () async { + return controller.errorLocationType.isEmpty; + }, + barrierDismissible: false, + ); + }); + } else { + Future.microtask(() { + Get.defaultDialog( + title: 'خطا', + content: const Text( + ' دسترسی به سرویس مکان‌یابی غیرفعال است', + ), + cancel: ROutlinedElevated( + text: 'بررسی مجدد', + width: 120, + textStyle: AppFonts.yekan16, + onPressed: () async { + await controller.checkPermission(); + }, + ), + confirm: RElevated( + text: 'اجازه دادن', + textStyle: AppFonts.yekan16, + width: 120, + onPressed: () async { + var res = await controller.checkPermission( + request: true, + ); + if (res) { + controller.errorLocationType.remove( + ErrorLocationType.permissionDenied, + ); + Get.back(); + } + }, + ), + + contentPadding: EdgeInsets.all(8), + onWillPop: () async { + return controller.errorLocationType.isEmpty; + }, + barrierDismissible: false, + ); + }); + } + } + return const SizedBox.shrink(); + }, controller.errorLocationType), + + ObxValue( + (currentIndex) => IndexedStack( + index: currentIndex.value, + children: controller.pages, + ), + controller.currentIndex, + ), Align( alignment: Alignment.bottomCenter, child: WaveBottomNavigation( items: [ - WaveBottomNavigationItem( - title: 'خانه', - icon:Assets.vecMapSvg, - ), + WaveBottomNavigationItem(title: 'خانه', icon: Assets.vecMapSvg), WaveBottomNavigationItem( title: 'عملیات', - icon:Assets.vecUserSvg, + icon: Assets.vecUserSvg, ), WaveBottomNavigationItem( title: 'افزودن', - icon:Assets.vecAddSvg, + icon: Assets.vecAddSvg, ), WaveBottomNavigationItem( title: 'آمار', - icon:Assets.vecDiagramSvg, - ), WaveBottomNavigationItem( + icon: Assets.vecDiagramSvg, + ), + WaveBottomNavigationItem( title: 'تماس', - icon:Assets.vecCallSvg, - ), WaveBottomNavigationItem( + icon: Assets.vecCallSvg, + ), + WaveBottomNavigationItem( title: 'مکان ', - icon:Assets.vecGpsSvg, - ), WaveBottomNavigationItem( + icon: Assets.vecGpsSvg, + ), + WaveBottomNavigationItem( title: 'تاریخ', - icon:Assets.vecCalendarSvg, + icon: Assets.vecCalendarSvg, ), ], onPageChanged: (index) { diff --git a/features/inspection/lib/presentation/routes/app_pages.dart b/features/inspection/lib/presentation/routes/app_pages.dart index b1ec38c..aeb25c4 100644 --- a/features/inspection/lib/presentation/routes/app_pages.dart +++ b/features/inspection/lib/presentation/routes/app_pages.dart @@ -26,7 +26,7 @@ sealed class InspectionPages { page: () => RootPage(), binding: BindingsBuilder(() { Get.put(RootLogic()); - Get.put(SupervisionFilterLogic()); + Get.put(InspectorFilterLogic()); Get.lazyPut(() => LocationDetailsLogic(), fenix: true); Get.lazyPut(() => ActionLogic(), fenix: true); Get.lazyPut(() => ProfileLogic(), fenix: true); diff --git a/packages/core/lib/core.dart b/packages/core/lib/core.dart index 4d57a1b..f6d3b76 100644 --- a/packages/core/lib/core.dart +++ b/packages/core/lib/core.dart @@ -14,6 +14,8 @@ export 'package:persian_datetime_picker/persian_datetime_picker.dart'; //Map and location export 'package:latlong2/latlong.dart'; export 'package:flutter_map/flutter_map.dart'; +export 'package:geolocator/geolocator.dart'; +export 'package:flutter_map_animations/flutter_map_animations.dart';