mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
Add Croatian and Slovenian localizations, implement locale preferences, and update settings screen
- Created `app_localizations_hr.dart` and `app_localizations_sl.dart` for Croatian and Slovenian translations. - Added `app_sl.arb` file for Slovenian localization strings. - Enhanced `main.dart` to support locale selection and initialization. - Updated `home_screen.dart` and `settings_screen.dart` to handle locale changes and display current language. - Implemented `locale_preferences.dart` service for managing locale settings using SharedPreferences. - Modified `pubspec.yaml` to include `flutter_localizations` and enable localization file generation.
This commit is contained in:
@@ -1,54 +1,14 @@
|
|||||||
{
|
{
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"allow": [
|
"allow": [
|
||||||
"Bash(flutter analyze:*)",
|
"Bash(flutter gen-l10n:*)",
|
||||||
"Bash(flutter devices:*)",
|
"Bash(flutter pub run:*)",
|
||||||
"Bash(flutter build:*)",
|
"Bash(flutter pub run build_runner build:*)",
|
||||||
"Bash(flutter install:*)",
|
"Bash(flutter packages pub run intl_translation:generate_from_arb:*)",
|
||||||
"Bash(open:*)",
|
"Bash(dart pub global activate:*)",
|
||||||
"Bash(xcrun devicectl device uninstall app:*)",
|
"Bash(dart pub global run intl_utils:generate:*)",
|
||||||
"Bash(pod repo update:*)",
|
"Bash(dart pub global deactivate:*)",
|
||||||
"Bash(pod install)",
|
"Bash(flutter precache:*)"
|
||||||
"Bash(flutter clean:*)",
|
|
||||||
"Bash(flutter pub get:*)",
|
|
||||||
"Bash(flutter run:*)",
|
|
||||||
"Bash(nc:*)",
|
|
||||||
"Bash(pkill:*)",
|
|
||||||
"WebFetch(domain:github.com)",
|
|
||||||
"WebFetch(domain:raw.githubusercontent.com)",
|
|
||||||
"Bash(dart run:*)",
|
|
||||||
"Bash(dart test_sar_debug.dart:*)",
|
|
||||||
"Read(//Users/dz0ny/meshcore-sar/MeshCore/**)",
|
|
||||||
"Bash(cat:*)",
|
|
||||||
"Read(//Users/dz0ny/.pub-cache/hosted/pub.dev/**)",
|
|
||||||
"Bash(find:*)",
|
|
||||||
"Read(//Users/dz0ny/meshcore-sar/**)",
|
|
||||||
"Bash(git grep:*)",
|
|
||||||
"Bash(dart analyze:*)",
|
|
||||||
"Bash(flutter logs --clear)",
|
|
||||||
"Bash(for file in /Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/providers/contacts_provider.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/providers/connection_provider.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/providers/messages_provider.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/screens/messages_tab.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/screens/map_management_screen.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/screens/home_screen.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/services/ble/ble_connection_manager.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/services/ble/ble_response_handler.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/services/ble/ble_command_sender.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/services/meshcore_ble_service.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/services/contact_storage_service.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/services/message_storage_service.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/services/cayenne_lpp_parser.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/services/tile_cache_service.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/services/background_location_service.dart )",
|
|
||||||
"Bash(/Users/dz0ny/meshcore-sar/meshcore_sar_app/lib/widgets/contacts/room_login_sheet.dart)",
|
|
||||||
"Bash(do)",
|
|
||||||
"Bash(if grep -q \"debugPrint(\" \"$file\")",
|
|
||||||
"Bash(! grep -q \"import.*debug_print.dart\" \"$file\")",
|
|
||||||
"Bash(then)",
|
|
||||||
"Bash(echo:*)",
|
|
||||||
"Bash(fi)",
|
|
||||||
"Bash(done)"
|
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|||||||
3
l10n.yaml
Normal file
3
l10n.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
arb-dir: lib/l10n
|
||||||
|
template-arb-file: app_en.arb
|
||||||
|
output-localization-file: app_localizations.dart
|
||||||
461
lib/l10n/app_en.arb
Normal file
461
lib/l10n/app_en.arb
Normal file
@@ -0,0 +1,461 @@
|
|||||||
|
{
|
||||||
|
"@@locale": "en",
|
||||||
|
|
||||||
|
"appTitle": "MeshCore SAR",
|
||||||
|
"@appTitle": {
|
||||||
|
"description": "The application title"
|
||||||
|
},
|
||||||
|
|
||||||
|
"messages": "Messages",
|
||||||
|
"@messages": {
|
||||||
|
"description": "Messages tab label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"contacts": "Contacts",
|
||||||
|
"@contacts": {
|
||||||
|
"description": "Contacts tab label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"map": "Map",
|
||||||
|
"@map": {
|
||||||
|
"description": "Map tab label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"settings": "Settings",
|
||||||
|
"@settings": {
|
||||||
|
"description": "Settings screen title"
|
||||||
|
},
|
||||||
|
|
||||||
|
"connect": "Connect",
|
||||||
|
"@connect": {
|
||||||
|
"description": "Connect button label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"disconnect": "Disconnect",
|
||||||
|
"@disconnect": {
|
||||||
|
"description": "Disconnect button label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"scanningForDevices": "Scanning for devices...",
|
||||||
|
"@scanningForDevices": {
|
||||||
|
"description": "Text shown when scanning for BLE devices"
|
||||||
|
},
|
||||||
|
|
||||||
|
"noDevicesFound": "No devices found",
|
||||||
|
"@noDevicesFound": {
|
||||||
|
"description": "Text shown when no BLE devices are found"
|
||||||
|
},
|
||||||
|
|
||||||
|
"scanAgain": "Scan Again",
|
||||||
|
"@scanAgain": {
|
||||||
|
"description": "Button to restart BLE scanning"
|
||||||
|
},
|
||||||
|
|
||||||
|
"tapToConnect": "Tap to connect",
|
||||||
|
"@tapToConnect": {
|
||||||
|
"description": "Subtitle text for device in scan list"
|
||||||
|
},
|
||||||
|
|
||||||
|
"deviceNotConnected": "Device not connected",
|
||||||
|
"@deviceNotConnected": {
|
||||||
|
"description": "Error message when device is not connected"
|
||||||
|
},
|
||||||
|
|
||||||
|
"locationPermissionDenied": "Location permission denied",
|
||||||
|
"@locationPermissionDenied": {
|
||||||
|
"description": "Error when location permission is denied"
|
||||||
|
},
|
||||||
|
|
||||||
|
"locationPermissionPermanentlyDenied": "Location permission permanently denied. Please enable in Settings.",
|
||||||
|
"@locationPermissionPermanentlyDenied": {
|
||||||
|
"description": "Error when location permission is permanently denied"
|
||||||
|
},
|
||||||
|
|
||||||
|
"locationServicesDisabled": "Location services are disabled. Please enable them in Settings.",
|
||||||
|
"@locationServicesDisabled": {
|
||||||
|
"description": "Error when location services are disabled"
|
||||||
|
},
|
||||||
|
|
||||||
|
"failedToGetGpsLocation": "Failed to get GPS location",
|
||||||
|
"@failedToGetGpsLocation": {
|
||||||
|
"description": "Error when GPS location cannot be obtained"
|
||||||
|
},
|
||||||
|
|
||||||
|
"advertisedAtLocation": "Advertised at {latitude}, {longitude}",
|
||||||
|
"@advertisedAtLocation": {
|
||||||
|
"description": "Success message showing advertised location",
|
||||||
|
"placeholders": {
|
||||||
|
"latitude": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"longitude": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"failedToAdvertise": "Failed to advertise: {error}",
|
||||||
|
"@failedToAdvertise": {
|
||||||
|
"description": "Error message for failed advertisement",
|
||||||
|
"placeholders": {
|
||||||
|
"error": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"reconnecting": "Reconnecting... ({attempt}/{max})",
|
||||||
|
"@reconnecting": {
|
||||||
|
"description": "Text shown during reconnection attempts",
|
||||||
|
"placeholders": {
|
||||||
|
"attempt": {
|
||||||
|
"type": "int"
|
||||||
|
},
|
||||||
|
"max": {
|
||||||
|
"type": "int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"cancelReconnection": "Cancel reconnection",
|
||||||
|
"@cancelReconnection": {
|
||||||
|
"description": "Tooltip for cancel reconnection button"
|
||||||
|
},
|
||||||
|
|
||||||
|
"mapManagement": "Map Management",
|
||||||
|
"@mapManagement": {
|
||||||
|
"description": "Menu item for map management"
|
||||||
|
},
|
||||||
|
|
||||||
|
"general": "General",
|
||||||
|
"@general": {
|
||||||
|
"description": "General settings section header"
|
||||||
|
},
|
||||||
|
|
||||||
|
"theme": "Theme",
|
||||||
|
"@theme": {
|
||||||
|
"description": "Theme setting label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"chooseTheme": "Choose Theme",
|
||||||
|
"@chooseTheme": {
|
||||||
|
"description": "Theme selection dialog title"
|
||||||
|
},
|
||||||
|
|
||||||
|
"light": "Light",
|
||||||
|
"@light": {
|
||||||
|
"description": "Light theme option"
|
||||||
|
},
|
||||||
|
|
||||||
|
"dark": "Dark",
|
||||||
|
"@dark": {
|
||||||
|
"description": "Dark theme option"
|
||||||
|
},
|
||||||
|
|
||||||
|
"blueLightTheme": "Blue light theme",
|
||||||
|
"@blueLightTheme": {
|
||||||
|
"description": "Description for blue light theme"
|
||||||
|
},
|
||||||
|
|
||||||
|
"blueDarkTheme": "Blue dark theme",
|
||||||
|
"@blueDarkTheme": {
|
||||||
|
"description": "Description for blue dark theme"
|
||||||
|
},
|
||||||
|
|
||||||
|
"sarRed": "SAR Red",
|
||||||
|
"@sarRed": {
|
||||||
|
"description": "SAR Red theme option"
|
||||||
|
},
|
||||||
|
|
||||||
|
"alertEmergencyMode": "Alert/Emergency mode",
|
||||||
|
"@alertEmergencyMode": {
|
||||||
|
"description": "Description for SAR Red theme"
|
||||||
|
},
|
||||||
|
|
||||||
|
"sarGreen": "SAR Green",
|
||||||
|
"@sarGreen": {
|
||||||
|
"description": "SAR Green theme option"
|
||||||
|
},
|
||||||
|
|
||||||
|
"safeAllClearMode": "Safe/All Clear mode",
|
||||||
|
"@safeAllClearMode": {
|
||||||
|
"description": "Description for SAR Green theme"
|
||||||
|
},
|
||||||
|
|
||||||
|
"autoSystem": "Auto (System)",
|
||||||
|
"@autoSystem": {
|
||||||
|
"description": "Auto/System theme option"
|
||||||
|
},
|
||||||
|
|
||||||
|
"followSystemTheme": "Follow system theme",
|
||||||
|
"@followSystemTheme": {
|
||||||
|
"description": "Description for system theme"
|
||||||
|
},
|
||||||
|
|
||||||
|
"showRxTxIndicators": "Show RX/TX Indicators",
|
||||||
|
"@showRxTxIndicators": {
|
||||||
|
"description": "Setting to show RX/TX indicators"
|
||||||
|
},
|
||||||
|
|
||||||
|
"displayPacketActivity": "Display packet activity indicators in top bar",
|
||||||
|
"@displayPacketActivity": {
|
||||||
|
"description": "Description for RX/TX indicators setting"
|
||||||
|
},
|
||||||
|
|
||||||
|
"language": "Language",
|
||||||
|
"@language": {
|
||||||
|
"description": "Language setting label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"chooseLanguage": "Choose Language",
|
||||||
|
"@chooseLanguage": {
|
||||||
|
"description": "Language selection dialog title"
|
||||||
|
},
|
||||||
|
|
||||||
|
"english": "English",
|
||||||
|
"@english": {
|
||||||
|
"description": "English language option"
|
||||||
|
},
|
||||||
|
|
||||||
|
"slovenian": "Slovenian",
|
||||||
|
"@slovenian": {
|
||||||
|
"description": "Slovenian language option"
|
||||||
|
},
|
||||||
|
|
||||||
|
"croatian": "Croatian",
|
||||||
|
"@croatian": {
|
||||||
|
"description": "Croatian language option"
|
||||||
|
},
|
||||||
|
|
||||||
|
"locationBroadcasting": "Location Broadcasting",
|
||||||
|
"@locationBroadcasting": {
|
||||||
|
"description": "Location settings section header"
|
||||||
|
},
|
||||||
|
|
||||||
|
"autoLocationTracking": "Auto Location Tracking",
|
||||||
|
"@autoLocationTracking": {
|
||||||
|
"description": "Auto location tracking setting"
|
||||||
|
},
|
||||||
|
|
||||||
|
"automaticallyBroadcastPosition": "Automatically broadcast position updates",
|
||||||
|
"@automaticallyBroadcastPosition": {
|
||||||
|
"description": "Description for auto location tracking"
|
||||||
|
},
|
||||||
|
|
||||||
|
"configureTracking": "Configure Tracking",
|
||||||
|
"@configureTracking": {
|
||||||
|
"description": "Configure tracking button label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"distanceAndTimeThresholds": "Distance and time thresholds",
|
||||||
|
"@distanceAndTimeThresholds": {
|
||||||
|
"description": "Description for tracking configuration"
|
||||||
|
},
|
||||||
|
|
||||||
|
"locationTrackingConfiguration": "Location Tracking Configuration",
|
||||||
|
"@locationTrackingConfiguration": {
|
||||||
|
"description": "Tracking configuration dialog title"
|
||||||
|
},
|
||||||
|
|
||||||
|
"configureWhenLocationBroadcasts": "Configure when location broadcasts are sent to the mesh network",
|
||||||
|
"@configureWhenLocationBroadcasts": {
|
||||||
|
"description": "Description for tracking configuration dialog"
|
||||||
|
},
|
||||||
|
|
||||||
|
"minimumDistance": "Minimum Distance",
|
||||||
|
"@minimumDistance": {
|
||||||
|
"description": "Minimum distance setting label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"broadcastAfterMoving": "Broadcast only after moving {distance} meters",
|
||||||
|
"@broadcastAfterMoving": {
|
||||||
|
"description": "Description for minimum distance",
|
||||||
|
"placeholders": {
|
||||||
|
"distance": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"maximumDistance": "Maximum Distance",
|
||||||
|
"@maximumDistance": {
|
||||||
|
"description": "Maximum distance setting label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"alwaysBroadcastAfterMoving": "Always broadcast after moving {distance} meters",
|
||||||
|
"@alwaysBroadcastAfterMoving": {
|
||||||
|
"description": "Description for maximum distance",
|
||||||
|
"placeholders": {
|
||||||
|
"distance": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"minimumTimeInterval": "Minimum Time Interval",
|
||||||
|
"@minimumTimeInterval": {
|
||||||
|
"description": "Minimum time interval setting label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"alwaysBroadcastEvery": "Always broadcast every {duration}",
|
||||||
|
"@alwaysBroadcastEvery": {
|
||||||
|
"description": "Description for time interval",
|
||||||
|
"placeholders": {
|
||||||
|
"duration": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"save": "Save",
|
||||||
|
"@save": {
|
||||||
|
"description": "Save button label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"@cancel": {
|
||||||
|
"description": "Cancel button label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"close": "Close",
|
||||||
|
"@close": {
|
||||||
|
"description": "Close button label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"about": "About",
|
||||||
|
"@about": {
|
||||||
|
"description": "About section header"
|
||||||
|
},
|
||||||
|
|
||||||
|
"appVersion": "App Version",
|
||||||
|
"@appVersion": {
|
||||||
|
"description": "App version label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"appName": "App Name",
|
||||||
|
"@appName": {
|
||||||
|
"description": "App name label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"aboutMeshCoreSar": "About MeshCore SAR",
|
||||||
|
"@aboutMeshCoreSar": {
|
||||||
|
"description": "About dialog title"
|
||||||
|
},
|
||||||
|
|
||||||
|
"aboutDescription": "A Search & Rescue application designed for emergency response teams. Features include:\n\n• BLE mesh networking for device-to-device communication\n• Offline maps with multiple layer options\n• Real-time team member tracking\n• SAR tactical markers (found person, fire, staging)\n• Contact management and messaging\n• GPS tracking with compass heading\n• Map tile caching for offline use",
|
||||||
|
"@aboutDescription": {
|
||||||
|
"description": "About dialog description"
|
||||||
|
},
|
||||||
|
|
||||||
|
"technologiesUsed": "Technologies Used:",
|
||||||
|
"@technologiesUsed": {
|
||||||
|
"description": "Technologies used section title"
|
||||||
|
},
|
||||||
|
|
||||||
|
"technologiesList": "• Flutter for cross-platform development\n• BLE (Bluetooth Low Energy) for mesh networking\n• OpenStreetMap for mapping\n• Provider for state management\n• SharedPreferences for local storage",
|
||||||
|
"@technologiesList": {
|
||||||
|
"description": "List of technologies used"
|
||||||
|
},
|
||||||
|
|
||||||
|
"developer": "Developer",
|
||||||
|
"@developer": {
|
||||||
|
"description": "Developer section header"
|
||||||
|
},
|
||||||
|
|
||||||
|
"packageName": "Package Name",
|
||||||
|
"@packageName": {
|
||||||
|
"description": "Package name label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"sampleData": "Sample Data",
|
||||||
|
"@sampleData": {
|
||||||
|
"description": "Sample data section header"
|
||||||
|
},
|
||||||
|
|
||||||
|
"sampleDataDescription": "Load or clear sample contacts, channel messages, and SAR markers for testing",
|
||||||
|
"@sampleDataDescription": {
|
||||||
|
"description": "Sample data section description"
|
||||||
|
},
|
||||||
|
|
||||||
|
"loadSampleData": "Load Sample Data",
|
||||||
|
"@loadSampleData": {
|
||||||
|
"description": "Load sample data button"
|
||||||
|
},
|
||||||
|
|
||||||
|
"clearAllData": "Clear All Data",
|
||||||
|
"@clearAllData": {
|
||||||
|
"description": "Clear all data button"
|
||||||
|
},
|
||||||
|
|
||||||
|
"clearAllDataConfirmTitle": "Clear All Data",
|
||||||
|
"@clearAllDataConfirmTitle": {
|
||||||
|
"description": "Clear data confirmation dialog title"
|
||||||
|
},
|
||||||
|
|
||||||
|
"clearAllDataConfirmMessage": "This will clear all contacts and SAR markers. Are you sure?",
|
||||||
|
"@clearAllDataConfirmMessage": {
|
||||||
|
"description": "Clear data confirmation message"
|
||||||
|
},
|
||||||
|
|
||||||
|
"clear": "Clear",
|
||||||
|
"@clear": {
|
||||||
|
"description": "Clear button label"
|
||||||
|
},
|
||||||
|
|
||||||
|
"loadedSampleData": "Loaded {teamCount} team members, {channelCount} channels, {sarCount} SAR markers, {messageCount} messages",
|
||||||
|
"@loadedSampleData": {
|
||||||
|
"description": "Success message after loading sample data",
|
||||||
|
"placeholders": {
|
||||||
|
"teamCount": {
|
||||||
|
"type": "int"
|
||||||
|
},
|
||||||
|
"channelCount": {
|
||||||
|
"type": "int"
|
||||||
|
},
|
||||||
|
"sarCount": {
|
||||||
|
"type": "int"
|
||||||
|
},
|
||||||
|
"messageCount": {
|
||||||
|
"type": "int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"failedToLoadSampleData": "Failed to load sample data: {error}",
|
||||||
|
"@failedToLoadSampleData": {
|
||||||
|
"description": "Error message when sample data fails to load",
|
||||||
|
"placeholders": {
|
||||||
|
"error": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"allDataCleared": "All data cleared",
|
||||||
|
"@allDataCleared": {
|
||||||
|
"description": "Success message after clearing all data"
|
||||||
|
},
|
||||||
|
|
||||||
|
"failedToStartBackgroundTracking": "Failed to start background tracking. Check permissions and BLE connection.",
|
||||||
|
"@failedToStartBackgroundTracking": {
|
||||||
|
"description": "Error message when background tracking fails to start"
|
||||||
|
},
|
||||||
|
|
||||||
|
"locationBroadcast": "Location broadcast: {latitude}, {longitude}",
|
||||||
|
"@locationBroadcast": {
|
||||||
|
"description": "Success message for location broadcast",
|
||||||
|
"placeholders": {
|
||||||
|
"latitude": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"longitude": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"defaultPinInfo": "The default pin for devices without a screen is 123456. Trouble pairing? Forget the bluetooth device in system settings.",
|
||||||
|
"@defaultPinInfo": {
|
||||||
|
"description": "Information about default PIN for pairing"
|
||||||
|
}
|
||||||
|
}
|
||||||
161
lib/l10n/app_hr.arb
Normal file
161
lib/l10n/app_hr.arb
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
{
|
||||||
|
"@@locale": "hr",
|
||||||
|
|
||||||
|
"appTitle": "MeshCore SAR",
|
||||||
|
|
||||||
|
"messages": "Poruke",
|
||||||
|
|
||||||
|
"contacts": "Kontakti",
|
||||||
|
|
||||||
|
"map": "Karta",
|
||||||
|
|
||||||
|
"settings": "Postavke",
|
||||||
|
|
||||||
|
"connect": "Poveži",
|
||||||
|
|
||||||
|
"disconnect": "Prekini",
|
||||||
|
|
||||||
|
"scanningForDevices": "Skeniranje uređaja...",
|
||||||
|
|
||||||
|
"noDevicesFound": "Nisu pronađeni uređaji",
|
||||||
|
|
||||||
|
"scanAgain": "Skeniraj ponovno",
|
||||||
|
|
||||||
|
"tapToConnect": "Dodirnite za povezivanje",
|
||||||
|
|
||||||
|
"deviceNotConnected": "Uređaj nije povezan",
|
||||||
|
|
||||||
|
"locationPermissionDenied": "Dopuštenje za lokaciju odbijeno",
|
||||||
|
|
||||||
|
"locationPermissionPermanentlyDenied": "Dopuštenje za lokaciju trajno odbijeno. Molimo omogućite u Postavkama.",
|
||||||
|
|
||||||
|
"locationServicesDisabled": "Usluge lokacije su onemogućene. Molimo omogućite ih u Postavkama.",
|
||||||
|
|
||||||
|
"failedToGetGpsLocation": "Neuspjelo dobivanje GPS lokacije",
|
||||||
|
|
||||||
|
"advertisedAtLocation": "Objavljeno na {latitude}, {longitude}",
|
||||||
|
|
||||||
|
"failedToAdvertise": "Neuspjela objava: {error}",
|
||||||
|
|
||||||
|
"reconnecting": "Ponovno povezivanje... ({attempt}/{max})",
|
||||||
|
|
||||||
|
"cancelReconnection": "Otkaži ponovno povezivanje",
|
||||||
|
|
||||||
|
"mapManagement": "Upravljanje kartom",
|
||||||
|
|
||||||
|
"general": "Općenito",
|
||||||
|
|
||||||
|
"theme": "Tema",
|
||||||
|
|
||||||
|
"chooseTheme": "Odaberite temu",
|
||||||
|
|
||||||
|
"light": "Svijetla",
|
||||||
|
|
||||||
|
"dark": "Tamna",
|
||||||
|
|
||||||
|
"blueLightTheme": "Plava svijetla tema",
|
||||||
|
|
||||||
|
"blueDarkTheme": "Plava tamna tema",
|
||||||
|
|
||||||
|
"sarRed": "SAR crvena",
|
||||||
|
|
||||||
|
"alertEmergencyMode": "Način upozorenja/hitna situacija",
|
||||||
|
|
||||||
|
"sarGreen": "SAR zelena",
|
||||||
|
|
||||||
|
"safeAllClearMode": "Način sigurno/sve jasno",
|
||||||
|
|
||||||
|
"autoSystem": "Automatski (Sustav)",
|
||||||
|
|
||||||
|
"followSystemTheme": "Slijedi sistemsku temu",
|
||||||
|
|
||||||
|
"showRxTxIndicators": "Prikaži RX/TX indikatore",
|
||||||
|
|
||||||
|
"displayPacketActivity": "Prikaži indikatore aktivnosti paketa u gornjoj traci",
|
||||||
|
|
||||||
|
"language": "Jezik",
|
||||||
|
|
||||||
|
"chooseLanguage": "Odaberite jezik",
|
||||||
|
|
||||||
|
"english": "Engleski",
|
||||||
|
|
||||||
|
"slovenian": "Slovenski",
|
||||||
|
|
||||||
|
"croatian": "Hrvatski",
|
||||||
|
|
||||||
|
"locationBroadcasting": "Emitiranje lokacije",
|
||||||
|
|
||||||
|
"autoLocationTracking": "Automatsko praćenje lokacije",
|
||||||
|
|
||||||
|
"automaticallyBroadcastPosition": "Automatski emitiraj ažuriranja pozicije",
|
||||||
|
|
||||||
|
"configureTracking": "Konfiguriraj praćenje",
|
||||||
|
|
||||||
|
"distanceAndTimeThresholds": "Pragovi udaljenosti i vremena",
|
||||||
|
|
||||||
|
"locationTrackingConfiguration": "Konfiguracija praćenja lokacije",
|
||||||
|
|
||||||
|
"configureWhenLocationBroadcasts": "Konfigurirajte kada se emitiranja lokacije šalju u mesh mrežu",
|
||||||
|
|
||||||
|
"minimumDistance": "Minimalna udaljenost",
|
||||||
|
|
||||||
|
"broadcastAfterMoving": "Emitiraj tek nakon pomicanja {distance} metara",
|
||||||
|
|
||||||
|
"maximumDistance": "Maksimalna udaljenost",
|
||||||
|
|
||||||
|
"alwaysBroadcastAfterMoving": "Uvijek emitiraj nakon pomicanja {distance} metara",
|
||||||
|
|
||||||
|
"minimumTimeInterval": "Minimalni vremenski interval",
|
||||||
|
|
||||||
|
"alwaysBroadcastEvery": "Uvijek emitiraj svakih {duration}",
|
||||||
|
|
||||||
|
"save": "Spremi",
|
||||||
|
|
||||||
|
"cancel": "Otkaži",
|
||||||
|
|
||||||
|
"close": "Zatvori",
|
||||||
|
|
||||||
|
"about": "O aplikaciji",
|
||||||
|
|
||||||
|
"appVersion": "Verzija aplikacije",
|
||||||
|
|
||||||
|
"appName": "Ime aplikacije",
|
||||||
|
|
||||||
|
"aboutMeshCoreSar": "O MeshCore SAR",
|
||||||
|
|
||||||
|
"aboutDescription": "Aplikacija za potragu i spašavanje dizajnirana za timove za hitne slučajeve. Značajke uključuju:\n\n• BLE mesh mrežu za komunikaciju uređaj-uređaj\n• Offline karte s više slojeva\n• Praćenje članova tima u stvarnom vremenu\n• SAR taktički markeri (pronađena osoba, požar, zbirno mjesto)\n• Upravljanje kontaktima i razmjena poruka\n• GPS praćenje s kompasnim smjerom\n• Predmemoriranje karata za offline upotrebu",
|
||||||
|
|
||||||
|
"technologiesUsed": "Korištene tehnologije:",
|
||||||
|
|
||||||
|
"technologiesList": "• Flutter za višeplatformski razvoj\n• BLE (Bluetooth Low Energy) za mesh mrežu\n• OpenStreetMap za kartografiju\n• Provider za upravljanje stanjem\n• SharedPreferences za lokalno pohranu",
|
||||||
|
|
||||||
|
"developer": "Programer",
|
||||||
|
|
||||||
|
"packageName": "Ime paketa",
|
||||||
|
|
||||||
|
"sampleData": "Primjer podataka",
|
||||||
|
|
||||||
|
"sampleDataDescription": "Učitajte ili očistite primjere kontakata, poruka kanala i SAR markera za testiranje",
|
||||||
|
|
||||||
|
"loadSampleData": "Učitaj primjer podataka",
|
||||||
|
|
||||||
|
"clearAllData": "Očisti sve podatke",
|
||||||
|
|
||||||
|
"clearAllDataConfirmTitle": "Očisti sve podatke",
|
||||||
|
|
||||||
|
"clearAllDataConfirmMessage": "Ovo će očistiti sve kontakte i SAR markere. Jeste li sigurni?",
|
||||||
|
|
||||||
|
"clear": "Očisti",
|
||||||
|
|
||||||
|
"loadedSampleData": "Učitano {teamCount} članova tima, {channelCount} kanala, {sarCount} SAR markera, {messageCount} poruka",
|
||||||
|
|
||||||
|
"failedToLoadSampleData": "Neuspjelo učitavanje primjera podataka: {error}",
|
||||||
|
|
||||||
|
"allDataCleared": "Svi podaci očišćeni",
|
||||||
|
|
||||||
|
"failedToStartBackgroundTracking": "Neuspjelo pokretanje praćenja u pozadini. Provjerite dopuštenja i BLE vezu.",
|
||||||
|
|
||||||
|
"locationBroadcast": "Emitiranje lokacije: {latitude}, {longitude}",
|
||||||
|
|
||||||
|
"defaultPinInfo": "Zadani PIN za uređaje bez zaslona je 123456. Problemi s uparivanjem? Zaboravite bluetooth uređaj u postavkama sustava."
|
||||||
|
}
|
||||||
617
lib/l10n/app_localizations.dart
Normal file
617
lib/l10n/app_localizations.dart
Normal file
@@ -0,0 +1,617 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
import 'package:intl/intl.dart' as intl;
|
||||||
|
|
||||||
|
import 'app_localizations_en.dart';
|
||||||
|
import 'app_localizations_hr.dart';
|
||||||
|
import 'app_localizations_sl.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
|
||||||
|
/// Callers can lookup localized strings with an instance of AppLocalizations
|
||||||
|
/// returned by `AppLocalizations.of(context)`.
|
||||||
|
///
|
||||||
|
/// Applications need to include `AppLocalizations.delegate()` in their app's
|
||||||
|
/// `localizationDelegates` list, and the locales they support in the app's
|
||||||
|
/// `supportedLocales` list. For example:
|
||||||
|
///
|
||||||
|
/// ```dart
|
||||||
|
/// import 'l10n/app_localizations.dart';
|
||||||
|
///
|
||||||
|
/// return MaterialApp(
|
||||||
|
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||||
|
/// supportedLocales: AppLocalizations.supportedLocales,
|
||||||
|
/// home: MyApplicationHome(),
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Update pubspec.yaml
|
||||||
|
///
|
||||||
|
/// Please make sure to update your pubspec.yaml to include the following
|
||||||
|
/// packages:
|
||||||
|
///
|
||||||
|
/// ```yaml
|
||||||
|
/// dependencies:
|
||||||
|
/// # Internationalization support.
|
||||||
|
/// flutter_localizations:
|
||||||
|
/// sdk: flutter
|
||||||
|
/// intl: any # Use the pinned version from flutter_localizations
|
||||||
|
///
|
||||||
|
/// # Rest of dependencies
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## iOS Applications
|
||||||
|
///
|
||||||
|
/// iOS applications define key application metadata, including supported
|
||||||
|
/// locales, in an Info.plist file that is built into the application bundle.
|
||||||
|
/// To configure the locales supported by your app, you’ll need to edit this
|
||||||
|
/// file.
|
||||||
|
///
|
||||||
|
/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file.
|
||||||
|
/// Then, in the Project Navigator, open the Info.plist file under the Runner
|
||||||
|
/// project’s Runner folder.
|
||||||
|
///
|
||||||
|
/// Next, select the Information Property List item, select Add Item from the
|
||||||
|
/// Editor menu, then select Localizations from the pop-up menu.
|
||||||
|
///
|
||||||
|
/// Select and expand the newly-created Localizations item then, for each
|
||||||
|
/// locale your application supports, add a new item and select the locale
|
||||||
|
/// you wish to add from the pop-up menu in the Value field. This list should
|
||||||
|
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
|
||||||
|
/// property.
|
||||||
|
abstract class AppLocalizations {
|
||||||
|
AppLocalizations(String locale)
|
||||||
|
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
|
||||||
|
|
||||||
|
final String localeName;
|
||||||
|
|
||||||
|
static AppLocalizations? of(BuildContext context) {
|
||||||
|
return Localizations.of<AppLocalizations>(context, AppLocalizations);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const LocalizationsDelegate<AppLocalizations> delegate =
|
||||||
|
_AppLocalizationsDelegate();
|
||||||
|
|
||||||
|
/// A list of this localizations delegate along with the default localizations
|
||||||
|
/// delegates.
|
||||||
|
///
|
||||||
|
/// Returns a list of localizations delegates containing this delegate along with
|
||||||
|
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
|
||||||
|
/// and GlobalWidgetsLocalizations.delegate.
|
||||||
|
///
|
||||||
|
/// Additional delegates can be added by appending to this list in
|
||||||
|
/// MaterialApp. This list does not have to be used at all if a custom list
|
||||||
|
/// of delegates is preferred or required.
|
||||||
|
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
|
||||||
|
<LocalizationsDelegate<dynamic>>[
|
||||||
|
delegate,
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
GlobalCupertinoLocalizations.delegate,
|
||||||
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
];
|
||||||
|
|
||||||
|
/// A list of this localizations delegate's supported locales.
|
||||||
|
static const List<Locale> supportedLocales = <Locale>[
|
||||||
|
Locale('en'),
|
||||||
|
Locale('hr'),
|
||||||
|
Locale('sl'),
|
||||||
|
];
|
||||||
|
|
||||||
|
/// The application title
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'MeshCore SAR'**
|
||||||
|
String get appTitle;
|
||||||
|
|
||||||
|
/// Messages tab label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Messages'**
|
||||||
|
String get messages;
|
||||||
|
|
||||||
|
/// Contacts tab label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Contacts'**
|
||||||
|
String get contacts;
|
||||||
|
|
||||||
|
/// Map tab label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Map'**
|
||||||
|
String get map;
|
||||||
|
|
||||||
|
/// Settings screen title
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Settings'**
|
||||||
|
String get settings;
|
||||||
|
|
||||||
|
/// Connect button label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Connect'**
|
||||||
|
String get connect;
|
||||||
|
|
||||||
|
/// Disconnect button label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Disconnect'**
|
||||||
|
String get disconnect;
|
||||||
|
|
||||||
|
/// Text shown when scanning for BLE devices
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Scanning for devices...'**
|
||||||
|
String get scanningForDevices;
|
||||||
|
|
||||||
|
/// Text shown when no BLE devices are found
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'No devices found'**
|
||||||
|
String get noDevicesFound;
|
||||||
|
|
||||||
|
/// Button to restart BLE scanning
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Scan Again'**
|
||||||
|
String get scanAgain;
|
||||||
|
|
||||||
|
/// Subtitle text for device in scan list
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Tap to connect'**
|
||||||
|
String get tapToConnect;
|
||||||
|
|
||||||
|
/// Error message when device is not connected
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Device not connected'**
|
||||||
|
String get deviceNotConnected;
|
||||||
|
|
||||||
|
/// Error when location permission is denied
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Location permission denied'**
|
||||||
|
String get locationPermissionDenied;
|
||||||
|
|
||||||
|
/// Error when location permission is permanently denied
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Location permission permanently denied. Please enable in Settings.'**
|
||||||
|
String get locationPermissionPermanentlyDenied;
|
||||||
|
|
||||||
|
/// Error when location services are disabled
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Location services are disabled. Please enable them in Settings.'**
|
||||||
|
String get locationServicesDisabled;
|
||||||
|
|
||||||
|
/// Error when GPS location cannot be obtained
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Failed to get GPS location'**
|
||||||
|
String get failedToGetGpsLocation;
|
||||||
|
|
||||||
|
/// Success message showing advertised location
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Advertised at {latitude}, {longitude}'**
|
||||||
|
String advertisedAtLocation(String latitude, String longitude);
|
||||||
|
|
||||||
|
/// Error message for failed advertisement
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Failed to advertise: {error}'**
|
||||||
|
String failedToAdvertise(String error);
|
||||||
|
|
||||||
|
/// Text shown during reconnection attempts
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Reconnecting... ({attempt}/{max})'**
|
||||||
|
String reconnecting(int attempt, int max);
|
||||||
|
|
||||||
|
/// Tooltip for cancel reconnection button
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Cancel reconnection'**
|
||||||
|
String get cancelReconnection;
|
||||||
|
|
||||||
|
/// Menu item for map management
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Map Management'**
|
||||||
|
String get mapManagement;
|
||||||
|
|
||||||
|
/// General settings section header
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'General'**
|
||||||
|
String get general;
|
||||||
|
|
||||||
|
/// Theme setting label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Theme'**
|
||||||
|
String get theme;
|
||||||
|
|
||||||
|
/// Theme selection dialog title
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Choose Theme'**
|
||||||
|
String get chooseTheme;
|
||||||
|
|
||||||
|
/// Light theme option
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Light'**
|
||||||
|
String get light;
|
||||||
|
|
||||||
|
/// Dark theme option
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Dark'**
|
||||||
|
String get dark;
|
||||||
|
|
||||||
|
/// Description for blue light theme
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Blue light theme'**
|
||||||
|
String get blueLightTheme;
|
||||||
|
|
||||||
|
/// Description for blue dark theme
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Blue dark theme'**
|
||||||
|
String get blueDarkTheme;
|
||||||
|
|
||||||
|
/// SAR Red theme option
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'SAR Red'**
|
||||||
|
String get sarRed;
|
||||||
|
|
||||||
|
/// Description for SAR Red theme
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Alert/Emergency mode'**
|
||||||
|
String get alertEmergencyMode;
|
||||||
|
|
||||||
|
/// SAR Green theme option
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'SAR Green'**
|
||||||
|
String get sarGreen;
|
||||||
|
|
||||||
|
/// Description for SAR Green theme
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Safe/All Clear mode'**
|
||||||
|
String get safeAllClearMode;
|
||||||
|
|
||||||
|
/// Auto/System theme option
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Auto (System)'**
|
||||||
|
String get autoSystem;
|
||||||
|
|
||||||
|
/// Description for system theme
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Follow system theme'**
|
||||||
|
String get followSystemTheme;
|
||||||
|
|
||||||
|
/// Setting to show RX/TX indicators
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Show RX/TX Indicators'**
|
||||||
|
String get showRxTxIndicators;
|
||||||
|
|
||||||
|
/// Description for RX/TX indicators setting
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Display packet activity indicators in top bar'**
|
||||||
|
String get displayPacketActivity;
|
||||||
|
|
||||||
|
/// Language setting label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Language'**
|
||||||
|
String get language;
|
||||||
|
|
||||||
|
/// Language selection dialog title
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Choose Language'**
|
||||||
|
String get chooseLanguage;
|
||||||
|
|
||||||
|
/// English language option
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'English'**
|
||||||
|
String get english;
|
||||||
|
|
||||||
|
/// Slovenian language option
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Slovenian'**
|
||||||
|
String get slovenian;
|
||||||
|
|
||||||
|
/// Croatian language option
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Croatian'**
|
||||||
|
String get croatian;
|
||||||
|
|
||||||
|
/// Location settings section header
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Location Broadcasting'**
|
||||||
|
String get locationBroadcasting;
|
||||||
|
|
||||||
|
/// Auto location tracking setting
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Auto Location Tracking'**
|
||||||
|
String get autoLocationTracking;
|
||||||
|
|
||||||
|
/// Description for auto location tracking
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Automatically broadcast position updates'**
|
||||||
|
String get automaticallyBroadcastPosition;
|
||||||
|
|
||||||
|
/// Configure tracking button label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Configure Tracking'**
|
||||||
|
String get configureTracking;
|
||||||
|
|
||||||
|
/// Description for tracking configuration
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Distance and time thresholds'**
|
||||||
|
String get distanceAndTimeThresholds;
|
||||||
|
|
||||||
|
/// Tracking configuration dialog title
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Location Tracking Configuration'**
|
||||||
|
String get locationTrackingConfiguration;
|
||||||
|
|
||||||
|
/// Description for tracking configuration dialog
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Configure when location broadcasts are sent to the mesh network'**
|
||||||
|
String get configureWhenLocationBroadcasts;
|
||||||
|
|
||||||
|
/// Minimum distance setting label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Minimum Distance'**
|
||||||
|
String get minimumDistance;
|
||||||
|
|
||||||
|
/// Description for minimum distance
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Broadcast only after moving {distance} meters'**
|
||||||
|
String broadcastAfterMoving(String distance);
|
||||||
|
|
||||||
|
/// Maximum distance setting label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Maximum Distance'**
|
||||||
|
String get maximumDistance;
|
||||||
|
|
||||||
|
/// Description for maximum distance
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Always broadcast after moving {distance} meters'**
|
||||||
|
String alwaysBroadcastAfterMoving(String distance);
|
||||||
|
|
||||||
|
/// Minimum time interval setting label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Minimum Time Interval'**
|
||||||
|
String get minimumTimeInterval;
|
||||||
|
|
||||||
|
/// Description for time interval
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Always broadcast every {duration}'**
|
||||||
|
String alwaysBroadcastEvery(String duration);
|
||||||
|
|
||||||
|
/// Save button label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Save'**
|
||||||
|
String get save;
|
||||||
|
|
||||||
|
/// Cancel button label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Cancel'**
|
||||||
|
String get cancel;
|
||||||
|
|
||||||
|
/// Close button label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Close'**
|
||||||
|
String get close;
|
||||||
|
|
||||||
|
/// About section header
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'About'**
|
||||||
|
String get about;
|
||||||
|
|
||||||
|
/// App version label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'App Version'**
|
||||||
|
String get appVersion;
|
||||||
|
|
||||||
|
/// App name label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'App Name'**
|
||||||
|
String get appName;
|
||||||
|
|
||||||
|
/// About dialog title
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'About MeshCore SAR'**
|
||||||
|
String get aboutMeshCoreSar;
|
||||||
|
|
||||||
|
/// About dialog description
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'A Search & Rescue application designed for emergency response teams. Features include:\n\n• BLE mesh networking for device-to-device communication\n• Offline maps with multiple layer options\n• Real-time team member tracking\n• SAR tactical markers (found person, fire, staging)\n• Contact management and messaging\n• GPS tracking with compass heading\n• Map tile caching for offline use'**
|
||||||
|
String get aboutDescription;
|
||||||
|
|
||||||
|
/// Technologies used section title
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Technologies Used:'**
|
||||||
|
String get technologiesUsed;
|
||||||
|
|
||||||
|
/// List of technologies used
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'• Flutter for cross-platform development\n• BLE (Bluetooth Low Energy) for mesh networking\n• OpenStreetMap for mapping\n• Provider for state management\n• SharedPreferences for local storage'**
|
||||||
|
String get technologiesList;
|
||||||
|
|
||||||
|
/// Developer section header
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Developer'**
|
||||||
|
String get developer;
|
||||||
|
|
||||||
|
/// Package name label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Package Name'**
|
||||||
|
String get packageName;
|
||||||
|
|
||||||
|
/// Sample data section header
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Sample Data'**
|
||||||
|
String get sampleData;
|
||||||
|
|
||||||
|
/// Sample data section description
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Load or clear sample contacts, channel messages, and SAR markers for testing'**
|
||||||
|
String get sampleDataDescription;
|
||||||
|
|
||||||
|
/// Load sample data button
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Load Sample Data'**
|
||||||
|
String get loadSampleData;
|
||||||
|
|
||||||
|
/// Clear all data button
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Clear All Data'**
|
||||||
|
String get clearAllData;
|
||||||
|
|
||||||
|
/// Clear data confirmation dialog title
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Clear All Data'**
|
||||||
|
String get clearAllDataConfirmTitle;
|
||||||
|
|
||||||
|
/// Clear data confirmation message
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'This will clear all contacts and SAR markers. Are you sure?'**
|
||||||
|
String get clearAllDataConfirmMessage;
|
||||||
|
|
||||||
|
/// Clear button label
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Clear'**
|
||||||
|
String get clear;
|
||||||
|
|
||||||
|
/// Success message after loading sample data
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Loaded {teamCount} team members, {channelCount} channels, {sarCount} SAR markers, {messageCount} messages'**
|
||||||
|
String loadedSampleData(
|
||||||
|
int teamCount,
|
||||||
|
int channelCount,
|
||||||
|
int sarCount,
|
||||||
|
int messageCount,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Error message when sample data fails to load
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Failed to load sample data: {error}'**
|
||||||
|
String failedToLoadSampleData(String error);
|
||||||
|
|
||||||
|
/// Success message after clearing all data
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'All data cleared'**
|
||||||
|
String get allDataCleared;
|
||||||
|
|
||||||
|
/// Error message when background tracking fails to start
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Failed to start background tracking. Check permissions and BLE connection.'**
|
||||||
|
String get failedToStartBackgroundTracking;
|
||||||
|
|
||||||
|
/// Success message for location broadcast
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'Location broadcast: {latitude}, {longitude}'**
|
||||||
|
String locationBroadcast(String latitude, String longitude);
|
||||||
|
|
||||||
|
/// Information about default PIN for pairing
|
||||||
|
///
|
||||||
|
/// In en, this message translates to:
|
||||||
|
/// **'The default pin for devices without a screen is 123456. Trouble pairing? Forget the bluetooth device in system settings.'**
|
||||||
|
String get defaultPinInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppLocalizationsDelegate
|
||||||
|
extends LocalizationsDelegate<AppLocalizations> {
|
||||||
|
const _AppLocalizationsDelegate();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<AppLocalizations> load(Locale locale) {
|
||||||
|
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isSupported(Locale locale) =>
|
||||||
|
<String>['en', 'hr', 'sl'].contains(locale.languageCode);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppLocalizations lookupAppLocalizations(Locale locale) {
|
||||||
|
// Lookup logic when only language code is specified.
|
||||||
|
switch (locale.languageCode) {
|
||||||
|
case 'en':
|
||||||
|
return AppLocalizationsEn();
|
||||||
|
case 'hr':
|
||||||
|
return AppLocalizationsHr();
|
||||||
|
case 'sl':
|
||||||
|
return AppLocalizationsSl();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw FlutterError(
|
||||||
|
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
|
||||||
|
'an issue with the localizations generation tool. Please file an issue '
|
||||||
|
'on GitHub with a reproducible sample app and the gen-l10n configuration '
|
||||||
|
'that was used.',
|
||||||
|
);
|
||||||
|
}
|
||||||
281
lib/l10n/app_localizations_en.dart
Normal file
281
lib/l10n/app_localizations_en.dart
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
// ignore: unused_import
|
||||||
|
import 'package:intl/intl.dart' as intl;
|
||||||
|
import 'app_localizations.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
|
||||||
|
/// The translations for English (`en`).
|
||||||
|
class AppLocalizationsEn extends AppLocalizations {
|
||||||
|
AppLocalizationsEn([String locale = 'en']) : super(locale);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appTitle => 'MeshCore SAR';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get messages => 'Messages';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get contacts => 'Contacts';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get map => 'Map';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get settings => 'Settings';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get connect => 'Connect';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get disconnect => 'Disconnect';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanningForDevices => 'Scanning for devices...';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noDevicesFound => 'No devices found';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanAgain => 'Scan Again';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get tapToConnect => 'Tap to connect';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get deviceNotConnected => 'Device not connected';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationPermissionDenied => 'Location permission denied';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationPermissionPermanentlyDenied =>
|
||||||
|
'Location permission permanently denied. Please enable in Settings.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationServicesDisabled =>
|
||||||
|
'Location services are disabled. Please enable them in Settings.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get failedToGetGpsLocation => 'Failed to get GPS location';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String advertisedAtLocation(String latitude, String longitude) {
|
||||||
|
return 'Advertised at $latitude, $longitude';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String failedToAdvertise(String error) {
|
||||||
|
return 'Failed to advertise: $error';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String reconnecting(int attempt, int max) {
|
||||||
|
return 'Reconnecting... ($attempt/$max)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cancelReconnection => 'Cancel reconnection';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get mapManagement => 'Map Management';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get general => 'General';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get theme => 'Theme';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get chooseTheme => 'Choose Theme';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get light => 'Light';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get dark => 'Dark';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get blueLightTheme => 'Blue light theme';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get blueDarkTheme => 'Blue dark theme';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sarRed => 'SAR Red';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get alertEmergencyMode => 'Alert/Emergency mode';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sarGreen => 'SAR Green';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get safeAllClearMode => 'Safe/All Clear mode';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get autoSystem => 'Auto (System)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get followSystemTheme => 'Follow system theme';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get showRxTxIndicators => 'Show RX/TX Indicators';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get displayPacketActivity =>
|
||||||
|
'Display packet activity indicators in top bar';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get language => 'Language';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get chooseLanguage => 'Choose Language';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get english => 'English';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get slovenian => 'Slovenian';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get croatian => 'Croatian';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationBroadcasting => 'Location Broadcasting';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get autoLocationTracking => 'Auto Location Tracking';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get automaticallyBroadcastPosition =>
|
||||||
|
'Automatically broadcast position updates';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get configureTracking => 'Configure Tracking';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get distanceAndTimeThresholds => 'Distance and time thresholds';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationTrackingConfiguration => 'Location Tracking Configuration';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get configureWhenLocationBroadcasts =>
|
||||||
|
'Configure when location broadcasts are sent to the mesh network';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get minimumDistance => 'Minimum Distance';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String broadcastAfterMoving(String distance) {
|
||||||
|
return 'Broadcast only after moving $distance meters';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get maximumDistance => 'Maximum Distance';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String alwaysBroadcastAfterMoving(String distance) {
|
||||||
|
return 'Always broadcast after moving $distance meters';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get minimumTimeInterval => 'Minimum Time Interval';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String alwaysBroadcastEvery(String duration) {
|
||||||
|
return 'Always broadcast every $duration';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get save => 'Save';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cancel => 'Cancel';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get close => 'Close';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get about => 'About';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appVersion => 'App Version';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appName => 'App Name';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get aboutMeshCoreSar => 'About MeshCore SAR';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get aboutDescription =>
|
||||||
|
'A Search & Rescue application designed for emergency response teams. Features include:\n\n• BLE mesh networking for device-to-device communication\n• Offline maps with multiple layer options\n• Real-time team member tracking\n• SAR tactical markers (found person, fire, staging)\n• Contact management and messaging\n• GPS tracking with compass heading\n• Map tile caching for offline use';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get technologiesUsed => 'Technologies Used:';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get technologiesList =>
|
||||||
|
'• Flutter for cross-platform development\n• BLE (Bluetooth Low Energy) for mesh networking\n• OpenStreetMap for mapping\n• Provider for state management\n• SharedPreferences for local storage';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get developer => 'Developer';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get packageName => 'Package Name';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sampleData => 'Sample Data';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sampleDataDescription =>
|
||||||
|
'Load or clear sample contacts, channel messages, and SAR markers for testing';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get loadSampleData => 'Load Sample Data';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearAllData => 'Clear All Data';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearAllDataConfirmTitle => 'Clear All Data';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearAllDataConfirmMessage =>
|
||||||
|
'This will clear all contacts and SAR markers. Are you sure?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clear => 'Clear';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String loadedSampleData(
|
||||||
|
int teamCount,
|
||||||
|
int channelCount,
|
||||||
|
int sarCount,
|
||||||
|
int messageCount,
|
||||||
|
) {
|
||||||
|
return 'Loaded $teamCount team members, $channelCount channels, $sarCount SAR markers, $messageCount messages';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String failedToLoadSampleData(String error) {
|
||||||
|
return 'Failed to load sample data: $error';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get allDataCleared => 'All data cleared';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get failedToStartBackgroundTracking =>
|
||||||
|
'Failed to start background tracking. Check permissions and BLE connection.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String locationBroadcast(String latitude, String longitude) {
|
||||||
|
return 'Location broadcast: $latitude, $longitude';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get defaultPinInfo =>
|
||||||
|
'The default pin for devices without a screen is 123456. Trouble pairing? Forget the bluetooth device in system settings.';
|
||||||
|
}
|
||||||
281
lib/l10n/app_localizations_hr.dart
Normal file
281
lib/l10n/app_localizations_hr.dart
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
// ignore: unused_import
|
||||||
|
import 'package:intl/intl.dart' as intl;
|
||||||
|
import 'app_localizations.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
|
||||||
|
/// The translations for Croatian (`hr`).
|
||||||
|
class AppLocalizationsHr extends AppLocalizations {
|
||||||
|
AppLocalizationsHr([String locale = 'hr']) : super(locale);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appTitle => 'MeshCore SAR';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get messages => 'Poruke';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get contacts => 'Kontakti';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get map => 'Karta';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get settings => 'Postavke';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get connect => 'Poveži';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get disconnect => 'Prekini';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanningForDevices => 'Skeniranje uređaja...';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noDevicesFound => 'Nisu pronađeni uređaji';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanAgain => 'Skeniraj ponovno';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get tapToConnect => 'Dodirnite za povezivanje';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get deviceNotConnected => 'Uređaj nije povezan';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationPermissionDenied => 'Dopuštenje za lokaciju odbijeno';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationPermissionPermanentlyDenied =>
|
||||||
|
'Dopuštenje za lokaciju trajno odbijeno. Molimo omogućite u Postavkama.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationServicesDisabled =>
|
||||||
|
'Usluge lokacije su onemogućene. Molimo omogućite ih u Postavkama.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get failedToGetGpsLocation => 'Neuspjelo dobivanje GPS lokacije';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String advertisedAtLocation(String latitude, String longitude) {
|
||||||
|
return 'Objavljeno na $latitude, $longitude';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String failedToAdvertise(String error) {
|
||||||
|
return 'Neuspjela objava: $error';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String reconnecting(int attempt, int max) {
|
||||||
|
return 'Ponovno povezivanje... ($attempt/$max)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cancelReconnection => 'Otkaži ponovno povezivanje';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get mapManagement => 'Upravljanje kartom';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get general => 'Općenito';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get theme => 'Tema';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get chooseTheme => 'Odaberite temu';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get light => 'Svijetla';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get dark => 'Tamna';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get blueLightTheme => 'Plava svijetla tema';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get blueDarkTheme => 'Plava tamna tema';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sarRed => 'SAR crvena';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get alertEmergencyMode => 'Način upozorenja/hitna situacija';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sarGreen => 'SAR zelena';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get safeAllClearMode => 'Način sigurno/sve jasno';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get autoSystem => 'Automatski (Sustav)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get followSystemTheme => 'Slijedi sistemsku temu';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get showRxTxIndicators => 'Prikaži RX/TX indikatore';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get displayPacketActivity =>
|
||||||
|
'Prikaži indikatore aktivnosti paketa u gornjoj traci';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get language => 'Jezik';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get chooseLanguage => 'Odaberite jezik';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get english => 'Engleski';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get slovenian => 'Slovenski';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get croatian => 'Hrvatski';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationBroadcasting => 'Emitiranje lokacije';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get autoLocationTracking => 'Automatsko praćenje lokacije';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get automaticallyBroadcastPosition =>
|
||||||
|
'Automatski emitiraj ažuriranja pozicije';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get configureTracking => 'Konfiguriraj praćenje';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get distanceAndTimeThresholds => 'Pragovi udaljenosti i vremena';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationTrackingConfiguration => 'Konfiguracija praćenja lokacije';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get configureWhenLocationBroadcasts =>
|
||||||
|
'Konfigurirajte kada se emitiranja lokacije šalju u mesh mrežu';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get minimumDistance => 'Minimalna udaljenost';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String broadcastAfterMoving(String distance) {
|
||||||
|
return 'Emitiraj tek nakon pomicanja $distance metara';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get maximumDistance => 'Maksimalna udaljenost';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String alwaysBroadcastAfterMoving(String distance) {
|
||||||
|
return 'Uvijek emitiraj nakon pomicanja $distance metara';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get minimumTimeInterval => 'Minimalni vremenski interval';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String alwaysBroadcastEvery(String duration) {
|
||||||
|
return 'Uvijek emitiraj svakih $duration';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get save => 'Spremi';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cancel => 'Otkaži';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get close => 'Zatvori';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get about => 'O aplikaciji';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appVersion => 'Verzija aplikacije';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appName => 'Ime aplikacije';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get aboutMeshCoreSar => 'O MeshCore SAR';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get aboutDescription =>
|
||||||
|
'Aplikacija za potragu i spašavanje dizajnirana za timove za hitne slučajeve. Značajke uključuju:\n\n• BLE mesh mrežu za komunikaciju uređaj-uređaj\n• Offline karte s više slojeva\n• Praćenje članova tima u stvarnom vremenu\n• SAR taktički markeri (pronađena osoba, požar, zbirno mjesto)\n• Upravljanje kontaktima i razmjena poruka\n• GPS praćenje s kompasnim smjerom\n• Predmemoriranje karata za offline upotrebu';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get technologiesUsed => 'Korištene tehnologije:';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get technologiesList =>
|
||||||
|
'• Flutter za višeplatformski razvoj\n• BLE (Bluetooth Low Energy) za mesh mrežu\n• OpenStreetMap za kartografiju\n• Provider za upravljanje stanjem\n• SharedPreferences za lokalno pohranu';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get developer => 'Programer';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get packageName => 'Ime paketa';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sampleData => 'Primjer podataka';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sampleDataDescription =>
|
||||||
|
'Učitajte ili očistite primjere kontakata, poruka kanala i SAR markera za testiranje';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get loadSampleData => 'Učitaj primjer podataka';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearAllData => 'Očisti sve podatke';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearAllDataConfirmTitle => 'Očisti sve podatke';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearAllDataConfirmMessage =>
|
||||||
|
'Ovo će očistiti sve kontakte i SAR markere. Jeste li sigurni?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clear => 'Očisti';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String loadedSampleData(
|
||||||
|
int teamCount,
|
||||||
|
int channelCount,
|
||||||
|
int sarCount,
|
||||||
|
int messageCount,
|
||||||
|
) {
|
||||||
|
return 'Učitano $teamCount članova tima, $channelCount kanala, $sarCount SAR markera, $messageCount poruka';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String failedToLoadSampleData(String error) {
|
||||||
|
return 'Neuspjelo učitavanje primjera podataka: $error';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get allDataCleared => 'Svi podaci očišćeni';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get failedToStartBackgroundTracking =>
|
||||||
|
'Neuspjelo pokretanje praćenja u pozadini. Provjerite dopuštenja i BLE vezu.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String locationBroadcast(String latitude, String longitude) {
|
||||||
|
return 'Emitiranje lokacije: $latitude, $longitude';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get defaultPinInfo =>
|
||||||
|
'Zadani PIN za uređaje bez zaslona je 123456. Problemi s uparivanjem? Zaboravite bluetooth uređaj u postavkama sustava.';
|
||||||
|
}
|
||||||
281
lib/l10n/app_localizations_sl.dart
Normal file
281
lib/l10n/app_localizations_sl.dart
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
// ignore: unused_import
|
||||||
|
import 'package:intl/intl.dart' as intl;
|
||||||
|
import 'app_localizations.dart';
|
||||||
|
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
|
||||||
|
/// The translations for Slovenian (`sl`).
|
||||||
|
class AppLocalizationsSl extends AppLocalizations {
|
||||||
|
AppLocalizationsSl([String locale = 'sl']) : super(locale);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appTitle => 'MeshCore SAR';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get messages => 'Sporočila';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get contacts => 'Stiki';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get map => 'Zemljevid';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get settings => 'Nastavitve';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get connect => 'Poveži';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get disconnect => 'Prekini';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanningForDevices => 'Iskanje naprav...';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get noDevicesFound => 'Ni najdenih naprav';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get scanAgain => 'Ponovi iskanje';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get tapToConnect => 'Tapnite za povezavo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get deviceNotConnected => 'Naprava ni povezana';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationPermissionDenied => 'Dovoljenje za lokacijo zavrnjeno';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationPermissionPermanentlyDenied =>
|
||||||
|
'Dovoljenje za lokacijo trajno zavrnjeno. Prosimo, omogočite v Nastavitvah.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationServicesDisabled =>
|
||||||
|
'Lokacijske storitve so onemogočene. Prosimo, omogočite jih v Nastavitvah.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get failedToGetGpsLocation => 'Pridobitev GPS lokacije ni uspela';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String advertisedAtLocation(String latitude, String longitude) {
|
||||||
|
return 'Objavljeno na $latitude, $longitude';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String failedToAdvertise(String error) {
|
||||||
|
return 'Objava ni uspela: $error';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String reconnecting(int attempt, int max) {
|
||||||
|
return 'Ponovno povezovanje... ($attempt/$max)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cancelReconnection => 'Prekliči ponovno povezovanje';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get mapManagement => 'Upravljanje zemljevida';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get general => 'Splošno';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get theme => 'Tema';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get chooseTheme => 'Izberite temo';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get light => 'Svetla';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get dark => 'Temna';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get blueLightTheme => 'Modra svetla tema';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get blueDarkTheme => 'Modra temna tema';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sarRed => 'SAR rdeča';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get alertEmergencyMode => 'Način opozorila/nujni primer';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sarGreen => 'SAR zelena';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get safeAllClearMode => 'Način varno/vse jasno';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get autoSystem => 'Samodejno (Sistem)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get followSystemTheme => 'Sledi sistemski temi';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get showRxTxIndicators => 'Prikaži RX/TX kazalnike';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get displayPacketActivity =>
|
||||||
|
'Prikaži kazalnike aktivnosti paketov v zgornji vrstici';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get language => 'Jezik';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get chooseLanguage => 'Izberite jezik';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get english => 'Angleščina';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get slovenian => 'Slovenščina';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get croatian => 'Hrvaščina';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationBroadcasting => 'Oddajanje lokacije';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get autoLocationTracking => 'Samodejno sledenje lokaciji';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get automaticallyBroadcastPosition =>
|
||||||
|
'Samodejno oddajaj posodobitve položaja';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get configureTracking => 'Konfiguriraj sledenje';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get distanceAndTimeThresholds => 'Pragovi razdalje in časa';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get locationTrackingConfiguration => 'Konfiguracija sledenja lokaciji';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get configureWhenLocationBroadcasts =>
|
||||||
|
'Konfigurirajte, kdaj se oddajanja lokacije pošiljajo v omrežje mesh';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get minimumDistance => 'Minimalna razdalja';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String broadcastAfterMoving(String distance) {
|
||||||
|
return 'Oddajaj šele po premiku $distance metrov';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get maximumDistance => 'Maksimalna razdalja';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String alwaysBroadcastAfterMoving(String distance) {
|
||||||
|
return 'Vedno oddajaj po premiku $distance metrov';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get minimumTimeInterval => 'Minimalni časovni interval';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String alwaysBroadcastEvery(String duration) {
|
||||||
|
return 'Vedno oddajaj vsakih $duration';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get save => 'Shrani';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get cancel => 'Prekliči';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get close => 'Zapri';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get about => 'O aplikaciji';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appVersion => 'Različica aplikacije';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get appName => 'Ime aplikacije';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get aboutMeshCoreSar => 'O MeshCore SAR';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get aboutDescription =>
|
||||||
|
'Aplikacija za iskanje in reševanje, zasnovana za ekipe za odzivanje v nujnih primerih. Funkcije vključujejo:\n\n• BLE mesh omrežje za komunikacijo naprava-naprava\n• Brez povezave delujejo zemljevidi z več sloji\n• Sledenje članov ekipe v realnem času\n• SAR taktični označevalci (najdena oseba, ogenj, zbirališče)\n• Upravljanje stikov in sporočanje\n• GPS sledenje s kompasno smerjo\n• Predpomnenje ploščic zemljevida za uporabo brez povezave';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get technologiesUsed => 'Uporabljene tehnologije:';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get technologiesList =>
|
||||||
|
'• Flutter za večplatformni razvoj\n• BLE (Bluetooth Low Energy) za mesh omrežje\n• OpenStreetMap za kartografijo\n• Provider za upravljanje stanja\n• SharedPreferences za lokalno shranjevanje';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get developer => 'Razvijalec';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get packageName => 'Ime paketa';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sampleData => 'Vzorčni podatki';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get sampleDataDescription =>
|
||||||
|
'Naložite ali počistite vzorčne stike, sporočila kanalov in SAR označevalce za testiranje';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get loadSampleData => 'Naloži vzorčne podatke';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearAllData => 'Počisti vse podatke';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearAllDataConfirmTitle => 'Počisti vse podatke';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clearAllDataConfirmMessage =>
|
||||||
|
'To bo počistilo vse stike in SAR označevalce. Ste prepričani?';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get clear => 'Počisti';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String loadedSampleData(
|
||||||
|
int teamCount,
|
||||||
|
int channelCount,
|
||||||
|
int sarCount,
|
||||||
|
int messageCount,
|
||||||
|
) {
|
||||||
|
return 'Naloženih $teamCount članov ekipe, $channelCount kanalov, $sarCount SAR označevalcev, $messageCount sporočil';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String failedToLoadSampleData(String error) {
|
||||||
|
return 'Nalaganje vzorčnih podatkov ni uspelo: $error';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get allDataCleared => 'Vsi podatki počiščeni';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get failedToStartBackgroundTracking =>
|
||||||
|
'Zagon sledenja v ozadju ni uspel. Preverite dovoljenja in BLE povezavo.';
|
||||||
|
|
||||||
|
@override
|
||||||
|
String locationBroadcast(String latitude, String longitude) {
|
||||||
|
return 'Oddajanje lokacije: $latitude, $longitude';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get defaultPinInfo =>
|
||||||
|
'Privzeta PIN koda za naprave brez zaslona je 123456. Težave s seznanitvijo? Pozabite napravo bluetooth v sistemskih nastavitvah.';
|
||||||
|
}
|
||||||
161
lib/l10n/app_sl.arb
Normal file
161
lib/l10n/app_sl.arb
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
{
|
||||||
|
"@@locale": "sl",
|
||||||
|
|
||||||
|
"appTitle": "MeshCore SAR",
|
||||||
|
|
||||||
|
"messages": "Sporočila",
|
||||||
|
|
||||||
|
"contacts": "Stiki",
|
||||||
|
|
||||||
|
"map": "Zemljevid",
|
||||||
|
|
||||||
|
"settings": "Nastavitve",
|
||||||
|
|
||||||
|
"connect": "Poveži",
|
||||||
|
|
||||||
|
"disconnect": "Prekini",
|
||||||
|
|
||||||
|
"scanningForDevices": "Iskanje naprav...",
|
||||||
|
|
||||||
|
"noDevicesFound": "Ni najdenih naprav",
|
||||||
|
|
||||||
|
"scanAgain": "Ponovi iskanje",
|
||||||
|
|
||||||
|
"tapToConnect": "Tapnite za povezavo",
|
||||||
|
|
||||||
|
"deviceNotConnected": "Naprava ni povezana",
|
||||||
|
|
||||||
|
"locationPermissionDenied": "Dovoljenje za lokacijo zavrnjeno",
|
||||||
|
|
||||||
|
"locationPermissionPermanentlyDenied": "Dovoljenje za lokacijo trajno zavrnjeno. Prosimo, omogočite v Nastavitvah.",
|
||||||
|
|
||||||
|
"locationServicesDisabled": "Lokacijske storitve so onemogočene. Prosimo, omogočite jih v Nastavitvah.",
|
||||||
|
|
||||||
|
"failedToGetGpsLocation": "Pridobitev GPS lokacije ni uspela",
|
||||||
|
|
||||||
|
"advertisedAtLocation": "Objavljeno na {latitude}, {longitude}",
|
||||||
|
|
||||||
|
"failedToAdvertise": "Objava ni uspela: {error}",
|
||||||
|
|
||||||
|
"reconnecting": "Ponovno povezovanje... ({attempt}/{max})",
|
||||||
|
|
||||||
|
"cancelReconnection": "Prekliči ponovno povezovanje",
|
||||||
|
|
||||||
|
"mapManagement": "Upravljanje zemljevida",
|
||||||
|
|
||||||
|
"general": "Splošno",
|
||||||
|
|
||||||
|
"theme": "Tema",
|
||||||
|
|
||||||
|
"chooseTheme": "Izberite temo",
|
||||||
|
|
||||||
|
"light": "Svetla",
|
||||||
|
|
||||||
|
"dark": "Temna",
|
||||||
|
|
||||||
|
"blueLightTheme": "Modra svetla tema",
|
||||||
|
|
||||||
|
"blueDarkTheme": "Modra temna tema",
|
||||||
|
|
||||||
|
"sarRed": "SAR rdeča",
|
||||||
|
|
||||||
|
"alertEmergencyMode": "Način opozorila/nujni primer",
|
||||||
|
|
||||||
|
"sarGreen": "SAR zelena",
|
||||||
|
|
||||||
|
"safeAllClearMode": "Način varno/vse jasno",
|
||||||
|
|
||||||
|
"autoSystem": "Samodejno (Sistem)",
|
||||||
|
|
||||||
|
"followSystemTheme": "Sledi sistemski temi",
|
||||||
|
|
||||||
|
"showRxTxIndicators": "Prikaži RX/TX kazalnike",
|
||||||
|
|
||||||
|
"displayPacketActivity": "Prikaži kazalnike aktivnosti paketov v zgornji vrstici",
|
||||||
|
|
||||||
|
"language": "Jezik",
|
||||||
|
|
||||||
|
"chooseLanguage": "Izberite jezik",
|
||||||
|
|
||||||
|
"english": "Angleščina",
|
||||||
|
|
||||||
|
"slovenian": "Slovenščina",
|
||||||
|
|
||||||
|
"croatian": "Hrvaščina",
|
||||||
|
|
||||||
|
"locationBroadcasting": "Oddajanje lokacije",
|
||||||
|
|
||||||
|
"autoLocationTracking": "Samodejno sledenje lokaciji",
|
||||||
|
|
||||||
|
"automaticallyBroadcastPosition": "Samodejno oddajaj posodobitve položaja",
|
||||||
|
|
||||||
|
"configureTracking": "Konfiguriraj sledenje",
|
||||||
|
|
||||||
|
"distanceAndTimeThresholds": "Pragovi razdalje in časa",
|
||||||
|
|
||||||
|
"locationTrackingConfiguration": "Konfiguracija sledenja lokaciji",
|
||||||
|
|
||||||
|
"configureWhenLocationBroadcasts": "Konfigurirajte, kdaj se oddajanja lokacije pošiljajo v omrežje mesh",
|
||||||
|
|
||||||
|
"minimumDistance": "Minimalna razdalja",
|
||||||
|
|
||||||
|
"broadcastAfterMoving": "Oddajaj šele po premiku {distance} metrov",
|
||||||
|
|
||||||
|
"maximumDistance": "Maksimalna razdalja",
|
||||||
|
|
||||||
|
"alwaysBroadcastAfterMoving": "Vedno oddajaj po premiku {distance} metrov",
|
||||||
|
|
||||||
|
"minimumTimeInterval": "Minimalni časovni interval",
|
||||||
|
|
||||||
|
"alwaysBroadcastEvery": "Vedno oddajaj vsakih {duration}",
|
||||||
|
|
||||||
|
"save": "Shrani",
|
||||||
|
|
||||||
|
"cancel": "Prekliči",
|
||||||
|
|
||||||
|
"close": "Zapri",
|
||||||
|
|
||||||
|
"about": "O aplikaciji",
|
||||||
|
|
||||||
|
"appVersion": "Različica aplikacije",
|
||||||
|
|
||||||
|
"appName": "Ime aplikacije",
|
||||||
|
|
||||||
|
"aboutMeshCoreSar": "O MeshCore SAR",
|
||||||
|
|
||||||
|
"aboutDescription": "Aplikacija za iskanje in reševanje, zasnovana za ekipe za odzivanje v nujnih primerih. Funkcije vključujejo:\n\n• BLE mesh omrežje za komunikacijo naprava-naprava\n• Brez povezave delujejo zemljevidi z več sloji\n• Sledenje članov ekipe v realnem času\n• SAR taktični označevalci (najdena oseba, ogenj, zbirališče)\n• Upravljanje stikov in sporočanje\n• GPS sledenje s kompasno smerjo\n• Predpomnenje ploščic zemljevida za uporabo brez povezave",
|
||||||
|
|
||||||
|
"technologiesUsed": "Uporabljene tehnologije:",
|
||||||
|
|
||||||
|
"technologiesList": "• Flutter za večplatformni razvoj\n• BLE (Bluetooth Low Energy) za mesh omrežje\n• OpenStreetMap za kartografijo\n• Provider za upravljanje stanja\n• SharedPreferences za lokalno shranjevanje",
|
||||||
|
|
||||||
|
"developer": "Razvijalec",
|
||||||
|
|
||||||
|
"packageName": "Ime paketa",
|
||||||
|
|
||||||
|
"sampleData": "Vzorčni podatki",
|
||||||
|
|
||||||
|
"sampleDataDescription": "Naložite ali počistite vzorčne stike, sporočila kanalov in SAR označevalce za testiranje",
|
||||||
|
|
||||||
|
"loadSampleData": "Naloži vzorčne podatke",
|
||||||
|
|
||||||
|
"clearAllData": "Počisti vse podatke",
|
||||||
|
|
||||||
|
"clearAllDataConfirmTitle": "Počisti vse podatke",
|
||||||
|
|
||||||
|
"clearAllDataConfirmMessage": "To bo počistilo vse stike in SAR označevalce. Ste prepričani?",
|
||||||
|
|
||||||
|
"clear": "Počisti",
|
||||||
|
|
||||||
|
"loadedSampleData": "Naloženih {teamCount} članov ekipe, {channelCount} kanalov, {sarCount} SAR označevalcev, {messageCount} sporočil",
|
||||||
|
|
||||||
|
"failedToLoadSampleData": "Nalaganje vzorčnih podatkov ni uspelo: {error}",
|
||||||
|
|
||||||
|
"allDataCleared": "Vsi podatki počiščeni",
|
||||||
|
|
||||||
|
"failedToStartBackgroundTracking": "Zagon sledenja v ozadju ni uspel. Preverite dovoljenja in BLE povezavo.",
|
||||||
|
|
||||||
|
"locationBroadcast": "Oddajanje lokacije: {latitude}, {longitude}",
|
||||||
|
|
||||||
|
"defaultPinInfo": "Privzeta PIN koda za naprave brez zaslona je 123456. Težave s seznanitvijo? Pozabite napravo bluetooth v sistemskih nastavitvah."
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'providers/connection_provider.dart';
|
import 'providers/connection_provider.dart';
|
||||||
@@ -8,8 +9,10 @@ import 'providers/map_provider.dart';
|
|||||||
import 'providers/drawing_provider.dart';
|
import 'providers/drawing_provider.dart';
|
||||||
import 'providers/app_provider.dart';
|
import 'providers/app_provider.dart';
|
||||||
import 'services/tile_cache_service.dart';
|
import 'services/tile_cache_service.dart';
|
||||||
|
import 'services/locale_preferences.dart';
|
||||||
import 'screens/home_screen.dart';
|
import 'screens/home_screen.dart';
|
||||||
import 'theme/app_theme.dart';
|
import 'theme/app_theme.dart';
|
||||||
|
import 'l10n/app_localizations.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(const MeshCoreSarApp());
|
runApp(const MeshCoreSarApp());
|
||||||
@@ -24,6 +27,7 @@ class MeshCoreSarApp extends StatefulWidget {
|
|||||||
|
|
||||||
class _MeshCoreSarAppState extends State<MeshCoreSarApp> {
|
class _MeshCoreSarAppState extends State<MeshCoreSarApp> {
|
||||||
AppThemeMode _themeMode = AppThemeMode.system;
|
AppThemeMode _themeMode = AppThemeMode.system;
|
||||||
|
Locale? _locale;
|
||||||
bool _isInitialized = false;
|
bool _isInitialized = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -34,6 +38,7 @@ class _MeshCoreSarAppState extends State<MeshCoreSarApp> {
|
|||||||
|
|
||||||
Future<void> _initializeApp() async {
|
Future<void> _initializeApp() async {
|
||||||
await _loadThemePreference();
|
await _loadThemePreference();
|
||||||
|
await _loadLocalePreference();
|
||||||
setState(() {
|
setState(() {
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
});
|
});
|
||||||
@@ -47,12 +52,25 @@ class _MeshCoreSarAppState extends State<MeshCoreSarApp> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _loadLocalePreference() async {
|
||||||
|
final locale = await LocalePreferences.getLocale();
|
||||||
|
setState(() {
|
||||||
|
_locale = locale;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void _handleThemeChanged(AppThemeMode mode) {
|
void _handleThemeChanged(AppThemeMode mode) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_themeMode = mode;
|
_themeMode = mode;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _handleLocaleChanged(Locale? locale) {
|
||||||
|
setState(() {
|
||||||
|
_locale = locale;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (!_isInitialized) {
|
if (!_isInitialized) {
|
||||||
@@ -125,9 +143,19 @@ class _MeshCoreSarAppState extends State<MeshCoreSarApp> {
|
|||||||
title: 'MeshCore SAR',
|
title: 'MeshCore SAR',
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
theme: AppTheme.getTheme(_themeMode, systemBrightness),
|
theme: AppTheme.getTheme(_themeMode, systemBrightness),
|
||||||
|
locale: _locale,
|
||||||
|
localizationsDelegates: const [
|
||||||
|
AppLocalizations.delegate,
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
GlobalCupertinoLocalizations.delegate,
|
||||||
|
],
|
||||||
|
supportedLocales: LocalePreferences.supportedLocales,
|
||||||
home: HomeScreen(
|
home: HomeScreen(
|
||||||
onThemeChanged: _handleThemeChanged,
|
onThemeChanged: _handleThemeChanged,
|
||||||
|
onLocaleChanged: _handleLocaleChanged,
|
||||||
currentTheme: _themeMode,
|
currentTheme: _themeMode,
|
||||||
|
currentLocale: _locale,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,12 +18,16 @@ import '../utils/toast_logger.dart';
|
|||||||
|
|
||||||
class HomeScreen extends StatefulWidget {
|
class HomeScreen extends StatefulWidget {
|
||||||
final Function(AppThemeMode) onThemeChanged;
|
final Function(AppThemeMode) onThemeChanged;
|
||||||
|
final Function(Locale?) onLocaleChanged;
|
||||||
final AppThemeMode currentTheme;
|
final AppThemeMode currentTheme;
|
||||||
|
final Locale? currentLocale;
|
||||||
|
|
||||||
const HomeScreen({
|
const HomeScreen({
|
||||||
super.key,
|
super.key,
|
||||||
required this.onThemeChanged,
|
required this.onThemeChanged,
|
||||||
|
required this.onLocaleChanged,
|
||||||
required this.currentTheme,
|
required this.currentTheme,
|
||||||
|
required this.currentLocale,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -493,7 +497,9 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => SettingsScreen(
|
builder: (context) => SettingsScreen(
|
||||||
onThemeChanged: widget.onThemeChanged,
|
onThemeChanged: widget.onThemeChanged,
|
||||||
|
onLocaleChanged: widget.onLocaleChanged,
|
||||||
currentTheme: widget.currentTheme,
|
currentTheme: widget.currentTheme,
|
||||||
|
currentLocale: widget.currentLocale,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -575,14 +581,23 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
|
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
|
// LEFT SECTION: Name + BT/Battery status + Settings cog
|
||||||
Expanded(
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
// Name and status group
|
||||||
|
Flexible(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
const Text(
|
Text(
|
||||||
'MeshCore',
|
isConnected && deviceInfo.selfName != null
|
||||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
? deviceInfo.selfName!
|
||||||
|
: 'MeshCore',
|
||||||
|
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
if (isConnected)
|
if (isConnected)
|
||||||
Row(
|
Row(
|
||||||
@@ -635,12 +650,62 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
)
|
)
|
||||||
else if (provider.isReconnecting)
|
else if (provider.isReconnecting)
|
||||||
Text(
|
Text(
|
||||||
'Reconnecting... (${provider.reconnectionAttempt}/${provider.maxReconnectionAttempts})',
|
'Reconnecting...',
|
||||||
style: TextStyle(fontSize: 14, color: Colors.orange[600]),
|
style: TextStyle(fontSize: 12, color: Colors.orange[600]),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
// Settings cog - part of left group
|
||||||
|
if (isConnected) ...[
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const DeviceConfigScreen(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) =>
|
||||||
|
PacketLogScreen(bleService: provider.bleService),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 36,
|
||||||
|
height: 36,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: const Icon(Icons.settings, size: 20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// CENTER SECTION: Broadcast button (when connected)
|
||||||
|
if (isConnected) ...[
|
||||||
|
FilledButton(
|
||||||
|
onPressed: () => _advertiseDevice(context),
|
||||||
|
style: FilledButton.styleFrom(
|
||||||
|
backgroundColor: Colors.blue.shade700,
|
||||||
|
foregroundColor: Colors.white,
|
||||||
|
padding: const EdgeInsets.all(10),
|
||||||
|
minimumSize: const Size(40, 40),
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
),
|
||||||
|
child: const Icon(Icons.campaign, size: 20),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
|
||||||
|
// RIGHT SECTION: Connect button OR RX/TX indicators
|
||||||
if (!isConnected)
|
if (!isConnected)
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
@@ -663,7 +728,7 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
: const Icon(Icons.bluetooth, size: 18),
|
: const Icon(Icons.bluetooth, size: 18),
|
||||||
label: Text(
|
label: Text(
|
||||||
provider.isReconnecting
|
provider.isReconnecting
|
||||||
? 'Reconnecting (${provider.reconnectionAttempt}/${provider.maxReconnectionAttempts})'
|
? '${provider.reconnectionAttempt}/${provider.maxReconnectionAttempts}'
|
||||||
: 'Connect',
|
: 'Connect',
|
||||||
),
|
),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
@@ -691,25 +756,7 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
else
|
else if (_showRxTxIndicators)
|
||||||
Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
// Advertise button (broadcast location)
|
|
||||||
FilledButton(
|
|
||||||
onPressed: () => _advertiseDevice(context),
|
|
||||||
style: FilledButton.styleFrom(
|
|
||||||
backgroundColor: Colors.blue.shade700,
|
|
||||||
foregroundColor: Colors.white,
|
|
||||||
padding: const EdgeInsets.all(10),
|
|
||||||
minimumSize: const Size(40, 40),
|
|
||||||
shape: const CircleBorder(),
|
|
||||||
),
|
|
||||||
child: const Icon(Icons.campaign, size: 20),
|
|
||||||
),
|
|
||||||
if (_showRxTxIndicators) ...[
|
|
||||||
const SizedBox(width: 8),
|
|
||||||
// RX/TX indicators with long press to open packet log
|
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onLongPress: () {
|
onLongPress: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@@ -776,39 +823,6 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
|
||||||
],
|
|
||||||
// Settings button (tap for device settings, long press for packet logs)
|
|
||||||
GestureDetector(
|
|
||||||
onTap: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => const DeviceConfigScreen(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
onLongPress: () {
|
|
||||||
Navigator.push(
|
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) =>
|
|
||||||
PacketLogScreen(bleService: provider.bleService),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 36,
|
|
||||||
height: 36,
|
|
||||||
alignment: Alignment.center,
|
|
||||||
child: const Icon(Icons.settings, size: 20),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(width: 16),
|
|
||||||
|
|
||||||
// Disconnect button (prominent, icon only) - pushed to far right edge
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,17 +8,22 @@ import '../providers/contacts_provider.dart';
|
|||||||
import '../providers/messages_provider.dart';
|
import '../providers/messages_provider.dart';
|
||||||
import '../providers/app_provider.dart';
|
import '../providers/app_provider.dart';
|
||||||
import '../services/location_tracking_service.dart';
|
import '../services/location_tracking_service.dart';
|
||||||
|
import '../services/locale_preferences.dart';
|
||||||
import '../utils/sample_data_generator.dart';
|
import '../utils/sample_data_generator.dart';
|
||||||
import '../theme/app_theme.dart';
|
import '../theme/app_theme.dart';
|
||||||
|
|
||||||
class SettingsScreen extends StatefulWidget {
|
class SettingsScreen extends StatefulWidget {
|
||||||
final Function(AppThemeMode) onThemeChanged;
|
final Function(AppThemeMode) onThemeChanged;
|
||||||
|
final Function(Locale?) onLocaleChanged;
|
||||||
final AppThemeMode currentTheme;
|
final AppThemeMode currentTheme;
|
||||||
|
final Locale? currentLocale;
|
||||||
|
|
||||||
const SettingsScreen({
|
const SettingsScreen({
|
||||||
super.key,
|
super.key,
|
||||||
required this.onThemeChanged,
|
required this.onThemeChanged,
|
||||||
|
required this.onLocaleChanged,
|
||||||
required this.currentTheme,
|
required this.currentTheme,
|
||||||
|
required this.currentLocale,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -27,6 +32,7 @@ class SettingsScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _SettingsScreenState extends State<SettingsScreen> {
|
class _SettingsScreenState extends State<SettingsScreen> {
|
||||||
late AppThemeMode _selectedTheme;
|
late AppThemeMode _selectedTheme;
|
||||||
|
late Locale? _selectedLocale;
|
||||||
PackageInfo? _packageInfo;
|
PackageInfo? _packageInfo;
|
||||||
bool _isLoadingSampleData = false;
|
bool _isLoadingSampleData = false;
|
||||||
bool _showRxTxIndicators = true;
|
bool _showRxTxIndicators = true;
|
||||||
@@ -36,6 +42,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_selectedTheme = widget.currentTheme;
|
_selectedTheme = widget.currentTheme;
|
||||||
|
_selectedLocale = widget.currentLocale;
|
||||||
_loadPackageInfo();
|
_loadPackageInfo();
|
||||||
_initializeLocationService();
|
_initializeLocationService();
|
||||||
_loadRxTxPreference();
|
_loadRxTxPreference();
|
||||||
@@ -135,6 +142,18 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _saveLocalePreference(Locale? locale) async {
|
||||||
|
await LocalePreferences.setLocale(locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleLocaleChange(Locale? locale) {
|
||||||
|
setState(() {
|
||||||
|
_selectedLocale = locale;
|
||||||
|
});
|
||||||
|
_saveLocalePreference(locale);
|
||||||
|
widget.onLocaleChanged(locale);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _loadSampleData() async {
|
Future<void> _loadSampleData() async {
|
||||||
setState(() => _isLoadingSampleData = true);
|
setState(() => _isLoadingSampleData = true);
|
||||||
|
|
||||||
@@ -322,6 +341,13 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
await _saveRxTxPreference(value);
|
await _saveRxTxPreference(value);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.language),
|
||||||
|
title: const Text('Language'),
|
||||||
|
subtitle: Text(LocalePreferences.getDisplayName(_selectedLocale)),
|
||||||
|
trailing: const Icon(Icons.chevron_right),
|
||||||
|
onTap: () => _showLanguageDialog(),
|
||||||
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
|
|
||||||
// Location Settings Section
|
// Location Settings Section
|
||||||
@@ -761,6 +787,50 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showLanguageDialog() {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('Choose Language'),
|
||||||
|
content: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
RadioListTile<Locale?>(
|
||||||
|
title: const Text('System Default'),
|
||||||
|
subtitle: const Text('Follow system language'),
|
||||||
|
value: null,
|
||||||
|
groupValue: _selectedLocale,
|
||||||
|
onChanged: (value) {
|
||||||
|
_handleLocaleChange(value);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const Divider(),
|
||||||
|
...LocalePreferences.supportedLocales.map((locale) {
|
||||||
|
return RadioListTile<Locale?>(
|
||||||
|
title: Text(LocalePreferences.getNativeDisplayName(locale)),
|
||||||
|
value: locale,
|
||||||
|
groupValue: _selectedLocale,
|
||||||
|
onChanged: (value) {
|
||||||
|
_handleLocaleChange(value);
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: const Text('Cancel'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void _showAboutDialog() {
|
void _showAboutDialog() {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
|
|||||||
70
lib/services/locale_preferences.dart
Normal file
70
lib/services/locale_preferences.dart
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
/// Service for managing locale preferences
|
||||||
|
class LocalePreferences {
|
||||||
|
static const String _localeKey = 'app_locale';
|
||||||
|
|
||||||
|
/// Supported locales
|
||||||
|
static const List<Locale> supportedLocales = [
|
||||||
|
Locale('en'), // English
|
||||||
|
Locale('sl'), // Slovenian
|
||||||
|
Locale('hr'), // Croatian
|
||||||
|
];
|
||||||
|
|
||||||
|
/// Get the saved locale or return null to use system locale
|
||||||
|
static Future<Locale?> getLocale() async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
final localeCode = prefs.getString(_localeKey);
|
||||||
|
|
||||||
|
if (localeCode == null) {
|
||||||
|
return null; // Use system locale
|
||||||
|
}
|
||||||
|
|
||||||
|
return Locale(localeCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Save the selected locale
|
||||||
|
static Future<void> setLocale(Locale? locale) async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
|
||||||
|
if (locale == null) {
|
||||||
|
// Remove preference to use system locale
|
||||||
|
await prefs.remove(_localeKey);
|
||||||
|
} else {
|
||||||
|
await prefs.setString(_localeKey, locale.languageCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get display name for a locale
|
||||||
|
static String getDisplayName(Locale? locale) {
|
||||||
|
if (locale == null) {
|
||||||
|
return 'System Default';
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (locale.languageCode) {
|
||||||
|
case 'en':
|
||||||
|
return 'English';
|
||||||
|
case 'sl':
|
||||||
|
return 'Slovenščina';
|
||||||
|
case 'hr':
|
||||||
|
return 'Hrvatski';
|
||||||
|
default:
|
||||||
|
return locale.languageCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get native display name for a locale (shown in selection dialog)
|
||||||
|
static String getNativeDisplayName(Locale locale) {
|
||||||
|
switch (locale.languageCode) {
|
||||||
|
case 'en':
|
||||||
|
return 'English';
|
||||||
|
case 'sl':
|
||||||
|
return 'Slovenščina';
|
||||||
|
case 'hr':
|
||||||
|
return 'Hrvatski';
|
||||||
|
default:
|
||||||
|
return locale.languageCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -246,6 +246,11 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.0.0"
|
version: "6.0.0"
|
||||||
|
flutter_localizations:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
flutter_map:
|
flutter_map:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -361,7 +366,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.2"
|
version: "4.1.2"
|
||||||
intl:
|
intl:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
# Internationalization
|
||||||
|
intl: any
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
@@ -90,6 +95,9 @@ flutter:
|
|||||||
# the material Icons class.
|
# the material Icons class.
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|
||||||
|
# Enable generation of localization files
|
||||||
|
generate: true
|
||||||
|
|
||||||
# To add assets to your application, add an assets section, like this:
|
# To add assets to your application, add an assets section, like this:
|
||||||
# assets:
|
# assets:
|
||||||
# - images/a_dot_burr.jpeg
|
# - images/a_dot_burr.jpeg
|
||||||
|
|||||||
Reference in New Issue
Block a user