mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-08-12 22:20:20 +02:00
Finish localizations, remove now-inaccurate sandbox note
This commit is contained in:
@@ -90,7 +90,6 @@
|
||||
"simulate": "Simulieren",
|
||||
"productionDescription": "Hochladen in die Live-OSM-Datenbank (für alle Benutzer sichtbar)",
|
||||
"sandboxDescription": "Uploads gehen an die OSM Sandbox (sicher zum Testen, wird regelmäßig zurückgesetzt).",
|
||||
"sandboxNote": "HINWEIS: Aufgrund von OpenStreetMap-Limitierungen werden Kameras, die an die Sandbox übermittelt werden, NICHT in der Karte dieser App angezeigt.",
|
||||
"simulateDescription": "Uploads simulieren (kontaktiert OSM-Server nicht)"
|
||||
},
|
||||
"auth": {
|
||||
@@ -220,6 +219,7 @@
|
||||
"noAreasTitle": "Keine Offline-Bereiche",
|
||||
"noAreasSubtitle": "Laden Sie einen Kartenbereich für die Offline-Nutzung herunter.",
|
||||
"provider": "Anbieter",
|
||||
"maxZoom": "Max Zoom",
|
||||
"zoomLevels": "Z{}-{}",
|
||||
"latitude": "Breite",
|
||||
"longitude": "Länge",
|
||||
@@ -237,5 +237,22 @@
|
||||
"megabytes": "MB",
|
||||
"kilobytes": "KB",
|
||||
"progress": "{}%"
|
||||
},
|
||||
"refineTagsSheet": {
|
||||
"title": "Tags Verfeinern",
|
||||
"operatorProfile": "Betreiber-Profil",
|
||||
"done": "Fertig",
|
||||
"none": "Keine",
|
||||
"noAdditionalOperatorTags": "Keine zusätzlichen Betreiber-Tags",
|
||||
"additionalTags": "zusätzliche Tags",
|
||||
"additionalTagsTitle": "Zusätzliche Tags",
|
||||
"noTagsDefinedForProfile": "Keine Tags für dieses Betreiber-Profil definiert.",
|
||||
"noOperatorProfiles": "Keine Betreiber-Profile definiert",
|
||||
"noOperatorProfilesMessage": "Erstellen Sie Betreiber-Profile in den Einstellungen, um zusätzliche Tags auf Ihre Knoten-Übertragungen anzuwenden."
|
||||
},
|
||||
"layerSelector": {
|
||||
"cannotChangeTileTypes": "Kachel-Typen können während des Herunterladens von Offline-Bereichen nicht geändert werden",
|
||||
"selectMapLayer": "Kartenschicht Auswählen",
|
||||
"noTileProvidersAvailable": "Keine Kachel-Anbieter verfügbar"
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,6 @@
|
||||
"simulate": "Simulate",
|
||||
"productionDescription": "Upload to the live OSM database (visible to all users)",
|
||||
"sandboxDescription": "Uploads go to the OSM Sandbox (safe for testing, resets regularly).",
|
||||
"sandboxNote": "NOTE: Due to OpenStreetMap limitations, cameras submitted to the sandbox will NOT appear on the map in this app.",
|
||||
"simulateDescription": "Simulate uploads (does not contact OSM servers)"
|
||||
},
|
||||
"auth": {
|
||||
@@ -220,6 +219,7 @@
|
||||
"noAreasTitle": "No offline areas",
|
||||
"noAreasSubtitle": "Download a map area for offline use.",
|
||||
"provider": "Provider",
|
||||
"maxZoom": "Max zoom",
|
||||
"zoomLevels": "Z{}-{}",
|
||||
"latitude": "Lat",
|
||||
"longitude": "Lon",
|
||||
@@ -237,5 +237,22 @@
|
||||
"megabytes": "MB",
|
||||
"kilobytes": "KB",
|
||||
"progress": "{}%"
|
||||
},
|
||||
"refineTagsSheet": {
|
||||
"title": "Refine Tags",
|
||||
"operatorProfile": "Operator Profile",
|
||||
"done": "Done",
|
||||
"none": "None",
|
||||
"noAdditionalOperatorTags": "No additional operator tags",
|
||||
"additionalTags": "additional tags",
|
||||
"additionalTagsTitle": "Additional Tags",
|
||||
"noTagsDefinedForProfile": "No tags defined for this operator profile.",
|
||||
"noOperatorProfiles": "No operator profiles defined",
|
||||
"noOperatorProfilesMessage": "Create operator profiles in Settings to apply additional tags to your node submissions."
|
||||
},
|
||||
"layerSelector": {
|
||||
"cannotChangeTileTypes": "Cannot change tile types while downloading offline areas",
|
||||
"selectMapLayer": "Select Map Layer",
|
||||
"noTileProvidersAvailable": "No tile providers available"
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,6 @@
|
||||
"simulate": "Simular",
|
||||
"productionDescription": "Subir a la base de datos OSM en vivo (visible para todos los usuarios)",
|
||||
"sandboxDescription": "Las subidas van al Sandbox de OSM (seguro para pruebas, se reinicia regularmente).",
|
||||
"sandboxNote": "NOTA: Debido a las limitaciones de OpenStreetMap, las cámaras enviadas al sandbox NO aparecerán en el mapa de esta aplicación.",
|
||||
"simulateDescription": "Simular subidas (no contacta servidores OSM)"
|
||||
},
|
||||
"auth": {
|
||||
@@ -220,6 +219,7 @@
|
||||
"noAreasTitle": "Sin áreas sin conexión",
|
||||
"noAreasSubtitle": "Descarga un área del mapa para uso sin conexión.",
|
||||
"provider": "Proveedor",
|
||||
"maxZoom": "Zoom máx",
|
||||
"zoomLevels": "Z{}-{}",
|
||||
"latitude": "Lat",
|
||||
"longitude": "Lon",
|
||||
@@ -237,5 +237,22 @@
|
||||
"megabytes": "MB",
|
||||
"kilobytes": "KB",
|
||||
"progress": "{}%"
|
||||
},
|
||||
"refineTagsSheet": {
|
||||
"title": "Refinar Etiquetas",
|
||||
"operatorProfile": "Perfil de Operador",
|
||||
"done": "Listo",
|
||||
"none": "Ninguno",
|
||||
"noAdditionalOperatorTags": "Sin etiquetas adicionales de operador",
|
||||
"additionalTags": "etiquetas adicionales",
|
||||
"additionalTagsTitle": "Etiquetas Adicionales",
|
||||
"noTagsDefinedForProfile": "No hay etiquetas definidas para este perfil de operador.",
|
||||
"noOperatorProfiles": "No hay perfiles de operador definidos",
|
||||
"noOperatorProfilesMessage": "Cree perfiles de operador en Configuración para aplicar etiquetas adicionales a sus envíos de nodos."
|
||||
},
|
||||
"layerSelector": {
|
||||
"cannotChangeTileTypes": "No se pueden cambiar los tipos de teselas mientras se descargan áreas sin conexión",
|
||||
"selectMapLayer": "Seleccionar Capa del Mapa",
|
||||
"noTileProvidersAvailable": "No hay proveedores de teselas disponibles"
|
||||
}
|
||||
}
|
||||
@@ -90,7 +90,6 @@
|
||||
"simulate": "Simuler",
|
||||
"productionDescription": "Télécharger vers la base de données OSM en direct (visible pour tous les utilisateurs)",
|
||||
"sandboxDescription": "Les téléchargements vont vers le Sandbox OSM (sûr pour les tests, réinitialisé régulièrement).",
|
||||
"sandboxNote": "NOTE: En raison des limitations d'OpenStreetMap, les caméras soumises au sandbox n'apparaîtront PAS sur la carte dans cette application.",
|
||||
"simulateDescription": "Simuler les téléchargements (ne contacte pas les serveurs OSM)"
|
||||
},
|
||||
"auth": {
|
||||
@@ -220,6 +219,7 @@
|
||||
"noAreasTitle": "Aucune zone hors ligne",
|
||||
"noAreasSubtitle": "Téléchargez une zone de carte pour utilisation hors ligne.",
|
||||
"provider": "Fournisseur",
|
||||
"maxZoom": "Zoom max",
|
||||
"zoomLevels": "Z{}-{}",
|
||||
"latitude": "Lat",
|
||||
"longitude": "Lon",
|
||||
@@ -237,5 +237,22 @@
|
||||
"megabytes": "Mo",
|
||||
"kilobytes": "Ko",
|
||||
"progress": "{}%"
|
||||
},
|
||||
"refineTagsSheet": {
|
||||
"title": "Affiner les Étiquettes",
|
||||
"operatorProfile": "Profil d'Opérateur",
|
||||
"done": "Terminé",
|
||||
"none": "Aucun",
|
||||
"noAdditionalOperatorTags": "Aucune étiquette d'opérateur supplémentaire",
|
||||
"additionalTags": "étiquettes supplémentaires",
|
||||
"additionalTagsTitle": "Étiquettes Supplémentaires",
|
||||
"noTagsDefinedForProfile": "Aucune étiquette définie pour ce profil d'opérateur.",
|
||||
"noOperatorProfiles": "Aucun profil d'opérateur défini",
|
||||
"noOperatorProfilesMessage": "Créez des profils d'opérateur dans les Paramètres pour appliquer des étiquettes supplémentaires à vos soumissions de nœuds."
|
||||
},
|
||||
"layerSelector": {
|
||||
"cannotChangeTileTypes": "Impossible de changer les types de tuiles pendant le téléchargement des zones hors ligne",
|
||||
"selectMapLayer": "Sélectionner la Couche de Carte",
|
||||
"noTileProvidersAvailable": "Aucun fournisseur de tuiles disponible"
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ class _OfflineAreasSectionState extends State<OfflineAreasSection> {
|
||||
: '--';
|
||||
|
||||
String subtitle = '${locService.t('offlineAreas.provider')}: ${area.tileProviderDisplay}\n' +
|
||||
'Max zoom: Z${area.maxZoom}' + '\n' +
|
||||
'${locService.t('offlineAreas.maxZoom')}: Z${area.maxZoom}' + '\n' +
|
||||
'${locService.t('offlineAreas.latitude')}: ${area.bounds.southWest.latitude.toStringAsFixed(3)}, ${area.bounds.southWest.longitude.toStringAsFixed(3)}\n' +
|
||||
'${locService.t('offlineAreas.latitude')}: ${area.bounds.northEast.latitude.toStringAsFixed(3)}, ${area.bounds.northEast.longitude.toStringAsFixed(3)}';
|
||||
|
||||
|
||||
@@ -53,19 +53,9 @@ class UploadModeSection extends StatelessWidget {
|
||||
style: TextStyle(fontSize: 12, color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7))
|
||||
);
|
||||
case UploadMode.sandbox:
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
locService.t('uploadMode.sandboxDescription'),
|
||||
style: const TextStyle(fontSize: 12, color: Colors.orange),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
locService.t('uploadMode.sandboxNote'),
|
||||
style: const TextStyle(fontSize: 11, color: Colors.redAccent),
|
||||
),
|
||||
],
|
||||
return Text(
|
||||
locService.t('uploadMode.sandboxDescription'),
|
||||
style: const TextStyle(fontSize: 12, color: Colors.orange),
|
||||
);
|
||||
case UploadMode.simulate:
|
||||
default:
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
|
||||
import '../../app_state.dart';
|
||||
import '../../models/tile_provider.dart';
|
||||
import '../../services/offline_area_service.dart';
|
||||
import '../../services/localization_service.dart';
|
||||
|
||||
class LayerSelectorButton extends StatelessWidget {
|
||||
const LayerSelectorButton({super.key});
|
||||
@@ -22,9 +23,9 @@ class LayerSelectorButton extends StatelessWidget {
|
||||
final offlineService = OfflineAreaService();
|
||||
if (offlineService.hasActiveDownloads) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Cannot change tile types while downloading offline areas'),
|
||||
duration: Duration(seconds: 3),
|
||||
SnackBar(
|
||||
content: Text(LocalizationService.instance.t('layerSelector.cannotChangeTileTypes')),
|
||||
duration: const Duration(seconds: 3),
|
||||
),
|
||||
);
|
||||
return;
|
||||
@@ -58,6 +59,7 @@ class _LayerSelectorDialogState extends State<_LayerSelectorDialog> {
|
||||
Widget build(BuildContext context) {
|
||||
final appState = context.watch<AppState>();
|
||||
final providers = appState.tileProviders;
|
||||
final locService = LocalizationService.instance;
|
||||
|
||||
// Group tile types by provider for display
|
||||
final providerGroups = <TileProvider, List<TileType>>{};
|
||||
@@ -86,9 +88,9 @@ class _LayerSelectorDialogState extends State<_LayerSelectorDialog> {
|
||||
children: [
|
||||
const Icon(Icons.layers),
|
||||
const SizedBox(width: 8),
|
||||
const Text(
|
||||
'Select Map Layer',
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
|
||||
Text(
|
||||
locService.t('layerSelector.selectMapLayer'),
|
||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
|
||||
),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
@@ -104,10 +106,10 @@ class _LayerSelectorDialogState extends State<_LayerSelectorDialog> {
|
||||
padding: EdgeInsets.zero,
|
||||
children: [
|
||||
if (providerGroups.isEmpty)
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(24),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Center(
|
||||
child: Text('No tile providers available'),
|
||||
child: Text(locService.t('layerSelector.noTileProvidersAvailable')),
|
||||
),
|
||||
)
|
||||
else
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:provider/provider.dart';
|
||||
|
||||
import '../app_state.dart';
|
||||
import '../models/operator_profile.dart';
|
||||
import '../services/localization_service.dart';
|
||||
|
||||
class RefineTagsSheet extends StatefulWidget {
|
||||
const RefineTagsSheet({
|
||||
@@ -29,10 +30,11 @@ class _RefineTagsSheetState extends State<RefineTagsSheet> {
|
||||
Widget build(BuildContext context) {
|
||||
final appState = context.watch<AppState>();
|
||||
final operatorProfiles = appState.operatorProfiles;
|
||||
final locService = LocalizationService.instance;
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Refine Tags'),
|
||||
title: Text(locService.t('refineTagsSheet.title')),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
onPressed: () => Navigator.pop(context, widget.selectedOperatorProfile),
|
||||
@@ -40,34 +42,34 @@ class _RefineTagsSheetState extends State<RefineTagsSheet> {
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, _selectedOperatorProfile),
|
||||
child: const Text('Done'),
|
||||
child: Text(locService.t('refineTagsSheet.done')),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
const Text(
|
||||
'Operator Profile',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
Text(
|
||||
locService.t('refineTagsSheet.operatorProfile'),
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (operatorProfiles.isEmpty)
|
||||
const Card(
|
||||
Card(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(Icons.info_outline, color: Colors.grey, size: 48),
|
||||
SizedBox(height: 8),
|
||||
const Icon(Icons.info_outline, color: Colors.grey, size: 48),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'No operator profiles defined',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
locService.t('refineTagsSheet.noOperatorProfiles'),
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'Create operator profiles in Settings to apply additional tags to your node submissions.',
|
||||
style: TextStyle(color: Colors.grey),
|
||||
locService.t('refineTagsSheet.noOperatorProfilesMessage'),
|
||||
style: const TextStyle(color: Colors.grey),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
@@ -79,15 +81,15 @@ class _RefineTagsSheetState extends State<RefineTagsSheet> {
|
||||
child: Column(
|
||||
children: [
|
||||
RadioListTile<OperatorProfile?>(
|
||||
title: const Text('None'),
|
||||
subtitle: const Text('No additional operator tags'),
|
||||
title: Text(locService.t('refineTagsSheet.none')),
|
||||
subtitle: Text(locService.t('refineTagsSheet.noAdditionalOperatorTags')),
|
||||
value: null,
|
||||
groupValue: _selectedOperatorProfile,
|
||||
onChanged: (value) => setState(() => _selectedOperatorProfile = value),
|
||||
),
|
||||
...operatorProfiles.map((profile) => RadioListTile<OperatorProfile?>(
|
||||
title: Text(profile.name),
|
||||
subtitle: Text('${profile.tags.length} additional tags'),
|
||||
subtitle: Text('${profile.tags.length} ${locService.t('refineTagsSheet.additionalTags')}'),
|
||||
value: profile,
|
||||
groupValue: _selectedOperatorProfile,
|
||||
onChanged: (value) => setState(() => _selectedOperatorProfile = value),
|
||||
@@ -97,9 +99,9 @@ class _RefineTagsSheetState extends State<RefineTagsSheet> {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (_selectedOperatorProfile != null) ...[
|
||||
const Text(
|
||||
'Additional Tags',
|
||||
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
Text(
|
||||
locService.t('refineTagsSheet.additionalTagsTitle'),
|
||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Card(
|
||||
@@ -114,9 +116,9 @@ class _RefineTagsSheetState extends State<RefineTagsSheet> {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (_selectedOperatorProfile!.tags.isEmpty)
|
||||
const Text(
|
||||
'No tags defined for this operator profile.',
|
||||
style: TextStyle(color: Colors.grey),
|
||||
Text(
|
||||
locService.t('refineTagsSheet.noTagsDefinedForProfile'),
|
||||
style: const TextStyle(color: Colors.grey),
|
||||
)
|
||||
else
|
||||
...(_selectedOperatorProfile!.tags.entries.map((entry) =>
|
||||
|
||||
Reference in New Issue
Block a user