diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 643328c..dbeff41 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,11 +1,16 @@ { "mainTitle": "Traccar Client", + "trackingTitle": "Tracking", + "settingsTitle": "Settings", "saveButton": "Save", "cancelButton": "Cancel", + "statusButton": "Show status", + "settingsButton": "Change settings", "idLabel": "Device identifier", "urlLabel": "Server URL", "accuracyLabel": "Location accuracy", "intervalLabel": "Frequency", "distanceLabel": "Distance", - "bufferLabel": "Offline buffering" + "bufferLabel": "Offline buffering", + "trackingLabel": "Continuous tracking" } diff --git a/lib/main.dart b/lib/main.dart index 300c450..322a5ad 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,9 +15,14 @@ class MainApp extends StatelessWidget { @override Widget build(BuildContext context) { - return const MaterialApp( + return MaterialApp( localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed( + seedColor: Colors.green, + ), + ), home: MainScreen(), ); } diff --git a/lib/main_screen.dart b/lib/main_screen.dart index 073996a..cee1831 100644 --- a/lib/main_screen.dart +++ b/lib/main_screen.dart @@ -1,14 +1,126 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:traccar_client/preferences.dart'; +import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg; import 'status_screen.dart'; import 'settings_screen.dart'; -class MainScreen extends StatelessWidget { +class MainScreen extends StatefulWidget { const MainScreen({super.key}); + @override + State createState() => _MainScreenState(); +} + +class _MainScreenState extends State { + bool loading = true; + late SharedPreferences preferences; + bool trackingEnabled = false; + + @override + void initState() { + super.initState(); + _initState(); + } + + void _initState() async { + preferences = await SharedPreferences.getInstance(); + final state = await bg.BackgroundGeolocation.ready( + Preferences.geolocationConfig(preferences), + ); + setState(() { + loading = false; + trackingEnabled = state.enabled; + }); + bg.BackgroundGeolocation.onEnabledChange((bool enabled) { + setState(() { + trackingEnabled = enabled; + }); + }); + } + + 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), + trailing: Text(preferences.getString(Preferences.id) ?? ''), + leadingAndTrailingTextStyle: Theme.of(context).textTheme.bodyLarge, + ), + SwitchListTile( + contentPadding: EdgeInsets.zero, + title: Text(AppLocalizations.of(context)!.trackingLabel), + value: trackingEnabled, + onChanged: (bool value) { + if (value) { + bg.BackgroundGeolocation.start(); + } else { + bg.BackgroundGeolocation.stop(); + } + }, + ), + const SizedBox(height: 8), + 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), + trailing: Text(preferences.getString(Preferences.url) ?? ''), + leadingAndTrailingTextStyle: Theme.of(context).textTheme.bodyLarge, + ), + const SizedBox(height: 8), + FilledButton.tonal( + onPressed: () { + Navigator.push(context, MaterialPageRoute(builder: (_) => const SettingsScreen())); + }, + child: Text(AppLocalizations.of(context)!.settingsButton), + ), + ] + ), + ), + ); + } + @override Widget build(BuildContext context) { + if (loading) { + return const Center(child: CircularProgressIndicator()); + } + return Scaffold( appBar: AppBar( title: Text(AppLocalizations.of(context)!.mainTitle), @@ -17,126 +129,9 @@ class MainScreen extends StatelessWidget { padding: const EdgeInsets.all(16.0), child: Column( children: [ - // Tracking Card - Card( - elevation: 2, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Text( - 'Tracking', - style: TextStyle( - fontSize: 18, fontWeight: FontWeight.bold), - ), - const SizedBox(height: 16), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const Text('Device identifier'), - Row( - children: [ - const Text('{id}', style: TextStyle(color: Colors.grey)), - IconButton( - icon: const Icon(Icons.copy), - onPressed: () {}, - ), - ], - ), - ], - ), - SwitchListTile( - contentPadding: EdgeInsets.zero, - title: const Text('Continuous tracking'), - value: true, - onChanged: (bool value) {}, - ), - Align( - alignment: Alignment.centerRight, - child: ElevatedButton( - onPressed: () {}, - child: const Text('Send current location'), - ), - ), - ], - ), - ), - ), - - const SizedBox(height: 20), - - // Settings Card - Card( - elevation: 2, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(12), - ), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const Text( - 'Settings', - style: TextStyle( - fontSize: 18, fontWeight: FontWeight.bold), - ), - IconButton( - icon: const Icon(Icons.qr_code_scanner), - onPressed: () {}, - ), - ], - ), - const SizedBox(height: 16), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const Text('Server'), - Row( - children: [ - const Text('https://...', - style: TextStyle(color: Colors.grey)), - IconButton( - icon: const Icon(Icons.edit), - onPressed: () {}, - ), - ], - ), - ], - ), - Align( - alignment: Alignment.centerRight, - child: OutlinedButton( - onPressed: () => Navigator.push( - context, - MaterialPageRoute(builder: (_) => const SettingsScreen()), - ), - child: const Text('Advanced settings'), - ), - ), - Align( - alignment: Alignment.centerRight, - child: OutlinedButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute(builder: (_) => const StatusScreen()), - ); - }, - child: const Text('Show status'), - ), - ), - ], - ), - ), - ), + _buildTrackingCard(), + const SizedBox(height: 16), + _buildSettingsCard(), ], ), ), diff --git a/lib/settings_screen.dart b/lib/settings_screen.dart index dcf53fd..23cd6b0 100644 --- a/lib/settings_screen.dart +++ b/lib/settings_screen.dart @@ -21,10 +21,10 @@ class _SettingsScreenState extends State { @override void initState() { super.initState(); - _initPreferences(); + _initState(); } - void _initPreferences() async { + void _initState() async { preferences = await SharedPreferences.getInstance(); setState(() { loading = false; @@ -91,7 +91,7 @@ class _SettingsScreenState extends State { } return Scaffold( - appBar: AppBar(title: const Text('Settings')), + appBar: AppBar(title: Text(AppLocalizations.of(context)!.settingsTitle)), body: ListView( children: [ _buildListTile(AppLocalizations.of(context)!.idLabel, Preferences.id, false),