mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
feat: Enhance map functionality with download area selection and user location pointer
- Added download area selection feature in MapProvider with methods to enter, exit, and update bounds. - Implemented DownloadAreaOverlay widget for user interface during download area selection. - Integrated download area preview in MapManagementScreen with visual feedback. - Introduced LocationPointer widget to indicate user location and heading on the map. - Updated localization strings in app_sl.arb for improved clarity and accuracy. - Refactored map marker generation to utilize the new LocationPointer for user location representation. - Improved error handling in LocationTrackingService for initial position setting.
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
arb-dir: lib/l10n
|
arb-dir: lib/l10n
|
||||||
template-arb-file: app_en.arb
|
template-arb-file: app_en.arb
|
||||||
output-localization-file: app_localizations.dart
|
output-localization-file: app_localizations.dart
|
||||||
|
untranslated-messages-file: lib/l10n/untranslated.json
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
|
|
||||||
"autoSystem": "Automatski (Sustav)",
|
"autoSystem": "Automatski (Sustav)",
|
||||||
|
|
||||||
"followSystemTheme": "Slijedi sistemsku temu",
|
"followSystemTheme": "Slijedi temu sustava",
|
||||||
|
|
||||||
"showRxTxIndicators": "Prikaži RX/TX indikatore",
|
"showRxTxIndicators": "Prikaži RX/TX indikatore",
|
||||||
|
|
||||||
@@ -141,11 +141,11 @@
|
|||||||
|
|
||||||
"technologiesUsed": "Korištene tehnologije:",
|
"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",
|
"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 lokalnu pohranu",
|
||||||
|
|
||||||
"moreInfo": "Više informacija",
|
"moreInfo": "Više informacija",
|
||||||
|
|
||||||
"learnMoreAbout": "Saznajte više o MeshCore SAR",
|
"learnMoreAbout": "Saznajte više o MeshCore SAR-u",
|
||||||
|
|
||||||
"developer": "Programer",
|
"developer": "Programer",
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@
|
|||||||
|
|
||||||
"locationBroadcast": "Emitiranje lokacije: {latitude}, {longitude}",
|
"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.",
|
"defaultPinInfo": "Zadani PIN za uređaje bez zaslona je 123456. Problemi s uparivanjem? Zaboravite Bluetooth uređaj u postavkama sustava.",
|
||||||
|
|
||||||
"noMessagesYet": "Još nema poruka",
|
"noMessagesYet": "Još nema poruka",
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
|
|
||||||
"deleteDrawing": "Izbriši crtež",
|
"deleteDrawing": "Izbriši crtež",
|
||||||
|
|
||||||
"drawingTools": "Alati za crtanje",
|
|
||||||
|
|
||||||
"drawLine": "Nacrtaj liniju",
|
"drawLine": "Nacrtaj liniju",
|
||||||
|
|
||||||
@@ -433,7 +433,7 @@
|
|||||||
|
|
||||||
"accuracy": "Točnost",
|
"accuracy": "Točnost",
|
||||||
|
|
||||||
"distance": "Udaljenost",
|
|
||||||
|
|
||||||
"bearing": "Azimut",
|
"bearing": "Azimut",
|
||||||
|
|
||||||
@@ -467,7 +467,7 @@
|
|||||||
|
|
||||||
"degreesLeft": "{degrees}° lijevo",
|
"degreesLeft": "{degrees}° lijevo",
|
||||||
|
|
||||||
"latLonFormat": "Ššir: {latitude} Dužina: {longitude}",
|
"latLonFormat": "Šir: {latitude} Duž: {longitude}",
|
||||||
|
|
||||||
"noContactsYet": "Još nema kontakata",
|
"noContactsYet": "Još nema kontakata",
|
||||||
|
|
||||||
@@ -487,7 +487,7 @@
|
|||||||
|
|
||||||
"cacheSize": "Veličina predmemorije",
|
"cacheSize": "Veličina predmemorije",
|
||||||
|
|
||||||
"storeName": "Ime pohrane",
|
"storeName": "Naziv spremišta",
|
||||||
|
|
||||||
"noCacheStatistics": "Statistika predmemorije nije dostupna",
|
"noCacheStatistics": "Statistika predmemorije nije dostupna",
|
||||||
|
|
||||||
@@ -571,7 +571,7 @@
|
|||||||
|
|
||||||
"resetMapRotationTooltip": "Vrati kartu na sjever",
|
"resetMapRotationTooltip": "Vrati kartu na sjever",
|
||||||
|
|
||||||
"showMapDebugInfo": "Prikaži debug informacije karte",
|
"showMapDebugInfo": "Prikaži informacije za otklanjanje pogrešaka karte",
|
||||||
|
|
||||||
"displayZoomLevelBounds": "Prikaži razinu zumiranja i granice",
|
"displayZoomLevelBounds": "Prikaži razinu zumiranja i granice",
|
||||||
|
|
||||||
@@ -585,7 +585,7 @@
|
|||||||
|
|
||||||
"esriSatellite": "ESRI satelit",
|
"esriSatellite": "ESRI satelit",
|
||||||
|
|
||||||
"googleHybrid": "Google hibridno",
|
"googleHybrid": "Google hibridna karta",
|
||||||
|
|
||||||
"googleRoadmap": "Google cestovna karta",
|
"googleRoadmap": "Google cestovna karta",
|
||||||
|
|
||||||
@@ -769,8 +769,6 @@
|
|||||||
|
|
||||||
"trailHiddenRecording": "Putanja je skrivena (još se snima)",
|
"trailHiddenRecording": "Putanja je skrivena (još se snima)",
|
||||||
|
|
||||||
"distance": "Udaljenost",
|
|
||||||
|
|
||||||
"duration": "Trajanje",
|
"duration": "Trajanje",
|
||||||
|
|
||||||
"points": "Točke",
|
"points": "Točke",
|
||||||
@@ -849,7 +847,7 @@
|
|||||||
|
|
||||||
"lat": "Šir",
|
"lat": "Šir",
|
||||||
|
|
||||||
"lon": "Dug",
|
"lon": "Duž",
|
||||||
|
|
||||||
"useCurrentLocation": "Koristi trenutnu lokaciju",
|
"useCurrentLocation": "Koristi trenutnu lokaciju",
|
||||||
|
|
||||||
@@ -879,28 +877,27 @@
|
|||||||
"templateEmoji": "Emoji",
|
"templateEmoji": "Emoji",
|
||||||
"emojiRequired": "Emoji je obavezan",
|
"emojiRequired": "Emoji je obavezan",
|
||||||
"nameRequired": "Ime je obavezno",
|
"nameRequired": "Ime je obavezno",
|
||||||
"templateDescription": "Description (Optional)",
|
"templateDescription": "Opis (neobavezno)",
|
||||||
"templateDescriptionHint": "Add additional context...",
|
"templateDescriptionHint": "Dodajte dodatni kontekst...",
|
||||||
"templateColor": "Color",
|
"templateColor": "Boja",
|
||||||
"previewFormat": "Preview (SAR Message Format)",
|
"previewFormat": "Pregled (format SAR poruke)",
|
||||||
"importFromClipboard": "Uvezi",
|
"importFromClipboard": "Uvezi",
|
||||||
"exportToClipboard": "Izvezi",
|
"exportToClipboard": "Izvezi",
|
||||||
"deleteTemplateConfirmation": "Delete template '{name}'?",
|
"deleteTemplateConfirmation": "Izbrisati predložak '{name}'?",
|
||||||
"templateAdded": "Template added",
|
"templateAdded": "Predložak dodan",
|
||||||
"templateUpdated": "Template updated",
|
"templateUpdated": "Predložak ažuriran",
|
||||||
"templateDeleted": "Template deleted",
|
"templateDeleted": "Predložak izbrisan",
|
||||||
"templatesImported": "{count, plural, =0{No templates imported} =1{Imported 1 template} other{Imported {count} templates}}",
|
"templatesImported": "{count, plural, =0{Nema uvezenih predložaka} =1{Uvezen 1 predložak} other{Uvezeno {count} predložaka}}",
|
||||||
"templatesExported": "{count, plural, =1{Exported 1 template to clipboard} other{Exported {count} templates to clipboard}}",
|
"templatesExported": "{count, plural, =1{Izvezen 1 predložak u međuspremnik} other{Izvezeno {count} predložaka u međuspremnik}}",
|
||||||
"importFailed": "Import failed: {error}",
|
"importFailed": "Uvoz nije uspio: {error}",
|
||||||
"exportFailed": "Export failed: {error}",
|
"exportFailed": "Izvoz nije uspio: {error}",
|
||||||
"resetToDefaults": "Vrati na zadane",
|
"resetToDefaults": "Vrati na zadane",
|
||||||
"resetToDefaultsConfirmation": "Ovo će izbrisati sve prilagođene predloške i vratiti 4 zadana predloška. Nastaviti?",
|
"resetToDefaultsConfirmation": "Ovo će izbrisati sve prilagođene predloške i vratiti 4 zadana predloška. Nastaviti?",
|
||||||
"reset": "Vrati",
|
"reset": "Vrati",
|
||||||
"resetComplete": "Predlošci vraćeni na zadane",
|
"resetComplete": "Predlošci vraćeni na zadane",
|
||||||
"noTemplates": "No templates available",
|
"noTemplates": "Nema dostupnih predložaka",
|
||||||
"tapAddToCreate": "Tap + to create your first template",
|
"tapAddToCreate": "Dodirnite + za izradu prvog predloška",
|
||||||
"ok": "OK",
|
"ok": "OK",
|
||||||
"delete": "Obriši",
|
|
||||||
|
|
||||||
"permissionsSection": "Dozvole",
|
"permissionsSection": "Dozvole",
|
||||||
"locationPermission": "Dozvola za lokaciju",
|
"locationPermission": "Dozvola za lokaciju",
|
||||||
@@ -918,7 +915,7 @@
|
|||||||
"sarNavyBlueDescription": "Profesionalni/Operativni Način",
|
"sarNavyBlueDescription": "Profesionalni/Operativni Način",
|
||||||
|
|
||||||
"selectRecipient": "Odaberi primatelja",
|
"selectRecipient": "Odaberi primatelja",
|
||||||
"broadcastToAllNearby": "Emituj svima u blizini",
|
"broadcastToAllNearby": "Emitiraj svima u blizini",
|
||||||
"searchRecipients": "Pretraži primatelje...",
|
"searchRecipients": "Pretraži primatelje...",
|
||||||
"noContactsFound": "Nema kontakata",
|
"noContactsFound": "Nema kontakata",
|
||||||
"noRoomsFound": "Nema soba",
|
"noRoomsFound": "Nema soba",
|
||||||
@@ -946,9 +943,9 @@
|
|||||||
"sampleObjectVehicle": " Napušteno vozilo - provjeriti vlasnika",
|
"sampleObjectVehicle": " Napušteno vozilo - provjeriti vlasnika",
|
||||||
"sampleObjectCamping": " Otkrivena oprema za kampiranje",
|
"sampleObjectCamping": " Otkrivena oprema za kampiranje",
|
||||||
"sampleObjectTrailMarker": " Oznaka staze pronađena izvan puta",
|
"sampleObjectTrailMarker": " Oznaka staze pronađena izvan puta",
|
||||||
"sampleMsgAllTeamsCheckIn": "Svi timovi se jave",
|
"sampleMsgAllTeamsCheckIn": "Svi timovi, javite se",
|
||||||
"sampleMsgWeatherUpdate": "Ažuriranje vremena: Vedro nebo, temp 18°C",
|
"sampleMsgWeatherUpdate": "Ažuriranje vremena: Vedro nebo, temp 18°C",
|
||||||
"sampleMsgBaseCamp": "Bazni kamp uspostavljen na okupljalište",
|
"sampleMsgBaseCamp": "Bazni kamp uspostavljen na okupljalištu",
|
||||||
"sampleMsgTeamAlpha": "Tim se kreće prema sektoru 2",
|
"sampleMsgTeamAlpha": "Tim se kreće prema sektoru 2",
|
||||||
"sampleMsgRadioCheck": "Provjera radija - sve stanice odgovorite",
|
"sampleMsgRadioCheck": "Provjera radija - sve stanice odgovorite",
|
||||||
"sampleMsgWaterSupply": "Opskrba vodom dostupna na kontrolnoj točki 3",
|
"sampleMsgWaterSupply": "Opskrba vodom dostupna na kontrolnoj točki 3",
|
||||||
@@ -985,33 +982,33 @@
|
|||||||
"rectangleDrawing": "Pravokutni crtež",
|
"rectangleDrawing": "Pravokutni crtež",
|
||||||
"coordinatesCopiedToClipboard": "Koordinate kopirane u međuspremnik",
|
"coordinatesCopiedToClipboard": "Koordinate kopirane u međuspremnik",
|
||||||
|
|
||||||
"drawingShared": "Crtež karte",
|
"drawingShared": "Crtež podijeljen",
|
||||||
"drawingHidden": "Crtež sakriven s karte",
|
"drawingHidden": "Crtež sakriven s karte",
|
||||||
"alreadyShared": "{count, plural, =1{1 već podijeljeno} other{{count} već podijeljeno}}",
|
"alreadyShared": "{count, plural, =1{1 već podijeljeno} other{{count} već podijeljeno}}",
|
||||||
"newDrawingsShared": "Podijeljeno {count} novi{plural} crtež{plural}",
|
"newDrawingsShared": "Podijeljeno {count} novi{plural} crtež{plural}",
|
||||||
"drawingTools": "Alati za crtanje",
|
"drawingTools": "Alati za crtanje",
|
||||||
"shareDrawing": "Podijeli Crtež",
|
"shareDrawing": "Podijeli crtež",
|
||||||
"shareWithAllNearbyDevices": "Podijeli sa svim obližnjim uređajima",
|
"shareWithAllNearbyDevices": "Podijeli sa svim obližnjim uređajima",
|
||||||
"shareToRoom": "Podijeli u Sobu",
|
"shareToRoom": "Podijeli u Sobu",
|
||||||
"sendToPersistentStorage": "Pošalji u trajnu pohranu sobe",
|
"sendToPersistentStorage": "Pošalji u trajnu pohranu sobe",
|
||||||
"deleteDrawingConfirm": "Jeste li sigurni da želite izbrisati ovaj crtež?",
|
"deleteDrawingConfirm": "Jeste li sigurni da želite izbrisati ovaj crtež?",
|
||||||
"drawingDeleted": "Crtež izbrisan",
|
"drawingDeleted": "Crtež izbrisan",
|
||||||
"yourDrawingsCount": "Vaši Crteži ({count})",
|
"yourDrawingsCount": "Vaši crteži ({count})",
|
||||||
"shared": "Podijeljeno",
|
"shared": "Podijeljeno",
|
||||||
"line": "Linija",
|
"line": "Linija",
|
||||||
"rectangle": "Pravokutnik",
|
"rectangle": "Pravokutnik",
|
||||||
|
|
||||||
"updateAvailable": "Dostupno Ažuriranje",
|
"updateAvailable": "Dostupno ažuriranje",
|
||||||
"currentVersion": "Trenutna",
|
"currentVersion": "Trenutna verzija",
|
||||||
"latestVersion": "Najnovija",
|
"latestVersion": "Najnovija verzija",
|
||||||
"downloadUpdate": "Preuzmi",
|
"downloadUpdate": "Preuzmi ažuriranje",
|
||||||
"updateLater": "Kasnije",
|
"updateLater": "Kasnije",
|
||||||
|
|
||||||
"cadastralParcels": "Katastarske čestice",
|
"cadastralParcels": "Katastarske čestice",
|
||||||
"forestRoads": "Šumske ceste",
|
"forestRoads": "Šumske ceste",
|
||||||
"showCadastralParcels": "Prikaži katastarske čestice",
|
"showCadastralParcels": "Prikaži katastarske čestice",
|
||||||
"showForestRoads": "Prikaži šumske ceste",
|
"showForestRoads": "Prikaži šumske ceste",
|
||||||
"wmsOverlays": "WMS Prekrivanja",
|
"wmsOverlays": "WMS prekrivanja",
|
||||||
|
|
||||||
"recentMessages": "Nedavne poruke",
|
"recentMessages": "Nedavne poruke",
|
||||||
|
|
||||||
@@ -1036,31 +1033,31 @@
|
|||||||
"wizardNext": "Dalje",
|
"wizardNext": "Dalje",
|
||||||
"wizardGetStarted": "Započni",
|
"wizardGetStarted": "Započni",
|
||||||
"wizardWelcomeTitle": "Dobrodošli u MeshCore SAR",
|
"wizardWelcomeTitle": "Dobrodošli u MeshCore SAR",
|
||||||
"wizardWelcomeDescription": "Moćan alat za komunikaciju bez mreže za spasilačke operacije. Povežite se sa svojim timom koristeći mesh radio tehnologiju kada tradicionalne mreže nisu dostupne.",
|
"wizardWelcomeDescription": "Moćan alat za komunikaciju izvan mreže za spasilačke operacije. Povežite se s timom uz mesh radijsku tehnologiju kada tradicionalne mreže nisu dostupne.",
|
||||||
"wizardConnectingTitle": "Povezivanje s Radiom",
|
"wizardConnectingTitle": "Povezivanje s radiom",
|
||||||
"wizardConnectingDescription": "Povežite svoj pametni telefon s MeshCore radio uređajem putem Bluetootha kako biste započeli komunikaciju bez mreže.",
|
"wizardConnectingDescription": "Povežite telefon s MeshCore radijskim uređajem putem Bluetootha i započnite komunikaciju izvan mreže.",
|
||||||
"wizardConnectingFeature1": "Skeniraj obližnje MeshCore uređaje",
|
"wizardConnectingFeature1": "Skenira obližnje MeshCore uređaje",
|
||||||
"wizardConnectingFeature2": "Uparite se s vašim radiom putem Bluetootha",
|
"wizardConnectingFeature2": "Uparivanje s radijem putem Bluetootha",
|
||||||
"wizardConnectingFeature3": "Radi potpuno offline - internet nije potreban",
|
"wizardConnectingFeature3": "Radi potpuno izvan mreže — internet nije potreban",
|
||||||
"wizardSimpleModeTitle": "Jednostavan Način",
|
"wizardSimpleModeTitle": "Jednostavan način",
|
||||||
"wizardSimpleModeDescription": "Novi u mesh umrežavanju? Omogućite jednostavan način za pojednostavljeno sučelje samo s bitnim funkcijama.",
|
"wizardSimpleModeDescription": "Prvi put koristite mesh mrežu? Uključite jednostavan način za pojednostavljeno sučelje s osnovnim funkcijama.",
|
||||||
"wizardSimpleModeFeature1": "Sučelje prijateljsko početnicima s osnovnim funkcijama",
|
"wizardSimpleModeFeature1": "Sučelje prilagođeno početnicima s osnovnim funkcijama",
|
||||||
"wizardSimpleModeFeature2": "Prebacite na Napredni način bilo kada u Postavkama",
|
"wizardSimpleModeFeature2": "U svakom trenutku prebacite na napredni način u Postavkama",
|
||||||
"wizardChannelTitle": "Kanali",
|
"wizardChannelTitle": "Kanali",
|
||||||
"wizardChannelDescription": "Emitirajte poruke svima na kanalu, savršeno za objave i koordinaciju cijele ekipe.",
|
"wizardChannelDescription": "Šaljite poruke svima na kanalu — idealno za obavijesti i koordinaciju tima.",
|
||||||
"wizardChannelFeature1": "Javni kanal za opću komunikaciju ekipe",
|
"wizardChannelFeature1": "Javni kanal za opću komunikaciju ekipe",
|
||||||
"wizardChannelFeature2": "Stvorite prilagođene kanale za specifične grupe",
|
"wizardChannelFeature2": "Stvorite prilagođene kanale za specifične grupe",
|
||||||
"wizardChannelFeature3": "Poruke se automatski prosljeđuju putem mreže",
|
"wizardChannelFeature3": "Poruke se automatski prosljeđuju putem mreže",
|
||||||
"wizardContactsTitle": "Kontakti",
|
"wizardContactsTitle": "Kontakti",
|
||||||
"wizardContactsDescription": "Vaši članovi tima se automatski pojavljuju kada se pridruže mesh mreži. Pošaljite im direktne poruke ili pogledajte njihovu lokaciju.",
|
"wizardContactsDescription": "Članovi tima se prikazuju automatski kada se pridruže mesh mreži. Šaljite im izravne poruke ili pogledajte njihovu lokaciju.",
|
||||||
"wizardContactsFeature1": "Kontakti se automatski otkrivaju",
|
"wizardContactsFeature1": "Kontakti se automatski otkrivaju",
|
||||||
"wizardContactsFeature2": "Šaljite privatne direktne poruke",
|
"wizardContactsFeature2": "Šaljite privatne direktne poruke",
|
||||||
"wizardContactsFeature3": "Pogledajte razinu baterije i vrijeme zadnjeg viđenja",
|
"wizardContactsFeature3": "Prikažite stanje baterije i vrijeme zadnje aktivnosti",
|
||||||
"wizardMapTitle": "Karta & Lokacija",
|
"wizardMapTitle": "Karta i lokacija",
|
||||||
"wizardMapDescription": "Pratite svoj tim u stvarnom vremenu i označite važne lokacije za spasilačke operacije.",
|
"wizardMapDescription": "Pratite tim u stvarnom vremenu i označavajte ključne lokacije za spasilačke operacije.",
|
||||||
"wizardMapFeature1": "SAR oznake za pronađene osobe, požare i područja postavljanja",
|
"wizardMapFeature1": "SAR oznake za pronađene osobe, požare i točke okupljanja",
|
||||||
"wizardMapFeature2": "GPS praćenje članova tima u stvarnom vremenu",
|
"wizardMapFeature2": "GPS praćenje članova tima u stvarnom vremenu",
|
||||||
"wizardMapFeature3": "Preuzmite offline karte za udaljena područja",
|
"wizardMapFeature3": "Preuzmite karte za rad izvan mreže",
|
||||||
"wizardMapFeature4": "Crtajte oblike i dijelite taktičke informacije",
|
"wizardMapFeature4": "Crtajte oblike i dijelite taktičke informacije",
|
||||||
"viewWelcomeTutorial": "Pogledaj uputu dobrodošlice"
|
"viewWelcomeTutorial": "Pogledaj uputu dobrodošlice"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get autoSystem => 'Automatski (Sustav)';
|
String get autoSystem => 'Automatski (Sustav)';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get followSystemTheme => 'Slijedi sistemsku temu';
|
String get followSystemTheme => 'Slijedi temu sustava';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get showRxTxIndicators => 'Prikaži RX/TX indikatore';
|
String get showRxTxIndicators => 'Prikaži RX/TX indikatore';
|
||||||
@@ -240,13 +240,13 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get technologiesList =>
|
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';
|
'• 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 lokalnu pohranu';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get moreInfo => 'Više informacija';
|
String get moreInfo => 'Više informacija';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get learnMoreAbout => 'Saznajte više o MeshCore SAR';
|
String get learnMoreAbout => 'Saznajte više o MeshCore SAR-u';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get developer => 'Programer';
|
String get developer => 'Programer';
|
||||||
@@ -306,7 +306,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get defaultPinInfo =>
|
String get defaultPinInfo =>
|
||||||
'Zadani PIN za uređaje bez zaslona je 123456. Problemi s uparivanjem? Zaboravite bluetooth uređaj u postavkama sustava.';
|
'Zadani PIN za uređaje bez zaslona je 123456. Problemi s uparivanjem? Zaboravite Bluetooth uređaj u postavkama sustava.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get noMessagesYet => 'Još nema poruka';
|
String get noMessagesYet => 'Još nema poruka';
|
||||||
@@ -318,7 +318,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get deleteContact => 'Izbriši kontakt';
|
String get deleteContact => 'Izbriši kontakt';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get delete => 'Obriši';
|
String get delete => 'Izbriši';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get viewOnMap => 'Prikaži na karti';
|
String get viewOnMap => 'Prikaži na karti';
|
||||||
@@ -815,7 +815,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String latLonFormat(String latitude, String longitude) {
|
String latLonFormat(String latitude, String longitude) {
|
||||||
return 'Ššir: $latitude Dužina: $longitude';
|
return 'Šir: $latitude Duž: $longitude';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -847,7 +847,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get cacheSize => 'Veličina predmemorije';
|
String get cacheSize => 'Veličina predmemorije';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get storeName => 'Ime pohrane';
|
String get storeName => 'Naziv spremišta';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get noCacheStatistics => 'Statistika predmemorije nije dostupna';
|
String get noCacheStatistics => 'Statistika predmemorije nije dostupna';
|
||||||
@@ -992,7 +992,8 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get resetMapRotationTooltip => 'Vrati kartu na sjever';
|
String get resetMapRotationTooltip => 'Vrati kartu na sjever';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get showMapDebugInfo => 'Prikaži debug informacije karte';
|
String get showMapDebugInfo =>
|
||||||
|
'Prikaži informacije za otklanjanje pogrešaka karte';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get displayZoomLevelBounds => 'Prikaži razinu zumiranja i granice';
|
String get displayZoomLevelBounds => 'Prikaži razinu zumiranja i granice';
|
||||||
@@ -1014,7 +1015,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get esriSatellite => 'ESRI satelit';
|
String get esriSatellite => 'ESRI satelit';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get googleHybrid => 'Google hibridno';
|
String get googleHybrid => 'Google hibridna karta';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get googleRoadmap => 'Google cestovna karta';
|
String get googleRoadmap => 'Google cestovna karta';
|
||||||
@@ -1310,12 +1311,12 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String exportFailed(String error) {
|
String exportFailed(String error) {
|
||||||
return 'Export failed: $error';
|
return 'Izvoz nije uspio: $error';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String importFailed(String error) {
|
String importFailed(String error) {
|
||||||
return 'Import failed: $error';
|
return 'Uvoz nije uspio: $error';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1495,7 +1496,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get lat => 'Šir';
|
String get lat => 'Šir';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get lon => 'Dug';
|
String get lon => 'Duž';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get useCurrentLocation => 'Koristi trenutnu lokaciju';
|
String get useCurrentLocation => 'Koristi trenutnu lokaciju';
|
||||||
@@ -1563,16 +1564,16 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get nameRequired => 'Ime je obavezno';
|
String get nameRequired => 'Ime je obavezno';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateDescription => 'Description (Optional)';
|
String get templateDescription => 'Opis (neobavezno)';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateDescriptionHint => 'Add additional context...';
|
String get templateDescriptionHint => 'Dodajte dodatni kontekst...';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateColor => 'Color';
|
String get templateColor => 'Boja';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get previewFormat => 'Preview (SAR Message Format)';
|
String get previewFormat => 'Pregled (format SAR poruke)';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get importFromClipboard => 'Uvezi';
|
String get importFromClipboard => 'Uvezi';
|
||||||
@@ -1582,26 +1583,26 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String deleteTemplateConfirmation(String name) {
|
String deleteTemplateConfirmation(String name) {
|
||||||
return 'Delete template \'$name\'?';
|
return 'Izbrisati predložak \'$name\'?';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateAdded => 'Template added';
|
String get templateAdded => 'Predložak dodan';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateUpdated => 'Template updated';
|
String get templateUpdated => 'Predložak ažuriran';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateDeleted => 'Template deleted';
|
String get templateDeleted => 'Predložak izbrisan';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String templatesImported(int count) {
|
String templatesImported(int count) {
|
||||||
String _temp0 = intl.Intl.pluralLogic(
|
String _temp0 = intl.Intl.pluralLogic(
|
||||||
count,
|
count,
|
||||||
locale: localeName,
|
locale: localeName,
|
||||||
other: 'Imported $count templates',
|
other: 'Uvezeno $count predložaka',
|
||||||
one: 'Imported 1 template',
|
one: 'Uvezen 1 predložak',
|
||||||
zero: 'No templates imported',
|
zero: 'Nema uvezenih predložaka',
|
||||||
);
|
);
|
||||||
return '$_temp0';
|
return '$_temp0';
|
||||||
}
|
}
|
||||||
@@ -1611,8 +1612,8 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String _temp0 = intl.Intl.pluralLogic(
|
String _temp0 = intl.Intl.pluralLogic(
|
||||||
count,
|
count,
|
||||||
locale: localeName,
|
locale: localeName,
|
||||||
other: 'Exported $count templates to clipboard',
|
other: 'Izvezeno $count predložaka u međuspremnik',
|
||||||
one: 'Exported 1 template to clipboard',
|
one: 'Izvezen 1 predložak u međuspremnik',
|
||||||
);
|
);
|
||||||
return '$_temp0';
|
return '$_temp0';
|
||||||
}
|
}
|
||||||
@@ -1631,10 +1632,10 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get resetComplete => 'Predlošci vraćeni na zadane';
|
String get resetComplete => 'Predlošci vraćeni na zadane';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get noTemplates => 'No templates available';
|
String get noTemplates => 'Nema dostupnih predložaka';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get tapAddToCreate => 'Tap + to create your first template';
|
String get tapAddToCreate => 'Dodirnite + za izradu prvog predloška';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get ok => 'OK';
|
String get ok => 'OK';
|
||||||
@@ -1691,7 +1692,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get selectRecipient => 'Odaberi primatelja';
|
String get selectRecipient => 'Odaberi primatelja';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get broadcastToAllNearby => 'Emituj svima u blizini';
|
String get broadcastToAllNearby => 'Emitiraj svima u blizini';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get searchRecipients => 'Pretraži primatelje...';
|
String get searchRecipients => 'Pretraži primatelje...';
|
||||||
@@ -1773,14 +1774,14 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get sampleObjectTrailMarker => ' Oznaka staze pronađena izvan puta';
|
String get sampleObjectTrailMarker => ' Oznaka staze pronađena izvan puta';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get sampleMsgAllTeamsCheckIn => 'Svi timovi se jave';
|
String get sampleMsgAllTeamsCheckIn => 'Svi timovi, javite se';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get sampleMsgWeatherUpdate =>
|
String get sampleMsgWeatherUpdate =>
|
||||||
'Ažuriranje vremena: Vedro nebo, temp 18°C';
|
'Ažuriranje vremena: Vedro nebo, temp 18°C';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get sampleMsgBaseCamp => 'Bazni kamp uspostavljen na okupljalište';
|
String get sampleMsgBaseCamp => 'Bazni kamp uspostavljen na okupljalištu';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get sampleMsgTeamAlpha => 'Tim se kreće prema sektoru 2';
|
String get sampleMsgTeamAlpha => 'Tim se kreće prema sektoru 2';
|
||||||
@@ -1893,7 +1894,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
'Koordinate kopirane u međuspremnik';
|
'Koordinate kopirane u međuspremnik';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get drawingShared => 'Crtež karte';
|
String get drawingShared => 'Crtež podijeljen';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get drawingHidden => 'Crtež sakriven s karte';
|
String get drawingHidden => 'Crtež sakriven s karte';
|
||||||
@@ -1915,7 +1916,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get shareDrawing => 'Podijeli Crtež';
|
String get shareDrawing => 'Podijeli crtež';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get shareWithAllNearbyDevices =>
|
String get shareWithAllNearbyDevices =>
|
||||||
@@ -1936,7 +1937,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String yourDrawingsCount(int count) {
|
String yourDrawingsCount(int count) {
|
||||||
return 'Vaši Crteži ($count)';
|
return 'Vaši crteži ($count)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1949,16 +1950,16 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get rectangle => 'Pravokutnik';
|
String get rectangle => 'Pravokutnik';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get updateAvailable => 'Dostupno Ažuriranje';
|
String get updateAvailable => 'Dostupno ažuriranje';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get currentVersion => 'Trenutna';
|
String get currentVersion => 'Trenutna verzija';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get latestVersion => 'Najnovija';
|
String get latestVersion => 'Najnovija verzija';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get downloadUpdate => 'Preuzmi';
|
String get downloadUpdate => 'Preuzmi ažuriranje';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get updateLater => 'Kasnije';
|
String get updateLater => 'Kasnije';
|
||||||
@@ -1976,7 +1977,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
String get showForestRoads => 'Prikaži šumske ceste';
|
String get showForestRoads => 'Prikaži šumske ceste';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wmsOverlays => 'WMS Prekrivanja';
|
String get wmsOverlays => 'WMS prekrivanja';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get recentMessages => 'Nedavne poruke';
|
String get recentMessages => 'Nedavne poruke';
|
||||||
@@ -2048,47 +2049,47 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardWelcomeDescription =>
|
String get wizardWelcomeDescription =>
|
||||||
'Moćan alat za komunikaciju bez mreže za spasilačke operacije. Povežite se sa svojim timom koristeći mesh radio tehnologiju kada tradicionalne mreže nisu dostupne.';
|
'Moćan alat za komunikaciju izvan mreže za spasilačke operacije. Povežite se s timom uz mesh radijsku tehnologiju kada tradicionalne mreže nisu dostupne.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardConnectingTitle => 'Povezivanje s Radiom';
|
String get wizardConnectingTitle => 'Povezivanje s radiom';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardConnectingDescription =>
|
String get wizardConnectingDescription =>
|
||||||
'Povežite svoj pametni telefon s MeshCore radio uređajem putem Bluetootha kako biste započeli komunikaciju bez mreže.';
|
'Povežite telefon s MeshCore radijskim uređajem putem Bluetootha i započnite komunikaciju izvan mreže.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardConnectingFeature1 => 'Skeniraj obližnje MeshCore uređaje';
|
String get wizardConnectingFeature1 => 'Skenira obližnje MeshCore uređaje';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardConnectingFeature2 =>
|
String get wizardConnectingFeature2 =>
|
||||||
'Uparite se s vašim radiom putem Bluetootha';
|
'Uparivanje s radijem putem Bluetootha';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardConnectingFeature3 =>
|
String get wizardConnectingFeature3 =>
|
||||||
'Radi potpuno offline - internet nije potreban';
|
'Radi potpuno izvan mreže — internet nije potreban';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardSimpleModeTitle => 'Jednostavan Način';
|
String get wizardSimpleModeTitle => 'Jednostavan način';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardSimpleModeDescription =>
|
String get wizardSimpleModeDescription =>
|
||||||
'Novi u mesh umrežavanju? Omogućite jednostavan način za pojednostavljeno sučelje samo s bitnim funkcijama.';
|
'Prvi put koristite mesh mrežu? Uključite jednostavan način za pojednostavljeno sučelje s osnovnim funkcijama.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardSimpleModeFeature1 =>
|
String get wizardSimpleModeFeature1 =>
|
||||||
'Sučelje prijateljsko početnicima s osnovnim funkcijama';
|
'Sučelje prilagođeno početnicima s osnovnim funkcijama';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardSimpleModeFeature2 =>
|
String get wizardSimpleModeFeature2 =>
|
||||||
'Prebacite na Napredni način bilo kada u Postavkama';
|
'U svakom trenutku prebacite na napredni način u Postavkama';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardChannelTitle => 'Kanali';
|
String get wizardChannelTitle => 'Kanali';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardChannelDescription =>
|
String get wizardChannelDescription =>
|
||||||
'Emitirajte poruke svima na kanalu, savršeno za objave i koordinaciju cijele ekipe.';
|
'Šaljite poruke svima na kanalu — idealno za obavijesti i koordinaciju tima.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardChannelFeature1 => 'Javni kanal za opću komunikaciju ekipe';
|
String get wizardChannelFeature1 => 'Javni kanal za opću komunikaciju ekipe';
|
||||||
@@ -2106,7 +2107,7 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardContactsDescription =>
|
String get wizardContactsDescription =>
|
||||||
'Vaši članovi tima se automatski pojavljuju kada se pridruže mesh mreži. Pošaljite im direktne poruke ili pogledajte njihovu lokaciju.';
|
'Članovi tima se prikazuju automatski kada se pridruže mesh mreži. Šaljite im izravne poruke ili pogledajte njihovu lokaciju.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardContactsFeature1 => 'Kontakti se automatski otkrivaju';
|
String get wizardContactsFeature1 => 'Kontakti se automatski otkrivaju';
|
||||||
@@ -2116,26 +2117,25 @@ class AppLocalizationsHr extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardContactsFeature3 =>
|
String get wizardContactsFeature3 =>
|
||||||
'Pogledajte razinu baterije i vrijeme zadnjeg viđenja';
|
'Prikažite stanje baterije i vrijeme zadnje aktivnosti';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapTitle => 'Karta & Lokacija';
|
String get wizardMapTitle => 'Karta i lokacija';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapDescription =>
|
String get wizardMapDescription =>
|
||||||
'Pratite svoj tim u stvarnom vremenu i označite važne lokacije za spasilačke operacije.';
|
'Pratite tim u stvarnom vremenu i označavajte ključne lokacije za spasilačke operacije.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapFeature1 =>
|
String get wizardMapFeature1 =>
|
||||||
'SAR oznake za pronađene osobe, požare i područja postavljanja';
|
'SAR oznake za pronađene osobe, požare i točke okupljanja';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapFeature2 =>
|
String get wizardMapFeature2 =>
|
||||||
'GPS praćenje članova tima u stvarnom vremenu';
|
'GPS praćenje članova tima u stvarnom vremenu';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapFeature3 =>
|
String get wizardMapFeature3 => 'Preuzmite karte za rad izvan mreže';
|
||||||
'Preuzmite offline karte za udaljena područja';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapFeature4 =>
|
String get wizardMapFeature4 =>
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get defaultPinInfo =>
|
String get defaultPinInfo =>
|
||||||
'Privzeta PIN koda za naprave brez zaslona je 123456. Težave s seznanitvijo? Pozabite napravo bluetooth v sistemskih nastavitvah.';
|
'Privzeta PIN koda za naprave brez zaslona je 123456. Težave s seznanitvijo? Pozabite napravo Bluetooth v sistemskih nastavitvah.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get noMessagesYet => 'Še ni sporočil';
|
String get noMessagesYet => 'Še ni sporočil';
|
||||||
@@ -829,7 +829,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String get teamMembers => 'Člani ekipe';
|
String get teamMembers => 'Člani ekipe';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get repeaters => 'Repetitorji';
|
String get repeaters => 'Ponavljalniki';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get rooms => 'Sobe';
|
String get rooms => 'Sobe';
|
||||||
@@ -992,7 +992,8 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String get resetMapRotationTooltip => 'Ponastavi zemljevid na sever';
|
String get resetMapRotationTooltip => 'Ponastavi zemljevid na sever';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get showMapDebugInfo => 'Prikaži debug informacije zemljevida';
|
String get showMapDebugInfo =>
|
||||||
|
'Prikaži informacije za razhroščevanje zemljevida';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get displayZoomLevelBounds => 'Prikaži nivo povečave in meje';
|
String get displayZoomLevelBounds => 'Prikaži nivo povečave in meje';
|
||||||
@@ -1014,7 +1015,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String get esriSatellite => 'ESRI satelit';
|
String get esriSatellite => 'ESRI satelit';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get googleHybrid => 'Google hibridno';
|
String get googleHybrid => 'Google hibridni zemljevid';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get googleRoadmap => 'Google cestni zemljevid';
|
String get googleRoadmap => 'Google cestni zemljevid';
|
||||||
@@ -1313,12 +1314,12 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String exportFailed(String error) {
|
String exportFailed(String error) {
|
||||||
return 'Export failed: $error';
|
return 'Izvoz ni uspel: $error';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String importFailed(String error) {
|
String importFailed(String error) {
|
||||||
return 'Import failed: $error';
|
return 'Uvoz ni uspel: $error';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1497,7 +1498,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String get lat => 'Šir';
|
String get lat => 'Šir';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get lon => 'Dol';
|
String get lon => 'Dolž';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get useCurrentLocation => 'Uporabi trenutno lokacijo';
|
String get useCurrentLocation => 'Uporabi trenutno lokacijo';
|
||||||
@@ -1509,7 +1510,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String get chatNode => 'Vozlišče za klepet';
|
String get chatNode => 'Vozlišče za klepet';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get repeater => 'Ojačevalnik';
|
String get repeater => 'Ponavljalnik';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get roomChannel => 'Soba/Kanal';
|
String get roomChannel => 'Soba/Kanal';
|
||||||
@@ -1565,16 +1566,16 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String get nameRequired => 'Ime je obvezno';
|
String get nameRequired => 'Ime je obvezno';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateDescription => 'Description (Optional)';
|
String get templateDescription => 'Opis (neobvezno)';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateDescriptionHint => 'Add additional context...';
|
String get templateDescriptionHint => 'Dodajte dodatni kontekst...';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateColor => 'Color';
|
String get templateColor => 'Barva';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get previewFormat => 'Preview (SAR Message Format)';
|
String get previewFormat => 'Predogled (oblika SAR sporočila)';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get importFromClipboard => 'Uvozi';
|
String get importFromClipboard => 'Uvozi';
|
||||||
@@ -1584,26 +1585,26 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String deleteTemplateConfirmation(String name) {
|
String deleteTemplateConfirmation(String name) {
|
||||||
return 'Delete template \'$name\'?';
|
return 'Izbrišem predlogo \'$name\'?';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateAdded => 'Template added';
|
String get templateAdded => 'Predloga dodana';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateUpdated => 'Template updated';
|
String get templateUpdated => 'Predloga posodobljena';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get templateDeleted => 'Template deleted';
|
String get templateDeleted => 'Predloga izbrisana';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String templatesImported(int count) {
|
String templatesImported(int count) {
|
||||||
String _temp0 = intl.Intl.pluralLogic(
|
String _temp0 = intl.Intl.pluralLogic(
|
||||||
count,
|
count,
|
||||||
locale: localeName,
|
locale: localeName,
|
||||||
other: 'Imported $count templates',
|
other: 'Uvoženih $count predlog',
|
||||||
one: 'Imported 1 template',
|
one: 'Uvožena 1 predloga',
|
||||||
zero: 'No templates imported',
|
zero: 'Ni uvoženih predlog',
|
||||||
);
|
);
|
||||||
return '$_temp0';
|
return '$_temp0';
|
||||||
}
|
}
|
||||||
@@ -1613,8 +1614,8 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String _temp0 = intl.Intl.pluralLogic(
|
String _temp0 = intl.Intl.pluralLogic(
|
||||||
count,
|
count,
|
||||||
locale: localeName,
|
locale: localeName,
|
||||||
other: 'Exported $count templates to clipboard',
|
other: 'Izvoženih $count predlog v odložišče',
|
||||||
one: 'Exported 1 template to clipboard',
|
one: 'Izvožena 1 predloga v odložišče',
|
||||||
);
|
);
|
||||||
return '$_temp0';
|
return '$_temp0';
|
||||||
}
|
}
|
||||||
@@ -1633,10 +1634,10 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String get resetComplete => 'Predloge ponastavljene na privzeto';
|
String get resetComplete => 'Predloge ponastavljene na privzeto';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get noTemplates => 'No templates available';
|
String get noTemplates => 'Ni razpoložljivih predlog';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get tapAddToCreate => 'Tap + to create your first template';
|
String get tapAddToCreate => 'Tapnite + za ustvarjanje prve predloge';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get ok => 'OK';
|
String get ok => 'OK';
|
||||||
@@ -1839,7 +1840,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
'Helikopter za evakuacijo prihod 10 minut';
|
'Helikopter za evakuacijo prihod 10 minut';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get sampleMsgEmergencyResolved => 'Nujnost rešena - vse čisto';
|
String get sampleMsgEmergencyResolved => 'Nujna situacija rešena – vse čisto';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get sampleMsgEmergencyStagingArea => ' Nujno zbirališče';
|
String get sampleMsgEmergencyStagingArea => ' Nujno zbirališče';
|
||||||
@@ -1894,7 +1895,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String get coordinatesCopiedToClipboard => 'Koordinate kopirane v odložišče';
|
String get coordinatesCopiedToClipboard => 'Koordinate kopirane v odložišče';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get drawingShared => 'Risba zemljevida';
|
String get drawingShared => 'Risba deljena';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get drawingHidden => 'Risba skrita z zemljevida';
|
String get drawingHidden => 'Risba skrita z zemljevida';
|
||||||
@@ -1916,7 +1917,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get shareDrawing => 'Deli Risbo';
|
String get shareDrawing => 'Deli risbo';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get shareWithAllNearbyDevices => 'Deli z vsemi bližnjimi napravami';
|
String get shareWithAllNearbyDevices => 'Deli z vsemi bližnjimi napravami';
|
||||||
@@ -1936,7 +1937,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String yourDrawingsCount(int count) {
|
String yourDrawingsCount(int count) {
|
||||||
return 'Vaše Risbe ($count)';
|
return 'Vaše risbe ($count)';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -1949,16 +1950,16 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String get rectangle => 'Pravokotnik';
|
String get rectangle => 'Pravokotnik';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get updateAvailable => 'Na Voljo Posodobitev';
|
String get updateAvailable => 'Na voljo je posodobitev';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get currentVersion => 'Trenutna';
|
String get currentVersion => 'Trenutna različica';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get latestVersion => 'Najnovejša';
|
String get latestVersion => 'Najnovejša različica';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get downloadUpdate => 'Prenesi';
|
String get downloadUpdate => 'Prenesi posodobitev';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get updateLater => 'Kasneje';
|
String get updateLater => 'Kasneje';
|
||||||
@@ -1976,7 +1977,7 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
String get showForestRoads => 'Prikaži gozdne ceste';
|
String get showForestRoads => 'Prikaži gozdne ceste';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wmsOverlays => 'WMS Prekrivanja';
|
String get wmsOverlays => 'WMS prekrivanja';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get recentMessages => 'Nedavna sporočila';
|
String get recentMessages => 'Nedavna sporočila';
|
||||||
@@ -2047,47 +2048,47 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardWelcomeDescription =>
|
String get wizardWelcomeDescription =>
|
||||||
'Močno orodje za komunikacijo brez omrežja za reševalne operacije. Povežite se s svojo ekipo z uporabo mrežne radijske tehnologije, ko tradicionalna omrežja niso na voljo.';
|
'Zmogljivo orodje za komunikacijo brez omrežja za reševalne operacije. S svojo ekipo se povežite z mesh radijsko tehnologijo, ko tradicionalna omrežja niso na voljo.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardConnectingTitle => 'Povezava z Radijem';
|
String get wizardConnectingTitle => 'Povezava z radijem';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardConnectingDescription =>
|
String get wizardConnectingDescription =>
|
||||||
'Povežite svoj pametni telefon z napravo MeshCore radio preko Bluetootha za začetek komunikacije brez omrežja.';
|
'Svoj telefon povežite z radijsko napravo MeshCore prek Bluetootha in začnite komunicirati brez omrežja.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardConnectingFeature1 => 'Iskanje bližnjih naprav MeshCore';
|
String get wizardConnectingFeature1 => 'Poišče bližnje naprave MeshCore';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardConnectingFeature2 =>
|
String get wizardConnectingFeature2 =>
|
||||||
'Združite s svojim radijem preko Bluetootha';
|
'Seznanitev z radijsko napravo prek Bluetootha';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardConnectingFeature3 =>
|
String get wizardConnectingFeature3 =>
|
||||||
'Deluje popolnoma brez povezave - internet ni potreben';
|
'Deluje povsem brez povezave — internet ni potreben';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardSimpleModeTitle => 'Preprost Način';
|
String get wizardSimpleModeTitle => 'Preprost način';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardSimpleModeDescription =>
|
String get wizardSimpleModeDescription =>
|
||||||
'Novi v mrežnem omrežju? Omogočite preprost način za poenostavljen vmesnik z le bistvenimi funkcijami.';
|
'Ste novi v mesh omrežju? Vključite preprost način za poenostavljen vmesnik z osnovnimi funkcijami.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardSimpleModeFeature1 =>
|
String get wizardSimpleModeFeature1 =>
|
||||||
'Vmesnik prijazen za začetnike z osnovnimi funkcijami';
|
'Vmesnik, prilagojen začetnikom, z osnovnimi funkcijami';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardSimpleModeFeature2 =>
|
String get wizardSimpleModeFeature2 =>
|
||||||
'Kadarkoli preklopite na napredni način v nastavitvah';
|
'Na napredni način lahko kadarkoli preklopite v nastavitvah';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardChannelTitle => 'Kanali';
|
String get wizardChannelTitle => 'Kanali';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardChannelDescription =>
|
String get wizardChannelDescription =>
|
||||||
'Oddajajte sporočila vsem na kanalu, popolno za objave in usklajevanje cele ekipe.';
|
'Pošiljajte sporočila vsem na kanalu — idealno za obvestila in koordinacijo ekipe.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardChannelFeature1 =>
|
String get wizardChannelFeature1 =>
|
||||||
@@ -2099,47 +2100,47 @@ class AppLocalizationsSl extends AppLocalizations {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardChannelFeature3 =>
|
String get wizardChannelFeature3 =>
|
||||||
'Sporočila so samodejno posredovana preko mreže';
|
'Sporočila se samodejno posredujejo prek mreže';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardContactsTitle => 'Stiki';
|
String get wizardContactsTitle => 'Stiki';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardContactsDescription =>
|
String get wizardContactsDescription =>
|
||||||
'Vaši člani ekipe se samodejno prikažejo, ko se pridružijo mrežnemu omrežju. Pošljite jim neposredna sporočila ali si oglejte njihovo lokacijo.';
|
'Člani ekipe se prikažejo samodejno, ko se pridružijo mesh omrežju. Pošiljajte jim neposredna sporočila ali si oglejte njihovo lokacijo.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardContactsFeature1 => 'Stiki se odkrijejo samodejno';
|
String get wizardContactsFeature1 => 'Samodejno odkrivanje stikov';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardContactsFeature2 =>
|
String get wizardContactsFeature2 =>
|
||||||
'Pošiljajte zasebna neposredna sporočila';
|
'Pošiljanje zasebnih neposrednih sporočil';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardContactsFeature3 =>
|
String get wizardContactsFeature3 =>
|
||||||
'Oglejte si raven baterije in čas zadnjega ogleda';
|
'Prikaz stanja baterije in časa zadnje aktivnosti';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapTitle => 'Zemljevid & Lokacija';
|
String get wizardMapTitle => 'Zemljevid in lokacija';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapDescription =>
|
String get wizardMapDescription =>
|
||||||
'Sledite svoji ekipi v realnem času in označite pomembne lokacije za reševalne operacije.';
|
'Spremljajte svojo ekipo v realnem času in označujte ključne lokacije za reševalne operacije.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapFeature1 =>
|
String get wizardMapFeature1 =>
|
||||||
'SAR označevalci za najdene osebe, požare in območja postavitve';
|
'SAR označevalci za najdene osebe, požare in zbirna mesta';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapFeature2 => 'Sledenje GPS članov ekipe v realnem času';
|
String get wizardMapFeature2 => 'Sledenje članom ekipe z GPS v realnem času';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapFeature3 =>
|
String get wizardMapFeature3 =>
|
||||||
'Prenesite zemljevide brez povezave za oddaljene kraje';
|
'Prenesite zemljevide za uporabo brez povezave';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get wizardMapFeature4 =>
|
String get wizardMapFeature4 =>
|
||||||
'Narišite oblike in delite taktične informacije';
|
'Rišite oblike in delite taktične informacije';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get viewWelcomeTutorial => 'Ogled vadnice dobrodošlice';
|
String get viewWelcomeTutorial => 'Ogled vadnice dobrodošlice';
|
||||||
|
|||||||
@@ -175,7 +175,7 @@
|
|||||||
|
|
||||||
"locationBroadcast": "Oddajanje lokacije: {latitude}, {longitude}",
|
"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.",
|
"defaultPinInfo": "Privzeta PIN koda za naprave brez zaslona je 123456. Težave s seznanitvijo? Pozabite napravo Bluetooth v sistemskih nastavitvah.",
|
||||||
|
|
||||||
"noMessagesYet": "Še ni sporočil",
|
"noMessagesYet": "Še ni sporočil",
|
||||||
|
|
||||||
@@ -185,6 +185,8 @@
|
|||||||
|
|
||||||
"delete": "Izbriši",
|
"delete": "Izbriši",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"viewOnMap": "Poglej na zemljevidu",
|
"viewOnMap": "Poglej na zemljevidu",
|
||||||
|
|
||||||
"refresh": "Osveži",
|
"refresh": "Osveži",
|
||||||
@@ -359,7 +361,7 @@
|
|||||||
|
|
||||||
"noGpsData": "Ni GPS podatkov",
|
"noGpsData": "Ni GPS podatkov",
|
||||||
|
|
||||||
"distance": "Razdalja",
|
|
||||||
|
|
||||||
"pingingDirect": "Pinganje {name} (neposredno preko poti)...",
|
"pingingDirect": "Pinganje {name} (neposredno preko poti)...",
|
||||||
|
|
||||||
@@ -435,6 +437,8 @@
|
|||||||
|
|
||||||
"distance": "Razdalja",
|
"distance": "Razdalja",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"bearing": "Azimut",
|
"bearing": "Azimut",
|
||||||
|
|
||||||
"direction": "Smer",
|
"direction": "Smer",
|
||||||
@@ -475,7 +479,7 @@
|
|||||||
|
|
||||||
"teamMembers": "Člani ekipe",
|
"teamMembers": "Člani ekipe",
|
||||||
|
|
||||||
"repeaters": "Repetitorji",
|
"repeaters": "Ponavljalniki",
|
||||||
|
|
||||||
"rooms": "Sobe",
|
"rooms": "Sobe",
|
||||||
|
|
||||||
@@ -571,7 +575,7 @@
|
|||||||
|
|
||||||
"resetMapRotationTooltip": "Ponastavi zemljevid na sever",
|
"resetMapRotationTooltip": "Ponastavi zemljevid na sever",
|
||||||
|
|
||||||
"showMapDebugInfo": "Prikaži debug informacije zemljevida",
|
"showMapDebugInfo": "Prikaži informacije za razhroščevanje zemljevida",
|
||||||
|
|
||||||
"displayZoomLevelBounds": "Prikaži nivo povečave in meje",
|
"displayZoomLevelBounds": "Prikaži nivo povečave in meje",
|
||||||
|
|
||||||
@@ -585,7 +589,7 @@
|
|||||||
|
|
||||||
"esriSatellite": "ESRI satelit",
|
"esriSatellite": "ESRI satelit",
|
||||||
|
|
||||||
"googleHybrid": "Google hibridno",
|
"googleHybrid": "Google hibridni zemljevid",
|
||||||
|
|
||||||
"googleRoadmap": "Google cestni zemljevid",
|
"googleRoadmap": "Google cestni zemljevid",
|
||||||
|
|
||||||
@@ -769,8 +773,6 @@
|
|||||||
|
|
||||||
"trailHiddenRecording": "Pot je skrita (še se snema)",
|
"trailHiddenRecording": "Pot je skrita (še se snema)",
|
||||||
|
|
||||||
"distance": "Razdalja",
|
|
||||||
|
|
||||||
"duration": "Trajanje",
|
"duration": "Trajanje",
|
||||||
|
|
||||||
"points": "Točke",
|
"points": "Točke",
|
||||||
@@ -849,7 +851,7 @@
|
|||||||
|
|
||||||
"lat": "Šir",
|
"lat": "Šir",
|
||||||
|
|
||||||
"lon": "Dol",
|
"lon": "Dolž",
|
||||||
|
|
||||||
"useCurrentLocation": "Uporabi trenutno lokacijo",
|
"useCurrentLocation": "Uporabi trenutno lokacijo",
|
||||||
|
|
||||||
@@ -857,7 +859,7 @@
|
|||||||
|
|
||||||
"chatNode": "Vozlišče za klepet",
|
"chatNode": "Vozlišče za klepet",
|
||||||
|
|
||||||
"repeater": "Ojačevalnik",
|
"repeater": "Ponavljalnik",
|
||||||
|
|
||||||
"roomChannel": "Soba/Kanal",
|
"roomChannel": "Soba/Kanal",
|
||||||
|
|
||||||
@@ -879,28 +881,27 @@
|
|||||||
"templateEmoji": "Emoji",
|
"templateEmoji": "Emoji",
|
||||||
"emojiRequired": "Emoji je obvezen",
|
"emojiRequired": "Emoji je obvezen",
|
||||||
"nameRequired": "Ime je obvezno",
|
"nameRequired": "Ime je obvezno",
|
||||||
"templateDescription": "Description (Optional)",
|
"templateDescription": "Opis (neobvezno)",
|
||||||
"templateDescriptionHint": "Add additional context...",
|
"templateDescriptionHint": "Dodajte dodatni kontekst...",
|
||||||
"templateColor": "Color",
|
"templateColor": "Barva",
|
||||||
"previewFormat": "Preview (SAR Message Format)",
|
"previewFormat": "Predogled (oblika SAR sporočila)",
|
||||||
"importFromClipboard": "Uvozi",
|
"importFromClipboard": "Uvozi",
|
||||||
"exportToClipboard": "Izvozi",
|
"exportToClipboard": "Izvozi",
|
||||||
"deleteTemplateConfirmation": "Delete template '{name}'?",
|
"deleteTemplateConfirmation": "Izbrišem predlogo '{name}'?",
|
||||||
"templateAdded": "Template added",
|
"templateAdded": "Predloga dodana",
|
||||||
"templateUpdated": "Template updated",
|
"templateUpdated": "Predloga posodobljena",
|
||||||
"templateDeleted": "Template deleted",
|
"templateDeleted": "Predloga izbrisana",
|
||||||
"templatesImported": "{count, plural, =0{No templates imported} =1{Imported 1 template} other{Imported {count} templates}}",
|
"templatesImported": "{count, plural, =0{Ni uvoženih predlog} =1{Uvožena 1 predloga} other{Uvoženih {count} predlog}}",
|
||||||
"templatesExported": "{count, plural, =1{Exported 1 template to clipboard} other{Exported {count} templates to clipboard}}",
|
"templatesExported": "{count, plural, =1{Izvožena 1 predloga v odložišče} other{Izvoženih {count} predlog v odložišče}}",
|
||||||
"importFailed": "Import failed: {error}",
|
"importFailed": "Uvoz ni uspel: {error}",
|
||||||
"exportFailed": "Export failed: {error}",
|
"exportFailed": "Izvoz ni uspel: {error}",
|
||||||
"resetToDefaults": "Ponastavi na privzeto",
|
"resetToDefaults": "Ponastavi na privzeto",
|
||||||
"resetToDefaultsConfirmation": "To bo izbrisalo vse prilagojene predloge in obnovilo 4 privzete predloge. Nadaljevati?",
|
"resetToDefaultsConfirmation": "To bo izbrisalo vse prilagojene predloge in obnovilo 4 privzete predloge. Nadaljevati?",
|
||||||
"reset": "Ponastavi",
|
"reset": "Ponastavi",
|
||||||
"resetComplete": "Predloge ponastavljene na privzeto",
|
"resetComplete": "Predloge ponastavljene na privzeto",
|
||||||
"noTemplates": "No templates available",
|
"noTemplates": "Ni razpoložljivih predlog",
|
||||||
"tapAddToCreate": "Tap + to create your first template",
|
"tapAddToCreate": "Tapnite + za ustvarjanje prve predloge",
|
||||||
"ok": "OK",
|
"ok": "OK",
|
||||||
"delete": "Izbriši",
|
|
||||||
|
|
||||||
"permissionsSection": "Dovoljenja",
|
"permissionsSection": "Dovoljenja",
|
||||||
"locationPermission": "Dovoljenje za lokacijo",
|
"locationPermission": "Dovoljenje za lokacijo",
|
||||||
@@ -965,7 +966,7 @@
|
|||||||
"sampleMsgPriorityHelicopter": "PRIORITETA: Potrebna podpora helikopterja",
|
"sampleMsgPriorityHelicopter": "PRIORITETA: Potrebna podpora helikopterja",
|
||||||
"sampleMsgMedicalTeamEnRoute": "Medicinska ekipa na poti do vaše lokacije",
|
"sampleMsgMedicalTeamEnRoute": "Medicinska ekipa na poti do vaše lokacije",
|
||||||
"sampleMsgEvacHelicopter": "Helikopter za evakuacijo prihod 10 minut",
|
"sampleMsgEvacHelicopter": "Helikopter za evakuacijo prihod 10 minut",
|
||||||
"sampleMsgEmergencyResolved": "Nujnost rešena - vse čisto",
|
"sampleMsgEmergencyResolved": "Nujna situacija rešena – vse čisto",
|
||||||
"sampleMsgEmergencyStagingArea": " Nujno zbirališče",
|
"sampleMsgEmergencyStagingArea": " Nujno zbirališče",
|
||||||
"sampleMsgEmergencyServices": "Nujne službe obveščene in se odzivajo",
|
"sampleMsgEmergencyServices": "Nujne službe obveščene in se odzivajo",
|
||||||
"sampleAlphaTeamLead": "Vodja Ekipe",
|
"sampleAlphaTeamLead": "Vodja Ekipe",
|
||||||
@@ -985,33 +986,33 @@
|
|||||||
"rectangleDrawing": "Pravokotna risba",
|
"rectangleDrawing": "Pravokotna risba",
|
||||||
"coordinatesCopiedToClipboard": "Koordinate kopirane v odložišče",
|
"coordinatesCopiedToClipboard": "Koordinate kopirane v odložišče",
|
||||||
|
|
||||||
"drawingShared": "Risba zemljevida",
|
"drawingShared": "Risba deljena",
|
||||||
"drawingHidden": "Risba skrita z zemljevida",
|
"drawingHidden": "Risba skrita z zemljevida",
|
||||||
"alreadyShared": "{count, plural, =1{1 že deljeno} other{{count} že deljeno}}",
|
"alreadyShared": "{count, plural, =1{1 že deljeno} other{{count} že deljeno}}",
|
||||||
"newDrawingsShared": "Deljeno {count} nov{plural} risb{plural}",
|
"newDrawingsShared": "Deljeno {count} nov{plural} risb{plural}",
|
||||||
"drawingTools": "Orodja za risanje",
|
|
||||||
"shareDrawing": "Deli Risbo",
|
"shareDrawing": "Deli risbo",
|
||||||
"shareWithAllNearbyDevices": "Deli z vsemi bližnjimi napravami",
|
"shareWithAllNearbyDevices": "Deli z vsemi bližnjimi napravami",
|
||||||
"shareToRoom": "Deli v Sobo",
|
"shareToRoom": "Deli v Sobo",
|
||||||
"sendToPersistentStorage": "Pošlji v trajno shrambo sobe",
|
"sendToPersistentStorage": "Pošlji v trajno shrambo sobe",
|
||||||
"deleteDrawingConfirm": "Ali ste prepričani, da želite izbrisati to risbo?",
|
"deleteDrawingConfirm": "Ali ste prepričani, da želite izbrisati to risbo?",
|
||||||
"drawingDeleted": "Risba izbrisana",
|
"drawingDeleted": "Risba izbrisana",
|
||||||
"yourDrawingsCount": "Vaše Risbe ({count})",
|
"yourDrawingsCount": "Vaše risbe ({count})",
|
||||||
"shared": "Deljeno",
|
"shared": "Deljeno",
|
||||||
"line": "Črta",
|
"line": "Črta",
|
||||||
"rectangle": "Pravokotnik",
|
"rectangle": "Pravokotnik",
|
||||||
|
|
||||||
"updateAvailable": "Na Voljo Posodobitev",
|
"updateAvailable": "Na voljo je posodobitev",
|
||||||
"currentVersion": "Trenutna",
|
"currentVersion": "Trenutna različica",
|
||||||
"latestVersion": "Najnovejša",
|
"latestVersion": "Najnovejša različica",
|
||||||
"downloadUpdate": "Prenesi",
|
"downloadUpdate": "Prenesi posodobitev",
|
||||||
"updateLater": "Kasneje",
|
"updateLater": "Kasneje",
|
||||||
|
|
||||||
"cadastralParcels": "Katastrske parcele",
|
"cadastralParcels": "Katastrske parcele",
|
||||||
"forestRoads": "Gozdne ceste",
|
"forestRoads": "Gozdne ceste",
|
||||||
"showCadastralParcels": "Prikaži katastrske parcele",
|
"showCadastralParcels": "Prikaži katastrske parcele",
|
||||||
"showForestRoads": "Prikaži gozdne ceste",
|
"showForestRoads": "Prikaži gozdne ceste",
|
||||||
"wmsOverlays": "WMS Prekrivanja",
|
"wmsOverlays": "WMS prekrivanja",
|
||||||
|
|
||||||
"recentMessages": "Nedavna sporočila",
|
"recentMessages": "Nedavna sporočila",
|
||||||
|
|
||||||
@@ -1036,31 +1037,31 @@
|
|||||||
"wizardNext": "Naprej",
|
"wizardNext": "Naprej",
|
||||||
"wizardGetStarted": "Začni",
|
"wizardGetStarted": "Začni",
|
||||||
"wizardWelcomeTitle": "Dobrodošli v MeshCore SAR",
|
"wizardWelcomeTitle": "Dobrodošli v MeshCore SAR",
|
||||||
"wizardWelcomeDescription": "Močno orodje za komunikacijo brez omrežja za reševalne operacije. Povežite se s svojo ekipo z uporabo mrežne radijske tehnologije, ko tradicionalna omrežja niso na voljo.",
|
"wizardWelcomeDescription": "Zmogljivo orodje za komunikacijo brez omrežja za reševalne operacije. S svojo ekipo se povežite z mesh radijsko tehnologijo, ko tradicionalna omrežja niso na voljo.",
|
||||||
"wizardConnectingTitle": "Povezava z Radijem",
|
"wizardConnectingTitle": "Povezava z radijem",
|
||||||
"wizardConnectingDescription": "Povežite svoj pametni telefon z napravo MeshCore radio preko Bluetootha za začetek komunikacije brez omrežja.",
|
"wizardConnectingDescription": "Svoj telefon povežite z radijsko napravo MeshCore prek Bluetootha in začnite komunicirati brez omrežja.",
|
||||||
"wizardConnectingFeature1": "Iskanje bližnjih naprav MeshCore",
|
"wizardConnectingFeature1": "Poišče bližnje naprave MeshCore",
|
||||||
"wizardConnectingFeature2": "Združite s svojim radijem preko Bluetootha",
|
"wizardConnectingFeature2": "Seznanitev z radijsko napravo prek Bluetootha",
|
||||||
"wizardConnectingFeature3": "Deluje popolnoma brez povezave - internet ni potreben",
|
"wizardConnectingFeature3": "Deluje povsem brez povezave — internet ni potreben",
|
||||||
"wizardSimpleModeTitle": "Preprost Način",
|
"wizardSimpleModeTitle": "Preprost način",
|
||||||
"wizardSimpleModeDescription": "Novi v mrežnem omrežju? Omogočite preprost način za poenostavljen vmesnik z le bistvenimi funkcijami.",
|
"wizardSimpleModeDescription": "Ste novi v mesh omrežju? Vključite preprost način za poenostavljen vmesnik z osnovnimi funkcijami.",
|
||||||
"wizardSimpleModeFeature1": "Vmesnik prijazen za začetnike z osnovnimi funkcijami",
|
"wizardSimpleModeFeature1": "Vmesnik, prilagojen začetnikom, z osnovnimi funkcijami",
|
||||||
"wizardSimpleModeFeature2": "Kadarkoli preklopite na napredni način v nastavitvah",
|
"wizardSimpleModeFeature2": "Na napredni način lahko kadarkoli preklopite v nastavitvah",
|
||||||
"wizardChannelTitle": "Kanali",
|
"wizardChannelTitle": "Kanali",
|
||||||
"wizardChannelDescription": "Oddajajte sporočila vsem na kanalu, popolno za objave in usklajevanje cele ekipe.",
|
"wizardChannelDescription": "Pošiljajte sporočila vsem na kanalu — idealno za obvestila in koordinacijo ekipe.",
|
||||||
"wizardChannelFeature1": "Javni kanal za splošno komunikacijo ekipe",
|
"wizardChannelFeature1": "Javni kanal za splošno komunikacijo ekipe",
|
||||||
"wizardChannelFeature2": "Ustvarite kanale po meri za določene skupine",
|
"wizardChannelFeature2": "Ustvarite kanale po meri za določene skupine",
|
||||||
"wizardChannelFeature3": "Sporočila so samodejno posredovana preko mreže",
|
"wizardChannelFeature3": "Sporočila se samodejno posredujejo prek mreže",
|
||||||
"wizardContactsTitle": "Stiki",
|
"wizardContactsTitle": "Stiki",
|
||||||
"wizardContactsDescription": "Vaši člani ekipe se samodejno prikažejo, ko se pridružijo mrežnemu omrežju. Pošljite jim neposredna sporočila ali si oglejte njihovo lokacijo.",
|
"wizardContactsDescription": "Člani ekipe se prikažejo samodejno, ko se pridružijo mesh omrežju. Pošiljajte jim neposredna sporočila ali si oglejte njihovo lokacijo.",
|
||||||
"wizardContactsFeature1": "Stiki se odkrijejo samodejno",
|
"wizardContactsFeature1": "Samodejno odkrivanje stikov",
|
||||||
"wizardContactsFeature2": "Pošiljajte zasebna neposredna sporočila",
|
"wizardContactsFeature2": "Pošiljanje zasebnih neposrednih sporočil",
|
||||||
"wizardContactsFeature3": "Oglejte si raven baterije in čas zadnjega ogleda",
|
"wizardContactsFeature3": "Prikaz stanja baterije in časa zadnje aktivnosti",
|
||||||
"wizardMapTitle": "Zemljevid & Lokacija",
|
"wizardMapTitle": "Zemljevid in lokacija",
|
||||||
"wizardMapDescription": "Sledite svoji ekipi v realnem času in označite pomembne lokacije za reševalne operacije.",
|
"wizardMapDescription": "Spremljajte svojo ekipo v realnem času in označujte ključne lokacije za reševalne operacije.",
|
||||||
"wizardMapFeature1": "SAR označevalci za najdene osebe, požare in območja postavitve",
|
"wizardMapFeature1": "SAR označevalci za najdene osebe, požare in zbirna mesta",
|
||||||
"wizardMapFeature2": "Sledenje GPS članov ekipe v realnem času",
|
"wizardMapFeature2": "Sledenje članom ekipe z GPS v realnem času",
|
||||||
"wizardMapFeature3": "Prenesite zemljevide brez povezave za oddaljene kraje",
|
"wizardMapFeature3": "Prenesite zemljevide za uporabo brez povezave",
|
||||||
"wizardMapFeature4": "Narišite oblike in delite taktične informacije",
|
"wizardMapFeature4": "Rišite oblike in delite taktične informacije",
|
||||||
"viewWelcomeTutorial": "Ogled vadnice dobrodošlice"
|
"viewWelcomeTutorial": "Ogled vadnice dobrodošlice"
|
||||||
}
|
}
|
||||||
|
|||||||
1
lib/l10n/untranslated.json
Normal file
1
lib/l10n/untranslated.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
import 'package:latlong2/latlong.dart';
|
import 'package:latlong2/latlong.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import '../models/location_trail.dart';
|
import '../models/location_trail.dart';
|
||||||
@@ -27,6 +28,10 @@ class MapProvider with ChangeNotifier {
|
|||||||
// Imported trail (from GPX)
|
// Imported trail (from GPX)
|
||||||
LocationTrail? _importedTrail;
|
LocationTrail? _importedTrail;
|
||||||
|
|
||||||
|
// Download area selection
|
||||||
|
bool _isSelectingDownloadArea = false;
|
||||||
|
LatLngBounds? _downloadAreaBounds;
|
||||||
|
|
||||||
LatLng? get targetLocation => _targetLocation;
|
LatLng? get targetLocation => _targetLocation;
|
||||||
double? get targetZoom => _targetZoom;
|
double? get targetZoom => _targetZoom;
|
||||||
bool get shouldAnimate => _shouldAnimate;
|
bool get shouldAnimate => _shouldAnimate;
|
||||||
@@ -48,6 +53,10 @@ class MapProvider with ChangeNotifier {
|
|||||||
// Imported trail getters
|
// Imported trail getters
|
||||||
LocationTrail? get importedTrail => _importedTrail;
|
LocationTrail? get importedTrail => _importedTrail;
|
||||||
|
|
||||||
|
// Download area getters
|
||||||
|
bool get isSelectingDownloadArea => _isSelectingDownloadArea;
|
||||||
|
LatLngBounds? get downloadAreaBounds => _downloadAreaBounds;
|
||||||
|
|
||||||
void navigateToLocation({
|
void navigateToLocation({
|
||||||
required LatLng location,
|
required LatLng location,
|
||||||
double zoom = 15.0,
|
double zoom = 15.0,
|
||||||
@@ -302,4 +311,24 @@ class MapProvider with ChangeNotifier {
|
|||||||
_isTrailVisible = true;
|
_isTrailVisible = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Enter download area selection mode with initial bounds
|
||||||
|
void enterDownloadAreaMode(LatLngBounds initialBounds) {
|
||||||
|
_isSelectingDownloadArea = true;
|
||||||
|
_downloadAreaBounds = initialBounds;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Exit download area selection mode
|
||||||
|
void exitDownloadAreaMode() {
|
||||||
|
_isSelectingDownloadArea = false;
|
||||||
|
_downloadAreaBounds = null;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Update the download area bounds (while dragging/resizing)
|
||||||
|
void updateDownloadAreaBounds(LatLngBounds bounds) {
|
||||||
|
_downloadAreaBounds = bounds;
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -887,7 +887,44 @@ class _MapManagementScreenState extends State<MapManagementScreen> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert zoom level to user-friendly description
|
||||||
|
String _getZoomDescription(int zoom) {
|
||||||
|
if (zoom <= 5) {
|
||||||
|
return 'Continental view (very low detail)';
|
||||||
|
} else if (zoom <= 8) {
|
||||||
|
return 'Country view (low detail)';
|
||||||
|
} else if (zoom <= 10) {
|
||||||
|
return 'Regional view (basic detail)';
|
||||||
|
} else if (zoom <= 12) {
|
||||||
|
return 'City view (moderate detail)';
|
||||||
|
} else if (zoom <= 15) {
|
||||||
|
return 'Neighborhood view (good detail)';
|
||||||
|
} else if (zoom <= 17) {
|
||||||
|
return 'Street view (high detail)';
|
||||||
|
} else {
|
||||||
|
return 'Building view (very high detail)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildDownloadCard() {
|
Widget _buildDownloadCard() {
|
||||||
|
// Calculate current bounds for preview
|
||||||
|
LatLngBounds? previewBounds;
|
||||||
|
try {
|
||||||
|
final north = double.tryParse(_northController.text);
|
||||||
|
final south = double.tryParse(_southController.text);
|
||||||
|
final east = double.tryParse(_eastController.text);
|
||||||
|
final west = double.tryParse(_westController.text);
|
||||||
|
|
||||||
|
if (north != null && south != null && east != null && west != null) {
|
||||||
|
previewBounds = LatLngBounds(
|
||||||
|
LatLng(south, west),
|
||||||
|
LatLng(north, east),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Invalid bounds, preview will be null
|
||||||
|
}
|
||||||
|
|
||||||
return Card(
|
return Card(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(16),
|
padding: const EdgeInsets.all(16),
|
||||||
@@ -900,6 +937,80 @@ class _MapManagementScreenState extends State<MapManagementScreen> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
// Preview map (if bounds are valid)
|
||||||
|
if (previewBounds != null) ...[
|
||||||
|
Container(
|
||||||
|
height: 200,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(color: Colors.grey[300]!),
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
FlutterMap(
|
||||||
|
options: MapOptions(
|
||||||
|
initialCenter: previewBounds.center,
|
||||||
|
initialZoom: 12.0,
|
||||||
|
minZoom: 1,
|
||||||
|
maxZoom: 19,
|
||||||
|
interactionOptions: const InteractionOptions(
|
||||||
|
flags: InteractiveFlag.none, // Static preview
|
||||||
|
),
|
||||||
|
onMapReady: () {
|
||||||
|
// Fit bounds after map is ready would require MapController
|
||||||
|
// For now, center on bounds center
|
||||||
|
},
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
TileLayer(
|
||||||
|
urlTemplate: _selectedLayer.urlTemplate,
|
||||||
|
userAgentPackageName: 'com.meshcore.sar',
|
||||||
|
),
|
||||||
|
// Blue rectangle showing download area
|
||||||
|
PolygonLayer(
|
||||||
|
polygons: [
|
||||||
|
Polygon(
|
||||||
|
points: [
|
||||||
|
LatLng(previewBounds.north, previewBounds.west),
|
||||||
|
LatLng(previewBounds.north, previewBounds.east),
|
||||||
|
LatLng(previewBounds.south, previewBounds.east),
|
||||||
|
LatLng(previewBounds.south, previewBounds.west),
|
||||||
|
],
|
||||||
|
color: Colors.blue.withValues(alpha: 0.2),
|
||||||
|
borderColor: Colors.blue,
|
||||||
|
borderStrokeWidth: 3.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// Label overlay
|
||||||
|
Positioned(
|
||||||
|
top: 8,
|
||||||
|
left: 8,
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.black.withValues(alpha: 0.6),
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'Download Area Preview',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
],
|
||||||
|
|
||||||
// Map Layer Selection
|
// Map Layer Selection
|
||||||
DropdownButtonFormField<MapLayer>(
|
DropdownButtonFormField<MapLayer>(
|
||||||
initialValue: _selectedLayer,
|
initialValue: _selectedLayer,
|
||||||
@@ -1010,13 +1121,22 @@ class _MapManagementScreenState extends State<MapManagementScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(AppLocalizations.of(context)!.minZoom(_minZoom)),
|
Text(
|
||||||
|
AppLocalizations.of(context)!.minZoom(_minZoom),
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
_getZoomDescription(_minZoom),
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
Slider(
|
Slider(
|
||||||
value: _minZoom.toDouble(),
|
value: _minZoom.toDouble(),
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 19,
|
max: 19,
|
||||||
divisions: 18,
|
divisions: 18,
|
||||||
label: '$_minZoom',
|
label: '$_minZoom - ${_getZoomDescription(_minZoom)}',
|
||||||
onChanged: _isDownloading
|
onChanged: _isDownloading
|
||||||
? null
|
? null
|
||||||
: (value) {
|
: (value) {
|
||||||
@@ -1036,13 +1156,22 @@ class _MapManagementScreenState extends State<MapManagementScreen> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(AppLocalizations.of(context)!.maxZoom(_maxZoom)),
|
Text(
|
||||||
|
AppLocalizations.of(context)!.maxZoom(_maxZoom),
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.w500),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
_getZoomDescription(_maxZoom),
|
||||||
|
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||||
|
color: Colors.grey[600],
|
||||||
|
),
|
||||||
|
),
|
||||||
Slider(
|
Slider(
|
||||||
value: _maxZoom.toDouble(),
|
value: _maxZoom.toDouble(),
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 19,
|
max: 19,
|
||||||
divisions: 18,
|
divisions: 18,
|
||||||
label: '$_maxZoom',
|
label: '$_maxZoom - ${_getZoomDescription(_maxZoom)}',
|
||||||
onChanged: _isDownloading
|
onChanged: _isDownloading
|
||||||
? null
|
? null
|
||||||
: (value) {
|
: (value) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import '../widgets/map/drawing_toolbar.dart';
|
|||||||
import '../widgets/map/location_trail_layer.dart';
|
import '../widgets/map/location_trail_layer.dart';
|
||||||
import '../widgets/map/trail_controls.dart';
|
import '../widgets/map/trail_controls.dart';
|
||||||
import '../widgets/map/map_message_overlay.dart';
|
import '../widgets/map/map_message_overlay.dart';
|
||||||
|
import '../widgets/map/download_area_overlay.dart';
|
||||||
import '../widgets/messages/sar_update_sheet.dart';
|
import '../widgets/messages/sar_update_sheet.dart';
|
||||||
import '../l10n/app_localizations.dart';
|
import '../l10n/app_localizations.dart';
|
||||||
import 'map_management_screen.dart';
|
import 'map_management_screen.dart';
|
||||||
@@ -708,21 +709,10 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
|
|||||||
try {
|
try {
|
||||||
// Get current map bounds
|
// Get current map bounds
|
||||||
final bounds = _mapController.camera.visibleBounds;
|
final bounds = _mapController.camera.visibleBounds;
|
||||||
final currentZoom = _mapController.camera.zoom.round();
|
|
||||||
|
|
||||||
// Navigate to Map Management screen with pre-populated data
|
// Enter download area selection mode (show preview overlay)
|
||||||
final appProvider = context.read<AppProvider>();
|
final mapProvider = context.read<MapProvider>();
|
||||||
Navigator.push(
|
mapProvider.enterDownloadAreaMode(bounds);
|
||||||
context,
|
|
||||||
MaterialPageRoute(
|
|
||||||
builder: (context) => MapManagementScreen(
|
|
||||||
tileCacheService: appProvider.tileCacheService,
|
|
||||||
initialLayer: _currentLayer,
|
|
||||||
initialBounds: bounds,
|
|
||||||
initialZoom: currentZoom,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('Error accessing map camera: $e');
|
debugPrint('Error accessing map camera: $e');
|
||||||
}
|
}
|
||||||
@@ -1550,13 +1540,15 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
|
|||||||
widget.onNavigateToMessages?.call();
|
widget.onNavigateToMessages?.call();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
// User location marker
|
// User location marker with directional pointer
|
||||||
if (_markerService.generateUserLocationMarker(
|
if (_markerService.generateUserLocationMarker(
|
||||||
position: _locationService.currentPosition,
|
position: _locationService.currentPosition,
|
||||||
|
heading: _currentHeading,
|
||||||
context: context,
|
context: context,
|
||||||
) != null)
|
) != null)
|
||||||
_markerService.generateUserLocationMarker(
|
_markerService.generateUserLocationMarker(
|
||||||
position: _locationService.currentPosition,
|
position: _locationService.currentPosition,
|
||||||
|
heading: _currentHeading,
|
||||||
context: context,
|
context: context,
|
||||||
)!,
|
)!,
|
||||||
// Measurement point 1 marker
|
// Measurement point 1 marker
|
||||||
@@ -1745,6 +1737,36 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
// Download area selection polygon (rendered on top when in selection mode)
|
||||||
|
Consumer<MapProvider>(
|
||||||
|
builder: (context, mapProvider, _) {
|
||||||
|
if (!mapProvider.isSelectingDownloadArea || mapProvider.downloadAreaBounds == null) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
final bounds = mapProvider.downloadAreaBounds!;
|
||||||
|
|
||||||
|
// Add padding to the bounds so the rectangle is visible within the screen
|
||||||
|
// Calculate 5% padding on each side
|
||||||
|
final latPadding = (bounds.north - bounds.south) * 0.05;
|
||||||
|
final lonPadding = (bounds.east - bounds.west) * 0.05;
|
||||||
|
|
||||||
|
return PolygonLayer(
|
||||||
|
polygons: [
|
||||||
|
Polygon(
|
||||||
|
points: [
|
||||||
|
LatLng(bounds.north - latPadding, bounds.west + lonPadding), // Top-left
|
||||||
|
LatLng(bounds.north - latPadding, bounds.east - lonPadding), // Top-right
|
||||||
|
LatLng(bounds.south + latPadding, bounds.east - lonPadding), // Bottom-right
|
||||||
|
LatLng(bounds.south + latPadding, bounds.west + lonPadding), // Bottom-left
|
||||||
|
],
|
||||||
|
color: Colors.blue.withValues(alpha: 0.2),
|
||||||
|
borderColor: Colors.blue,
|
||||||
|
borderStrokeWidth: 3.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -1761,6 +1783,52 @@ class _MapTabState extends State<MapTab> with AutomaticKeepAliveClientMixin {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
// Download area overlay (shown when in download area selection mode)
|
||||||
|
Consumer<MapProvider>(
|
||||||
|
builder: (context, mapProvider, _) {
|
||||||
|
if (!mapProvider.isSelectingDownloadArea || mapProvider.downloadAreaBounds == null) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
return DownloadAreaOverlay(
|
||||||
|
bounds: mapProvider.downloadAreaBounds!,
|
||||||
|
onConfirm: () {
|
||||||
|
// Navigate to map management screen with selected bounds
|
||||||
|
final bounds = mapProvider.downloadAreaBounds!;
|
||||||
|
final zoom = _mapController.camera.zoom.round();
|
||||||
|
|
||||||
|
// Find matching layer from MapLayer.allLayers to avoid instance mismatch
|
||||||
|
// Only pass initialLayer if it's in allLayers (standard layers only)
|
||||||
|
MapLayer? initialLayer;
|
||||||
|
try {
|
||||||
|
initialLayer = MapLayer.allLayers.firstWhere(
|
||||||
|
(layer) => layer.type == _currentLayer.type,
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
// Current layer not in allLayers (WMS/vector), don't pass it
|
||||||
|
initialLayer = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.of(context).push(
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => MapManagementScreen(
|
||||||
|
tileCacheService: _tileCache,
|
||||||
|
initialBounds: bounds,
|
||||||
|
initialLayer: initialLayer,
|
||||||
|
initialZoom: zoom,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Exit download area selection mode
|
||||||
|
mapProvider.exitDownloadAreaMode();
|
||||||
|
},
|
||||||
|
onCancel: () {
|
||||||
|
// Exit download area selection mode
|
||||||
|
mapProvider.exitDownloadAreaMode();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
// Exit fullscreen button - top left (only shown in fullscreen mode)
|
// Exit fullscreen button - top left (only shown in fullscreen mode)
|
||||||
if (_isFullscreen)
|
if (_isFullscreen)
|
||||||
Positioned(
|
Positioned(
|
||||||
|
|||||||
@@ -412,9 +412,10 @@ class LocationTrackingService {
|
|||||||
debugPrint('✅ [LocationTracking] Initial position set without broadcast');
|
debugPrint('✅ [LocationTracking] Initial position set without broadcast');
|
||||||
debugPrint(' Next broadcast allowed in ${minTimeIntervalSeconds}s');
|
debugPrint(' Next broadcast allowed in ${minTimeIntervalSeconds}s');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('❌ [LocationTracking] Failed to set initial position: $e');
|
debugPrint('⚠️ [LocationTracking] Failed to set initial position: $e');
|
||||||
onError?.call('Failed to set initial position: $e');
|
debugPrint(' Will retry on next GPS update');
|
||||||
// Don't mark as set on failure, so it will retry on next update
|
// Don't mark as set on failure, so it will retry on next update
|
||||||
|
// Don't call onError - this is not critical since it will retry automatically
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:latlong2/latlong.dart';
|
|||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import '../models/contact.dart';
|
import '../models/contact.dart';
|
||||||
import '../models/sar_marker.dart';
|
import '../models/sar_marker.dart';
|
||||||
|
import '../widgets/map/location_pointer.dart';
|
||||||
|
|
||||||
/// Centralized service for map marker management.
|
/// Centralized service for map marker management.
|
||||||
///
|
///
|
||||||
@@ -222,47 +223,31 @@ class MapMarkerService {
|
|||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate user location marker.
|
/// Generate user location marker with directional pointer.
|
||||||
///
|
///
|
||||||
/// Parameters:
|
/// Parameters:
|
||||||
/// - [position]: Current GPS position
|
/// - [position]: Current GPS position
|
||||||
|
/// - [heading]: Current heading in degrees (0-360, where 0 = North)
|
||||||
|
/// Pass null or -1 if heading unavailable
|
||||||
/// - [context]: Build context for theme access
|
/// - [context]: Build context for theme access
|
||||||
///
|
///
|
||||||
/// Returns null if position is unavailable.
|
/// Returns null if position is unavailable.
|
||||||
Marker? generateUserLocationMarker({
|
Marker? generateUserLocationMarker({
|
||||||
required Position? position,
|
required Position? position,
|
||||||
|
double? heading,
|
||||||
required BuildContext context,
|
required BuildContext context,
|
||||||
}) {
|
}) {
|
||||||
if (position == null) return null;
|
if (position == null) return null;
|
||||||
|
|
||||||
return Marker(
|
return Marker(
|
||||||
point: LatLng(position.latitude, position.longitude),
|
point: LatLng(position.latitude, position.longitude),
|
||||||
width: 40,
|
width: 60,
|
||||||
height: 40,
|
height: 60,
|
||||||
rotate: false, // Don't rotate with map
|
rotate: false, // Don't rotate with map - we handle rotation internally
|
||||||
child: Container(
|
child: LocationPointer(
|
||||||
decoration: BoxDecoration(
|
heading: heading,
|
||||||
color: Theme.of(context).colorScheme.primary.withValues(alpha: 0.3),
|
color: Theme.of(context).colorScheme.primary,
|
||||||
shape: BoxShape.circle,
|
size: 60,
|
||||||
),
|
|
||||||
child: Container(
|
|
||||||
margin: const EdgeInsets.all(8),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
boxShadow: const [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black26,
|
|
||||||
blurRadius: 4,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
child: const Icon(
|
|
||||||
Icons.my_location,
|
|
||||||
color: Colors.white,
|
|
||||||
size: 16,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -468,8 +468,9 @@ class MeshCoreBleService {
|
|||||||
required double latitude,
|
required double latitude,
|
||||||
required double longitude,
|
required double longitude,
|
||||||
}) async {
|
}) async {
|
||||||
// This command returns OK (0x00) response, so wait for acknowledgment
|
// This command updates device's advertised location
|
||||||
await _commandSender.writeDataAndWaitForAck(
|
// Fire-and-forget - no ACK needed since actual broadcast happens via sendSelfAdvert
|
||||||
|
await _commandSender.writeData(
|
||||||
FrameBuilder.buildSetAdvertLatLon(
|
FrameBuilder.buildSetAdvertLatLon(
|
||||||
latitude: latitude,
|
latitude: latitude,
|
||||||
longitude: longitude,
|
longitude: longitude,
|
||||||
|
|||||||
108
lib/widgets/map/download_area_overlay.dart
Normal file
108
lib/widgets/map/download_area_overlay.dart
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_map/flutter_map.dart';
|
||||||
|
|
||||||
|
/// Overlay widget that displays controls for download area selection.
|
||||||
|
/// The actual polygon should be rendered inside FlutterMap's children.
|
||||||
|
class DownloadAreaOverlay extends StatelessWidget {
|
||||||
|
final LatLngBounds bounds;
|
||||||
|
final VoidCallback onConfirm;
|
||||||
|
final VoidCallback onCancel;
|
||||||
|
|
||||||
|
const DownloadAreaOverlay({
|
||||||
|
super.key,
|
||||||
|
required this.bounds,
|
||||||
|
required this.onConfirm,
|
||||||
|
required this.onCancel,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
// Control buttons at the top
|
||||||
|
Positioned(
|
||||||
|
top: 16,
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
child: Card(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(12.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Download Area Selection',
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'The blue rectangle shows the area to be downloaded. '
|
||||||
|
'To change the area, tap Cancel and select download again.',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Expanded(
|
||||||
|
child: OutlinedButton.icon(
|
||||||
|
onPressed: onCancel,
|
||||||
|
icon: const Icon(Icons.close),
|
||||||
|
label: const Text('Cancel'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 12),
|
||||||
|
Expanded(
|
||||||
|
child: FilledButton.icon(
|
||||||
|
onPressed: onConfirm,
|
||||||
|
icon: const Icon(Icons.check),
|
||||||
|
label: const Text('Confirm'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// Area info at the bottom
|
||||||
|
Positioned(
|
||||||
|
bottom: 16,
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
child: Card(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(12.0),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'Area Bounds',
|
||||||
|
style: Theme.of(context).textTheme.titleSmall,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
'N: ${bounds.north.toStringAsFixed(4)}° '
|
||||||
|
'S: ${bounds.south.toStringAsFixed(4)}°',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'E: ${bounds.east.toStringAsFixed(4)}° '
|
||||||
|
'W: ${bounds.west.toStringAsFixed(4)}°',
|
||||||
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
175
lib/widgets/map/location_pointer.dart
Normal file
175
lib/widgets/map/location_pointer.dart
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// A navigation arrow pointer that indicates the user's location and direction of travel.
|
||||||
|
///
|
||||||
|
/// The pointer consists of:
|
||||||
|
/// - An outer semi-transparent circle representing GPS accuracy
|
||||||
|
/// - An inner triangular arrow pointing in the direction of travel/heading
|
||||||
|
/// - Optional rotation based on compass or GPS heading
|
||||||
|
class LocationPointer extends StatelessWidget {
|
||||||
|
/// The heading in degrees (0-360, where 0 = North, 90 = East)
|
||||||
|
/// If null or -1, the pointer will not rotate
|
||||||
|
final double? heading;
|
||||||
|
|
||||||
|
/// The primary color for the pointer
|
||||||
|
final Color color;
|
||||||
|
|
||||||
|
/// The size of the entire widget
|
||||||
|
final double size;
|
||||||
|
|
||||||
|
const LocationPointer({
|
||||||
|
super.key,
|
||||||
|
this.heading,
|
||||||
|
required this.color,
|
||||||
|
this.size = 40.0,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
// Determine if we have valid heading data
|
||||||
|
final hasValidHeading = heading != null && heading! >= 0;
|
||||||
|
|
||||||
|
// Calculate rotation angle (convert heading to radians)
|
||||||
|
final rotationAngle = hasValidHeading ? (heading! * 3.14159 / 180.0) : 0.0;
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
child: Stack(
|
||||||
|
alignment: Alignment.center,
|
||||||
|
children: [
|
||||||
|
// Outer accuracy circle (very subtle, light blue)
|
||||||
|
Container(
|
||||||
|
width: size * 0.6,
|
||||||
|
height: size * 0.6,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFF4285F4).withValues(alpha: 0.2),
|
||||||
|
shape: BoxShape.circle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Inner rotatable arrow pointer (much larger - 90% of size)
|
||||||
|
Transform.rotate(
|
||||||
|
angle: rotationAngle,
|
||||||
|
child: CustomPaint(
|
||||||
|
size: Size(size * 0.9, size * 0.9),
|
||||||
|
painter: _NavigationPointerPainter(
|
||||||
|
color: color,
|
||||||
|
hasValidHeading: hasValidHeading,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Custom painter that draws a navigation arrow pointer
|
||||||
|
class _NavigationPointerPainter extends CustomPainter {
|
||||||
|
final Color color;
|
||||||
|
final bool hasValidHeading;
|
||||||
|
|
||||||
|
_NavigationPointerPainter({
|
||||||
|
required this.color,
|
||||||
|
required this.hasValidHeading,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
final center = Offset(size.width / 2, size.height / 2);
|
||||||
|
final width = size.width;
|
||||||
|
final height = size.height;
|
||||||
|
|
||||||
|
if (hasValidHeading) {
|
||||||
|
// Create navigation arrow with V-shaped cutout at bottom
|
||||||
|
final arrowPath = Path();
|
||||||
|
|
||||||
|
// Top point (sharp tip)
|
||||||
|
arrowPath.moveTo(center.dx, height * 0.08);
|
||||||
|
|
||||||
|
// Right side down to bottom right
|
||||||
|
arrowPath.lineTo(center.dx + width * 0.42, height * 0.92);
|
||||||
|
|
||||||
|
// V-cutout at bottom - right side to center
|
||||||
|
arrowPath.lineTo(center.dx, height * 0.70);
|
||||||
|
|
||||||
|
// V-cutout - center to left side
|
||||||
|
arrowPath.lineTo(center.dx - width * 0.42, height * 0.92);
|
||||||
|
|
||||||
|
// Left side back up to top
|
||||||
|
arrowPath.lineTo(center.dx, height * 0.08);
|
||||||
|
|
||||||
|
arrowPath.close();
|
||||||
|
|
||||||
|
// Draw shadow for depth
|
||||||
|
final shadowPaint = Paint()
|
||||||
|
..color = Colors.black.withValues(alpha: 0.25)
|
||||||
|
..style = PaintingStyle.fill
|
||||||
|
..maskFilter = const MaskFilter.blur(BlurStyle.normal, 4);
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(2, 2);
|
||||||
|
canvas.drawPath(arrowPath, shadowPaint);
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
// Left side (lighter cyan) - #75D5F0
|
||||||
|
final leftSidePath = Path();
|
||||||
|
leftSidePath.moveTo(center.dx, height * 0.08);
|
||||||
|
leftSidePath.lineTo(center.dx - width * 0.42, height * 0.92);
|
||||||
|
leftSidePath.lineTo(center.dx, height * 0.70);
|
||||||
|
leftSidePath.close();
|
||||||
|
|
||||||
|
final leftPaint = Paint()
|
||||||
|
..color = const Color(0xFF75D5F0)
|
||||||
|
..style = PaintingStyle.fill;
|
||||||
|
canvas.drawPath(leftSidePath, leftPaint);
|
||||||
|
|
||||||
|
// Right side (darker cyan) - #00B8E6
|
||||||
|
final rightSidePath = Path();
|
||||||
|
rightSidePath.moveTo(center.dx, height * 0.08);
|
||||||
|
rightSidePath.lineTo(center.dx, height * 0.70);
|
||||||
|
rightSidePath.lineTo(center.dx + width * 0.42, height * 0.92);
|
||||||
|
rightSidePath.close();
|
||||||
|
|
||||||
|
final rightPaint = Paint()
|
||||||
|
..color = const Color(0xFF00B8E6)
|
||||||
|
..style = PaintingStyle.fill;
|
||||||
|
canvas.drawPath(rightSidePath, rightPaint);
|
||||||
|
|
||||||
|
// Optional: Draw white border for contrast
|
||||||
|
final borderPaint = Paint()
|
||||||
|
..color = Colors.white
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeWidth = 2.0
|
||||||
|
..strokeJoin = StrokeJoin.round;
|
||||||
|
canvas.drawPath(arrowPath, borderPaint);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// No heading available - draw a blue circle with white border
|
||||||
|
final circlePaint = Paint()
|
||||||
|
..color = const Color(0xFF4285F4)
|
||||||
|
..style = PaintingStyle.fill;
|
||||||
|
|
||||||
|
canvas.drawCircle(center, width * 0.4, circlePaint);
|
||||||
|
|
||||||
|
// White border
|
||||||
|
final borderPaint = Paint()
|
||||||
|
..color = Colors.white
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeWidth = 2.5;
|
||||||
|
canvas.drawCircle(center, width * 0.4, borderPaint);
|
||||||
|
|
||||||
|
// Center white dot
|
||||||
|
final centerDot = Paint()
|
||||||
|
..color = Colors.white
|
||||||
|
..style = PaintingStyle.fill;
|
||||||
|
canvas.drawCircle(center, width * 0.15, centerDot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(_NavigationPointerPainter oldDelegate) {
|
||||||
|
return oldDelegate.color != color ||
|
||||||
|
oldDelegate.hasValidHeading != hasValidHeading;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user