Finish main screen

This commit is contained in:
Anton Tananaev 2025-05-07 22:06:29 -07:00
parent 81e9b01b6a
commit 828d664166
4 changed files with 131 additions and 126 deletions

View file

@ -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"
}

View file

@ -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(),
);
}

View file

@ -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<MainScreen> createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
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(),
],
),
),

View file

@ -21,10 +21,10 @@ class _SettingsScreenState extends State<SettingsScreen> {
@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<SettingsScreen> {
}
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),