mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
Refactor localization in UI components and error messages
- Updated various UI components to utilize AppLocalizations for better internationalization support. - Replaced hardcoded strings with localized strings in home_screen.dart, ble_connection_manager.dart, contact_tile.dart, room_login_sheet.dart, compass widgets, and sar_update_sheet.dart. - Improved user feedback messages by integrating localization for actions like pinging contacts, displaying connection statuses, and error notifications. - Enhanced the clarity of UI elements by ensuring all text is translatable, improving the overall user experience for non-English speakers.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import '../../../models/contact.dart';
|
||||
|
||||
/// Contact list section for the compass dialog.
|
||||
@@ -28,7 +29,7 @@ class CompassContactList extends StatelessWidget {
|
||||
}
|
||||
|
||||
if (position == null) {
|
||||
return const Text('Location unavailable');
|
||||
return Text(AppLocalizations.of(context)!.locationUnavailable);
|
||||
}
|
||||
|
||||
// Calculate bearings and distances
|
||||
@@ -60,13 +61,14 @@ class CompassContactList extends StatelessWidget {
|
||||
contactsWithBearing.sort((a, b) =>
|
||||
(a['distance'] as double).compareTo(b['distance'] as double));
|
||||
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 16, bottom: 8),
|
||||
child: Text(
|
||||
'Nearby Contacts',
|
||||
l10n.nearbyContacts,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -120,7 +122,7 @@ class CompassContactList extends StatelessWidget {
|
||||
),
|
||||
if (heading != null)
|
||||
Text(
|
||||
_formatRelativeBearing(bearing, heading!),
|
||||
_formatRelativeBearing(bearing, heading!, context),
|
||||
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||
color: Colors.grey,
|
||||
),
|
||||
@@ -189,7 +191,8 @@ class CompassContactList extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
String _formatRelativeBearing(double bearing, double heading) {
|
||||
String _formatRelativeBearing(double bearing, double heading, BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
// Calculate relative bearing (how much to turn from current heading)
|
||||
double relative = bearing - heading;
|
||||
|
||||
@@ -204,11 +207,11 @@ class CompassContactList extends StatelessWidget {
|
||||
final absRelative = relative.abs().round();
|
||||
|
||||
if (absRelative < 10) {
|
||||
return 'ahead';
|
||||
return l10n.ahead;
|
||||
} else if (relative > 0) {
|
||||
return '$absRelative° right';
|
||||
return l10n.degreesRight(absRelative);
|
||||
} else {
|
||||
return '$absRelative° left';
|
||||
return l10n.degreesLeft(absRelative);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../../l10n/app_localizations.dart';
|
||||
|
||||
/// Filter controls for the compass dialog.
|
||||
/// Allows filtering of contacts and SAR marker types.
|
||||
@@ -32,15 +33,16 @@ class CompassFilters extends StatefulWidget {
|
||||
|
||||
class _CompassFiltersState extends State<CompassFilters> {
|
||||
void _showFilterDialog() {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => StatefulBuilder(
|
||||
builder: (context, setDialogState) => AlertDialog(
|
||||
title: const Row(
|
||||
title: Row(
|
||||
children: [
|
||||
Icon(Icons.filter_list, size: 20),
|
||||
SizedBox(width: 8),
|
||||
Text('Filter Markers'),
|
||||
const Icon(Icons.filter_list, size: 20),
|
||||
const SizedBox(width: 8),
|
||||
Text(l10n.filterMarkers),
|
||||
],
|
||||
),
|
||||
contentPadding: const EdgeInsets.fromLTRB(24, 16, 24, 0),
|
||||
@@ -52,7 +54,7 @@ class _CompassFiltersState extends State<CompassFilters> {
|
||||
_CompactFilterItem(
|
||||
icon: Icons.person,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
label: 'Contacts',
|
||||
label: l10n.contactsFilter,
|
||||
value: widget.showContacts,
|
||||
onChanged: (value) {
|
||||
widget.onShowContactsChanged(value);
|
||||
@@ -66,7 +68,7 @@ class _CompassFiltersState extends State<CompassFilters> {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8, bottom: 8, top: 4),
|
||||
child: Text(
|
||||
'SAR Markers',
|
||||
l10n.sarMarkers,
|
||||
style: Theme.of(context).textTheme.labelLarge?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -75,7 +77,7 @@ class _CompassFiltersState extends State<CompassFilters> {
|
||||
_CompactFilterItem(
|
||||
icon: Icons.person_pin,
|
||||
color: Colors.green,
|
||||
label: 'Found Person',
|
||||
label: l10n.foundPerson,
|
||||
value: widget.showFoundPerson,
|
||||
onChanged: (value) {
|
||||
widget.onShowFoundPersonChanged(value);
|
||||
@@ -86,7 +88,7 @@ class _CompassFiltersState extends State<CompassFilters> {
|
||||
_CompactFilterItem(
|
||||
icon: Icons.local_fire_department,
|
||||
color: Colors.red,
|
||||
label: 'Fire',
|
||||
label: l10n.fire,
|
||||
value: widget.showFire,
|
||||
onChanged: (value) {
|
||||
widget.onShowFireChanged(value);
|
||||
@@ -97,7 +99,7 @@ class _CompassFiltersState extends State<CompassFilters> {
|
||||
_CompactFilterItem(
|
||||
icon: Icons.home_work,
|
||||
color: Colors.orange,
|
||||
label: 'Staging Area',
|
||||
label: l10n.stagingArea,
|
||||
value: widget.showStagingArea,
|
||||
onChanged: (value) {
|
||||
widget.onShowStagingAreaChanged(value);
|
||||
@@ -112,11 +114,11 @@ class _CompassFiltersState extends State<CompassFilters> {
|
||||
widget.onShowAll();
|
||||
setDialogState(() {});
|
||||
},
|
||||
child: const Text('Show All'),
|
||||
child: Text(l10n.showAll),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: const Text('Close'),
|
||||
child: Text(l10n.close),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -126,9 +128,10 @@ class _CompassFiltersState extends State<CompassFilters> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
return IconButton(
|
||||
icon: const Icon(Icons.filter_list),
|
||||
tooltip: 'Filter markers',
|
||||
tooltip: l10n.filterMarkersTooltip,
|
||||
onPressed: () => _showFilterDialog(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:ui' as ui;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import '../../../l10n/app_localizations.dart';
|
||||
import '../../../models/contact.dart';
|
||||
import '../../../models/sar_marker.dart';
|
||||
|
||||
@@ -76,18 +77,19 @@ class CompassHeader extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildInfoRow(BuildContext context, double? heading, Position? position) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
_buildInfoCard(
|
||||
context,
|
||||
'Heading',
|
||||
l10n.heading,
|
||||
heading != null ? '${heading.round()}°' : '--',
|
||||
Icons.explore,
|
||||
),
|
||||
_buildInfoCard(
|
||||
context,
|
||||
'Elevation',
|
||||
l10n.elevation,
|
||||
position?.altitude != null
|
||||
? '${position!.altitude.round()}m'
|
||||
: '--',
|
||||
@@ -95,7 +97,7 @@ class CompassHeader extends StatelessWidget {
|
||||
),
|
||||
_buildInfoCard(
|
||||
context,
|
||||
'Accuracy',
|
||||
l10n.accuracy,
|
||||
position?.accuracy != null
|
||||
? '±${position!.accuracy.round()}m'
|
||||
: '--',
|
||||
@@ -566,12 +568,16 @@ class _LocationFormatToggleState extends State<_LocationFormatToggle> {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final String displayText;
|
||||
|
||||
if (_showDMS) {
|
||||
displayText = '${_formatDMS(position.latitude, true)} ${_formatDMS(position.longitude, false)}';
|
||||
} else {
|
||||
displayText = 'Lat: ${position.latitude.toStringAsFixed(5)} Lon: ${position.longitude.toStringAsFixed(5)}';
|
||||
displayText = l10n.latLonFormat(
|
||||
position.latitude.toStringAsFixed(5),
|
||||
position.longitude.toStringAsFixed(5),
|
||||
);
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import '../../../models/sar_marker.dart';
|
||||
|
||||
/// SAR marker list section for the compass dialog.
|
||||
@@ -28,7 +29,7 @@ class CompassSarList extends StatelessWidget {
|
||||
}
|
||||
|
||||
if (position == null) {
|
||||
return const Text('Location unavailable');
|
||||
return Text(AppLocalizations.of(context)!.locationUnavailable);
|
||||
}
|
||||
|
||||
// Calculate bearings and distances for SAR markers
|
||||
@@ -58,13 +59,14 @@ class CompassSarList extends StatelessWidget {
|
||||
markersWithBearing.sort((a, b) =>
|
||||
(a['distance'] as double).compareTo(b['distance'] as double));
|
||||
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 16, top: 16, bottom: 8),
|
||||
child: Text(
|
||||
'SAR Markers',
|
||||
l10n.sarMarkers,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@@ -139,7 +141,7 @@ class CompassSarList extends StatelessWidget {
|
||||
),
|
||||
if (heading != null)
|
||||
Text(
|
||||
_formatRelativeBearing(bearing, heading!),
|
||||
_formatRelativeBearing(bearing, heading!, context),
|
||||
style: Theme.of(context).textTheme.labelSmall?.copyWith(
|
||||
color: Colors.grey,
|
||||
),
|
||||
@@ -208,7 +210,8 @@ class CompassSarList extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
String _formatRelativeBearing(double bearing, double heading) {
|
||||
String _formatRelativeBearing(double bearing, double heading, BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
// Calculate relative bearing (how much to turn from current heading)
|
||||
double relative = bearing - heading;
|
||||
|
||||
@@ -223,11 +226,11 @@ class CompassSarList extends StatelessWidget {
|
||||
final absRelative = relative.abs().round();
|
||||
|
||||
if (absRelative < 10) {
|
||||
return 'ahead';
|
||||
return l10n.ahead;
|
||||
} else if (relative > 0) {
|
||||
return '$absRelative° right';
|
||||
return l10n.degreesRight(absRelative);
|
||||
} else {
|
||||
return '$absRelative° left';
|
||||
return l10n.degreesLeft(absRelative);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user