import 'dart:developer' as developer; import 'package:flutter/material.dart'; import 'package:traccar_client/preferences.dart'; import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg; import 'l10n/app_localizations.dart'; import 'status_screen.dart'; import 'settings_screen.dart'; class MainScreen extends StatefulWidget { const MainScreen({super.key}); @override State createState() => _MainScreenState(); } class _MainScreenState extends State { bool trackingEnabled = false; bool? stopDetection; bool? isMoving; @override void initState() { super.initState(); _initState(); } void _initState() async { final state = await bg.BackgroundGeolocation.state; setState(() { trackingEnabled = state.enabled; stopDetection = Preferences.instance.getBool(Preferences.stopDetection); isMoving = state.isMoving; }); bg.BackgroundGeolocation.onEnabledChange((bool enabled) { setState(() { trackingEnabled = enabled; }); }); bg.BackgroundGeolocation.onMotionChange((bg.Location location) { setState(() { isMoving = location.isMoving; }); }); } Future _checkBatteryOptimizations(BuildContext context) async { try { if (!await bg.DeviceSettings.isIgnoringBatteryOptimizations) { final request = await bg.DeviceSettings.showIgnoreBatteryOptimizations(); if (!request.seen && context.mounted) { showDialog( context: context, builder: (_) => AlertDialog( content: Text(AppLocalizations.of(context)!.optimizationMessage), actions: [ TextButton( onPressed: () { Navigator.of(context).pop(); bg.DeviceSettings.show(request); }, child: Text(AppLocalizations.of(context)!.okButton), ), ], ), ); } } } catch (error) { debugPrint(error.toString()); } } Widget _buildTrackingCard() { return Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ListTile( contentPadding: EdgeInsets.zero, title: Text(AppLocalizations.of(context)!.trackingTitle), titleTextStyle: Theme.of(context).textTheme.headlineMedium, ), ListTile( contentPadding: EdgeInsets.zero, title: Text(AppLocalizations.of(context)!.idLabel), subtitle: Text(Preferences.instance.getString(Preferences.id) ?? ''), ), SwitchListTile( contentPadding: EdgeInsets.zero, title: Text(AppLocalizations.of(context)!.trackingLabel), value: trackingEnabled, onChanged: (bool value) { if (value) { bg.BackgroundGeolocation.start(); _checkBatteryOptimizations(context); } else { bg.BackgroundGeolocation.stop(); } }, ), if (stopDetection == false) SwitchListTile( contentPadding: EdgeInsets.zero, title: Text(AppLocalizations.of(context)!.motionLabel), value: isMoving == true, onChanged: (bool value) { if (value) { bg.BackgroundGeolocation.changePace(true); } else { bg.BackgroundGeolocation.changePace(false); } }, ), const SizedBox(height: 8), OverflowBar( spacing: 8, children: [ FilledButton.tonal( onPressed: () async { try { await bg.BackgroundGeolocation.getCurrentPosition(samples: 1, persist: true, extras: {'manual': true}); } catch (error) { developer.log('Failed to fetch location', error: error); } }, child: Text(AppLocalizations.of(context)!.locationButton), ), FilledButton.tonal( onPressed: () { Navigator.push(context, MaterialPageRoute(builder: (_) => const StatusScreen())); }, child: Text(AppLocalizations.of(context)!.statusButton), ), ], ), ], ), ), ); } Widget _buildSettingsCard() { return Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ListTile( contentPadding: EdgeInsets.zero, title: Text(AppLocalizations.of(context)!.settingsTitle), titleTextStyle: Theme.of(context).textTheme.headlineMedium, ), ListTile( contentPadding: EdgeInsets.zero, title: Text(AppLocalizations.of(context)!.urlLabel), subtitle: Text(Preferences.instance.getString(Preferences.url) ?? ''), ), const SizedBox(height: 8), OverflowBar( spacing: 8, children: [ FilledButton.tonal( onPressed: () async { await Navigator.push(context, MaterialPageRoute(builder: (_) => const SettingsScreen())); setState(() { stopDetection = Preferences.instance.getBool(Preferences.stopDetection); }); }, child: Text(AppLocalizations.of(context)!.settingsButton), ), ], ), ] ), ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Traccar Client'), ), body: SingleChildScrollView( padding: const EdgeInsets.all(16.0), child: Column( children: [ _buildTrackingCard(), const SizedBox(height: 16), _buildSettingsCard(), ], ), ), ); } }