mimic google behavior with location icon button
This commit is contained in:
		@@ -1,4 +1,5 @@
 | 
			
		||||
import 'package:app/extensions/obtainProviderExtension.dart';
 | 
			
		||||
import 'package:app/extensions/positionLatLngExtension.dart';
 | 
			
		||||
import 'package:app/state/mapState.dart';
 | 
			
		||||
import 'package:app/state/timeStatusState.dart';
 | 
			
		||||
import 'package:app/util/watchState.dart';
 | 
			
		||||
@@ -19,41 +20,70 @@ class HomeView extends StatefulWidget {
 | 
			
		||||
 | 
			
		||||
class _HomePageState extends State<HomeView> {
 | 
			
		||||
  bool locationEnabled = false;
 | 
			
		||||
 | 
			
		||||
  Future<LatLng?> getLatLng() async {
 | 
			
		||||
    LocationPermission permission = await Geolocator.checkPermission();
 | 
			
		||||
    if (permission == LocationPermission.denied) {
 | 
			
		||||
      permission = await Geolocator.requestPermission();
 | 
			
		||||
      if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) {
 | 
			
		||||
        return null;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setState(() {
 | 
			
		||||
      locationEnabled = true;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    Position? position;
 | 
			
		||||
    try {
 | 
			
		||||
      position = await Geolocator.getCurrentPosition();
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      position = await Geolocator.getLastKnownPosition();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (position != null) {
 | 
			
		||||
      return LatLng(position.latitude, position.longitude);
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool locationLoading = false;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    super.initState();
 | 
			
		||||
 | 
			
		||||
    Geolocator.checkPermission().then((permission) => setState(() {
 | 
			
		||||
      locationEnabled = permission != LocationPermission.denied && permission != LocationPermission.deniedForever;
 | 
			
		||||
    }));
 | 
			
		||||
    Geolocator.getServiceStatusStream().listen((status) {
 | 
			
		||||
      setState(() {
 | 
			
		||||
        locationEnabled = status == ServiceStatus.enabled;
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    requestLiveLocation(context.obtainState<MapState>(), false, true, true);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> requestLiveLocation(MapState mapState, bool ask, bool orLast, bool loadingIndicator) async {
 | 
			
		||||
    Position? position;
 | 
			
		||||
    LocationPermission permission = await Geolocator.checkPermission();
 | 
			
		||||
 | 
			
		||||
    if (loadingIndicator && permission != LocationPermission.deniedForever) {
 | 
			
		||||
      setState(() {
 | 
			
		||||
        locationLoading = true;
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) {
 | 
			
		||||
      if (ask && permission != LocationPermission.deniedForever) {
 | 
			
		||||
        permission = await Geolocator.requestPermission();
 | 
			
		||||
      }
 | 
			
		||||
      if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) {
 | 
			
		||||
        if (orLast) position = await Geolocator.getLastKnownPosition();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) {
 | 
			
		||||
      if (position != null) {
 | 
			
		||||
        setState(() => locationEnabled = true);
 | 
			
		||||
        mapState.setCurrentLocation(position.latlng());
 | 
			
		||||
      }
 | 
			
		||||
      setState(() => locationLoading = false);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      position = await Geolocator.getCurrentPosition();
 | 
			
		||||
      setState(() {
 | 
			
		||||
        locationEnabled = true;
 | 
			
		||||
      });
 | 
			
		||||
      mapState.setLocationLive(true);
 | 
			
		||||
      mapState.setCurrentLocation(position.latlng());
 | 
			
		||||
      Geolocator.getServiceStatusStream().first.then((_) => setState(() {
 | 
			
		||||
        mapState.setLocationLive(false);
 | 
			
		||||
      }));
 | 
			
		||||
    } catch (_) {
 | 
			
		||||
      if (orLast) {
 | 
			
		||||
        position = await Geolocator.getLastKnownPosition();
 | 
			
		||||
        if (position != null) {
 | 
			
		||||
          setState(() => locationEnabled = true);
 | 
			
		||||
          mapState.setCurrentLocation(position.latlng());
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setState(() => locationLoading = false);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
@@ -72,9 +102,6 @@ class _HomePageState extends State<HomeView> {
 | 
			
		||||
                delegate: LocationSearchDelegate(),
 | 
			
		||||
              );
 | 
			
		||||
              mapState.setActiveMarker(latLng);
 | 
			
		||||
              if (latLng != null) {
 | 
			
		||||
                mapState.getMapController.move(latLng, 16);
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
          ),
 | 
			
		||||
          IconButton(
 | 
			
		||||
@@ -90,26 +117,15 @@ class _HomePageState extends State<HomeView> {
 | 
			
		||||
      ),
 | 
			
		||||
      floatingActionButton: FloatingActionButton(
 | 
			
		||||
        child: WatchState<MapState>((context, state) {
 | 
			
		||||
          if(locationEnabled)  {
 | 
			
		||||
            if(state.isCurrentlyLoading) {
 | 
			
		||||
              return const Padding(padding: EdgeInsets.all(15), child: CircularProgressIndicator(strokeWidth: 3));
 | 
			
		||||
            } else {
 | 
			
		||||
              return const Icon(Icons.my_location);
 | 
			
		||||
            }
 | 
			
		||||
          if (locationLoading) {
 | 
			
		||||
            return const Padding(padding: EdgeInsets.all(15), child: CircularProgressIndicator(strokeWidth: 3));
 | 
			
		||||
          }
 | 
			
		||||
          if (locationEnabled) {
 | 
			
		||||
            return Icon(state.isLocationLive ? Icons.my_location : Icons.location_searching);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          return const Icon(Icons.location_disabled);
 | 
			
		||||
        }),
 | 
			
		||||
        onPressed: () async {
 | 
			
		||||
          MapState mapState = context.obtainState<MapState>();
 | 
			
		||||
          mapState.setLoading(true);
 | 
			
		||||
          LatLng? latLng = await getLatLng();
 | 
			
		||||
          if (latLng != null) {
 | 
			
		||||
            mapState.setCurrentLocation(latLng);
 | 
			
		||||
            mapState.getMapController.move(latLng, 16);
 | 
			
		||||
          }
 | 
			
		||||
          mapState.setLoading(false);
 | 
			
		||||
        },
 | 
			
		||||
        onPressed: () => requestLiveLocation(context.obtainState<MapState>(), true, false, true),
 | 
			
		||||
      ),
 | 
			
		||||
      body: Column(
 | 
			
		||||
        children: [
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
import 'package:app/extensions/obtainProviderExtension.dart';
 | 
			
		||||
import 'package:app/state/mapState.dart';
 | 
			
		||||
import 'package:app/util/watchState.dart';
 | 
			
		||||
import 'package:flutter/cupertino.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter_map/flutter_map.dart';
 | 
			
		||||
import 'package:http/http.dart';
 | 
			
		||||
@@ -20,10 +19,13 @@ class _MapViewState extends State<MapView> {
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return FlutterMap(
 | 
			
		||||
      mapController: context.obtainState<MapState>().getMapController,
 | 
			
		||||
      options: const MapOptions(
 | 
			
		||||
        initialCenter: LatLng(50.354, 7.5845),
 | 
			
		||||
      options: MapOptions(
 | 
			
		||||
        onPositionChanged: (position, hasGesture) => {
 | 
			
		||||
          if (hasGesture) context.obtainState<MapState>().setLocationLive(false)
 | 
			
		||||
        },
 | 
			
		||||
        initialCenter: const LatLng(50.354, 7.5845),
 | 
			
		||||
        initialZoom: 16,
 | 
			
		||||
        interactionOptions: InteractionOptions(
 | 
			
		||||
        interactionOptions: const InteractionOptions(
 | 
			
		||||
          flags: InteractiveFlag.all & ~InteractiveFlag.rotate
 | 
			
		||||
        )
 | 
			
		||||
      ),
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user