import 'dart:async'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'main.dart'; import 'about.dart'; extension on SpeedUnit { double fromMetersPerSecond(double metersPerSecond) => switch (this) { SpeedUnit.kilometersPerHour => metersPerSecond * 3.6, SpeedUnit.milesPerHour => metersPerSecond * 2.236936, }; String get acronym => switch (this) { SpeedUnit.kilometersPerHour => 'kmph', SpeedUnit.milesPerHour => 'mph', }; } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State createState() => _HomePageState(); } class _HomePageState extends State { StreamSubscription? _positionStream; double _speed = 0.0; double _speedAccuracy = 0.0; SpeedUnit _speedUnit = SpeedUnit.milesPerHour; LocationSettings _locationSettings = LocationSettings(); void _initPositionStream() { _positionStream = Geolocator.getPositionStream( locationSettings: _locationSettings, ).listen((Position? position) { if (position != null) { setState(() { _speed = position.speed; _speedAccuracy = position.speedAccuracy; }); } }); } @override void initState() { super.initState(); Geolocator.checkPermission() .then( (permission) => permission == LocationPermission.denied ? Geolocator.requestPermission() : permission, ) .then((permission) { if (![ LocationPermission.deniedForever, LocationPermission.denied, ].contains(permission)) { _initPositionStream(); } }); } @override void dispose() { super.dispose(); _positionStream?.cancel(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( actions: [ MenuAnchor( builder: (context, controller, child) => IconButton( icon: Icon(Icons.more_vert), onPressed: () => controller.isOpen ? controller.close() : controller.open(), tooltip: "Navigation menu", ), menuChildren: [ MenuItemButton(child: Text('Settings')), MenuItemButton( child: Text('About'), onPressed: () => Navigator.push( context, MaterialPageRoute(builder: (context) => AboutPage()), ), ), ], ), ], ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Flex(direction: Axis.horizontal), Text( '${_speedUnit.fromMetersPerSecond(_speed).round()} ${_speedUnit.acronym}', style: Theme.of(context).textTheme.displayLarge, ), Text( '± ${_speedUnit.fromMetersPerSecond(_speedAccuracy).round()} ${_speedUnit.acronym}', style: Theme.of(context).textTheme.displaySmall, ), ], ), ), ); } }