feat: UX polish, localization, advert relocation, and map filter fixes

- i18n: translate connection screen + chat tab keys into 13 locales;
  add "Send my contact" (advert) strings in all locales
- feat: move self-advert from home header into composer "+" action menu
  (new lib/utils/advert_helper.dart, always shows Flood/Direct sheet)
- fix: hide-repeaters map toggle was bypassed in simple mode
- fix: simple mode map now shows only favourite chat contacts
- fix: wrap ListTiles in Material (contact_tile secondary actions,
  inferred contact group card) to satisfy Flutter ink assertions
- device-authoritative contact/channel sync and UX review fixes

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Janez T
2026-06-12 10:01:10 +02:00
parent 3e1113035d
commit ba27843166
62 changed files with 12546 additions and 2521 deletions

View File

@@ -2493,5 +2493,125 @@
"enterRegionName": "Nazwa regionu (np. auckland)",
"noRegionsFound": "Nie znaleziono regionów na tym przekaźniku.",
"regionScopeSet": "Zakres regionu ustawiony na {name}",
"regionScopeCleared": "Zakres regionu wyczyszczony"
"regionScopeCleared": "Zakres regionu wyczyszczony",
"simpleMode": "Tryb prosty",
"simpleModeDescription": "Tylko czat i mapa z ulubionymi kontaktami",
"simpleModeRequiresLockedDestination": "Aby użyć trybu prostego, najpierw włącz „Zablokuj cel” z kanałem",
"noFavouriteContacts": "Brak ulubionych kontaktów",
"selectDestinationFirst": "Najpierw wybierz kanał, kontakt lub pokój",
"recipientNoLongerAvailable": "Odbiorca nie jest już dostępny",
"failedToSendMessage": "Nie udało się wysłać: {error}",
"tictactoeDirectOnly": "Kółko i krzyżyk działa tylko w wiadomościach bezpośrednich. Najpierw wybierz kontakt.",
"deviceKeyUnavailable": "Klucz urządzenia jest niedostępny",
"imageCompressionFailed": "Kompresja obrazu nie powiodła się",
"imageFragmentationFailed": "Fragmentacja obrazu nie powiodła się",
"failedToAnnounceImage": "Nie udało się ogłosić obrazu",
"noRecipientSelected": "Nie wybrano odbiorcy",
"imageSendFailed": "Wysyłanie obrazu nie powiodło się",
"microphonePermissionRequiredForVoice": "Wiadomości głosowe wymagają uprawnienia do mikrofonu",
"recordingDiscarded": "Nagranie odrzucone",
"publicChannelMediaWarning": "Za chwilę wyślesz {mediaType} na kanał publiczny. Nie jest to zalecane, ponieważ może to odebrać każdy w sieci mesh. Wybierz kanał prywatny lub oznaczony, chyba że właśnie tego chcesz.",
"selectPrivateChannelToShareLocation": "Wybierz prywatny kanał, aby udostępnić swoją lokalizację.",
"stopSharingMyLocation": "Przestań udostępniać moją lokalizację",
"shareMyLocation": "Udostępnij moją lokalizację",
"stopRecording": "Zatrzymaj nagrywanie",
"recordVoice": "Nagraj wiadomość głosową",
"moreActions": "Więcej działań",
"noMessagesInFilter": "Brak wiadomości w tym filtrze",
"noMatchesInFilter": "Brak dopasowań w tym filtrze",
"syncFailed": "Synchronizacja nie powiodła się: {error}",
"invalidLink": "Nieprawidłowy link",
"cannotOpenLink": "Nie można otworzyć linku",
"failedToOpenLink": "Nie udało się otworzyć linku",
"failedToResendMessage": "Nie udało się ponownie wysłać wiadomości",
"retryFailed": "Ponowna próba nie powiodła się: {error}",
"deleteDrawingAndMessage": "Usuń rysunek i wiadomość",
"lastEchoRelay": "Ostatnie echo przekaźnik",
"lastEchoPath": "Ostatnie echo ścieżka",
"lastEchoBytesReport": "Ostatnie echo raport bajtów",
"noGpsCoordinatesAvailable": "Brak dostępnych współrzędnych GPS",
"notASarMarker": "To nie jest znacznik SAR",
"failedToSaveTemplate": "Nie udało się zapisać szablonu: {error}",
"drawingNotFound": "Nie znaleziono rysunku",
"unknownDrawingType": "Nieznany typ rysunku",
"customMapMarker": "Niestandardowy znacznik mapy",
"customMapPointLabel": "Punkt: {point}",
"mapIdLabel": "ID mapy: {id}",
"cannotFetchVoice": "Nie można pobrać wiadomości głosowej",
"senderContactUnknown": "Kontakt nadawcy jest nieznany. Najpierw zsynchronizuj kontakty.",
"senderRouteUnknown": "Trasa nadawcy jest nieznana. Najpierw zsynchronizuj kontakty/ścieżkę.",
"messageTooFar": "Wiadomość jest zbyt daleko ({hops} skoków, maks. {maxHops}).",
"senderRouteNoPathResponse": "Trasa nadawcy nie odpowiedziała na sprawdzenie ścieżki. Zsynchronizuj kontakty/ścieżkę i spróbuj ponownie.",
"senderRouteNoRawResponse": "Trasa nadawcy nie odpowiedziała na surowej ścieżce transportowej.",
"voiceFetchOverHops": "Pobieranie głosu przez {hops} skoków może chwilę potrwać.",
"voiceReceiveCanceled": "Odbieranie głosu anulowane",
"fetchingMissingVoiceFragments": "Pobieranie brakujących fragmentów głosu",
"receivingVoice": "Odbieranie głosu",
"cannotFetchImage": "Nie można pobrać obrazu",
"imageFetchOverHops": "Pobieranie obrazu przez {hops} skoków może chwilę potrwać.",
"imageAlreadyBeingReceived": "Obraz jest już odbierany",
"loadImage": "Wczytaj obraz",
"imageFetchFailedToSendRequest": "Nie udało się wysłać żądania pobrania obrazu",
"imageUnavailable": "Obraz chwilowo niedostępny",
"imageFetchTimedOut": "Upłynął limit czasu pobierania obrazu",
"imageReceiveCanceled": "Odbieranie obrazu anulowane",
"closeImagePreview": "Zamknij podgląd obrazu",
"recordingReleaseToSend": "Nagrywanie... puść, aby wysłać",
"sendingVoice": "Wysyłanie głosu...",
"sendLongPressToRecordVoice": "Wyślij (przytrzymaj, aby nagrać głos)",
"discardRecording": "Odrzuć nagranie",
"hopCount": "{count, plural, one{{count} skok} few{{count} skoki} many{{count} skoków} other{{count} skoku}}",
"channelsSectionDescription": "Kanały rozgłoszeniowe dla pobliskiego ruchu mesh",
"roomsSectionDescription": "Wspólne przestrzenie do bieżącej koordynacji zespołu",
"contactsSectionDescription": "Osoby i urządzenia w bezpośrednim zasięgu",
"noRecentChatters": "Brak ostatnich rozmówców",
"public": "Publiczny",
"failedToSendTicTacToeMove": "Nie udało się wysłać ruchu w kółko i krzyżyk",
"youWon": "Wygrałeś",
"opponentWon": "Wygrał przeciwnik",
"gameDraw": "Remis",
"yourTurn": "Twoja kolej",
"opponentTurn": "Kolej przeciwnika",
"pleaseEnterValidCoordinates": "Wprowadź prawidłowe współrzędne",
"locationNotAvailable": "Lokalizacja niedostępna",
"customCaveMapPoint": "Niestandardowy punkt mapy jaskini",
"mapPoint": "Punkt mapy",
"fetchingMissingImageFragments": "Pobieranie brakujących fragmentów…",
"loadingImage": "Wczytywanie…",
"receivingImage": "Odbieranie…",
"tapToLoad": "Dotknij, aby wczytać",
"connectDevice": "Połącz urządzenie",
"chooseTransportSubtitle": "Wybierz transport: Bluetooth, WiFi lub port szeregowy",
"ble": "BLE",
"network": "Sieć",
"serial": "Port szeregowy",
"scan": "Skanuj",
"pressScanToSearchForDevices": "Naciśnij Skanuj, aby wyszukać pobliskie urządzenia",
"failedToConnectToDevice": "Nie udało się połączyć z {name}",
"unknownDevice": "Nieznane urządzenie",
"showingCachedResultsTapRefresh": "Wyświetlane są wyniki z pamięci podręcznej. Dotknij odświeżania, aby zeskanować ponownie.",
"scanningLocalNetworkOnPort": "Skanowanie sieci lokalnej w poszukiwaniu urządzeń MeshCore WiFi na porcie {port}",
"cancelScanAndAddServer": "Anuluj skanowanie i dodaj serwer",
"addServer": "Dodaj serwer",
"scanningProgressIps": "Skanowanie... {scanned}/{total} adresów IP",
"cancelAndEnterManually": "Anuluj i wprowadź ręcznie",
"noRecentOrDiscoveredServers": "Brak ostatnich ani wykrytych serwerów",
"recentlyUsed": "Ostatnio używane",
"connecting": "Łączenie...",
"discoveredOnThisNetwork": "Wykryte w tej sieci",
"serverNoLongerAvailable": "Serwer {host}:{port} nie jest już dostępny. Zeskanuj ponownie, aby znaleźć aktywne serwery.",
"failedToConnectToHost": "Nie udało się połączyć z {host}:{port}",
"enterValidIpAddress": "Wprowadź prawidłowy adres IP",
"enterValidTcpPort": "Wprowadź prawidłowy port TCP",
"ipAddress": "Adres IP",
"tcpPort": "Port TCP",
"customServerPort": "Niestandardowy port serwera",
"chat": "Czat",
"restoringPreviousLink": "Przywracanie poprzedniego połączenia",
"noDeviceConnected": "Brak połączonego urządzenia",
"sendAdvert": "Wyślij mój kontakt",
"advertMode": "Wyślij mój kontakt",
"advertModeSubtitle": "Wybierz, jak daleko mają dotrzeć Twoje dane kontaktowe.",
"floodAdvertSent": "Kontakt wysłano do całej sieci mesh",
"directAdvertSent": "Kontakt wysłano do urządzeń w pobliżu"
}