feat: add send location button to force immediate report

This commit is contained in:
fiatcode 2026-04-30 13:23:07 +07:00
parent 4eade880b1
commit cd34c8bbf3
No known key found for this signature in database
5 changed files with 92 additions and 31 deletions

View file

@ -55,6 +55,16 @@ class LocationBridge {
}
}
static Future<bool> reportLocation() async {
try {
final result = await _methodChannel.invokeMethod<bool>('reportLocation');
return result ?? false;
} on PlatformException catch (e) {
debugPrint('Failed to report location: ${e.message}');
return false;
}
}
static Stream<Map<String, dynamic>> get locationUpdates {
_locationStream ??= _eventChannel.receiveBroadcastStream().map(
(event) => Map<String, dynamic>.from(event as Map),

View file

@ -154,32 +154,61 @@ class _MainScreenState extends State<MainScreen> {
}
Widget _buildActionButtons() {
return Row(
return Column(
children: [
Expanded(
child: ElevatedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const SettingsScreen()),
);
},
icon: const Icon(Icons.settings),
label: const Text('Settings'),
),
),
const SizedBox(width: 16),
Expanded(
child: ElevatedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const StatusScreen()),
);
},
icon: const Icon(Icons.history),
label: const Text('Status/Logs'),
if (_isTracking)
Padding(
padding: const EdgeInsets.only(bottom: 16),
child: SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: () async {
final success = await LocationBridge.reportLocation();
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
success
? 'Location reported'
: 'Failed to report location',
),
),
);
}
},
icon: const Icon(Icons.send),
label: const Text('Send Location'),
),
),
),
Row(
children: [
Expanded(
child: ElevatedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const SettingsScreen()),
);
},
icon: const Icon(Icons.settings),
label: const Text('Settings'),
),
),
const SizedBox(width: 16),
Expanded(
child: ElevatedButton.icon(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const StatusScreen()),
);
},
icon: const Icon(Icons.history),
label: const Text('Status/Logs'),
),
),
],
),
],
);

View file

@ -12,7 +12,6 @@ class SettingsScreen extends StatefulWidget {
class _SettingsScreenState extends State<SettingsScreen> {
late TextEditingController _serverUrlController;
late TextEditingController _deviceIdController;
late TextEditingController _passwordController;
late int _accuracy;
late int _distanceFilter;
late int _interval;
@ -25,7 +24,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
super.initState();
_serverUrlController = TextEditingController(text: Preferences.serverUrl);
_deviceIdController = TextEditingController(text: Preferences.deviceId);
_passwordController = TextEditingController(text: Preferences.password);
_accuracy = Preferences.accuracy;
_distanceFilter = Preferences.distanceFilter;
_interval = Preferences.interval;
@ -38,14 +36,12 @@ class _SettingsScreenState extends State<SettingsScreen> {
void dispose() {
_serverUrlController.dispose();
_deviceIdController.dispose();
_passwordController.dispose();
super.dispose();
}
Future<void> _saveSettings() async {
await Preferences.setServerUrl(_serverUrlController.text);
await Preferences.setDeviceId(_deviceIdController.text);
await Preferences.setPassword(_passwordController.text);
await Preferences.setAccuracy(_accuracy);
await Preferences.setDistanceFilter(_distanceFilter);
await Preferences.setInterval(_interval);
@ -56,7 +52,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
await LocationBridge.updateConfig({
'serverUrl': _serverUrlController.text,
'deviceId': _deviceIdController.text,
'password': _passwordController.text,
'accuracy': _accuracy,
'distanceFilter': _distanceFilter,
'interval': _interval,
@ -82,7 +77,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
_buildSectionHeader('Server'),
_buildTextField('Server URL', _serverUrlController),
_buildTextField('Device ID', _deviceIdController),
_buildTextField('Password', _passwordController, obscure: true),
const SizedBox(height: 16),
_buildSectionHeader('Location'),
_buildAccuracyDropdown(),