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

@@ -1878,5 +1878,125 @@
"enterRegionName": "Nome regione (es. auckland)",
"noRegionsFound": "Nessuna regione trovata su questo ripetitore.",
"regionScopeSet": "Ambito regionale impostato su {name}",
"regionScopeCleared": "Ambito regionale cancellato"
"regionScopeCleared": "Ambito regionale cancellato",
"simpleMode": "Modalità semplice",
"simpleModeDescription": "Solo chat e mappa con i contatti preferiti",
"simpleModeRequiresLockedDestination": "Attiva prima «Blocca destinazione» con un canale per usare la modalità semplice",
"noFavouriteContacts": "Nessun contatto preferito",
"selectDestinationFirst": "Seleziona prima un canale, un contatto o una stanza",
"recipientNoLongerAvailable": "Il destinatario non è più disponibile",
"failedToSendMessage": "Invio non riuscito: {error}",
"tictactoeDirectOnly": "Il tris funziona solo nei messaggi diretti. Scegli prima un contatto.",
"deviceKeyUnavailable": "La chiave del dispositivo non è disponibile",
"imageCompressionFailed": "Compressione dell'immagine non riuscita",
"imageFragmentationFailed": "Frammentazione dell'immagine non riuscita",
"failedToAnnounceImage": "Annuncio dell'immagine non riuscito",
"noRecipientSelected": "Nessun destinatario selezionato",
"imageSendFailed": "Invio dell'immagine non riuscito",
"microphonePermissionRequiredForVoice": "Per i messaggi vocali è necessario il permesso del microfono",
"recordingDiscarded": "Registrazione scartata",
"publicChannelMediaWarning": "Stai per inviare {mediaType} al Canale Pubblico. Non è consigliato, perché chiunque sulla rete mesh potrebbe riceverlo. Scegli un canale privato o con tag, a meno che non sia ciò che vuoi.",
"selectPrivateChannelToShareLocation": "Seleziona un canale privato per condividere la tua posizione.",
"stopSharingMyLocation": "Smetti di condividere la mia posizione",
"shareMyLocation": "Condividi la mia posizione",
"stopRecording": "Interrompi registrazione",
"recordVoice": "Registra messaggio vocale",
"moreActions": "Altre azioni",
"noMessagesInFilter": "Nessun messaggio in questo filtro",
"noMatchesInFilter": "Nessuna corrispondenza in questo filtro",
"syncFailed": "Sincronizzazione non riuscita: {error}",
"invalidLink": "Link non valido",
"cannotOpenLink": "Impossibile aprire il link",
"failedToOpenLink": "Apertura del link non riuscita",
"failedToResendMessage": "Reinvio del messaggio non riuscito",
"retryFailed": "Nuovo tentativo non riuscito: {error}",
"deleteDrawingAndMessage": "Elimina disegno e messaggio",
"lastEchoRelay": "Ultimo eco: relay",
"lastEchoPath": "Ultimo eco: percorso",
"lastEchoBytesReport": "Ultimo eco: report byte",
"noGpsCoordinatesAvailable": "Nessuna coordinata GPS disponibile",
"notASarMarker": "Non è un marcatore SAR",
"failedToSaveTemplate": "Salvataggio del modello non riuscito: {error}",
"drawingNotFound": "Disegno non trovato",
"unknownDrawingType": "Tipo di disegno sconosciuto",
"customMapMarker": "Marcatore mappa personalizzato",
"customMapPointLabel": "Punto: {point}",
"mapIdLabel": "ID mappa: {id}",
"cannotFetchVoice": "Impossibile recuperare il vocale",
"senderContactUnknown": "Il contatto del mittente è sconosciuto. Sincronizza prima i contatti.",
"senderRouteUnknown": "Il percorso del mittente è sconosciuto. Sincronizza prima contatti/percorso.",
"messageTooFar": "Il messaggio è troppo lontano ({hops} hop, max {maxHops}).",
"senderRouteNoPathResponse": "Il percorso del mittente non ha risposto alla verifica. Sincronizza contatti/percorso e riprova.",
"senderRouteNoRawResponse": "Il percorso del mittente non ha risposto sul percorso di trasporto raw.",
"voiceFetchOverHops": "Il recupero del vocale su {hops} hop può richiedere un po' di tempo.",
"voiceReceiveCanceled": "Ricezione vocale annullata",
"fetchingMissingVoiceFragments": "Recupero dei frammenti vocali mancanti",
"receivingVoice": "Ricezione vocale",
"cannotFetchImage": "Impossibile recuperare l'immagine",
"imageFetchOverHops": "Il recupero dell'immagine su {hops} hop può richiedere un po' di tempo.",
"imageAlreadyBeingReceived": "L'immagine è già in ricezione",
"loadImage": "Carica immagine",
"imageFetchFailedToSendRequest": "Invio della richiesta immagine non riuscito",
"imageUnavailable": "Immagine al momento non disponibile",
"imageFetchTimedOut": "Recupero dell'immagine scaduto",
"imageReceiveCanceled": "Ricezione dell'immagine annullata",
"closeImagePreview": "Chiudi anteprima immagine",
"recordingReleaseToSend": "Registrazione... rilascia per inviare",
"sendingVoice": "Invio vocale...",
"sendLongPressToRecordVoice": "Invia (pressione lunga per registrare un vocale)",
"discardRecording": "Scarta registrazione",
"hopCount": "{count, plural, =1{1 hop} other{{count} hop}}",
"channelsSectionDescription": "Canali broadcast per il traffico mesh nelle vicinanze",
"roomsSectionDescription": "Spazi condivisi per il coordinamento continuo del team",
"contactsSectionDescription": "Persone e dispositivi raggiungibili direttamente",
"noRecentChatters": "Nessun partecipante recente",
"public": "Pubblico",
"failedToSendTicTacToeMove": "Invio della mossa di tris non riuscito",
"youWon": "Hai vinto",
"opponentWon": "Ha vinto l'avversario",
"gameDraw": "Pareggio",
"yourTurn": "Tocca a te",
"opponentTurn": "Tocca all'avversario",
"pleaseEnterValidCoordinates": "Inserisci coordinate valide",
"locationNotAvailable": "Posizione non disponibile",
"customCaveMapPoint": "Punto mappa grotta personalizzato",
"mapPoint": "Punto mappa",
"fetchingMissingImageFragments": "Recupero frammenti mancanti…",
"loadingImage": "Caricamento…",
"receivingImage": "Ricezione…",
"tapToLoad": "Tocca per caricare",
"connectDevice": "Connetti dispositivo",
"chooseTransportSubtitle": "Scegli il trasporto Bluetooth, WiFi o Seriale",
"ble": "BLE",
"network": "Rete",
"serial": "Seriale",
"scan": "Cerca",
"pressScanToSearchForDevices": "Premi Cerca per trovare i dispositivi nelle vicinanze",
"failedToConnectToDevice": "Impossibile connettersi a {name}",
"unknownDevice": "Dispositivo sconosciuto",
"showingCachedResultsTapRefresh": "Risultati in cache. Tocca Aggiorna per ripetere la scansione.",
"scanningLocalNetworkOnPort": "Scansione della rete locale per dispositivi MeshCore WiFi sulla porta {port}",
"cancelScanAndAddServer": "Annulla la scansione e aggiungi un server",
"addServer": "Aggiungi server",
"scanningProgressIps": "Scansione... {scanned}/{total} IP",
"cancelAndEnterManually": "Annulla e inserisci manualmente",
"noRecentOrDiscoveredServers": "Nessun server recente o rilevato per ora",
"recentlyUsed": "Usati di recente",
"connecting": "Connessione...",
"discoveredOnThisNetwork": "Rilevati su questa rete",
"serverNoLongerAvailable": "Il server {host}:{port} non è più disponibile. Esegui di nuovo la scansione per trovare server attivi.",
"failedToConnectToHost": "Impossibile connettersi a {host}:{port}",
"enterValidIpAddress": "Inserisci un indirizzo IP valido",
"enterValidTcpPort": "Inserisci una porta TCP valida",
"ipAddress": "Indirizzo IP",
"tcpPort": "Porta TCP",
"customServerPort": "Porta server personalizzata",
"chat": "Chat",
"restoringPreviousLink": "Ripristino del collegamento precedente",
"noDeviceConnected": "Nessun dispositivo connesso",
"sendAdvert": "Invia il mio contatto",
"advertMode": "Invia il mio contatto",
"advertModeSubtitle": "Scegli quanto lontano devono viaggiare le tue informazioni di contatto.",
"floodAdvertSent": "Contatto inviato attraverso la rete mesh",
"directAdvertSent": "Contatto inviato ai dispositivi vicini"
}