mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-02-13 01:03:03 +00:00
Navigation settings
This commit is contained in:
@@ -292,5 +292,41 @@
|
||||
"networkStatus": {
|
||||
"showIndicator": "Netzwerkstatus-Anzeige anzeigen",
|
||||
"showIndicatorSubtitle": "Netzwerk-Ladestatus und Fehlerstatus auf der Karte anzeigen"
|
||||
},
|
||||
"navigation": {
|
||||
"searchLocation": "Ort suchen",
|
||||
"searchPlaceholder": "Orte oder Koordinaten suchen...",
|
||||
"routeTo": "Route zu",
|
||||
"routeFrom": "Route von",
|
||||
"selectLocation": "Ort auswählen",
|
||||
"calculatingRoute": "Route wird berechnet...",
|
||||
"routeCalculationFailed": "Routenberechnung fehlgeschlagen",
|
||||
"start": "Start",
|
||||
"resume": "Fortsetzen",
|
||||
"endRoute": "Route beenden",
|
||||
"routeOverview": "Routenübersicht",
|
||||
"retry": "Wiederholen",
|
||||
"cancelSearch": "Suche abbrechen",
|
||||
"noResultsFound": "Keine Ergebnisse gefunden",
|
||||
"searching": "Suche...",
|
||||
"location": "Standort",
|
||||
"startPoint": "Start",
|
||||
"endPoint": "Ende",
|
||||
"startSelect": "Start (auswählen)",
|
||||
"endSelect": "Ende (auswählen)",
|
||||
"distance": "Entfernung: {} km",
|
||||
"routeActive": "Route aktiv",
|
||||
"navigationSettings": "Navigation",
|
||||
"navigationSettingsSubtitle": "Routenplanung und Vermeidungseinstellungen",
|
||||
"avoidanceDistance": "Vermeidungsabstand",
|
||||
"avoidanceDistanceSubtitle": "Mindestabstand zu Überwachungsgeräten",
|
||||
"searchHistory": "Max. Suchverlauf",
|
||||
"searchHistorySubtitle": "Maximale Anzahl kürzlicher Suchen zum Merken",
|
||||
"units": "Einheiten",
|
||||
"unitsSubtitle": "Anzeigeeinheiten für Entfernungen und Messungen",
|
||||
"metric": "Metrisch (km, m)",
|
||||
"imperial": "Britisch (mi, ft)",
|
||||
"meters": "Meter",
|
||||
"feet": "Fuß"
|
||||
}
|
||||
}
|
||||
@@ -292,5 +292,41 @@
|
||||
"networkStatus": {
|
||||
"showIndicator": "Show network status indicator",
|
||||
"showIndicatorSubtitle": "Display network loading and error status on the map"
|
||||
},
|
||||
"navigation": {
|
||||
"searchLocation": "Search Location",
|
||||
"searchPlaceholder": "Search places or coordinates...",
|
||||
"routeTo": "Route To",
|
||||
"routeFrom": "Route From",
|
||||
"selectLocation": "Select Location",
|
||||
"calculatingRoute": "Calculating route...",
|
||||
"routeCalculationFailed": "Route calculation failed",
|
||||
"start": "Start",
|
||||
"resume": "Resume",
|
||||
"endRoute": "End Route",
|
||||
"routeOverview": "Route Overview",
|
||||
"retry": "Retry",
|
||||
"cancelSearch": "Cancel search",
|
||||
"noResultsFound": "No results found",
|
||||
"searching": "Searching...",
|
||||
"location": "Location",
|
||||
"startPoint": "Start",
|
||||
"endPoint": "End",
|
||||
"startSelect": "Start (select)",
|
||||
"endSelect": "End (select)",
|
||||
"distance": "Distance: {} km",
|
||||
"routeActive": "Route active",
|
||||
"navigationSettings": "Navigation",
|
||||
"navigationSettingsSubtitle": "Route planning and avoidance settings",
|
||||
"avoidanceDistance": "Avoidance Distance",
|
||||
"avoidanceDistanceSubtitle": "Minimum distance to stay away from surveillance devices",
|
||||
"searchHistory": "Max Search History",
|
||||
"searchHistorySubtitle": "Maximum number of recent searches to remember",
|
||||
"units": "Units",
|
||||
"unitsSubtitle": "Display units for distances and measurements",
|
||||
"metric": "Metric (km, m)",
|
||||
"imperial": "Imperial (mi, ft)",
|
||||
"meters": "meters",
|
||||
"feet": "feet"
|
||||
}
|
||||
}
|
||||
@@ -292,5 +292,41 @@
|
||||
"networkStatus": {
|
||||
"showIndicator": "Mostrar indicador de estado de red",
|
||||
"showIndicatorSubtitle": "Mostrar estado de carga y errores de red en el mapa"
|
||||
},
|
||||
"navigation": {
|
||||
"searchLocation": "Buscar ubicación",
|
||||
"searchPlaceholder": "Buscar lugares o coordenadas...",
|
||||
"routeTo": "Ruta a",
|
||||
"routeFrom": "Ruta desde",
|
||||
"selectLocation": "Seleccionar ubicación",
|
||||
"calculatingRoute": "Calculando ruta...",
|
||||
"routeCalculationFailed": "Falló el cálculo de ruta",
|
||||
"start": "Iniciar",
|
||||
"resume": "Continuar",
|
||||
"endRoute": "Finalizar ruta",
|
||||
"routeOverview": "Vista de ruta",
|
||||
"retry": "Reintentar",
|
||||
"cancelSearch": "Cancelar búsqueda",
|
||||
"noResultsFound": "No se encontraron resultados",
|
||||
"searching": "Buscando...",
|
||||
"location": "Ubicación",
|
||||
"startPoint": "Inicio",
|
||||
"endPoint": "Fin",
|
||||
"startSelect": "Inicio (seleccionar)",
|
||||
"endSelect": "Fin (seleccionar)",
|
||||
"distance": "Distancia: {} km",
|
||||
"routeActive": "Ruta activa",
|
||||
"navigationSettings": "Navegación",
|
||||
"navigationSettingsSubtitle": "Configuración de planificación de rutas y evitación",
|
||||
"avoidanceDistance": "Distancia de evitación",
|
||||
"avoidanceDistanceSubtitle": "Distancia mínima para mantenerse alejado de dispositivos de vigilancia",
|
||||
"searchHistory": "Historial máximo de búsqueda",
|
||||
"searchHistorySubtitle": "Número máximo de búsquedas recientes para recordar",
|
||||
"units": "Unidades",
|
||||
"unitsSubtitle": "Unidades de visualización para distancias y medidas",
|
||||
"metric": "Métrico (km, m)",
|
||||
"imperial": "Imperial (mi, ft)",
|
||||
"meters": "metros",
|
||||
"feet": "pies"
|
||||
}
|
||||
}
|
||||
@@ -292,5 +292,41 @@
|
||||
"networkStatus": {
|
||||
"showIndicator": "Afficher l'indicateur de statut réseau",
|
||||
"showIndicatorSubtitle": "Afficher l'état de chargement et d'erreur réseau sur la carte"
|
||||
},
|
||||
"navigation": {
|
||||
"searchLocation": "Rechercher lieu",
|
||||
"searchPlaceholder": "Rechercher lieux ou coordonnées...",
|
||||
"routeTo": "Itinéraire vers",
|
||||
"routeFrom": "Itinéraire depuis",
|
||||
"selectLocation": "Sélectionner lieu",
|
||||
"calculatingRoute": "Calcul de l'itinéraire...",
|
||||
"routeCalculationFailed": "Échec du calcul d'itinéraire",
|
||||
"start": "Démarrer",
|
||||
"resume": "Reprendre",
|
||||
"endRoute": "Terminer l'itinéraire",
|
||||
"routeOverview": "Vue d'ensemble",
|
||||
"retry": "Réessayer",
|
||||
"cancelSearch": "Annuler recherche",
|
||||
"noResultsFound": "Aucun résultat trouvé",
|
||||
"searching": "Recherche...",
|
||||
"location": "Lieu",
|
||||
"startPoint": "Début",
|
||||
"endPoint": "Fin",
|
||||
"startSelect": "Début (sélectionner)",
|
||||
"endSelect": "Fin (sélectionner)",
|
||||
"distance": "Distance: {} km",
|
||||
"routeActive": "Itinéraire actif",
|
||||
"navigationSettings": "Navigation",
|
||||
"navigationSettingsSubtitle": "Paramètres de planification d'itinéraire et d'évitement",
|
||||
"avoidanceDistance": "Distance d'évitement",
|
||||
"avoidanceDistanceSubtitle": "Distance minimale pour éviter les dispositifs de surveillance",
|
||||
"searchHistory": "Historique de recherche max",
|
||||
"searchHistorySubtitle": "Nombre maximum de recherches récentes à retenir",
|
||||
"units": "Unités",
|
||||
"unitsSubtitle": "Unités d'affichage pour distances et mesures",
|
||||
"metric": "Métrique (km, m)",
|
||||
"imperial": "Impérial (mi, ft)",
|
||||
"meters": "mètres",
|
||||
"feet": "pieds"
|
||||
}
|
||||
}
|
||||
@@ -292,5 +292,41 @@
|
||||
"networkStatus": {
|
||||
"showIndicator": "Mostra indicatore di stato di rete",
|
||||
"showIndicatorSubtitle": "Visualizza lo stato di caricamento e errori di rete sulla mappa"
|
||||
},
|
||||
"navigation": {
|
||||
"searchLocation": "Cerca posizione",
|
||||
"searchPlaceholder": "Cerca luoghi o coordinate...",
|
||||
"routeTo": "Percorso verso",
|
||||
"routeFrom": "Percorso da",
|
||||
"selectLocation": "Seleziona posizione",
|
||||
"calculatingRoute": "Calcolo percorso...",
|
||||
"routeCalculationFailed": "Calcolo percorso fallito",
|
||||
"start": "Inizia",
|
||||
"resume": "Riprendi",
|
||||
"endRoute": "Termina percorso",
|
||||
"routeOverview": "Panoramica percorso",
|
||||
"retry": "Riprova",
|
||||
"cancelSearch": "Annulla ricerca",
|
||||
"noResultsFound": "Nessun risultato trovato",
|
||||
"searching": "Ricerca in corso...",
|
||||
"location": "Posizione",
|
||||
"startPoint": "Inizio",
|
||||
"endPoint": "Fine",
|
||||
"startSelect": "Inizio (seleziona)",
|
||||
"endSelect": "Fine (seleziona)",
|
||||
"distance": "Distanza: {} km",
|
||||
"routeActive": "Percorso attivo",
|
||||
"navigationSettings": "Navigazione",
|
||||
"navigationSettingsSubtitle": "Impostazioni pianificazione percorso ed evitamento",
|
||||
"avoidanceDistance": "Distanza di evitamento",
|
||||
"avoidanceDistanceSubtitle": "Distanza minima da mantenere dai dispositivi di sorveglianza",
|
||||
"searchHistory": "Cronologia ricerca max",
|
||||
"searchHistorySubtitle": "Numero massimo di ricerche recenti da ricordare",
|
||||
"units": "Unità",
|
||||
"unitsSubtitle": "Unità di visualizzazione per distanze e misure",
|
||||
"metric": "Metrico (km, m)",
|
||||
"imperial": "Imperiale (mi, ft)",
|
||||
"meters": "metri",
|
||||
"feet": "piedi"
|
||||
}
|
||||
}
|
||||
@@ -292,5 +292,41 @@
|
||||
"networkStatus": {
|
||||
"showIndicator": "Exibir indicador de status de rede",
|
||||
"showIndicatorSubtitle": "Mostrar status de carregamento e erro de rede no mapa"
|
||||
},
|
||||
"navigation": {
|
||||
"searchLocation": "Buscar localização",
|
||||
"searchPlaceholder": "Buscar locais ou coordenadas...",
|
||||
"routeTo": "Rota para",
|
||||
"routeFrom": "Rota de",
|
||||
"selectLocation": "Selecionar localização",
|
||||
"calculatingRoute": "Calculando rota...",
|
||||
"routeCalculationFailed": "Falha no cálculo da rota",
|
||||
"start": "Iniciar",
|
||||
"resume": "Continuar",
|
||||
"endRoute": "Terminar rota",
|
||||
"routeOverview": "Visão geral da rota",
|
||||
"retry": "Tentar novamente",
|
||||
"cancelSearch": "Cancelar busca",
|
||||
"noResultsFound": "Nenhum resultado encontrado",
|
||||
"searching": "Buscando...",
|
||||
"location": "Localização",
|
||||
"startPoint": "Início",
|
||||
"endPoint": "Fim",
|
||||
"startSelect": "Início (selecionar)",
|
||||
"endSelect": "Fim (selecionar)",
|
||||
"distance": "Distância: {} km",
|
||||
"routeActive": "Rota ativa",
|
||||
"navigationSettings": "Navegação",
|
||||
"navigationSettingsSubtitle": "Configurações de planejamento de rota e evasão",
|
||||
"avoidanceDistance": "Distância de evasão",
|
||||
"avoidanceDistanceSubtitle": "Distância mínima para ficar longe de dispositivos de vigilância",
|
||||
"searchHistory": "Histórico máximo de busca",
|
||||
"searchHistorySubtitle": "Número máximo de buscas recentes para lembrar",
|
||||
"units": "Unidades",
|
||||
"unitsSubtitle": "Unidades de exibição para distâncias e medidas",
|
||||
"metric": "Métrico (km, m)",
|
||||
"imperial": "Imperial (mi, ft)",
|
||||
"meters": "metros",
|
||||
"feet": "pés"
|
||||
}
|
||||
}
|
||||
@@ -292,5 +292,41 @@
|
||||
"networkStatus": {
|
||||
"showIndicator": "显示网络状态指示器",
|
||||
"showIndicatorSubtitle": "在地图上显示网络加载和错误状态"
|
||||
},
|
||||
"navigation": {
|
||||
"searchLocation": "搜索位置",
|
||||
"searchPlaceholder": "搜索地点或坐标...",
|
||||
"routeTo": "路线至",
|
||||
"routeFrom": "路线从",
|
||||
"selectLocation": "选择位置",
|
||||
"calculatingRoute": "计算路线中...",
|
||||
"routeCalculationFailed": "路线计算失败",
|
||||
"start": "开始",
|
||||
"resume": "继续",
|
||||
"endRoute": "结束路线",
|
||||
"routeOverview": "路线概览",
|
||||
"retry": "重试",
|
||||
"cancelSearch": "取消搜索",
|
||||
"noResultsFound": "未找到结果",
|
||||
"searching": "搜索中...",
|
||||
"location": "位置",
|
||||
"startPoint": "起点",
|
||||
"endPoint": "终点",
|
||||
"startSelect": "起点(选择)",
|
||||
"endSelect": "终点(选择)",
|
||||
"distance": "距离:{} 公里",
|
||||
"routeActive": "路线活跃",
|
||||
"navigationSettings": "导航",
|
||||
"navigationSettingsSubtitle": "路线规划和回避设置",
|
||||
"avoidanceDistance": "回避距离",
|
||||
"avoidanceDistanceSubtitle": "与监控设备保持的最小距离",
|
||||
"searchHistory": "最大搜索历史",
|
||||
"searchHistorySubtitle": "要记住的最近搜索次数",
|
||||
"units": "单位",
|
||||
"unitsSubtitle": "距离和测量的显示单位",
|
||||
"metric": "公制(公里,米)",
|
||||
"imperial": "英制(英里,英尺)",
|
||||
"meters": "米",
|
||||
"feet": "英尺"
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import 'app_state.dart';
|
||||
import 'screens/home_screen.dart';
|
||||
import 'screens/settings_screen.dart';
|
||||
import 'screens/profiles_settings_screen.dart';
|
||||
import 'screens/navigation_settings_screen.dart';
|
||||
import 'screens/offline_settings_screen.dart';
|
||||
import 'screens/advanced_settings_screen.dart';
|
||||
import 'screens/language_settings_screen.dart';
|
||||
@@ -64,6 +65,7 @@ class DeFlockApp extends StatelessWidget {
|
||||
'/': (context) => const HomeScreen(),
|
||||
'/settings': (context) => const SettingsScreen(),
|
||||
'/settings/profiles': (context) => const ProfilesSettingsScreen(),
|
||||
'/settings/navigation': (context) => const NavigationSettingsScreen(),
|
||||
'/settings/offline': (context) => const OfflineSettingsScreen(),
|
||||
'/settings/advanced': (context) => const AdvancedSettingsScreen(),
|
||||
'/settings/language': (context) => const LanguageSettingsScreen(),
|
||||
|
||||
124
lib/screens/navigation_settings_screen.dart
Normal file
124
lib/screens/navigation_settings_screen.dart
Normal file
@@ -0,0 +1,124 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/localization_service.dart';
|
||||
import '../app_state.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class NavigationSettingsScreen extends StatelessWidget {
|
||||
const NavigationSettingsScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final locService = LocalizationService.instance;
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: LocalizationService.instance,
|
||||
builder: (context, child) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(locService.t('navigation.navigationSettings')),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Coming soon message
|
||||
Card(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.info_outline, color: Colors.blue),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'Navigation Features',
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Navigation and routing settings will be available here. Coming soon:\n\n'
|
||||
'• Surveillance avoidance distance\n'
|
||||
'• Route planning preferences\n'
|
||||
'• Search history management\n'
|
||||
'• Distance units (metric/imperial)',
|
||||
style: Theme.of(context).textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
// Placeholder settings (disabled for now)
|
||||
_buildDisabledSetting(
|
||||
context,
|
||||
icon: Icons.warning_outlined,
|
||||
title: locService.t('navigation.avoidanceDistance'),
|
||||
subtitle: locService.t('navigation.avoidanceDistanceSubtitle'),
|
||||
value: '100 ${locService.t('navigation.meters')}',
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
|
||||
_buildDisabledSetting(
|
||||
context,
|
||||
icon: Icons.history,
|
||||
title: locService.t('navigation.searchHistory'),
|
||||
subtitle: locService.t('navigation.searchHistorySubtitle'),
|
||||
value: '10 searches',
|
||||
),
|
||||
|
||||
const Divider(),
|
||||
|
||||
_buildDisabledSetting(
|
||||
context,
|
||||
icon: Icons.straighten,
|
||||
title: locService.t('navigation.units'),
|
||||
subtitle: locService.t('navigation.unitsSubtitle'),
|
||||
value: locService.t('navigation.metric'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDisabledSetting(
|
||||
BuildContext context, {
|
||||
required IconData icon,
|
||||
required String title,
|
||||
required String subtitle,
|
||||
required String value,
|
||||
}) {
|
||||
return Opacity(
|
||||
opacity: 0.5,
|
||||
child: ListTile(
|
||||
leading: Icon(icon),
|
||||
title: Text(title),
|
||||
subtitle: Text(subtitle),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
value,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Theme.of(context).textTheme.bodySmall?.color?.withOpacity(0.6),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(Icons.chevron_right, size: 16),
|
||||
],
|
||||
),
|
||||
enabled: false,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,15 @@ class SettingsScreen extends StatelessWidget {
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
_buildNavigationTile(
|
||||
context,
|
||||
icon: Icons.navigation,
|
||||
title: locService.t('navigation.navigationSettings'),
|
||||
subtitle: locService.t('navigation.navigationSettingsSubtitle'),
|
||||
onTap: () => Navigator.pushNamed(context, '/settings/navigation'),
|
||||
),
|
||||
const Divider(),
|
||||
|
||||
_buildNavigationTile(
|
||||
context,
|
||||
icon: Icons.cloud_off,
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
|
||||
|
||||
import '../../app_state.dart';
|
||||
import '../../dev_config.dart';
|
||||
import '../../services/localization_service.dart';
|
||||
import '../camera_icon.dart';
|
||||
import 'layer_selector_button.dart';
|
||||
|
||||
@@ -126,7 +127,9 @@ class MapOverlays extends StatelessWidget {
|
||||
mini: true,
|
||||
heroTag: "search_nav",
|
||||
onPressed: onSearchPressed,
|
||||
tooltip: appState.showRouteButton ? 'Route Overview' : 'Search Location',
|
||||
tooltip: appState.showRouteButton
|
||||
? LocalizationService.instance.t('navigation.routeOverview')
|
||||
: LocalizationService.instance.t('navigation.searchLocation'),
|
||||
child: Icon(appState.showRouteButton ? Icons.route : Icons.search),
|
||||
),
|
||||
if (onSearchPressed != null && (appState.showSearchButton || appState.showRouteButton))
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
|
||||
import '../app_state.dart';
|
||||
import '../services/localization_service.dart';
|
||||
|
||||
class NavigationSheet extends StatelessWidget {
|
||||
final VoidCallback? onStartRoute;
|
||||
@@ -94,32 +95,32 @@ class NavigationSheet extends StatelessWidget {
|
||||
// SEARCH MODE: Initial location with route options
|
||||
if (navigationMode == AppNavigationMode.search && !appState.isSettingSecondPoint && !appState.isCalculating && !appState.showingOverview && provisionalLocation != null) ...[
|
||||
_buildLocationInfo(
|
||||
label: 'Location',
|
||||
label: LocalizationService.instance.t('navigation.location'),
|
||||
coordinates: provisionalLocation,
|
||||
address: provisionalAddress,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.directions),
|
||||
label: const Text('Route To'),
|
||||
onPressed: () {
|
||||
appState.startRoutePlanning(thisLocationIsStart: false);
|
||||
},
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.directions),
|
||||
label: Text(LocalizationService.instance.t('navigation.routeTo')),
|
||||
onPressed: () {
|
||||
appState.startRoutePlanning(thisLocationIsStart: false);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.my_location),
|
||||
label: const Text('Route From'),
|
||||
onPressed: () {
|
||||
appState.startRoutePlanning(thisLocationIsStart: true);
|
||||
},
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.my_location),
|
||||
label: Text(LocalizationService.instance.t('navigation.routeFrom')),
|
||||
onPressed: () {
|
||||
appState.startRoutePlanning(thisLocationIsStart: true);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -129,7 +130,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
// Show existing route points
|
||||
if (appState.routeStart != null) ...[
|
||||
_buildLocationInfo(
|
||||
label: 'Start',
|
||||
label: LocalizationService.instance.t('navigation.startPoint'),
|
||||
coordinates: appState.routeStart!,
|
||||
address: appState.routeStartAddress,
|
||||
),
|
||||
@@ -137,7 +138,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
],
|
||||
if (appState.routeEnd != null) ...[
|
||||
_buildLocationInfo(
|
||||
label: 'End',
|
||||
label: LocalizationService.instance.t('navigation.endPoint'),
|
||||
coordinates: appState.routeEnd!,
|
||||
address: appState.routeEndAddress,
|
||||
),
|
||||
@@ -146,7 +147,9 @@ class NavigationSheet extends StatelessWidget {
|
||||
|
||||
// Show the point we're selecting
|
||||
_buildLocationInfo(
|
||||
label: appState.settingRouteStart ? 'Start (select)' : 'End (select)',
|
||||
label: appState.settingRouteStart
|
||||
? LocalizationService.instance.t('navigation.startSelect')
|
||||
: LocalizationService.instance.t('navigation.endSelect'),
|
||||
coordinates: provisionalLocation,
|
||||
address: provisionalAddress,
|
||||
),
|
||||
@@ -154,7 +157,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
|
||||
ElevatedButton.icon(
|
||||
icon: const Icon(Icons.check),
|
||||
label: const Text('Select Location'),
|
||||
label: Text(LocalizationService.instance.t('navigation.selectLocation')),
|
||||
onPressed: () {
|
||||
debugPrint('[NavigationSheet] Select Location button pressed');
|
||||
appState.selectSecondRoutePoint();
|
||||
@@ -172,11 +175,14 @@ class NavigationSheet extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Text('Calculating route...', textAlign: TextAlign.center),
|
||||
Text(
|
||||
LocalizationService.instance.t('navigation.calculatingRoute'),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () => appState.cancelNavigation(),
|
||||
child: const Text('Cancel'),
|
||||
child: Text(LocalizationService.instance.t('actions.cancel')),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -189,7 +195,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Route calculation failed',
|
||||
LocalizationService.instance.t('navigation.routeCalculationFailed'),
|
||||
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
@@ -205,7 +211,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.refresh),
|
||||
label: const Text('Retry'),
|
||||
label: Text(LocalizationService.instance.t('navigation.retry')),
|
||||
onPressed: () {
|
||||
// Retry route calculation
|
||||
appState.retryRouteCalculation();
|
||||
@@ -216,7 +222,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.close),
|
||||
label: const Text('Cancel'),
|
||||
label: Text(LocalizationService.instance.t('actions.cancel')),
|
||||
onPressed: () => appState.cancelNavigation(),
|
||||
),
|
||||
),
|
||||
@@ -228,7 +234,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
if (appState.showingOverview) ...[
|
||||
if (appState.routeStart != null) ...[
|
||||
_buildLocationInfo(
|
||||
label: 'Start',
|
||||
label: LocalizationService.instance.t('navigation.startPoint'),
|
||||
coordinates: appState.routeStart!,
|
||||
address: appState.routeStartAddress,
|
||||
),
|
||||
@@ -236,7 +242,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
],
|
||||
if (appState.routeEnd != null) ...[
|
||||
_buildLocationInfo(
|
||||
label: 'End',
|
||||
label: LocalizationService.instance.t('navigation.endPoint'),
|
||||
coordinates: appState.routeEnd!,
|
||||
address: appState.routeEndAddress,
|
||||
),
|
||||
@@ -244,7 +250,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
],
|
||||
if (appState.routeDistance != null) ...[
|
||||
Text(
|
||||
'Distance: ${(appState.routeDistance! / 1000).toStringAsFixed(1)} km',
|
||||
LocalizationService.instance.t('navigation.distance', params: [(appState.routeDistance! / 1000).toStringAsFixed(1)]),
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -257,7 +263,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.play_arrow),
|
||||
label: const Text('Start'),
|
||||
label: Text(LocalizationService.instance.t('navigation.start')),
|
||||
onPressed: onStartRoute ?? () => appState.startRoute(),
|
||||
),
|
||||
),
|
||||
@@ -265,7 +271,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.close),
|
||||
label: const Text('Cancel'),
|
||||
label: Text(LocalizationService.instance.t('actions.cancel')),
|
||||
onPressed: () => appState.cancelNavigation(),
|
||||
),
|
||||
),
|
||||
@@ -274,7 +280,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.play_arrow),
|
||||
label: const Text('Resume'),
|
||||
label: Text(LocalizationService.instance.t('navigation.resume')),
|
||||
onPressed: onResumeRoute ?? () => appState.hideRouteOverview(),
|
||||
),
|
||||
),
|
||||
@@ -282,7 +288,7 @@ class NavigationSheet extends StatelessWidget {
|
||||
Expanded(
|
||||
child: ElevatedButton.icon(
|
||||
icon: const Icon(Icons.close),
|
||||
label: const Text('End Route'),
|
||||
label: Text(LocalizationService.instance.t('navigation.endRoute')),
|
||||
onPressed: () => appState.cancelRoute(),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:provider/provider.dart';
|
||||
|
||||
import '../app_state.dart';
|
||||
import '../models/search_result.dart';
|
||||
import '../services/localization_service.dart';
|
||||
import '../widgets/debouncer.dart';
|
||||
|
||||
class LocationSearchBar extends StatefulWidget {
|
||||
@@ -115,24 +116,24 @@ class _LocationSearchBarState extends State<LocationSearchBar> {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (isLoading)
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
),
|
||||
SizedBox(width: 12),
|
||||
Text('Searching...'),
|
||||
const SizedBox(width: 12),
|
||||
Text(LocalizationService.instance.t('navigation.searching')),
|
||||
],
|
||||
),
|
||||
)
|
||||
else if (results.isEmpty && _controller.text.isNotEmpty)
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(16),
|
||||
child: Text('No results found'),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(LocalizationService.instance.t('navigation.noResultsFound')),
|
||||
)
|
||||
else
|
||||
...results.map((result) => ListTile(
|
||||
@@ -179,14 +180,14 @@ class _LocationSearchBarState extends State<LocationSearchBar> {
|
||||
controller: _controller,
|
||||
focusNode: _focusNode,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Search places or coordinates...',
|
||||
hintText: LocalizationService.instance.t('navigation.searchPlaceholder'),
|
||||
prefixIcon: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: _onCancel,
|
||||
tooltip: 'Cancel search',
|
||||
tooltip: LocalizationService.instance.t('navigation.cancelSearch'),
|
||||
),
|
||||
const Icon(Icons.search),
|
||||
],
|
||||
@@ -196,7 +197,7 @@ class _LocationSearchBarState extends State<LocationSearchBar> {
|
||||
? IconButton(
|
||||
icon: const Icon(Icons.clear),
|
||||
onPressed: _onClear,
|
||||
tooltip: 'Clear text',
|
||||
tooltip: LocalizationService.instance.t('actions.clear'),
|
||||
)
|
||||
: null,
|
||||
border: OutlineInputBorder(
|
||||
|
||||
Reference in New Issue
Block a user