From a9dd5a3c7622c375b4f474514ec208ab0b4211cf Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 14 Jun 2022 08:39:55 +0200 Subject: [PATCH 01/20] support sasl/temporary-auth-failure if the server is unable to query the database throwing a temporary-auth-failure might be more appropriate --- .../siacs/conversations/entities/Account.java | 3 +++ .../conversations/xmpp/XmppConnection.java | 23 ++++++++++++------- src/main/res/values/strings.xml | 1 + 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 37f8114e870ce6d90df196fe2e3a7400dabebbe0..dc354adc4a90e19639fe72a5fbbe069bf6a3967c 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -627,6 +627,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable ONLINE(false), NO_INTERNET(false), UNAUTHORIZED, + TEMPORARY_AUTH_FAILURE, SERVER_NOT_FOUND, REGISTRATION_SUCCESSFUL(false), REGISTRATION_FAILED(true, false), @@ -732,6 +733,8 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable return R.string.payment_required; case MISSING_INTERNET_PERMISSION: return R.string.missing_internet_permission; + case TEMPORARY_AUTH_FAILURE: + return R.string.account_status_temporary_auth_failure; default: return R.string.account_status_unknown; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index c3a3b153261acbaac29354b7493d76d7d8943df1..06195aaed1647e471d27df15f92b1bfe536630dc 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -12,6 +12,8 @@ import android.util.SparseArray; import androidx.annotation.NonNull; +import com.google.common.base.Strings; + import org.xmlpull.v1.XmlPullParserException; import java.io.ByteArrayInputStream; @@ -489,20 +491,25 @@ public class XmppConnection implements Runnable { } else if (nextTag.isStart("failure")) { final Element failure = tagReader.readElement(nextTag); if (Namespace.SASL.equals(failure.getNamespace())) { - final String text = failure.findChildContent("text"); - if (failure.hasChild("account-disabled") && text != null) { - Matcher matcher = Patterns.AUTOLINK_WEB_URL.matcher(text); + if (failure.hasChild("temporary-auth-failure")) { + throw new StateChangingException(Account.State.TEMPORARY_AUTH_FAILURE); + } else if (failure.hasChild("account-disabled")) { + final String text = failure.findChildContent("text"); + if ( Strings.isNullOrEmpty(text)) { + throw new StateChangingException(Account.State.UNAUTHORIZED); + } + final Matcher matcher = Patterns.AUTOLINK_WEB_URL.matcher(text); if (matcher.find()) { final HttpUrl url; try { url = HttpUrl.get(text.substring(matcher.start(), matcher.end())); - if (url.isHttps()) { - this.redirectionUrl = url; - throw new StateChangingException(Account.State.PAYMENT_REQUIRED); - } - } catch (IllegalArgumentException e) { + } catch (final IllegalArgumentException e) { throw new StateChangingException(Account.State.UNAUTHORIZED); } + if (url.isHttps()) { + this.redirectionUrl = url; + throw new StateChangingException(Account.State.PAYMENT_REQUIRED); + } } } throw new StateChangingException(Account.State.UNAUTHORIZED); diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 20c7cbef8533b05e9dd80c32413f9863c589faf1..ee5cbce8138454aa05280581348134ed904091f7 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -976,5 +976,6 @@ Plain text document Account registrations are not supported No XMPP address found + Temporary authentication failure From 30dff9ac054b1a1baf19025f635d626ff70e99d5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 14 Jun 2022 08:48:04 +0200 Subject: [PATCH 02/20] pulled translations from transifex --- src/conversations/res/values-nl/strings.xml | 5 +- src/conversations/res/values-szl/strings.xml | 16 + src/main/res/values-da-rDK/strings.xml | 8 + src/main/res/values-de/strings.xml | 3 +- src/main/res/values-el/strings.xml | 3 +- src/main/res/values-es/strings.xml | 21 + src/main/res/values-fr/strings.xml | 24 +- src/main/res/values-gl/strings.xml | 3 +- src/main/res/values-it/strings.xml | 16 +- src/main/res/values-ja/strings.xml | 6 +- src/main/res/values-nl/strings.xml | 19 + src/main/res/values-pl/strings.xml | 3 +- src/main/res/values-pt-rBR/strings.xml | 16 +- src/main/res/values-pt/strings.xml | 2 + src/main/res/values-ro-rRO/strings.xml | 3 +- src/main/res/values-szl/strings.xml | 1025 ++++++++++++++++++ src/main/res/values-tr-rTR/strings.xml | 3 +- src/main/res/values-zh-rCN/strings.xml | 3 +- src/quicksy/res/values-szl/strings.xml | 12 + 19 files changed, 1168 insertions(+), 23 deletions(-) create mode 100644 src/conversations/res/values-szl/strings.xml create mode 100644 src/main/res/values-szl/strings.xml create mode 100644 src/quicksy/res/values-szl/strings.xml diff --git a/src/conversations/res/values-nl/strings.xml b/src/conversations/res/values-nl/strings.xml index 968a276d18989ed42a5811069baec18858bbdf08..f04a6b2de854536f5d485592953ec8a7f36ca073 100644 --- a/src/conversations/res/values-nl/strings.xml +++ b/src/conversations/res/values-nl/strings.xml @@ -8,4 +8,7 @@ Je ontving een uitnodiging voor %1$s. We zullen je helpen een account aan te maken.\nWanneer je %1$s als je provider kiest kan je met gebruikers van andere providers communiceren door hen je volledige XMPP-adres te geven. Je ontving een uitnodiging voor %1$s. Er werd reeds een gebruikersnaam voor jou gekozen. We zullen je helpen een account aan te maken.\nJe zal met gebruikers van andere providers communiceren door hen je volledige XMPP-adres te geven. Je server uitnodiging - \ No newline at end of file + Tik op de delen knop om een uitnodiging te versturen naar %1$s + Als je contactpersoon in de buurt is, kan deze ook onderstaande code scannen om de uitnodiging te aanvaarden. + Deel de uitnodiging met ... + \ No newline at end of file diff --git a/src/conversations/res/values-szl/strings.xml b/src/conversations/res/values-szl/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..6e0134d065afd48b7dbf893d2383ebb4c2c8d576 --- /dev/null +++ b/src/conversations/res/values-szl/strings.xml @@ -0,0 +1,16 @@ + + + Wybier liferanta XMPP + Użyj conversations.im + Stwōrz nowe kōnto + Mosz już kōnto XMPP? Tak może być, jeźli już używosz inkszego klijynta XMPP aboś używoł abo używała wcześnij Conversations. Jak niy, to możesz stworzić teroz nowe kōnto XMPP.\nDorada: Niykerzi liferańcio emaili dowajōm tyż kōnta XMPP. + XMPP to je nec wartkich wiadōmości niyzależny ôd liferanta. Możesz używać tego klijynta ze serwerym XMPP, jaki sie wybieresz.\nAle dlo twojij wygody ułacniyli my tworzynie kōnt na conversations.im; liferańcie ekstra dopasowanym do używanio ze Conversations. + Mosz zaproszynie na %1$s. Pokludzymy cie bez proces tworzynio kōnta.\nPo wybraniu %1$s za liferanta, poradzisz kōmunikować sie ze używoczami ôd inkszych liferantōw bez danie im swojij połnyj adresy XMPP. + Mosz zaproszynie na %1$s. Miano ôd używocza już je do ciebie wybrane. Pokludzymy cie bez proces tworzynio kōnta.\nBydzie szło kōmunikować sie ze używoczami ôd inkszych liferantōw bez danie im swojij połnyj adresy XMPP. + Twoje zaproszynie na serwer + Niynoleżnie sformatowany kod lifrowanio + Tyknij knefla dzielynio sie, żeby posłać kōntaktowi zaproszynie na %1$s. + Jeźli kōntakt je blisko, to może tyż zeskanować kod niżyj, żeby zaakceptować twoje zaproszynie. + Pōdź na %1$s i pogodej zy mnōm: %2$s + Poślij zaproszynie do… + \ No newline at end of file diff --git a/src/main/res/values-da-rDK/strings.xml b/src/main/res/values-da-rDK/strings.xml index 22f4bce2d0e9c6620cf977755be1f645ad30b253..c07353a6ac76346306fc0d88ee79e1e574168bf4 100644 --- a/src/main/res/values-da-rDK/strings.xml +++ b/src/main/res/values-da-rDK/strings.xml @@ -465,6 +465,7 @@ Download mislykkes: Fil ikke fundet Download mislykkes: Kunne ikke forbinde til vært Download mislykkes: Kunne ikke skrive til fil + Download mislykkes: Ugyldig fil TOR netværk er utilgængelig Bind fejl Serveren er ikke ansvarlig for dette domæne @@ -622,6 +623,8 @@ Tøm privat lagerplads, hvor filer opbevares (De kan downloades igen fra serveren) Jeg fulgte dette link fra en pålidelig kilde Du er ved bekræfte OMEMO-nøgler af %1$s efter du har klikket på et link. Dette er kun sikkert, hvis du fulgte linket fra troværdig kilde hvor kun %2$s kunne have offentliggjort dette link. + Du er ved at bekræfte dine OMEMO-nøgler til din konto. Det er kun sikkert, hvis du fulgte linket fra en troværdig kilde, hvor kun du kan have offentliggjort dette link. + Fortsæt Beskræft OMEMO-nøgler Vis inaktive Skjul inaktive @@ -904,6 +907,7 @@ Indkommende videoopkald Forbinder Forbundet + Forbinder igen Accepter opkald Afslut opkald Svar @@ -919,6 +923,8 @@ Læg på Udgående opkald Igangværende videoopkald + Forbinder igen opkald + Forbinder igen videoopkald Deaktiver TOR for at lave opkald Indkommende opkald Indkommende opkald · %s @@ -968,4 +974,6 @@ Sikkerhedskopieringen er startet. Du får en notifikation, når den er afsluttet. Kunne ikke aktivere video. Ren tekstdokument + Kontoregistrering er ikke understøttet + Ingen XMPP-adresse fundet diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index a928266b1e4092c0b3d3ed7f15d922bb7d4a5f7f..b54309ed27fb793f500ca2f9653b3c18376eef5f 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -976,5 +976,4 @@ Textdokument Kontoregistrierungen werden nicht unterstützt Keine XMPP-Adresse gefunden - - + diff --git a/src/main/res/values-el/strings.xml b/src/main/res/values-el/strings.xml index d6a8cd209f3dd9c1d276fbb0ba9873d61f10cdc7..22b188af49c88619c75c2bc94073de7a655e5041 100644 --- a/src/main/res/values-el/strings.xml +++ b/src/main/res/values-el/strings.xml @@ -975,5 +975,4 @@ Έγγραφο απλού κειμένου Δεν υποστηρίζονται εγγραφές λογαριασμών Δεν βρέθηκε διεύθυνση XMPP - - + diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index c958b30b2c3333f34df43749f8eefdfb8b5f2c3c..d2c5b8afd7ac1d3de9a1aa3f058c0e4afcd38770 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -33,6 +33,9 @@ %d conversación sin leer + %dconversaciones sin leer + + %dconversaciones sin leer @@ -447,6 +450,7 @@ Cancelar %d certificado eliminado + %d certificados eliminados %d certificados eliminados Cambiar el botón de “Enviar” por el botón de acción rápida @@ -465,6 +469,7 @@ Error al descargar: Archivo no encontrado Error al descargar: No se ha podido conectar con el servidor Falló la descarga: No se puede escribir el fichero + Error al descargar: Archivo no válido Red Tor no disponible. Fallo de enlace El servidor no es responsable de este dominio @@ -504,6 +509,7 @@ %1$d de %2$d cuentas conectadas %d mensaje + %d mensajes %d mensajes Cargar más mensajes @@ -622,6 +628,8 @@ Limpiar datos privados de ficheros descargados (Pueden volver a descargarse desde el servidor) Enlace desde una fuente de confianza Vas a verificar las claves OMEMO de %1$s después de hacer click en el enlace. Esto solo es seguro si conseguiste este enlace desde una fuente de confianza donde solo %2$s pudo haber publicado el enlace + Está a punto de verificar las claves OMEMO de su propia cuenta. Esto solamente es seguro si ha seguido este enlace desde una fuente segura, donde solo usted lo haya publicado. + Continuar Verificar claves OMEMO Mostrar inactivos Ocultar inactivos @@ -629,26 +637,32 @@ ¿Estás seguro de que quieres eliminar la verificación de este dispositivo?\nEste dispositivo y los mensajes que lleguen desde allí serán marcados como \"No confiables\". %d segundo + %d segundos %d segundos %d minuto + %d minutos %d minutos %d hora + %d horas %d horas %d día + %d días %d días %d semana + %d semanas %d semanas %d mes + %d meses %d meses Borrado automático de mensajes @@ -904,6 +918,7 @@ Videollamada entrante Conectando Conectado + Reconectando Aceptar llamada Terminar llamada Contestar @@ -919,6 +934,8 @@ Colgar Llamada saliente Video llamada saliente + Reconectando llamada + Reconectando video llamada Deshabilitar Tor para hacer llamadas Llamada entrante Llamada entrante · %s @@ -952,10 +969,12 @@ Añadir contacto, crear o unirse a un grupo de chat, o descubrir canales Ver %1$d Participante + Ver %1$d Participantes Ver %1$d Participantes Un mensaje no se ha podido entregar + Algunos mensajes no se han podido entregar Algunos mensajes no se han podido entregar Envíos fallidos @@ -968,4 +987,6 @@ La copia de seguridad ha empezado. Recibirás una notificación cuando se haya completado. No se ha podido habilitar el vídeo. Documento de texto plano + Los registros de cuenta no están soportados + Dirección XMPP no encontrada diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index 8e177693e2926e7113289f68911d4a9c40ac043b..807a45f529ea01ccb17b614820a12e9a3f16a745 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -33,6 +33,9 @@ %d conversation non lue + %d conversations non lues + + %d conversations non lues @@ -444,6 +447,7 @@ Annuler %d certificat supprimé + %d certificats supprimés %d certificats supprimés Remplacer le bouton « Envoyer » par une action rapide @@ -462,12 +466,14 @@ Échec du téléchargement : impossible de trouver le fichier Échec du téléchargement : impossible de se connecter à l\'hôte Échec du téléchargement : Écriture impossible + Échec du téléchargement : Fichier non valide Réseau Tor inaccessible La liaison a échoué Le serveur n\'est pas responsable pour ce domaine Détraqué Disponibilité Absent quand l\'appareil est verrouillé + Afficher comme étant absent lorsque l\'appareil est verrouillé Occupé en mode silence Occupé lorsque l\'appareil est en mode silencieux Indisponible en mode vibreur @@ -500,6 +506,7 @@ %1$d compte(s) sur %2$d connecté(s) %d message + %d messages %d messages Charger plus de messages @@ -624,26 +631,32 @@ Êtes-vous sûr de vouloir retirer la vérification pour cet appareil ?\nCet appareil et les messages qui en proviennent seront marqués comme « indignes de confiance ». %d seconde + %d secondes %d secondes %d minute + %d minutes %d minutes %d heure + %d heures %d heures %d jour + %d jours %d jours %d semaine + %d semaines %d semaines %d mois + %d mois %d mois Suppression messages auto @@ -899,6 +912,7 @@ Appel vidéo entrant Connexion en cours Connecté + Reconnexion en cours Accepter les appels Fin d\'appel Décrocher @@ -910,9 +924,12 @@ Connexion perdue Appel annulé Échec de l\'application + Vérification du problème Raccrocher Appel en cours Appel vidéo en cours + En cours de reconnexion de l\'appel + En cours de reconnexion de l\'appel vidéo Désactivez Tor afin de passer des appels Appel entrant Appel entrant · %s @@ -946,10 +963,12 @@ Ajouter un contact, créer ou joindre un groupe de discussion, ou découvrir les salons Voir %1$d participant + Voir %1$d participants Voir %1$d participants Certains messages n\'ont pas pu être distribués + Certains messages n\'ont pu être distribués Certains messages n\'ont pu être distribués Échec lors de la livraison @@ -957,8 +976,9 @@ Aucune application trouvée Inviter à Conversations Impossible de lire l\'invitation + Le serveur ne prend pas en charge la génération d\'invitations + Aucun compte actif ne prend en charge cette fonctionalité Impossible d’activer la vidéo. La création de nouveaux comptes n’est pas prise en charge Aucune adresse XMPP trouvée - - + diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 419dcf82b1a94423e5bc0879dc0ed0dd2cf9c552..76b0f937a5031d34fc21b38736021eea0f631b77 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -976,5 +976,4 @@ Documento de texto plano Non está permitido o rexistro de novas contas Non se atopa un enderezo XMPP - - + diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index af7c4b93df38a7cde2770fab35c466be84aea9cc..a665e79c7820c6f124b76da7b736c322b7e50cca 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -33,6 +33,9 @@ %d conversazione non letta + %d conversazioni non lette + + %d conversazioni non lette @@ -447,6 +450,7 @@ Annulla Cancellato il %d certificato + Cancellati %d certificati Cancellati %d certificati Sostituisci il tasto \"Invio\" con un\'azione rapida @@ -505,6 +509,7 @@ %1$d su %2$d profili connessi %d messaggio + %d messaggi %d messaggi Carica altri messaggi @@ -632,26 +637,32 @@ Sei sicuro di volere rimuovere la verifica di questo dispositivo?\nIl dispositivo e i messaggi provenienti da esso verranno segnati come \"Non fidato\". %d secondo + %d secondi %d secondi %d minuto + %d minuti %d minuti %d ora + %d ore %d ore %d giorno + %d giorni %d giorni %d settimana + %d settimane %d settimane %d mese + %d mesi %d mesi Eliminazione automatica dei messaggi @@ -958,10 +969,12 @@ Aggiungi un contatto, crea o visita una chat di gruppo, o scopri canali Vedi %1$d partecipante + Vedi %1$d partecipanti Vedi %1$d partecipanti Un messaggio non è stato recapitato + Alcuni messaggi non sono stati recapitati Alcuni messaggi non sono stati recapitati Recapiti falliti @@ -976,5 +989,4 @@ Documento di testo Le registrazioni di profili non sono supportate Nessun indirizzo XMPP trovato - - + diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml index 452ef18f851c502d90bdb09d6316cdcab4c83340..a207bb71c53123744b78e3c5507e8be489efa6c9 100644 --- a/src/main/res/values-ja/strings.xml +++ b/src/main/res/values-ja/strings.xml @@ -217,6 +217,8 @@ OpenPGP 鍵 ID OMEMO フィンガープリント v\\OMEMO フィンガープリント + OMEMO フィンガープリント (メッセージ起源) + v\\OMEMO フィンガープリント (メッセージ起源) 他のデバイス OMEMO フィンガープリントを信頼 鍵の取得中… @@ -459,6 +461,7 @@ ダウンロードに失敗しました: ファイルが見つかりません ダウンロードに失敗しました: ホストに接続できませんでした ダウンロードに失敗しました: ファイルに書き込みできません + ダウンロード失敗: 無効なファイル Tor ネットワークが利用できません バインド失敗 そのサーバーはこのドメインに責任を持ちません @@ -954,5 +957,4 @@ プレーンテキスト文書 アカウント登録はサポートされていません XMPPアドレスがみつかりません - - + diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index 32915d274528d69212640bb8aad4377342caa95e..b08726ee89a3f0d014976c481d795beeb6eab593 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -4,6 +4,7 @@ Nieuw gesprek Accounts beheren Account beheren + Gesprek sluiten Contactgegevens Gespreksgegevens Kanaalinformatie @@ -28,6 +29,13 @@ zojuist 1 min. geleden %d min. geleden + + %d ongelezen gesprek + + + %d ongelezen gesprekken + + versturen… Bericht aan het ontsleutelen. Even geduld… OpenPGP-versleuteld bericht @@ -63,6 +71,8 @@ Deblokkeren Opslaan Oké + %1$s is gecrasht + Door crashrapportages via uw XMPP account te sturen help je de ontwikkeling van %1$s. Nu versturen Niet opnieuw vragen Verbinding maken met account mislukt @@ -155,6 +165,7 @@ OpenPGP-publieke sleutel publiceren OpenPGP-publieke sleutel verwijderen Weet je zeker dat je je OpenPGP-publieke sleutel uit je aanwezigheidsaankondiging wil verwijderen?\nJe contacten zullen je geen OpenPGP-versleutelde berichten meer kunnen sturen. + OpenPGP-publieke sleutel gepubliceerd. Account inschakelen Weet je het zeker? Stem opnemen @@ -178,8 +189,11 @@ niet beschikbaar Ontbrekende publieke sleutel-aankondigingen zojuist voor het laatst gezien + een minuut geleden voor het laatst gezien %d minuten geleden voor het laatst gezien + een uur geleden voor het laatst gezien %d uur geleden voor het laatst gezien + een dag geleden voor het laatst gezien %d dagen geleden voor het laatst gezien OpenPGP-sleutel-ID OMEMO-vingerafdruk @@ -220,6 +234,7 @@ %s hebben tot hier gelezen Iedereen heeft tot hier gelezen Publiceer + Tik op avatar om een foto uit de galerij te kiezen Publiceren… De server weigerde de publicatie van je afbeelding Fout bij opslaan van avatar @@ -230,6 +245,7 @@ Verbind Deze account bestaat al Volgende + Sessie is tot stand gekomen Overslaan Meldingen uitschakelen Inschakelen @@ -297,6 +313,7 @@ %s aangeboden om te downloaden Bestandsoverdracht annuleren bestandsoverdracht geannuleerd + Geen app om bestand te openen Dynamische tags Toon enkel-lezen tags onder contacten Meldingen inschakelen @@ -314,6 +331,7 @@ Wachtwoord wijzigen Huidig wachtwoord Nieuw wachtwoord + Wachtwoord mag niet leeg zijn Alle accounts inschakelen Alle accounts uitschakelen Actie uitvoeren met @@ -370,6 +388,7 @@ Laat je contacten weten wanneer je ze een nieuw bericht schrijft Locatie versturen Locatie weergeven + Geen app om locatie weer te geven Locatie Gesprek gesloten Privégroep verlaten diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index b3ce1103740a676478ccbc035959cb1632e5a508..4b49a6501fd40d97d29ffe31fb4d0201307b99a4 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -1003,5 +1003,4 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż Dokument zwykłego tekstu Rejestracja kont nie jest wspierana Nie znaleziono adresu XMPP - - + diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml index 79d6ea79887ee96cff8944d6e75e5ddb7c315b06..9bcf1aaeae49fc3270a10e14891f18e2e489427c 100644 --- a/src/main/res/values-pt-rBR/strings.xml +++ b/src/main/res/values-pt-rBR/strings.xml @@ -33,6 +33,9 @@ %d conversa não lida + %d conversas não lidas + + %d conversas não lidas @@ -447,6 +450,7 @@ Cancelar %d certificado cancelado + %d certificados cancelados %d certificados cancelados Troca o botão \"Enviar\" pelo de ação rápida @@ -505,6 +509,7 @@ %1$d de %2$d contas conectadas %d mensagem + %d mensagens %d mensagens Carregar mais mensagens @@ -632,26 +637,32 @@ Tem certeza que deseja remover a verificação para este dispositivo?\nEste dispositivo e as mensagens oriundas dele serão marcadas como \"não confiáveis\". %d segundo + %d segundos %d segundos %d minuto + %d minutos %d minutos %d hora + %d horas %d horas %d dia + %d dias %d dias %d semana + %d semanas %d semanas %d mês + %d meses %d meses Exclusão automática de mensagens @@ -958,10 +969,12 @@ Adicionar contato, criar ou associar-se a uma conversa em grupo ou descobrir canais Ver %1$d participante + Ver %1$d participantes Ver %1$d participantes Não foi possível enviar a mensagem + Não foi possível enviar algumas mensagens Não foi possível enviar algumas mensagens Entregas não efetuadas @@ -976,5 +989,4 @@ Documento em texto puro O registro de contas não está ativo Não foi encontrado nenhum endereço XMPP - - + diff --git a/src/main/res/values-pt/strings.xml b/src/main/res/values-pt/strings.xml index 1d7ea055fa14230bda1f1da8e70ee50962698d7c..125a0af4c526aff471eaf748f28ced1a1e1b8e35 100644 --- a/src/main/res/values-pt/strings.xml +++ b/src/main/res/values-pt/strings.xml @@ -308,6 +308,7 @@ Cancelar %d certificado apagado + %d certificados apagados %d certificados apagados Ação rápida @@ -348,6 +349,7 @@ %1$d de %2$d contas conectadas %d mensagem + %d mensagens %d mensagens Carregar mais mensagens diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index 1ed0d4caaa855c72469813af89b59c9546d0651d..a57f9d0ebf55536ca4471cd876cd0d7747740dd3 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -989,5 +989,4 @@ Document text Nu este posibilă înregistrarea unui cont Nu a fost găsită o adresă XMPP - - + diff --git a/src/main/res/values-szl/strings.xml b/src/main/res/values-szl/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..0ed32a5337f5e0cfbdb89479f1fa3f4a9b806c1b --- /dev/null +++ b/src/main/res/values-szl/strings.xml @@ -0,0 +1,1025 @@ + + + Sztelōnki + Nowo godka + Sztelōnki kōnt + Sztelōnki kōnta + Zawrzij godka + Informacyje kōntaktu + Informacyje kōnferyncyje + Informacyje kanału + Przidej kōnto + Edytuj miano + Przidej do kōntaktōw + Skasuj z rostera + Zablokuj kōntakt + Ôdblokuj kōntakt + Ôdblokuj dōmyna + Ôdblokuj dōmyna + Zablokuj kōntakt + Ôdblokuj kōntakt + Sztelōnki kōnt + Sztelōnki + Udostympnij we godce + Zacznij godka + Ôbier kōntakt + Ôbier kōntakty + Udostympnij bez + Czorno lista + przed chwilōm + minuta tymu + %d minut tymu + + %d niyprzeczytano kōnwersacyjo + + + %d niyprzeczytane kōnwersacyje + + + %d niyprzeczytanych kōnwersacyji + + + wysyłanie… + Ôdszyfrowowanie wiadōmości. To weźnie ino chwila… + Wiadōmość zaszyfrowano OpenPGP + Miano je już zajynte + Niynoleżny pseudōnim + Admin + Posiedziciel + Moderatōr + Uczestnik + Gość + Chcesz wymazać kōntakt %s ze listy\? Godki ze tym kōntaktym niy bydōm wymazane. + Na zicher chcesz zablokować wiadōmości ôd kōntaktu %s\? + Na zicher chcesz ôdblokować wiadōmości ôd kōntaktu %s\? + Zablokować wszyjske kōntakty ze %s\? + Ôdblokować wszyjske kōntakty ze %s\? + Kōntakt zablokowany + Zablokowane + Chcesz wymazać zokłodka %s\? Godki z niōm niy bydōm wymazane. + Zaregistruj nowe kōnto na serwerze + Umiyń hasło na serwerze + Udostympnij… + Zacznij godka + Zaproś kōntakt + Zaproś + Kōntakty + Kōntakt + Pociep + Nasztaluj + Przidej + Edytuj + Wymaż + Zablokuj + Ôdblokuj + Spamiyntej + OK + We %1$s doszło do awaryje + Jak używosz swojigo kōnta XMPP do wysyłanio sztrekōw sztapla, to pōmogosz przi budowaniu %1$s. + Wyślij teroz + Niy pytej zaś + Niy idzie połōnczyć z kōntym + Niy idzie połōnczyć z mockōm kōnt + Tyknij, coby sztelować swoje kōnta + Przidej zbiōr + Przidać tyn kōntakt do twojij listy kōntaktōw\? + Przidej kōntakt + wysyłanie sie niy podarziło + Rychtowanie do wysłanio ôbrozka + Rychtowanie do wysłanio ôbrozkōw + Udostympnianie zbiorōw. Czekej… + Wymaż historyjo + Wymaż historyjo kōnwersacyje + Chcesz wymazać wszyjske wiadōmości we tyj godce\? +\n +\nPozōr: To niy wpływo na wiadōmości trzimane na inkszych maszinach abo serwerach. + Wymaż zbiōr + Na zicher wymazać tyn zbiōr\? +\n +\nPozōr: To niy wpływo na kopije zbioru trzimane na inkszych maszinach abo serwerach. + Zawrzij potym tyż kōnwersacyjo + Ôbier maszina + Wyślij wiadōmość bez szyfrowanio + Wyślij wiadōmość + Wyślij wiadōmość do kōntaktu %s + Wyślij wiadōmość zaszyfrowano OMEMO + Wyślij wiadōmość zaszyfrowano v\\OMEMO + Wyślij zaszyfrowano wiadōmość (OpenPGP) + Przemianek je umiyniōny + Wyślij bez szyfrowanio + Niy idzie ôdszyfrować. Możno niy mosz noleznego prywatnego klucza. + OpenKeychain + %1$s używo <b>OpenKeychain</b>, żeby szyfrować i ôdszyfrowować wiadōmości i zarzōndzać twojimi publicznymi kluczami.<br><br>OpenKeychain je na licyncyji GPLv3+ i je dostympny we F-Droid abo Google Play.<br><br><small>(Puść %1$s na nowo po zainstalowaniu.)</small> + Zresztartuj + Zainstaluj + Zainstaluj OpenKeychain + ôferowanie… + czekanie… + Niy szło znojś klucza OpenPGP + Niy idzie zaszyfrować twojij wiadōmości, bo tyn kōntakt niy ôgłoszo swojigo publicznego klucza. +\n +\nPoproś kōntakt, żeby nasztalowoł OpenPGP. + Niy szło znojś kluczy OpenPGP + Niy idzie zaszyfrować twojij wiadōmości bo twoje kōntakty niy ôgłoszajōm swojich kluczy publicznych. +\n +\nPoproś, żeby nasztalowały OpenPGP. + Bazowe + Akceptuj zbiory + Autōmatycznie akceptuj zbiory myńsze niż… + Przidowki + Powiadōmiynie + Wibracyje + Wibruj, jak przidzie wiadōmość + Powiadōmiynie diodōm LED + Migej diodōm, jak przidzie wiadōmość + Zwōnek + Klang powiadōmiyń + Klang powiadōmiyń ô nowych wiadōmościach + Zwōnek przi przichodzōncych połōnczyniach + Czas bez powiadōmiyń + Dugość czasu, kej powiadōmiynia sōm wyciszōne po wykryciu aktywności na jednyj z twojich inkszych maszin. + Rozszyrzōne + Niy wysyłej reportōw awaryje + Jak wysyłosz sztreki sztapla, to pōmogosz przi budowaniu + Potwierdzynia wiadōmości + Przizwōl na wysyłanie do ôsōb ze listy kōntaktōw informacyje ô twojim dostaniu i przeczytaniu wiadōmości ôd nich + Blokuj zopisy ekranu + Skryj zawartość aplikacyje we szaltrze aplikacyji i zablokuj zopisy ekranu + UI + OpenKeychain zgłosiyło błōnd. + Zły klucz szyfrowanio. + Akceptować + Doszło do błyndu + Błōnd + Twoje kōnto + Wysyłej powiadōmiynia ôbecności + Dostowej powiadōmiynia ôbecności + Poproś ô powiadōmiynia ôbecności + Ôbier ôbroz + Zrōb fotografijo + Autōmatyczno zwolo na subskrypcyjo + Ôbrany zbiōr to niy ôbroz + Błōnd kōnwersyje ôbrazu + Niy szło znojś zbioru + Ôgōlny feler wchodu/wychodu. Możno skōńczōł sie plac na dane\? + Aplikacyjo użyto do ôbioru ôbrazu niy przizwolyła na ôdczyt zbioru. +\n +\nÔbier ôbroz przi użyciu inkszego mynedżera zbiorōw. + Aplikacyjo użyto do udostympniynio tego zbioru niy dała stykajōncych uprawniyń. + Niyznōmy + Tymczasowo zastawiōne + Połōnczōne + Łōnczynie… + Rozłōnczōne + Błōnd autoryzacyje + Niy szło znojś serwera + Brak połōnczynio + Błōnd registracyje + Miano zajynte + Zaregistrowano sprownie + Tyn serwer niy spiyro registracyje + Niynoleżny tokyn registracyje + Niy podarziła sie negocjacyjo TLS + Dōmyna niyweryfikowalno + Naruszynie prawideł + Serwer niykōmpatybilny + Błōnd potoku + Błōnd ôtwiyranio potoku + Bez szyfrowanio + OTR + OpenPGP + OMEMO + Wymaż kōnto + Zastow tymczasowo + Publikuj awatar + Udostympnij klucz publiczny OpenPGP + Wymaż klucz publiczny OpenPGP + Na zicher chcesz wymazać klucz publiczny OpenPGP ze swojij propagacyje ôbecności\? +\nTwoje kōntakty niy bydōm już mogły wysyłać ci wiadōmości zaszyfrowanych OpenPGP. + Klucz publiczny OpenPGP ôstoł ôpublikowany. + Włōncz kōnto + Na zicher\? + Wymazanie kōnta wymazuje cołko historyjo godek + Nagrej głos + Adresa XMPP + Zablokuj adresa XMPP + username@example.com + Hasło + To niyma noleżno adresa XMPP + Brak pamiyńci. Ôbroz je za srogi + Chcesz przidać %s do listy kōntaktōw\? + Informacyje ô serwerze + XEP-0313: MAM + XEP-0280: Kopije wiadōmości + XEP-0352: Skaźnik Sztandu Klijynta + XEP-0191: Rozkoz blokowanio + XEP-0237: Wersyjowanie listy + XEP-0198: Sztelōnki potoku + XEP-0215: Wykrywanie Zewnyntrznych Usug + XEP-0163: PEP (Awatary / OMEMO) + XEP-0363: Przesyłanie zbiorōw bez HTTP + XEP-0357: Push + dostympny + niydostympny + Brak informacyje ô kluczu publicznym + prawie widziany + widziany przed minutōm + widziany prze %d minutami + widziany przed godzinōm + widziany przed %d godzinami + widziany wczorej + widziany przed %d dniami + Wiadōmość zaszyfrowano. Zainstaluj OpenKeychain, coby ôdszyfrować. + Znojdziōne nowe wiadōmości zaszyfrowane we OpenPGP + ID klucza OpenPGP + Ôdcisk OMEMO + Ôdcisk v\\OMEMO + Ôdcisk OMEMO tyj wiadōmości + Ôdcisk v\\OMEMO tyj wiadōmości + Insze masziny + Zadufane ôdciski OMEMO + Pobiyranie kluczy… + Skōńczōno + Ôdszyfruj + Zokłodki + Szukej + Wpisz kōntakt + Wymaż kōntakt + Informacyje ô kōntakcie + Zablokuj kōntakt + Ôdblokuj kōntakt + Stwōrz + Ôbier + Kōntakt już istniyje + Prziwstōń + kanal@konferyncyje.prziklod.com/przemianek + kanal@konferyncyje.prziklod.com + Przidej za zokłodka + Wymaż zokłodka + Wymaż kōnferyncyjo + Wymaż kanał + Je żeś zicher, iże chcesz wymazać ta kōnferyncyjo\? +\n +\nPozōr: Ta kōnferyncyjo bydzie doimyntnie wymazano na serwerze. + Na zicher chcesz wymazać tyn kanał publiczny\? +\n +\nPozōr: Tyn kanał bydzie doimyntnie wymazany ze serwera. + Niy szło wymazać kōnferyncyje + Niy szło wymazać kanału + Edytuj tytuł kōnferyncyje + Tymat + Przistympowanie do kōnferyncyje… + Ôpuść izba + Kōntakt przidoł cie do listy kōntaktōw + Tyż przidej + Kōntakt %s przeczytoł dotōnd + Kōntakty %s przeczytały dotōnd + Kōntakty %1$s i %2$d inszych przeczytało dotōnd + Wszyjscy przeczytali dotōnd + Publikuj + Tyknij awatar, coby ôbrać ôbroz z galeryje + Publikowanie… + Serwer ôdkozoł publikacyje + Niy szło skōnwertować ôbrazu + Niy szło spamiyntać ôbrazu we pamiyńci masziny + (abo dugo przitrzim, coby nasztalować wychodny) + Twōj serwer niy umożliwo publikacyje awatarōw + szepce + do %s + Wyślij prywatno wiadōmość do %s + Połōncz + Kōnto już istniyje + Dalij + Połōnczōno ze serwerym + Przeskocz + Zastow powiadōmiynia + Włōncz + Kōnferyncyjo wymogo hasła + Wkludź hasło + Poproś kōntakt ô udostympniynie powiadōmiyń ô ôbecności. +\n +\nTo bydzie używane do skazowanio, jakigo programu używo twōj kōntakt. + Poproś teroz + Ignoruj + Pozōr: Wysyłanie bez powiadōmiyń ô ôbecności ze ôbōch strōn może prziniyś niyôczekowane problymy. +\n +\nIdź do „Informacyji ô kōntakcie” i wejzdrzij do subskrypcyji ôbecności. + Bezpieczyństwo + Przizwōl na poprowianie wiadōmości + Przizwōl swojim kōntaktōm poprowiać wiadōmości + Sztelōnki eksperta + Modyfikuj je pozornie + Ô %s + Godziny cisze + Poczōntek + Kōniec + Włōncz godziny cisze + Powiadōmiynia bydōm wyciszōne we ôbranych godzinach + Inksze + Synchrōnizuj ze zokłodkami + Przistympuj do godek grupowych autōmatycznie, jeźli tak pado zokłodka + Ôdcisk klucza OMEMO bōł skopiowany do skrytki + Ôd tyj grupy mosz wykluczynie + Kōnferyncyjo ino dlo czōnkōw + Ukrōcynie zasobu + Ze tyj kōnferyncyje cie wyciepli + Kōnferyncyjo ôstała zawarto + Już żeś niy je we tyj kōnferyncyji + ze użyciym kōnta %s + trzimane na %s + Wybadowanie %s na hoście HTTP + Brak połōnczynio. Sprōbuj zaś niyskorzij + Wybadej srogość %s + Wybadej srogość %1$s na %2$s + Ôpcyje wiadōmości + Cytata + Wraź za cytata + Skopiyruj ôryginalny URL + Wyślij zaś + URL zbioru + Skopiowano URL do skrytki + Skopiowano adresa XMPP do skrytki + Skopiowano kōmunikat błyndu do skrytki + adresa necowo + Zeskanuj kod + Pokoż kod QR + Pokoż wykoz wykluczyń + Informacyje kōnta + Potwiyrdź + Sprōbuj zaś + Usuga na piyrszym planie + Niy zwolo systymowi na przerwanie połōnczynio + Stwōrz kopijo ibryczno + Kopijo ibryczno bydzie spamiyntano we %s + Tworzynie kopije ibrycznyj + Kopijo ibryczno stworzōno + Kopijo ibryczno spamiyntano we %s + Prziwrocanie ze kopije ibrycznyj + Prziwrocanie ze kopije ibrycznyj gotowe + Niy zapōmnij ô aktywacyji tego kōnta. + Ôbier zbiōr + Ôdbiyranie %1$s (skōńczōne %2$d%%) + Pobier %s + Wymaż %s + zbiōr + Ôtwōrz %s + Wysyłanie (skōńczōne %1$d%%) + Rychtowanie do udostympniynio ôbrozka + Zapropōnowano pobranie zbioru %s + Pociep przesyłanie + niy szło udostympnić zbioru + transmisyjo zbioru pociepniynto + Zbiōr wymazany + Niy szło znojś aplikacyje do ôtwarcia zbioru + Niy szło znojś aplikacyje do ôtwarcia linka + Niy szło znojś aplikacyje do pokozanio kōntaktu + Dynamiczne tagi + Pokazuj etykety pod kōntaktami + Włōncz powiadōmiynia + Niy szło znojś serwera kōnferyncyje + Niy szło stworzić kōnferyncyje + Awatar kōnta + Skopiuj ôdcisk klucza OMEMO do skrytki + Wygyneruj zaś klucz OMEMO + Wymaż masziny + Na zicher chcesz wymazać wszyjske inksze masziny z ôgłoszynio OMEMO\? Jak twoje masziny sie zaś połōnczōm, to sie zaś ôgłoszōm, ale mogōm niy dostać wiadōmości wysłanych bez tyn czas. + Niy ma dostympnych kluczy dlo tego kōntaktu. +\nNiy szło pobrać nowych kluczy ze serwera. Możno je coś niy tak ze serwerym ôd twojigo kōntaktu\? + Brak dostympnych kluczy dlo tego kōntaktu. +\nDej pozōr, czy wzajymnie powiadōmiocie sie ô ôbecności. + Coś poszło źle + Pobiyranie historyje z serwera + Kōniec historyje na serwerze + Aktualizowanie… + Hasło było zmiyniōne! + Niy szło zmiynić hasła + Zmiyń hasło + Teroźne hasło + Nowe hasło + Hasło niy może być prōzne + Aktywuj wszyjske kōnta + Zastow wszyjske kōnta + Użyj + Brak stanowiska + Offline + Wykluczōny + Czōnek + Tryb rozszyrżōny + Prziznej uprawniynia czōnkostwa + Wymaż uprawniynia czōnkostwa + Prziznej uprawniynia administratora + Odbierz uprawniynia administratora + Prziznej uprawniynia posiedziciela + Wymaż uprawniynia posiedziciela + Wyciep z kōnferyncyje + Wyciep z kanału + Niy szło umiynić stanowiska ôd %s + Wyklucz + Wyklucz na kanale + Chcesz wyciepnōńć %s z publicznego kanału. Jedyny spusōb na to, to je wykluczyć ta ôsoba na dycki. + Wyklucz teroz + Niy szło zmiynić funkcyje %s + Kōnfiguracyjo prywatnyj kōnferyncyje + Kōnfiguracyjo publicznego kanału + Prywatne, ino dlo czōnkōw + Niych adresa XMPP bydzie widzialno dlo wszyjskich + Niych kanał bydzie moderowany + Niy bieresz udziału + Sztalōnki kōnferyncyje były zmiyniōne! + Niy idzie zmiynić sztelōnkōw kōnferyncyje + Nigdy + Ryncznie + Ôdłōż + Ôdpowiydz + Ôznocz za przeczytane + Sztelōnki wkludzanio + Enter wysyło + Używej knefla Enter do wysyłanio wiadōmości. Dycki możesz używać Ctrl+Enter, żeby wysłać wiadōmość, nawet jak ta ôpcyjo je zastawiōno. + Pokoż knefel Enter + Umiyń knefel emotikōnōw na Enter + zbiōr audio + zbiōr wideo + ôbroz + wektorowo grafika + Dokumynt PDF + Aplikacyjo Androida + Kōntakt + Avatar bōł sprownie ôpublikowany! + Wysyłanie %s + Propōnowanie %s + Skryj niydostympnych + %s pisze… + %s niy pisze + %s piszōm… + %s niy piszōm + Powiadōmiynia pisanio + Dowej znać kōntaktōm, jak dō nich piszesz + Wyślij lokalizacyjo + Pokoż lokalizacyjo + Niy szło znojś aplikacyje do pokazowanio lokalizacyje + Lokalizacyjo + Kōnwersacyjo zawarto + Ôpuś prywatno kōnferyncyjo + Ôpuś publiczny kanał + Niy dufej certyfikatōm systymowym + Wymogej ryncznego potwiyrdzanio certyfikatōw + Wymaż certyfikaty + Ôbier zadufane certyfikaty do wymazanio + Brak ryncznie zadufanych certyfikatōw + Wymaż certyfikaty + Wymaż zaznaczōne + Pociep + + Wymazany %d certyfikat + Wymazane %d certyfikaty + Wymazane %d certyfikatōw + + Zastōmp knefel wysyłanio gibkōm akcyjōm + Gibko akcyjo + Brak + Ôstatnio używano + Ôbier gibko akcyjo + Przeszukej kōntakty + Przeszukej zokłodki + Wyślij wiadōmość prywatno + %1$s już niy je we kōnferyncyji + Miano ôd używocza + Miano ôd używocza + Niynolezne miano ôd używocza + Pobiyranie niyudane: Niy szło znojś serwera + Pobiyranie niyudane: Niy szło znojś zbioru + Pobiyranie niyudane: Niy szło połōnczyć z hostym + Pobiyranie niyudane: Niy szło spamiyntać zbioru + Pobiyranie niypodarzōne: Niynoleżny zbiōr + Nec TOR je niydostympny + Błōnd połōnczynio + Serwer niy ôdpado dōmynie + Zepsute + Dostympność + Status „W ôddali”, kej ekran je zastawiōny + Ôznaczo twōj zasōb za „W ôddali”, kej ekran je zastawiōny + „Niy szterować” we trybie cichym + Ôznaczo twōj zasōb za „Niy szterować”, kej maszina je w trybie cichym + Traktuj tryb wibracyje jak tryb cichy + Ôznaczo twōj zasōb za „Niy szterować”, kej maszina je w trybie wibracyje + Rozszyrzōne sztelōnki połōnczynio + Pokoż miano ôd hosta i sztelōnki portu przi przidowaniu kōnta + xmpp.prziklod.com + Wloguj certyfikatym + Niy szło ôdczytać certyfikatu + Preferyncyje archiwizacyje + Preferyncyje archiwizacyje po strōnie serwera + Pobiyranie preferyncyji archiwizacyje. Czekej… + Niy idzie pobrać preferyncyji archiwizacyje + Wymogano CAPTCHA + Wkludź tekst z ôbrozka wyżyj + Lyńcuch certyfikatōw niyma zadufany + Adresa XMPP niy pasuje do certyfikatu + Ôdnōw certyfikat + Błōnd pobiyranio klucza OMEMO! + Klucz OMEMO zweryfikowany certyfikatym! + Twoja maszina niy spiyro ôbiyranio certyfikatōw klijynckich! + Połōnczynie + Połōncz bez nec TOR + Tuneluj wszyjske połōnczynia bez nec TOR. Wymogo aplikacyje Orbot + Miano hosta + Port + Adresa serwera abo .onion + To niyma noleżny numer portu + To niyma noleżne miano hosta + %1$d z %2$d kōnt połōnczōnych + + %d wiadōmość + %d wiadōmości + %d wiadōmości + + Zaladuj wiyncyj wiadōmości + Zbiōr dzielōny ze %s + Ôbroz dzielōny ze %s + Ôbrazy dzielōne ze %s + Tekst dzielōny ze %s + Przizwōl %1$s na dostymp do zewnyntrznego składu + Przizwōl %1$s na dostymp do aparatu + Synchrōnizuj z kōntaktami + %1$s potrzebuje twojij zwōle na dopasowanie twojich kōntaktōw XMPP z wykazym kōntaktōw w telefōnie. +\nTo pokoże jejich połne miana i awatary. +\n +\n%1$s ino przeczyto twoje kōntakty i dopasuje je lokalnie, bez wysyłanio na twōj serwer. + Quicksy potrzebuje dostympu do numerōw telefōnōw twojich kōntaktōw, coby zasugerować ci kōntakty, co już używajōm Quicksy. <br><br>Niy trzimiymy kopiji tych numerōw. +\n +\nAby dostać wiyncyj informacyje przeczytej naszo polityka prywatności</a>. <br><br>Teroz pojawi sie prośba ô zwōlo na dostymp do twojich kōntaktōw. + Powiadōm ô wszyskich wiadōmościach + Powiadōmiej ino w przipodku spōmniynio ô mie + Powiadōmiynia zastawiōne + Powiadōmiynia strzimane + Kōmpresyjo ôbrazōw + Podpowiydź: Użyj “Wybier zbiōr” zamiast “Wybier ôbroz”, coby wysłać pojedyncze ôbrozki bez kōmpresyje bez zglyndu na tyn sztalōnek. + Dycki + Ino sroge ôbrozki + Ôptymalizacyje używanio bateryje włōnczōne + Twoja maszina mo włōnczōne agresywne szporowanie bateryje, bez co %1$s może ôdbiyrać wiadōmości z ôpōźniyniym. +\nZastawiynie tych ôptymalizacyji je rekōmyndowane. + Twoja maszina mo włōnczōne agresywne szporowanie bateryje, bez co %1$s może ôdbiyrać wiadōmości z ôpōźniyniym. +\n +\nTeroz pojawi sie prośba ô jejich zastawiynie. + Zastow + Zaznaczōne przestrzyństwo je za sroge + (Brak aktywynych kōnt) + To pole je wymogane + Poprow wiadōmość + Wyślij poprawiōno wiadōmość + Tyn kōntakt już bōł ôd ciebie zweryfikowany. Bez wybranie “Gotowe” ino potwiyrdzosz, że %s noleży do tyj grupowyj godki. + To kōnto było ôd ciebie zastawiōne + Feler bezpieczyństwa: niynoleżny dostymp do zbioru! + Niy szło znojś aplikacyje do udostympniynio URI + Udostympnij URI ze pōmocōm… + Quicksy to modyfikacyjo popularnego klijynta XMPP Conversations, z autōmatycznym wykrywaniym kōntaktōw.<br><br>Zapisujesz sie przi użyciu numeru telefōnu i Quicksy autōmatycznie — podle numerōw telefōnōw we adresowyj ksiōnżce — zasugeruje potyncjalne kōntakty dlo ciebie.<br><br>Bez zapisanie sie zgodzosz sie na naszo <a href=https://quicksy.im/#privacy>polityka prywatności</a>. + Zgodzōm sie, kōntynuuj + Pokludzymy cie bez proces tworzynio kōnta na conversations.im.¹ +\nKej ôbieresz conversations.im za liferanta, to poradzisz kōmunikować sie ze używoczami inkszych liferantōw, jeźli podosz im swoja połno adresa XMPP. + Twoja połno adresa XMPP to: %s + Stwōrz kōnto + Użyj inkszego serwera + Ôbier miano ôd używocza + Regyruj dostympnościōm ryncznie + Sztaluj dostympność we ôknie edytowanio wiadōmości statusu. + Status + Pogodo + Je + Fōrt + Niy ma + Zajynte + Bezpieczne hasło je wygynerowane + Twoja maszina niy przizwolo na zastawiynie ôptymalizacyje bateryje + Registracyjo niy podarziła sie: sprōbuj niyskorzij + Registracyjo niy podarziła sie: hasło za słabe + Ôbier czōnkōw + Tworzynie kōnferyncyje… + Zaproś zaś + Zastow + Krōtki + Postrzedni + Dugi + Roznajmuj użycie + Informuje twoje kōntakty ô tym, kedy używosz Conversations + Prywatność + Tymat + Wybier paleta farbōw + Autōmatycznie + Jasny + Ciymny + Zielōny zadek + Używej zielōnego zadku dlo dostanych wiadōmości + Niy idzie sie połōnczyć z OpenKeychain + Ta maszina juz niy je używano + Kōmputer + Mobilniok + Tablet + Przeglōndarka necu + Kōnsola + Wymogany płat + Dej zwōlo na dostymp do Internetu + Jo + Kōntakt prosi ô udostympniynie statusu + Przizwōl + Brak zwōle na dostymp do %s + Niy szło znojś serwera + Brak ôdpowiedzi ôd zdalnego serwera + Niy szło zaktualizować kōnta + Zgłoś ta adresa XMPP za spamowanie. + Wymaż tożsamości OMEMO + Wygyneruj jeszcze roz klucze OMEMO. Wszyske twoje kōntakty bydōm musiały cie zaś zweryfikować. Użyj tego ino w ôstateczności. + Wymaż zaznaczōne klucze + Potrzebne połōnczynie, coby ôpublikować twōj awatar. + Pokoż kōmunikaty felerōw + Kōmunikat ô felerze + Szporowanie danych je włōnczōne + Twōj systym ôperacyjny blokuje dostymp do internetu %1$s, jak ôn funguje we zadku. Coby dostować powiadōmiynia ô nowych wiadōmościach, trzeba dać %1$s niyôgraniczōny dostymp do internetu, kedy szporowanie danych je włōnczōne. +\n%1$s bydzie durch ôgraniczoł transfer danych, kedy ino to je możliwe. + Twoja maszina niy spiyro zastawianio szporowanio danych dlo %1$s. + Niy szło stworzić tymczasowego zbioru + Maszina je zweryfikowano + Skopiyruj ôdcisk + Wszyske twoje klucze OMEMO sōm zweryfikowane + Kod kryskowy niy zawiyro ôdciskōw dlo tyj godki. + Zaufane ôdciski + Użyj fotoaparatu, coby zeskanować kod kryskowy kōntaktu + Czekej na ściōngniyńcie kluczy + Udostympnij bez kod QR + Udostympnij bez URI XMPP + Udostympnij bez link HTTP + Ôd Razu Ufej Przed Weryfikacyjōm + Autōmatycznie ufej wszyskim nowym maszinōm ôd niyzweryfikowanych kōntaktōw, ale proś ô rynczne potwierdzynie nowych maszin ôd zweryfikowanych kōntaktōw. + Ôd razu zaufane klucze OMEMO, to znaczy mogōm noleżeć do kogoś inkszego abo ftoś może sie podepnōńć. + Niezaufane + Niynoleżny kod kryskowy 2D + Wypucuj cache (używane ôd fotoaparatu) + Wysnoż cache + Wysnoż prywatny skłod + Wysnoż prywatny skłod, kaj sōm trzimane zbiory (mogōm być pobrane zaś z serwera) + Trefiōłch tyn link we zaufanym zdrzōdle + Zaroz zweryfikujesz klucz OMEMO %1$s bez klikniyńcie w link. To je bezpiecznie ino, kej link je ze zaufanego zdrzōdła, kaj ino %2$s mōg go ôpublikować. + Zaroz zweryfikujesz klucze OMEMO swojego kōnta. To je bezpieczne ino jeźli ôtwiyrosz tyn link ze zaufanego zdrzōdła, kaj ino ty możesz ôpublikować tyn link. + Dalij + Zweryfikuj klucze OMEMO + Pokoż niyaktywne + Skryj niyaktywne + Przestōń ufać maszinie + Je żeś zicher, iże chcesz cofnōńć weryfikacyjo tyj masziny\? +\nTa maszina, i wiadōmości, co bydōm z nij przichodzić, bydōm ôznaczane za niyzaufane. + + %d sekunda + %d sekundy + %d sekund + + + %d minuta + %d minuty + %d minut + + + %d godzina + %d godziny + %d godzin + + + %d dziyń + %d dni + %d dni + + + %d tydziyń + %d tydnie + %d tydni + + + %d miesiōnc + %d miesiōnce + %d miesiyncy + + Autōmatyczne wymazowanie wiadōmości + Autōmatycznie wymazuj z tyj masziny wiadōmości starsze aniżeli skōnfigurowany ôkres czasu. + Szyfrowanie wiadōmości + Bez pobiyranio wiadōmości bez lokalny ôkres retyncyje. + Kōmpresowanie filmu + Powiōnzane godki zawarte. + Kōntakt zablokowany. + Powiadōmiynia ôd cudzych ludzi + Powiadōmiej przi wiadōmościach i połōnczyniach ôd cudzych ludzi. + Prziszła widōmość ôd kogoś cudzego + Zablokuj cudzo ôsoba + Zablokuj cołko dōmyna + teroz online + Sprōbuj zaś ôdszyfrować + Feler sesyje + Starszy mechanizm SASL + Serwer wymogo registracyje na strōnie + Ôtwōrz strōna + Niy szło znojś aplikacyje do ôtwarciŏ strōny + Powiadōmiynia heads-up + Pokazuj powiadōmiynia Heads-up + Dzisiej + Wczorej + Potwiyrdź miano ôd hosta ze pōmocōm DNSSEC + Certyfikaty serwera, co posiadajōm noleżne miano ôd hosta, sōm uznowane za zweryfikowane + Certyfikat niy zawiyro adresy XMPP + czyńściowo + Nagrej film + Skopiyruj do skrytki + Wiadōmość skopiyrowano do skrytki + Wiadōmość + Prywatne wiadōmości sōm zastawiōne + Aplikacyje chrōniōne + Coby dostować wiadōmości, kedy ekran je zastawiōny, musisz przidać Conversations do listy chrōniōnych aplikacyji. + Zaakceptować niyznōmy certyfikat\? + Certyfikat ôd serwera niy ma podpisany ôd znōmego Amtu Certyfikacyje. + Zaakceptować niypasujōnce miano ôd serwera\? + Niy idzie potwiyrdzić serwera za “%s. Certyfikat je ważny ino dlo: + Chcesz kōntynuować połōnczynie\? + Informacyje certyfikatu: + Roz + Skaner kodōw QR potrzebuje dostympu do aparatu + Przewiń na spodek + Przewiń na spodek po wysłaniu wiadōmości + Edytuj kōmunikat statusu + Edytuj kōmunikat statusu + Zastow szyfrowanie + %1$s niy mogło wysłać zaszyfrowanyj wiadōmości do %2$s. Możliwe, iże kōntakt używo starego serwera abo klijynta, co niy spiyro OMEMO. + Niy podarziło sie pobranie listy maszin + Niy podarziło sie pobranie kluczy szyfrowanio + Podpowiydź: W niykerych przipodkach może pōmōc wzajymne przidanie sie do listy kōntaktōw. + Na zicher chcesz zastawić szyfrowanie OMEMO dlo tyj kōnwersacyje\? +\nAdministratōr twojigo serwera bydzie mōg czytać twoje wiadōmości, ale może to być jedyny spōsōb, coby kōmunikować sie z ludźmi, co używajōm starych klijyntōw. + Zastow teroz + Cychōnek: + Szyfrowanie OMEMO + OMEMO bydzie dycki używane w godkach 1:1 i prywatnych grupowych godkach. + OMEMO bydzie używane wychodnie przi nowych godkach. + OMEMO bydzie musiało być włōnczōne ryncznie przi nowych godkach. + Stwōrz Skrōt + Srogość czciōnki + Relatywno srogość czciōnki używanyj we aplikacyji. + Włōnczōne wychodnie + Zastawiōne wychodnie + Mało + Strzednio + Srogo + Wiadōmość niy była zaszyfrowano dlo tyj masziny. + Niy szło ôdszyfrować wiadōmości OMEMO. + cofnij + Udostympnianie lokalizacyje je zastawiōne + Zablokuj pozycyjo + Ôdblokuj pozycyjo + Skopiyruj lokalizacyjo + Udostympnij lokalizacyjo + Kerōnki + Udostympniej lokalizacyjo + Pokazuj lokalizacyjo + Udostympnij + Niy idzie zaczōńć nagrowanio + Czekej… + Przizwōl %1$s na dostymp do mikrofōnu + Szukej we widōmościach + GIF + Pokoż kōnwersacyjo + Przidowek Udostympnianio Lokalizacyje + Użyj Przidowka Udostympnianio Lokalizacyje zamiast wbudowanyj karty + Skopiyruj URL + Skopiyruj adresa XMPP + Udostympnianie zbiorōw bez HTTP S3 + Bezpostrzednie wyszukowanie + Na ekranie “Zacznij kōnwersacyjo” ôtwōrz tastatura i wraź kursōr w polu wyszukowanio + Awatar kōnwersacyje + Serwer niy spiyro awatarōw kōnwersacyje + Ino posiedziciel może zmiynić awatar kōnwersacyje + Miano ôd kōntaktu + Pseudōnim + Miano + Niy trza podować miana + Miano ôd kōnferyncyje + Ta kōnferyncyjo ôstała wymazano + Niy idzie zaczōńć nagrowanio + Usuga na piyrszym planie + Ta kategoryjo powiadōmiyń je używano, coby pokazować stałe powiadōmiynie, co ôznaczo, iże %1$s funguje. + Wiadōmość Statusu + Problymy z połōnczyniym + Ta kategoryjo powiadōmiyń je używano, coby pokazować stałe powiadōmiynie, co ôznaczo, iże Conversations mo problymy z połōnczyniym. + Wiadōmości + Połōnczynia + Wiadōmości + Połōnczynia, co przichodzōm + Połōnczynia, co wychodzōm + Ciche wiadōmości + Ta kategoryjo powiadōmiyń je używano coby pokazować powiadōmiynia, co niy powodujōm żodnych klangōw. Bez tyn przikłod w czasie aktywności na inkszyj maszinie (ôkres karyncyje). + Niypodarzōne wysyłki + Sztalōnki powiadōmiyń wiadōmości + Sztalōnki powiadōmiyń dlo połōnczyń, co przichodzōm + Ważność, Klang, Wibracyjo + Kōmpresyjo wideo + Pokoż media + Uczestnicy + Przeglōndarka mediōw + Zbiōr pōminiynty skirz naruszynio bezpiyczyństwa. + Jakość wideo + Niższo jakość gwarantuje myńszo srogość + Postrzednio (360p) + Wysoko (720p) + pociepniynte + Już tworzisz nowo wiadōmość. + Funkcyjo niyzaimplymyntowano + Niynoleżny kod kraju + Ôbier kroj + numer telefōnu + Zweryfikuj swōj numer telefōnu + Quicksy wyśle SMS (mogōm być naliczane płaty) coby zweryfikować numer telefōnu. Wpisz kod ôd kraju i numer telefōnu: + Zweryfikujymy numer telefōnu

%s

Zgodzo sie wszysko, abo chcesz zmiynić numer\?
+ %s to niy ma noleżny numer telefōnu. + Wkludź swōj numer telefōnu. + Przeszukej kraje + Zweryfikuj %s + Wysłali my SMS do %s. + Wysłali my dalszy SMS z 6 cyfrowym kodym. + Wkludź 6-cyfrowy kod PIN niżyj. + Wyślij SMS zaś + Wyślij SMS zaś (%s) + Czekej (%s) + nazod + Autōmatycznie bōł wrażōny prowdopodobny PIN ze skrytki. + Wkludź 6-cyfrowy PIN. + Na zicher chcesz przerwać procedura registracyje\? + Ja + Niy + Weryfikowanie… + Żōndanie SMS… + Wkludzōny PIN je niynoleżny. + Wysłany ôd nos PIN straciōł ważność. + Niyznōmy feler necu. + Niyznōmo ôdpowiydź serwera. + Niy idzie sie połōnczyć z serwerym. + Niy idzie dostać bezpiecznego połōnczynio. + Niy szło znojś serwera. + Coś poszło źle przi przetworzaniu twojigo żōndanio. + Niynoleżny wert używocza + Tymczasowo niydostympne. Sprōbuj niyskorzij. + Brak połōnczynio z necym. + Sprōbuj zaś za %s + Limit pytań spotrzebowany + Za moc prōb + Używosz zastarzałyj wersyje aplikacyje. + Aktualizuj + Twōj numer telefōnu je aktualnie wlogowany na inkszyj maszinie. + Wkludź swoje miano, coby ludzie, co cie majōm we kōntaktach, wiedzieli, fto żeś je. + Twoje miano + Wkludź swoje miano + Użyj knefla edycyje coby nasztalować swoje miano. + Ôdciepżōndanie + Zainstaluj Orbot + Puść Orbot + Żodno marketowo aplikacyjo niy je zainstalowano. + Tyn kanał sprawi, iże twoja adresa XMPP bydzie publiczno + e-book + Ôryginalne (niyskōmpresowane) + Ôtwōrz ze pōmocōm… + Profilowy ôbrozek Conversations + Ôbier kōnto + Prziwrōć kopijo ibryczno + Prziwrōć + Wkludź swoje hasło do kōnta %s coby prziwrōcić kopijo ibryczno. + Niy używej kopije ibrycznyj, coby klōnować (puszczać rōwnolygle) instalacyjo. Prziwrocanie kopije je przeznaczōne ino do migracyje abo kedy maszina była stracōno. + Niy idzie prziwrōcić kopije ibrycznyj. + Niy idzie ôdszyfrować kopije ibrycznyj. Je hasło noleżne\? + Kopijo i Prziwrocanie + Wkludź adresa XMPP + Nowo grupowo godka + Prziwstōń do publicznego kanału + Nowo prywatno grupowo godka + Nowy publiczny kanał + Miano ôd kanału + Adresa XMPP + Podej miano ôd kanału + Podej adresa XMPP + To je adresa XMPP. Podej miano. + Tworzynie kanału publicznego… + Tyn kanał już istniyje + Przistympujesz do istniyjōncego kanału + Niy szło spamiyntać kōnfiguracyje ôd kanału + Przizwōl wszyskim na zmiana tymatu + Przizwōl wszyskim na zaproszanie inkszych + Kożdy może zmiyniać tymat. + Posiedziciele mogōm zmiyniać tymat. + Administratorzi mogōm zmiyniać tymat. + Posiedziciele mogōm zaproszać inkszych. + Kożdy może zaproszać inkszych. + Adresy XMPP widzialne dlo administratorōw. + Adresy XMPP widzialne dlo wszyskich. + Tyn publiczny kanał niy mo uczestnikōw. Zaproś swoje kōntakty abo użyj udostympnianio, coby ôpublikować adresa XMPP. + Ta prywatno grupowo godka niy mo uczestnikōw. + Regyruj uprawniyniami + Wyszukej uczestnikōw + Zbiōr je za srogi + Przidej + Ôdkryj kanały + Wyszukej kanał + Możliwe naruszynie prywatności! + Ôdkrywanie kanałōw używo usugi trzecij fiyrmy <a href=https://search.jabber.network>search.jabber.network</a>. <br><br>Użycie tyj funkcyje prześle dō nij twoja adresa IP jak tyż kryteria wyszukowanio. Wejzdrzij na <a href=https://search.jabber.network/privacy>Polityka Prywatności</a>, coby dostać wiyncyj informacyji. + Już mōm kōnto + Przidej kōnto, co juz istniyje + Zaregistruj nowe kōnto + To wyglōndo jak miano ôd dōmyny + Przidej tak by tak + To wyglōndo jak adresa ôd kanału + Udostympnij zbiory kopiji ibrycznych + Kopijo ibryczno Conversations + Zdarzynie + Ôtwōrz kopijo ibryczno + Wybrany zbiōr to niy ma zbiōr kopije ibrycznyj Conversations + To kōnto już je nasztalowane + Podej hasło dlo tego kōnta + Niy idzie wykōnać tyj akcyje + Przistōmp do publicznego kanału… + Aplikacyjo, co udostympnio, niy dała zwōle na dostymp do tego zbioru. + Grupowe godki i kanały + jabber.network + Serwer lokalny + Wiynkszość używoczōw powinna ôbrać “jabber.network” dlo lepszych dorad ze cołkigo ekosystymu XMPP. + Metoda ôdkrywanio kanałōw + Kopijo ibryczno + Ô aplikacyji + Włōncz kōnto + Zazwōń + Przichodzi połōnczynie + Przichodzi połōnczynie wideo + Łōnczynie + Połōnczōny + Łōnczynie zaś + Akceptowanie połōnczynio + Kōńczynie połōnczynio + Ôdbier + Ôdciep + Wyszukowanie maszin + Zwōniynie + Zajynte + Niy idzie wykōnać połōnczynio + Połōnczynie serwane + Połōnczynie pociepniynte + Feler aplikacyje + Problym weryfikacyje + Rozłōncz + Połōnczynie wychodzi + Połōnczynie wideo wychodzi + Łōnczynie zaś + Łōnczynie zaś + Zastow Tor coby zwōnić + Połōnczynie przichodzōnce + Połōnczynie przichodzōnce · %s + Niyôdebrane · %s + Połōnczynie wychodzōnce + Połōnczynie wychodzōnce · %s + Niyôdebrane połōnczynie + Połōnczynie audio + Połōnczynie wideo + Pōmoc + Przejdź do kōnwersacyje + Twōj mikrofōn je niydostympny + Możesz mieć ino jedno połōnczynie w jednyj chwili. + Wrōć do trwajōncego połōnczynio + Niy idzie zmiynić fotoaparatu + Przidej do ôblubiōnych + Wymaż ze ôblubiōnych + Śledzynie GPX + Niy szło skorygować wiadōmości + Wszyske kōnwersacyje + Ta kōnwersacyjo + Twōj awatar + Awatar ôd %s + Zaszyfrowane bez OMEMO + Zaszyfrowane bez OpenPGP + Niyzaszyfrowane + Zawrzij + Nagrej głosowo wiadōmość + Grej źwiynk + Spauzuj źwiynk + Przidej kōntakt, stwōrz abo przistōmp do grupowyj godki, abo ôdkrywej kanały + + Pokoż %1$d uczestnika + Pokoż %1$d uczestnikōw + Pokoż %1$d uczestnikōw + + + Wiadōmość niy mogła być dolifrowano + Wielaś wiadōmości niy mogło być dolifrowanych + Wielaś wiadōmości niy mogło być dolifrowanych + + Niypodarzōne lifrowania + Wiyncyj ôpcyjōw + Żodno aplikacyjo niyznojdziōno + Zaproś do Conversations + Niy idzie przetworzić zaproszynio + Serwer niy spiyro gynerowanio zaproszyń + Żodne aktywne kōnta niy spiyrajōm tyj funkcyje + Tworzynie kopije ibrycznyj je puszczōne. Dostaniesz powiadōmiynie, jak bydzie gotowo. + Niy idzie włōnczyć wideo. + Dokumynt ze samym tekstym + Registracyjo kōnt niy je spiyrano + Żodno adresa XMPP niyznojdziōno +
diff --git a/src/main/res/values-tr-rTR/strings.xml b/src/main/res/values-tr-rTR/strings.xml index 266255aeddf34f7d383e36d4e647ca18f86af39d..283fee4d3330fc2e0865461d318dbeaaa86fbf7e 100644 --- a/src/main/res/values-tr-rTR/strings.xml +++ b/src/main/res/values-tr-rTR/strings.xml @@ -976,5 +976,4 @@ Düz metin dosyası Hesap kayıtları desteklenmemektedir. Herhangi bir XMPP adresi bulunamadı - - + diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 6c11f159da15df282778ff2b5372395b4e1d0dfd..4878bfc42dd5feab46619279699b5d020dc03d51 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -963,5 +963,4 @@ 纯文本文档 不支持注册账户 未找到 XMPP 地址 - - + diff --git a/src/quicksy/res/values-szl/strings.xml b/src/quicksy/res/values-szl/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..d3f43555982103416b9d878c08f2063ce4dc9503 --- /dev/null +++ b/src/quicksy/res/values-szl/strings.xml @@ -0,0 +1,12 @@ + + + Czas, jak dugo Quicksy je cichy po ôboczyniu aktywności na inkszyj maszinie + Jak wysyłosz sztreki sztapla, to pōmogosz przi budowaniu Quicksy + Informuj wszyske twoje kōntakty ô tym, kedy używosz Quicksy + Żeby durch dostować powiadōmiynia, nawet jak ekran je zgaszōny, musisz dodać Quicksy do listy chrōniōnych aplikacyji. + Profilowy ôbrozek Quicksy + Quicksy niy ma dostympne we twojim kraju. + Niy idzie zweryfikować tożsamości ôd serwera. + Niyznōmy feler bezpieczyństwa. + Przekroczynie czasu przi łōnczyniu ze serwerym. + From 467e34e2feb6a13c33ea24d9a1e9345689931a8c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 14 Jun 2022 08:52:11 +0200 Subject: [PATCH 03/20] bump various libraries --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 2e1870b2f4cf545f939c3f950c2ebda4a101d755..66f433fe10f0e3321a3e90f3b1cc9dc47edd4ec5 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.2.0' + classpath 'com.android.tools.build:gradle:7.2.1' } } @@ -33,7 +33,7 @@ configurations { dependencies { implementation 'androidx.viewpager:viewpager:1.0.0' - playstoreImplementation('com.google.firebase:firebase-messaging:23.0.3') { + playstoreImplementation('com.google.firebase:firebase-messaging:23.0.5') { exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' @@ -42,7 +42,7 @@ dependencies { quicksyPlaystoreImplementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1' implementation 'org.sufficientlysecure:openpgp-api:10.0' implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0' - implementation 'androidx.appcompat:appcompat:1.4.1' + implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'androidx.exifinterface:exifinterface:1.3.3' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' @@ -74,7 +74,7 @@ dependencies { implementation "com.squareup.okhttp3:okhttp:4.9.3" implementation 'com.google.guava:guava:30.1.1-android' - quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.12.44' + quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.12.49' implementation fileTree(include: ['libwebrtc-m99.aar'], dir: 'libs') } From 17b9ca9dec1796f9b9f598b3a93cec690a6f5ab5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 Jun 2022 07:18:07 +0200 Subject: [PATCH 04/20] =?UTF-8?q?use=20item=20id=20'current'=20for=20nick?= =?UTF-8?q?=20as=20fallback=20as=20per=20XEP-0060=20=C2=A712.20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/eu/siacs/conversations/generator/IqGenerator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java index 198a2e71a2fde8ce6b39366a86c389830651a17c..2776aa4f058aef2fa4d0a292b3c6c1f452123abd 100644 --- a/src/main/java/eu/siacs/conversations/generator/IqGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/IqGenerator.java @@ -131,6 +131,7 @@ public class IqGenerator extends AbstractGenerator { public IqPacket publishNick(String nick) { final Element item = new Element("item"); + item.setAttribute("id", "current"); item.addChild("nick", Namespace.NICK).setContent(nick); return publish(Namespace.NICK, item); } From 42bd8e6d619207b46b0ecf9262020379d78a85ee Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 Jun 2022 07:56:44 +0200 Subject: [PATCH 05/20] minor code clean up --- .../java/eu/siacs/conversations/ui/ConversationsActivity.java | 4 ++-- .../conversations/xmpp/jingle/JingleConnectionManager.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java index 308e139fc3ddf4e2bc7d32fef6f4a1798931cd15..6d0a03f8b3ebb1b038e2d9c6f5a2536694cafc4e 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java @@ -145,7 +145,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio return; } xmppConnectionService.getNotificationService().setIsInForeground(true); - Intent intent = pendingViewIntent.pop(); + final Intent intent = pendingViewIntent.pop(); if (intent != null) { if (processViewIntent(intent)) { if (binding.secondaryFragment != null) { @@ -159,7 +159,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio notifyFragmentOfBackendConnected(id); } - ActivityResult activityResult = postponedActivityResult.pop(); + final ActivityResult activityResult = postponedActivityResult.pop(); if (activityResult != null) { handleActivityResult(activityResult); } diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java index 533974a0f81a10a68e7a1c481a0678bfdf9c4b7c..0f9694915fd0cab677ece1614a7e039e87b4f563 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java @@ -569,9 +569,9 @@ public class JingleConnectionManager extends AbstractConnectionManager { } } synchronized (this.rtpSessionProposals) { - for (Map.Entry entry : + for (final Map.Entry entry : this.rtpSessionProposals.entrySet()) { - RtpSessionProposal proposal = entry.getKey(); + final RtpSessionProposal proposal = entry.getKey(); if (proposal.account == contact.getAccount() && contact.getJid().asBareJid().equals(proposal.with)) { final DeviceDiscoveryState preexistingState = entry.getValue(); From d9fa535f00a7c8daeed8dc8e0b6bd93650f23fab Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 Jun 2022 08:02:59 +0200 Subject: [PATCH 06/20] pulled translations from transifex --- src/main/res/values-de/strings.xml | 16 +++++++++------- src/main/res/values-es/strings.xml | 4 +++- src/main/res/values-gl/strings.xml | 4 +++- src/main/res/values-pt-rBR/strings.xml | 4 +++- src/main/res/values-ro-rRO/strings.xml | 4 +++- src/main/res/values-zh-rCN/strings.xml | 4 +++- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index b54309ed27fb793f500ca2f9653b3c18376eef5f..44632eca09ce601ac0b96fa91a4277c822c9958c 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -401,8 +401,8 @@ XMPP-Adressen für alle sichtbar machen Channel wird moderiert Du bist kein Mitglied - Gruppenchatoptionen wurden modifiziert! - Gruppenchatoptionen konnten nicht modifiziert werden + Gruppenchatoptionen wurden geändert! + Gruppenchatoptionen konnten nicht geändert werden Niemals Bis auf Weiteres Schlummern @@ -440,7 +440,7 @@ Zertifizierungsstellen nicht vertrauen Alle Zertifikate müssen manuell bestätigt werden Zertifikate löschen - Als vertrauenswürdig bestätigte Zertifikate löschen + Manuell bestätigte Zertifikate löschen Keine manuell bestätigten Zertifikate Zertifikate löschen Auswahl löschen @@ -481,13 +481,13 @@ Hostname- und Port-Optionen bei Kontoeinrichtung anzeigen xmpp.domain.de Mit Zertifikat anmelden - Zertifikat konnte nicht ausgewertet werden + Zertifikat konnte nicht verarbeitet werden Archivierungseinstellungen Archivierungseinstellungen des Servers Archivierungseinstellungen werden abgerufen. Bitte warten… Archivierungseinstellungen konnten nicht abgerufen werden CAPTCHA erforderlich - Gib den Text von obigem Bild ein + Gib den Text aus dem Bild oben ein Nicht vertrauenswürdige Zertifikatskette XMPP-Adresse stimmt nicht dem Zertifikat überein Zertifikat erneuern @@ -968,7 +968,7 @@ Weitere Optionen Keine Anwendung gefunden Einladung zu Conversations - Einladung kann nicht gelesen werden + Einladung kann nicht verarbeitet werden Server unterstützt keine Generierung von Einladungen Keine aktiven Konten unterstützen diese Funktion Die Sicherung wurde gestartet. Du bekommst eine Benachrichtigung, sobald sie fertig ist. @@ -976,4 +976,6 @@ Textdokument Kontoregistrierungen werden nicht unterstützt Keine XMPP-Adresse gefunden - + Temporärer Authentifizierungsfehler + + diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index d2c5b8afd7ac1d3de9a1aa3f058c0e4afcd38770..202d70fc7b3dc323a44e05fe98a238cf6caec79f 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -989,4 +989,6 @@ Documento de texto plano Los registros de cuenta no están soportados Dirección XMPP no encontrada - + Fallo temporal de autenticación + + diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 76b0f937a5031d34fc21b38736021eea0f631b77..338ff69b8d8e516a312992aefb19d19982c158a3 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -976,4 +976,6 @@ Documento de texto plano Non está permitido o rexistro de novas contas Non se atopa un enderezo XMPP - + Fallo temporal da autenticación + + diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml index 9bcf1aaeae49fc3270a10e14891f18e2e489427c..57fe94c67e043eacd0d598d222486b7e6715cf16 100644 --- a/src/main/res/values-pt-rBR/strings.xml +++ b/src/main/res/values-pt-rBR/strings.xml @@ -989,4 +989,6 @@ Documento em texto puro O registro de contas não está ativo Não foi encontrado nenhum endereço XMPP - + Falha temporária na autenticação + + diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index a57f9d0ebf55536ca4471cd876cd0d7747740dd3..c0c15cb4abbe4b575fbb88499d9fd52a15d68d47 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -989,4 +989,6 @@ Document text Nu este posibilă înregistrarea unui cont Nu a fost găsită o adresă XMPP - + Eroare temporară de autentificare + + diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 4878bfc42dd5feab46619279699b5d020dc03d51..be4aa4face764a0e86f050991d20d9eeffa6b333 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -963,4 +963,6 @@ 纯文本文档 不支持注册账户 未找到 XMPP 地址 - + 临时认证失败 + + From 84e08933f91844a58c7d85c319ecf401cb43889e Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Mon, 27 Jun 2022 13:34:26 -0500 Subject: [PATCH 07/20] A Quicky user can be a stranger At some point a refactor changed this check from checking that the quicksy domain itself is talking to you, to checking that anyone using quicksy is talking to you, which breaks the notifications from strangers setting for quicksy users. --- src/main/java/eu/siacs/conversations/entities/Conversation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index aeba1f14c7f4418d6123643f14f9e986435c3d6b..4a825fbb38b5b5cfe08507dafdd068f636b0d985 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -1076,7 +1076,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl && !contact.isOwnServer() && !contact.showInContactList() && !contact.isSelf() - && !JidHelper.isQuicksyDomain(contact.getJid()) + && !(contact.getJid().isDomainJid() && JidHelper.isQuicksyDomain(contact.getJid())) && sentMessagesCount() == 0; } From 206b09919bb71115097d072f3f0caa6c7f3d85b7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 1 Jul 2022 13:07:34 +0200 Subject: [PATCH 08/20] bump dependencies --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 66f433fe10f0e3321a3e90f3b1cc9dc47edd4ec5..ad5a88b9c563cf05782d8e401cce0ebfa19773d3 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ configurations { dependencies { implementation 'androidx.viewpager:viewpager:1.0.0' - playstoreImplementation('com.google.firebase:firebase-messaging:23.0.5') { + playstoreImplementation('com.google.firebase:firebase-messaging:23.0.6') { exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' From 65daeff1125a6d475dabb45f9a993dfee9fc41fd Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 1 Jul 2022 15:53:24 +0200 Subject: [PATCH 09/20] pulled translations from transifex --- src/main/res/values-de/strings.xml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 44632eca09ce601ac0b96fa91a4277c822c9958c..8372ff2dc4f36c3839865cc77f651add94eaadf6 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -178,7 +178,7 @@ OMEMO Konto löschen Vorübergehend abschalten - Avatar veröffentlichen + Profilbild veröffentlichen Öffentlichen OpenPGP-Schlüssel veröffentlichen Öffentlichen OpenPGP-Schlüssel verwerfen Bist du sicher, dass du deinen öffentlichen OpenPGP-Schlüssel aus deiner Anwesenheitsmitteilung entfernen möchtest?\nDeine Kontakte können dir dann keine OpenPGP-verschlüsselten Nachrichten senden. @@ -250,7 +250,7 @@ Channel konnte nicht gelöscht werden Gruppenchatthema bearbeiten Thema - Gruppenchat wird beigetreten… + Gruppenchat beigetreten… Verlassen Kontakt hat dich zur Kontaktliste hinzugefügt Auch hinzufügen @@ -259,13 +259,13 @@ %1$s +%2$d andere haben bis zu diesem Punkt gelesen Alle haben bis zu diesem Punkt gelesen Veröffentlichen - Avatar antippen, um ein Bild aus der Galerie auszuwählen + Profilbild antippen, um ein Bild aus der Galerie auszuwählen Veröffentliche… Der Server hat die Veröffentlichung des Avatars abgelehnt. Bild konnte nicht konvertiert werden - Avatar kann nicht gespeichert werden + Profilbild kann nicht gespeichert werden (Oder klicke lange, um den Standard wiederherzustellen) - Dein Server unterstützt die Veröffentlichung von Avataren nicht + Dein Server unterstützt die Veröffentlichung von Profilbildern nicht private Nachricht: an %s Private Nachricht an %s senden @@ -356,7 +356,7 @@ Benachrichtigungen aktivieren Keinen Gruppenchatserver gefunden Gruppenchat konnte nicht erstellt werden - Konto-Avatar + Konto-Profilbild OMEMO-Fingerabdruck in Zwischenablage kopieren OMEMO-Schlüssel erneuern Geräte entfernen @@ -420,7 +420,7 @@ PDF-Dokument Android App Kontakt - Avatar wurde veröffentlicht! + Profilbild wurde veröffentlicht! %s wird gesendet %s wird angeboten Offline verstecken @@ -477,7 +477,7 @@ Als Beschäftigt anzeigen, wenn sich das Gerät im lautlosen Modus befindet Vibration als Lautlos behandeln Als Beschäftigt anzeigen, wenn das Gerät auf Vibration eingestellt ist - Erweiterte Verbindungsoptionen + Erweiterte Verbindungseinstellungen Hostname- und Port-Optionen bei Kontoeinrichtung anzeigen xmpp.domain.de Mit Zertifikat anmelden @@ -515,7 +515,7 @@ %1$s den Zugriff auf den externen Speicher gewähren %1$s den Zugriff auf die Kamera gewähren Mit Kontakten synchronisieren - %1$s möchte die Erlaubnis, auf deine Kontakte zuzugreifen, um sie mit deiner XMPP-Kontaktliste abzugleichen.\nDadurch werden die vollständigen Namen und Avatare deiner Kontakte angezeigt.\n\n%1$s liest nur dein Adressbuch und gleicht es lokal ab, ohne dass etwas auf deinen Server hochgeladen wird. + %1$s möchte die Erlaubnis, auf deine Kontakte zuzugreifen, um sie mit deiner XMPP-Kontaktliste abzugleichen.\nDadurch werden die vollständigen Namen und Profilbilder deiner Kontakte angezeigt.\n\n%1$s liest nur dein Adressbuch und gleicht es lokal ab, ohne dass etwas auf deinen Server hochgeladen wird.
Wir werden keine Kopie dieser Telefonnummern speichern.\n\nFür weitere Informationen lies unsere Datenschutzerklärung.

Du wirst nun gefragt, ob du den Zugriff auf deine Kontakte erlauben möchtest.]]>
Bei allen Nachrichten benachrichtigen Nur benachrichtigen, wenn ich erwähnt werde @@ -595,7 +595,7 @@ OMEMO-Identitäten zurücksetzen Erzeuge neue OMEMO-Schlüssel. Alle deine Kontakte müssen sie erneut verifizieren. Verwende dies nur als letztes Mittel. Ausgewählte Schlüssel löschen - Du musst verbunden sein, um deinen Avatar zu veröffentlichen. + Du musst verbunden sein, um deinen Profilbild zu veröffentlichen. Zeige Fehlermeldung Fehlermeldung Datensparmodus aktiv @@ -745,9 +745,9 @@ HTTP-Dateifreigabe für S3 Direkte Suche Beim Dialog \'Unterhaltung beginnen\' Tastatur öffnen und den Cursor im Suchfeld platzieren - Gruppenchat-Avatar - Host unterstützt keine Gruppenchat-Avatare - Nur der Eigentümer kann den Gruppenchat-Avatar ändern + Gruppenchat-Profilbild + Host unterstützt keine Gruppenchat-Profilbilder + Nur der Eigentümer kann das Gruppenchat-Profilbild ändern Kontaktname Nickname Name @@ -946,8 +946,8 @@ Nachricht konnte nicht korrigiert werden Alle Unterhaltungen Diese Unterhaltung - Dein Avatar - Avatar für %s + Dein Profilbild + Profilbild für %s Verschlüsselt mit OMEMO Verschlüsselt mit OpenPGP Nicht verschlüsselt From 73c7d76bd6f729ac851747f545eca0efe80c3983 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 1 Jul 2022 15:53:36 +0200 Subject: [PATCH 10/20] add local only flag to foreground service --- .../services/NotificationService.java | 764 ++++++++++++------ 1 file changed, 529 insertions(+), 235 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index ca4499300ac6df8d7772211b74d8ef6649ea297d..abe6e9e11370833989844dd90bb23953c95c9e46 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -79,7 +79,8 @@ import eu.siacs.conversations.xmpp.jingle.Media; public class NotificationService { - private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = Executors.newSingleThreadScheduledExecutor(); + private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = + Executors.newSingleThreadScheduledExecutor(); public static final Object CATCHUP_LOCK = new Object(); @@ -137,7 +138,8 @@ public class NotificationService { @RequiresApi(api = Build.VERSION_CODES.O) void initializeChannels() { final Context c = mXmppConnectionService; - final NotificationManager notificationManager = c.getSystemService(NotificationManager.class); + final NotificationManager notificationManager = + c.getSystemService(NotificationManager.class); if (notificationManager == null) { return; } @@ -145,41 +147,60 @@ public class NotificationService { notificationManager.deleteNotificationChannel("export"); notificationManager.deleteNotificationChannel("incoming_calls"); - notificationManager.createNotificationChannelGroup(new NotificationChannelGroup("status", c.getString(R.string.notification_group_status_information))); - notificationManager.createNotificationChannelGroup(new NotificationChannelGroup("chats", c.getString(R.string.notification_group_messages))); - notificationManager.createNotificationChannelGroup(new NotificationChannelGroup("calls", c.getString(R.string.notification_group_calls))); - final NotificationChannel foregroundServiceChannel = new NotificationChannel("foreground", - c.getString(R.string.foreground_service_channel_name), - NotificationManager.IMPORTANCE_MIN); - foregroundServiceChannel.setDescription(c.getString(R.string.foreground_service_channel_description, c.getString(R.string.app_name))); + notificationManager.createNotificationChannelGroup( + new NotificationChannelGroup( + "status", c.getString(R.string.notification_group_status_information))); + notificationManager.createNotificationChannelGroup( + new NotificationChannelGroup( + "chats", c.getString(R.string.notification_group_messages))); + notificationManager.createNotificationChannelGroup( + new NotificationChannelGroup( + "calls", c.getString(R.string.notification_group_calls))); + final NotificationChannel foregroundServiceChannel = + new NotificationChannel( + "foreground", + c.getString(R.string.foreground_service_channel_name), + NotificationManager.IMPORTANCE_MIN); + foregroundServiceChannel.setDescription( + c.getString( + R.string.foreground_service_channel_description, + c.getString(R.string.app_name))); foregroundServiceChannel.setShowBadge(false); foregroundServiceChannel.setGroup("status"); notificationManager.createNotificationChannel(foregroundServiceChannel); - final NotificationChannel errorChannel = new NotificationChannel("error", - c.getString(R.string.error_channel_name), - NotificationManager.IMPORTANCE_LOW); + final NotificationChannel errorChannel = + new NotificationChannel( + "error", + c.getString(R.string.error_channel_name), + NotificationManager.IMPORTANCE_LOW); errorChannel.setDescription(c.getString(R.string.error_channel_description)); errorChannel.setShowBadge(false); errorChannel.setGroup("status"); notificationManager.createNotificationChannel(errorChannel); - final NotificationChannel videoCompressionChannel = new NotificationChannel("compression", - c.getString(R.string.video_compression_channel_name), - NotificationManager.IMPORTANCE_LOW); + final NotificationChannel videoCompressionChannel = + new NotificationChannel( + "compression", + c.getString(R.string.video_compression_channel_name), + NotificationManager.IMPORTANCE_LOW); videoCompressionChannel.setShowBadge(false); videoCompressionChannel.setGroup("status"); notificationManager.createNotificationChannel(videoCompressionChannel); - final NotificationChannel exportChannel = new NotificationChannel("backup", - c.getString(R.string.backup_channel_name), - NotificationManager.IMPORTANCE_LOW); + final NotificationChannel exportChannel = + new NotificationChannel( + "backup", + c.getString(R.string.backup_channel_name), + NotificationManager.IMPORTANCE_LOW); exportChannel.setShowBadge(false); exportChannel.setGroup("status"); notificationManager.createNotificationChannel(exportChannel); - final NotificationChannel incomingCallsChannel = new NotificationChannel(INCOMING_CALLS_NOTIFICATION_CHANNEL, - c.getString(R.string.incoming_calls_channel_name), - NotificationManager.IMPORTANCE_HIGH); + final NotificationChannel incomingCallsChannel = + new NotificationChannel( + INCOMING_CALLS_NOTIFICATION_CHANNEL, + c.getString(R.string.incoming_calls_channel_name), + NotificationManager.IMPORTANCE_HIGH); incomingCallsChannel.setSound(null, null); incomingCallsChannel.setShowBadge(false); incomingCallsChannel.setLightColor(LED_COLOR); @@ -189,22 +210,27 @@ public class NotificationService { incomingCallsChannel.enableVibration(false); notificationManager.createNotificationChannel(incomingCallsChannel); - final NotificationChannel ongoingCallsChannel = new NotificationChannel("ongoing_calls", - c.getString(R.string.ongoing_calls_channel_name), - NotificationManager.IMPORTANCE_LOW); + final NotificationChannel ongoingCallsChannel = + new NotificationChannel( + "ongoing_calls", + c.getString(R.string.ongoing_calls_channel_name), + NotificationManager.IMPORTANCE_LOW); ongoingCallsChannel.setShowBadge(false); ongoingCallsChannel.setGroup("calls"); notificationManager.createNotificationChannel(ongoingCallsChannel); - - final NotificationChannel messagesChannel = new NotificationChannel("messages", - c.getString(R.string.messages_channel_name), - NotificationManager.IMPORTANCE_HIGH); + final NotificationChannel messagesChannel = + new NotificationChannel( + "messages", + c.getString(R.string.messages_channel_name), + NotificationManager.IMPORTANCE_HIGH); messagesChannel.setShowBadge(true); - messagesChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), new AudioAttributes.Builder() - .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) - .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT) - .build()); + messagesChannel.setSound( + RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), + new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT) + .build()); messagesChannel.setLightColor(LED_COLOR); final int dat = 70; final long[] pattern = {0, 3 * dat, dat, dat}; @@ -213,19 +239,24 @@ public class NotificationService { messagesChannel.enableLights(true); messagesChannel.setGroup("chats"); notificationManager.createNotificationChannel(messagesChannel); - final NotificationChannel silentMessagesChannel = new NotificationChannel("silent_messages", - c.getString(R.string.silent_messages_channel_name), - NotificationManager.IMPORTANCE_LOW); - silentMessagesChannel.setDescription(c.getString(R.string.silent_messages_channel_description)); + final NotificationChannel silentMessagesChannel = + new NotificationChannel( + "silent_messages", + c.getString(R.string.silent_messages_channel_name), + NotificationManager.IMPORTANCE_LOW); + silentMessagesChannel.setDescription( + c.getString(R.string.silent_messages_channel_description)); silentMessagesChannel.setShowBadge(true); silentMessagesChannel.setLightColor(LED_COLOR); silentMessagesChannel.enableLights(true); silentMessagesChannel.setGroup("chats"); notificationManager.createNotificationChannel(silentMessagesChannel); - final NotificationChannel quietHoursChannel = new NotificationChannel("quiet_hours", - c.getString(R.string.title_pref_quiet_hours), - NotificationManager.IMPORTANCE_LOW); + final NotificationChannel quietHoursChannel = + new NotificationChannel( + "quiet_hours", + c.getString(R.string.title_pref_quiet_hours), + NotificationManager.IMPORTANCE_LOW); quietHoursChannel.setShowBadge(true); quietHoursChannel.setLightColor(LED_COLOR); quietHoursChannel.enableLights(true); @@ -235,14 +266,18 @@ public class NotificationService { notificationManager.createNotificationChannel(quietHoursChannel); - final NotificationChannel deliveryFailedChannel = new NotificationChannel("delivery_failed", - c.getString(R.string.delivery_failed_channel_name), - NotificationManager.IMPORTANCE_DEFAULT); + final NotificationChannel deliveryFailedChannel = + new NotificationChannel( + "delivery_failed", + c.getString(R.string.delivery_failed_channel_name), + NotificationManager.IMPORTANCE_DEFAULT); deliveryFailedChannel.setShowBadge(false); - deliveryFailedChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), new AudioAttributes.Builder() - .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) - .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT) - .build()); + deliveryFailedChannel.setSound( + RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), + new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT) + .build()); deliveryFailedChannel.setGroup("chats"); notificationManager.createNotificationChannel(deliveryFailedChannel); } @@ -256,16 +291,23 @@ public class NotificationService { } public boolean notificationsFromStrangers() { - return mXmppConnectionService.getBooleanPreference("notifications_from_strangers", R.bool.notifications_from_strangers); + return mXmppConnectionService.getBooleanPreference( + "notifications_from_strangers", R.bool.notifications_from_strangers); } private boolean isQuietHours() { - if (!mXmppConnectionService.getBooleanPreference("enable_quiet_hours", R.bool.enable_quiet_hours)) { + if (!mXmppConnectionService.getBooleanPreference( + "enable_quiet_hours", R.bool.enable_quiet_hours)) { return false; } - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService); - final long startTime = TimePreference.minutesToTimestamp(preferences.getLong("quiet_hours_start", TimePreference.DEFAULT_VALUE)); - final long endTime = TimePreference.minutesToTimestamp(preferences.getLong("quiet_hours_end", TimePreference.DEFAULT_VALUE)); + final SharedPreferences preferences = + PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService); + final long startTime = + TimePreference.minutesToTimestamp( + preferences.getLong("quiet_hours_start", TimePreference.DEFAULT_VALUE)); + final long endTime = + TimePreference.minutesToTimestamp( + preferences.getLong("quiet_hours_end", TimePreference.DEFAULT_VALUE)); final long nowTime = Calendar.getInstance().getTimeInMillis(); if (endTime < startTime) { @@ -278,7 +320,8 @@ public class NotificationService { public void pushFromBacklog(final Message message) { if (notify(message)) { synchronized (notifications) { - getBacklogMessageCounter((Conversation) message.getConversation()).incrementAndGet(); + getBacklogMessageCounter((Conversation) message.getConversation()) + .incrementAndGet(); pushToStack(message); } } @@ -329,7 +372,9 @@ public class NotificationService { private int getBacklogMessageCount(Account account) { int count = 0; - for (Iterator> it = mBacklogMessageCounter.entrySet().iterator(); it.hasNext(); ) { + for (Iterator> it = + mBacklogMessageCounter.entrySet().iterator(); + it.hasNext(); ) { Map.Entry entry = it.next(); if (entry.getKey().getAccount() == account) { count += entry.getValue().get(); @@ -357,7 +402,8 @@ public class NotificationService { public void push(final Message message) { synchronized (CATCHUP_LOCK) { - final XmppConnection connection = message.getConversation().getAccount().getXmppConnection(); + final XmppConnection connection = + message.getConversation().getAccount().getXmppConnection(); if (connection != null && connection.isWaitingForSmCatchup()) { connection.incrementSmCatchupMessageCounter(); pushFromBacklog(message); @@ -370,25 +416,43 @@ public class NotificationService { public void pushFailedDelivery(final Message message) { final Conversation conversation = (Conversation) message.getConversation(); final boolean isScreenLocked = !mXmppConnectionService.isScreenLocked(); - if (this.mIsInForeground && isScreenLocked && this.mOpenConversation == message.getConversation()) { - Log.d(Config.LOGTAG, message.getConversation().getAccount().getJid().asBareJid() + ": suppressing failed delivery notification because conversation is open"); + if (this.mIsInForeground + && isScreenLocked + && this.mOpenConversation == message.getConversation()) { + Log.d( + Config.LOGTAG, + message.getConversation().getAccount().getJid().asBareJid() + + ": suppressing failed delivery notification because conversation is open"); return; } final PendingIntent pendingIntent = createContentIntent(conversation); - final int notificationId = generateRequestCode(conversation, 0) + DELIVERY_FAILED_NOTIFICATION_ID; + final int notificationId = + generateRequestCode(conversation, 0) + DELIVERY_FAILED_NOTIFICATION_ID; final int failedDeliveries = conversation.countFailedDeliveries(); final Notification notification = new Builder(mXmppConnectionService, "delivery_failed") .setContentTitle(conversation.getName()) .setAutoCancel(true) .setSmallIcon(R.drawable.ic_error_white_24dp) - .setContentText(mXmppConnectionService.getResources().getQuantityText(R.plurals.some_messages_could_not_be_delivered, failedDeliveries)) + .setContentText( + mXmppConnectionService + .getResources() + .getQuantityText( + R.plurals.some_messages_could_not_be_delivered, + failedDeliveries)) .setGroup("delivery_failed") - .setContentIntent(pendingIntent).build(); + .setContentIntent(pendingIntent) + .build(); final Notification summaryNotification = new Builder(mXmppConnectionService, "delivery_failed") - .setContentTitle(mXmppConnectionService.getString(R.string.failed_deliveries)) - .setContentText(mXmppConnectionService.getResources().getQuantityText(R.plurals.some_messages_could_not_be_delivered, 1024)) + .setContentTitle( + mXmppConnectionService.getString(R.string.failed_deliveries)) + .setContentText( + mXmppConnectionService + .getResources() + .getQuantityText( + R.plurals.some_messages_could_not_be_delivered, + 1024)) .setSmallIcon(R.drawable.ic_error_white_24dp) .setGroup("delivery_failed") .setGroupSummary(true) @@ -398,32 +462,38 @@ public class NotificationService { notify(DELIVERY_FAILED_NOTIFICATION_ID, summaryNotification); } - public synchronized void startRinging(final AbstractJingleConnection.Id id, final Set media) { + public synchronized void startRinging( + final AbstractJingleConnection.Id id, final Set media) { showIncomingCallNotification(id, media); - final NotificationManager notificationManager = (NotificationManager) mXmppConnectionService.getSystemService(Context.NOTIFICATION_SERVICE); + final NotificationManager notificationManager = + (NotificationManager) + mXmppConnectionService.getSystemService(Context.NOTIFICATION_SERVICE); final int currentInterruptionFilter; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && notificationManager != null) { currentInterruptionFilter = notificationManager.getCurrentInterruptionFilter(); } else { - currentInterruptionFilter = 1; //INTERRUPTION_FILTER_ALL + currentInterruptionFilter = 1; // INTERRUPTION_FILTER_ALL } if (currentInterruptionFilter != 1) { - Log.d(Config.LOGTAG, "do not ring or vibrate because interruption filter has been set to " + currentInterruptionFilter); + Log.d( + Config.LOGTAG, + "do not ring or vibrate because interruption filter has been set to " + + currentInterruptionFilter); return; } final ScheduledFuture currentVibrationFuture = this.vibrationFuture; - this.vibrationFuture = SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate( - new VibrationRunnable(), - 0, - 3, - TimeUnit.SECONDS - ); + this.vibrationFuture = + SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate( + new VibrationRunnable(), 0, 3, TimeUnit.SECONDS); if (currentVibrationFuture != null) { currentVibrationFuture.cancel(true); } - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService); + final SharedPreferences preferences = + PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService); final Resources resources = mXmppConnectionService.getResources(); - final String ringtonePreference = preferences.getString("call_ringtone", resources.getString(R.string.incoming_call_ringtone)); + final String ringtonePreference = + preferences.getString( + "call_ringtone", resources.getString(R.string.incoming_call_ringtone)); if (Strings.isNullOrEmpty(ringtonePreference)) { Log.d(Config.LOGTAG, "ringtone has been set to none"); return; @@ -440,26 +510,34 @@ public class NotificationService { this.currentlyPlayingRingtone.play(); } - private void showIncomingCallNotification(final AbstractJingleConnection.Id id, final Set media) { - final Intent fullScreenIntent = new Intent(mXmppConnectionService, RtpSessionActivity.class); - fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, id.account.getJid().asBareJid().toEscapedString()); + private void showIncomingCallNotification( + final AbstractJingleConnection.Id id, final Set media) { + final Intent fullScreenIntent = + new Intent(mXmppConnectionService, RtpSessionActivity.class); + fullScreenIntent.putExtra( + RtpSessionActivity.EXTRA_ACCOUNT, + id.account.getJid().asBareJid().toEscapedString()); fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_WITH, id.with.toEscapedString()); fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, id.sessionId); fullScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); fullScreenIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - final NotificationCompat.Builder builder = new NotificationCompat.Builder(mXmppConnectionService, INCOMING_CALLS_NOTIFICATION_CHANNEL); + final NotificationCompat.Builder builder = + new NotificationCompat.Builder( + mXmppConnectionService, INCOMING_CALLS_NOTIFICATION_CHANNEL); if (media.contains(Media.VIDEO)) { builder.setSmallIcon(R.drawable.ic_videocam_white_24dp); - builder.setContentTitle(mXmppConnectionService.getString(R.string.rtp_state_incoming_video_call)); + builder.setContentTitle( + mXmppConnectionService.getString(R.string.rtp_state_incoming_video_call)); } else { builder.setSmallIcon(R.drawable.ic_call_white_24dp); - builder.setContentTitle(mXmppConnectionService.getString(R.string.rtp_state_incoming_call)); + builder.setContentTitle( + mXmppConnectionService.getString(R.string.rtp_state_incoming_call)); } final Contact contact = id.getContact(); - builder.setLargeIcon(mXmppConnectionService.getAvatarService().get( - contact, - AvatarService.getSystemUiAvatarSize(mXmppConnectionService)) - ); + builder.setLargeIcon( + mXmppConnectionService + .getAvatarService() + .get(contact, AvatarService.getSystemUiAvatarSize(mXmppConnectionService))); final Uri systemAccount = contact.getSystemAccount(); if (systemAccount != null) { builder.addPerson(systemAccount.toString()); @@ -470,38 +548,49 @@ public class NotificationService { builder.setCategory(NotificationCompat.CATEGORY_CALL); PendingIntent pendingIntent = createPendingRtpSession(id, Intent.ACTION_VIEW, 101); builder.setFullScreenIntent(pendingIntent, true); - builder.setContentIntent(pendingIntent); //old androids need this? + builder.setContentIntent(pendingIntent); // old androids need this? builder.setOngoing(true); - builder.addAction(new NotificationCompat.Action.Builder( - R.drawable.ic_call_end_white_48dp, - mXmppConnectionService.getString(R.string.dismiss_call), - createCallAction(id.sessionId, XmppConnectionService.ACTION_DISMISS_CALL, 102)) - .build()); - builder.addAction(new NotificationCompat.Action.Builder( - R.drawable.ic_call_white_24dp, - mXmppConnectionService.getString(R.string.answer_call), - createPendingRtpSession(id, RtpSessionActivity.ACTION_ACCEPT_CALL, 103)) - .build()); + builder.addAction( + new NotificationCompat.Action.Builder( + R.drawable.ic_call_end_white_48dp, + mXmppConnectionService.getString(R.string.dismiss_call), + createCallAction( + id.sessionId, + XmppConnectionService.ACTION_DISMISS_CALL, + 102)) + .build()); + builder.addAction( + new NotificationCompat.Action.Builder( + R.drawable.ic_call_white_24dp, + mXmppConnectionService.getString(R.string.answer_call), + createPendingRtpSession( + id, RtpSessionActivity.ACTION_ACCEPT_CALL, 103)) + .build()); modifyIncomingCall(builder); final Notification notification = builder.build(); notification.flags = notification.flags | Notification.FLAG_INSISTENT; notify(INCOMING_CALL_NOTIFICATION_ID, notification); } - public Notification getOngoingCallNotification(final XmppConnectionService.OngoingCall ongoingCall) { + public Notification getOngoingCallNotification( + final XmppConnectionService.OngoingCall ongoingCall) { final AbstractJingleConnection.Id id = ongoingCall.id; - final NotificationCompat.Builder builder = new NotificationCompat.Builder(mXmppConnectionService, "ongoing_calls"); + final NotificationCompat.Builder builder = + new NotificationCompat.Builder(mXmppConnectionService, "ongoing_calls"); if (ongoingCall.media.contains(Media.VIDEO)) { builder.setSmallIcon(R.drawable.ic_videocam_white_24dp); if (ongoingCall.reconnecting) { - builder.setContentTitle(mXmppConnectionService.getString(R.string.reconnecting_video_call)); + builder.setContentTitle( + mXmppConnectionService.getString(R.string.reconnecting_video_call)); } else { - builder.setContentTitle(mXmppConnectionService.getString(R.string.ongoing_video_call)); + builder.setContentTitle( + mXmppConnectionService.getString(R.string.ongoing_video_call)); } } else { builder.setSmallIcon(R.drawable.ic_call_white_24dp); if (ongoingCall.reconnecting) { - builder.setContentTitle(mXmppConnectionService.getString(R.string.reconnecting_call)); + builder.setContentTitle( + mXmppConnectionService.getString(R.string.reconnecting_call)); } else { builder.setContentTitle(mXmppConnectionService.getString(R.string.ongoing_call)); } @@ -512,21 +601,31 @@ public class NotificationService { builder.setCategory(NotificationCompat.CATEGORY_CALL); builder.setContentIntent(createPendingRtpSession(id, Intent.ACTION_VIEW, 101)); builder.setOngoing(true); - builder.addAction(new NotificationCompat.Action.Builder( - R.drawable.ic_call_end_white_48dp, - mXmppConnectionService.getString(R.string.hang_up), - createCallAction(id.sessionId, XmppConnectionService.ACTION_END_CALL, 104)) - .build()); + builder.addAction( + new NotificationCompat.Action.Builder( + R.drawable.ic_call_end_white_48dp, + mXmppConnectionService.getString(R.string.hang_up), + createCallAction( + id.sessionId, XmppConnectionService.ACTION_END_CALL, 104)) + .build()); return builder.build(); } - private PendingIntent createPendingRtpSession(final AbstractJingleConnection.Id id, final String action, final int requestCode) { - final Intent fullScreenIntent = new Intent(mXmppConnectionService, RtpSessionActivity.class); + private PendingIntent createPendingRtpSession( + final AbstractJingleConnection.Id id, final String action, final int requestCode) { + final Intent fullScreenIntent = + new Intent(mXmppConnectionService, RtpSessionActivity.class); fullScreenIntent.setAction(action); - fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, id.account.getJid().asBareJid().toEscapedString()); + fullScreenIntent.putExtra( + RtpSessionActivity.EXTRA_ACCOUNT, + id.account.getJid().asBareJid().toEscapedString()); fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_WITH, id.with.toEscapedString()); fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, id.sessionId); - return PendingIntent.getActivity(mXmppConnectionService, requestCode, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT); + return PendingIntent.getActivity( + mXmppConnectionService, + requestCode, + fullScreenIntent, + PendingIntent.FLAG_UPDATE_CURRENT); } public void cancelIncomingCallNotification() { @@ -552,7 +651,8 @@ public class NotificationService { } public static void cancelIncomingCallNotification(final Context context) { - final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); + final NotificationManagerCompat notificationManager = + NotificationManagerCompat.from(context); try { notificationManager.cancel(INCOMING_CALL_NOTIFICATION_ID); } catch (RuntimeException e) { @@ -563,21 +663,30 @@ public class NotificationService { private void pushNow(final Message message) { mXmppConnectionService.updateUnreadCountBadge(); if (!notify(message)) { - Log.d(Config.LOGTAG, message.getConversation().getAccount().getJid().asBareJid() + ": suppressing notification because turned off"); + Log.d( + Config.LOGTAG, + message.getConversation().getAccount().getJid().asBareJid() + + ": suppressing notification because turned off"); return; } final boolean isScreenLocked = mXmppConnectionService.isScreenLocked(); - if (this.mIsInForeground && !isScreenLocked && this.mOpenConversation == message.getConversation()) { - Log.d(Config.LOGTAG, message.getConversation().getAccount().getJid().asBareJid() + ": suppressing notification because conversation is open"); + if (this.mIsInForeground + && !isScreenLocked + && this.mOpenConversation == message.getConversation()) { + Log.d( + Config.LOGTAG, + message.getConversation().getAccount().getJid().asBareJid() + + ": suppressing notification because conversation is open"); return; } synchronized (notifications) { pushToStack(message); final Conversational conversation = message.getConversation(); final Account account = conversation.getAccount(); - final boolean doNotify = (!(this.mIsInForeground && this.mOpenConversation == null) || isScreenLocked) - && !account.inGracePeriod() - && !this.inMiniGracePeriod(account); + final boolean doNotify = + (!(this.mIsInForeground && this.mOpenConversation == null) || isScreenLocked) + && !account.inGracePeriod() + && !this.inMiniGracePeriod(account); updateNotification(doNotify, Collections.singletonList(conversation.getUuid())); } } @@ -638,13 +747,19 @@ public class NotificationService { updateNotification(notify, conversations, false); } - private void updateNotification(final boolean notify, final List conversations, final boolean summaryOnly) { - final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService); + private void updateNotification( + final boolean notify, final List conversations, final boolean summaryOnly) { + final SharedPreferences preferences = + PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService); final boolean quiteHours = isQuietHours(); - final boolean notifyOnlyOneChild = notify && conversations != null && conversations.size() == 1; //if this check is changed to > 0 catchup messages will create one notification per conversation - + final boolean notifyOnlyOneChild = + notify + && conversations != null + && conversations.size() + == 1; // if this check is changed to > 0 catchup messages will + // create one notification per conversation if (notifications.size() == 0) { cancel(NOTIFICATION_ID); @@ -654,7 +769,9 @@ public class NotificationService { } final Builder mBuilder; if (notifications.size() == 1 && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - mBuilder = buildSingleConversations(notifications.values().iterator().next(), notify, quiteHours); + mBuilder = + buildSingleConversations( + notifications.values().iterator().next(), notify, quiteHours); modifyForSoundVibrationAndLight(mBuilder, notify, quiteHours, preferences); notify(NOTIFICATION_ID, mBuilder.build()); } else { @@ -666,12 +783,16 @@ public class NotificationService { if (!summaryOnly) { for (Map.Entry> entry : notifications.entrySet()) { String uuid = entry.getKey(); - final boolean notifyThis = notifyOnlyOneChild ? conversations.contains(uuid) : notify; - Builder singleBuilder = buildSingleConversations(entry.getValue(), notifyThis, quiteHours); + final boolean notifyThis = + notifyOnlyOneChild ? conversations.contains(uuid) : notify; + Builder singleBuilder = + buildSingleConversations(entry.getValue(), notifyThis, quiteHours); if (!notifyOnlyOneChild) { - singleBuilder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY); + singleBuilder.setGroupAlertBehavior( + NotificationCompat.GROUP_ALERT_SUMMARY); } - modifyForSoundVibrationAndLight(singleBuilder, notifyThis, quiteHours, preferences); + modifyForSoundVibrationAndLight( + singleBuilder, notifyThis, quiteHours, preferences); singleBuilder.setGroup(CONVERSATIONS_GROUP); setNotificationColor(singleBuilder); notify(entry.getKey(), NOTIFICATION_ID, singleBuilder.build()); @@ -682,19 +803,28 @@ public class NotificationService { } } - private void modifyForSoundVibrationAndLight(Builder mBuilder, boolean notify, boolean quietHours, SharedPreferences preferences) { + private void modifyForSoundVibrationAndLight( + Builder mBuilder, boolean notify, boolean quietHours, SharedPreferences preferences) { final Resources resources = mXmppConnectionService.getResources(); - final String ringtone = preferences.getString("notification_ringtone", resources.getString(R.string.notification_ringtone)); - final boolean vibrate = preferences.getBoolean("vibrate_on_notification", resources.getBoolean(R.bool.vibrate_on_notification)); + final String ringtone = + preferences.getString( + "notification_ringtone", + resources.getString(R.string.notification_ringtone)); + final boolean vibrate = + preferences.getBoolean( + "vibrate_on_notification", + resources.getBoolean(R.bool.vibrate_on_notification)); final boolean led = preferences.getBoolean("led", resources.getBoolean(R.bool.led)); - final boolean headsup = preferences.getBoolean("notification_headsup", resources.getBoolean(R.bool.headsup_notifications)); + final boolean headsup = + preferences.getBoolean( + "notification_headsup", resources.getBoolean(R.bool.headsup_notifications)); if (notify && !quietHours) { if (vibrate) { final int dat = 70; final long[] pattern = {0, 3 * dat, dat, dat}; mBuilder.setVibrate(pattern); } else { - mBuilder.setVibrate(new long[]{0}); + mBuilder.setVibrate(new long[] {0}); } Uri uri = Uri.parse(ringtone); try { @@ -708,7 +838,12 @@ public class NotificationService { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { mBuilder.setCategory(Notification.CATEGORY_MESSAGE); } - mBuilder.setPriority(notify ? (headsup ? NotificationCompat.PRIORITY_HIGH : NotificationCompat.PRIORITY_DEFAULT) : NotificationCompat.PRIORITY_LOW); + mBuilder.setPriority( + notify + ? (headsup + ? NotificationCompat.PRIORITY_HIGH + : NotificationCompat.PRIORITY_DEFAULT) + : NotificationCompat.PRIORITY_LOW); setNotificationColor(mBuilder); mBuilder.setDefaults(0); if (led) { @@ -731,9 +866,18 @@ public class NotificationService { } private Builder buildMultipleConversation(final boolean notify, final boolean quietHours) { - final Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService, quietHours ? "quiet_hours" : (notify ? "messages" : "silent_messages")); + final Builder mBuilder = + new NotificationCompat.Builder( + mXmppConnectionService, + quietHours ? "quiet_hours" : (notify ? "messages" : "silent_messages")); final NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle(); - style.setBigContentTitle(mXmppConnectionService.getResources().getQuantityString(R.plurals.x_unread_conversations, notifications.size(), notifications.size())); + style.setBigContentTitle( + mXmppConnectionService + .getResources() + .getQuantityString( + R.plurals.x_unread_conversations, + notifications.size(), + notifications.size())); final StringBuilder names = new StringBuilder(); Conversation conversation = null; for (final ArrayList messages : notifications.values()) { @@ -743,11 +887,24 @@ public class NotificationService { SpannableString styledString; if (Config.HIDE_MESSAGE_TEXT_IN_NOTIFICATION) { int count = messages.size(); - styledString = new SpannableString(name + ": " + mXmppConnectionService.getResources().getQuantityString(R.plurals.x_messages, count, count)); + styledString = + new SpannableString( + name + + ": " + + mXmppConnectionService + .getResources() + .getQuantityString( + R.plurals.x_messages, count, count)); styledString.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), 0); style.addLine(styledString); } else { - styledString = new SpannableString(name + ": " + UIHelper.getMessagePreview(mXmppConnectionService, messages.get(0)).first); + styledString = + new SpannableString( + name + + ": " + + UIHelper.getMessagePreview( + mXmppConnectionService, messages.get(0)) + .first); styledString.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), 0); style.addLine(styledString); } @@ -758,7 +915,13 @@ public class NotificationService { if (names.length() >= 2) { names.delete(names.length() - 2, names.length()); } - final String contentTitle = mXmppConnectionService.getResources().getQuantityString(R.plurals.x_unread_conversations, notifications.size(), notifications.size()); + final String contentTitle = + mXmppConnectionService + .getResources() + .getQuantityString( + R.plurals.x_unread_conversations, + notifications.size(), + notifications.size()); mBuilder.setContentTitle(contentTitle); mBuilder.setTicker(contentTitle); mBuilder.setContentText(names.toString()); @@ -773,46 +936,72 @@ public class NotificationService { return mBuilder; } - private Builder buildSingleConversations(final ArrayList messages, final boolean notify, final boolean quietHours) { - final Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService, quietHours ? "quiet_hours" : (notify ? "messages" : "silent_messages")); + private Builder buildSingleConversations( + final ArrayList messages, final boolean notify, final boolean quietHours) { + final Builder mBuilder = + new NotificationCompat.Builder( + mXmppConnectionService, + quietHours ? "quiet_hours" : (notify ? "messages" : "silent_messages")); if (messages.size() >= 1) { final Conversation conversation = (Conversation) messages.get(0).getConversation(); - mBuilder.setLargeIcon(mXmppConnectionService.getAvatarService() - .get(conversation, AvatarService.getSystemUiAvatarSize(mXmppConnectionService))); + mBuilder.setLargeIcon( + mXmppConnectionService + .getAvatarService() + .get( + conversation, + AvatarService.getSystemUiAvatarSize(mXmppConnectionService))); mBuilder.setContentTitle(conversation.getName()); if (Config.HIDE_MESSAGE_TEXT_IN_NOTIFICATION) { int count = messages.size(); - mBuilder.setContentText(mXmppConnectionService.getResources().getQuantityString(R.plurals.x_messages, count, count)); + mBuilder.setContentText( + mXmppConnectionService + .getResources() + .getQuantityString(R.plurals.x_messages, count, count)); } else { Message message; - //TODO starting with Android 9 we might want to put images in MessageStyle - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P && (message = getImage(messages)) != null) { + // TODO starting with Android 9 we might want to put images in MessageStyle + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P + && (message = getImage(messages)) != null) { modifyForImage(mBuilder, message, messages); } else { modifyForTextOnly(mBuilder, messages); } - RemoteInput remoteInput = new RemoteInput.Builder("text_reply").setLabel(UIHelper.getMessageHint(mXmppConnectionService, conversation)).build(); + RemoteInput remoteInput = + new RemoteInput.Builder("text_reply") + .setLabel( + UIHelper.getMessageHint( + mXmppConnectionService, conversation)) + .build(); PendingIntent markAsReadPendingIntent = createReadPendingIntent(conversation); - NotificationCompat.Action markReadAction = new NotificationCompat.Action.Builder( - R.drawable.ic_drafts_white_24dp, - mXmppConnectionService.getString(R.string.mark_as_read), - markAsReadPendingIntent) - .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ) - .setShowsUserInterface(false) - .build(); + NotificationCompat.Action markReadAction = + new NotificationCompat.Action.Builder( + R.drawable.ic_drafts_white_24dp, + mXmppConnectionService.getString(R.string.mark_as_read), + markAsReadPendingIntent) + .setSemanticAction( + NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ) + .setShowsUserInterface(false) + .build(); final String replyLabel = mXmppConnectionService.getString(R.string.reply); final String lastMessageUuid = Iterables.getLast(messages).getUuid(); - final NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder( - R.drawable.ic_send_text_offline, - replyLabel, - createReplyIntent(conversation, lastMessageUuid, false)) - .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY) - .setShowsUserInterface(false) - .addRemoteInput(remoteInput).build(); - final NotificationCompat.Action wearReplyAction = new NotificationCompat.Action.Builder(R.drawable.ic_wear_reply, - replyLabel, - createReplyIntent(conversation, lastMessageUuid, true)).addRemoteInput(remoteInput).build(); - mBuilder.extend(new NotificationCompat.WearableExtender().addAction(wearReplyAction)); + final NotificationCompat.Action replyAction = + new NotificationCompat.Action.Builder( + R.drawable.ic_send_text_offline, + replyLabel, + createReplyIntent(conversation, lastMessageUuid, false)) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY) + .setShowsUserInterface(false) + .addRemoteInput(remoteInput) + .build(); + final NotificationCompat.Action wearReplyAction = + new NotificationCompat.Action.Builder( + R.drawable.ic_wear_reply, + replyLabel, + createReplyIntent(conversation, lastMessageUuid, true)) + .addRemoteInput(remoteInput) + .build(); + mBuilder.extend( + new NotificationCompat.WearableExtender().addAction(wearReplyAction)); int addedActionsCount = 1; mBuilder.addAction(markReadAction); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { @@ -823,23 +1012,31 @@ public class NotificationService { if (displaySnoozeAction(messages)) { String label = mXmppConnectionService.getString(R.string.snooze); PendingIntent pendingSnoozeIntent = createSnoozeIntent(conversation); - NotificationCompat.Action snoozeAction = new NotificationCompat.Action.Builder( - R.drawable.ic_notifications_paused_white_24dp, - label, - pendingSnoozeIntent).build(); + NotificationCompat.Action snoozeAction = + new NotificationCompat.Action.Builder( + R.drawable.ic_notifications_paused_white_24dp, + label, + pendingSnoozeIntent) + .build(); mBuilder.addAction(snoozeAction); ++addedActionsCount; } if (addedActionsCount < 3) { final Message firstLocationMessage = getFirstLocationMessage(messages); if (firstLocationMessage != null) { - final PendingIntent pendingShowLocationIntent = createShowLocationIntent(firstLocationMessage); + final PendingIntent pendingShowLocationIntent = + createShowLocationIntent(firstLocationMessage); if (pendingShowLocationIntent != null) { - final String label = mXmppConnectionService.getResources().getString(R.string.show_location); - NotificationCompat.Action locationAction = new NotificationCompat.Action.Builder( - R.drawable.ic_room_white_24dp, - label, - pendingShowLocationIntent).build(); + final String label = + mXmppConnectionService + .getResources() + .getString(R.string.show_location); + NotificationCompat.Action locationAction = + new NotificationCompat.Action.Builder( + R.drawable.ic_room_white_24dp, + label, + pendingShowLocationIntent) + .build(); mBuilder.addAction(locationAction); ++addedActionsCount; } @@ -848,12 +1045,22 @@ public class NotificationService { if (addedActionsCount < 3) { Message firstDownloadableMessage = getFirstDownloadableMessage(messages); if (firstDownloadableMessage != null) { - String label = mXmppConnectionService.getResources().getString(R.string.download_x_file, UIHelper.getFileDescriptionString(mXmppConnectionService, firstDownloadableMessage)); - PendingIntent pendingDownloadIntent = createDownloadIntent(firstDownloadableMessage); - NotificationCompat.Action downloadAction = new NotificationCompat.Action.Builder( - R.drawable.ic_file_download_white_24dp, - label, - pendingDownloadIntent).build(); + String label = + mXmppConnectionService + .getResources() + .getString( + R.string.download_x_file, + UIHelper.getFileDescriptionString( + mXmppConnectionService, + firstDownloadableMessage)); + PendingIntent pendingDownloadIntent = + createDownloadIntent(firstDownloadableMessage); + NotificationCompat.Action downloadAction = + new NotificationCompat.Action.Builder( + R.drawable.ic_file_download_white_24dp, + label, + pendingDownloadIntent) + .build(); mBuilder.addAction(downloadAction); ++addedActionsCount; } @@ -874,13 +1081,16 @@ public class NotificationService { return mBuilder; } - private void modifyForImage(final Builder builder, final Message message, final ArrayList messages) { + private void modifyForImage( + final Builder builder, final Message message, final ArrayList messages) { try { - final Bitmap bitmap = mXmppConnectionService.getFileBackend().getThumbnail(message, getPixel(288), false); + final Bitmap bitmap = + mXmppConnectionService + .getFileBackend() + .getThumbnail(message, getPixel(288), false); final ArrayList tmp = new ArrayList<>(); for (final Message msg : messages) { - if (msg.getType() == Message.TYPE_TEXT - && msg.getTransferable() == null) { + if (msg.getType() == Message.TYPE_TEXT && msg.getTransferable() == null) { tmp.add(msg); } } @@ -892,7 +1102,8 @@ public class NotificationService { builder.setContentText(text); builder.setTicker(text); } else { - final String description = UIHelper.getFileDescriptionString(mXmppConnectionService, message); + final String description = + UIHelper.getFileDescriptionString(mXmppConnectionService, message); builder.setContentText(description); builder.setTicker(description); } @@ -915,7 +1126,15 @@ public class NotificationService { builder.setName(UIHelper.getMessageDisplayName(message)); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - builder.setIcon(IconCompat.createWithBitmap(mXmppConnectionService.getAvatarService().get(message, AvatarService.getSystemUiAvatarSize(mXmppConnectionService), false))); + builder.setIcon( + IconCompat.createWithBitmap( + mXmppConnectionService + .getAvatarService() + .get( + message, + AvatarService.getSystemUiAvatarSize( + mXmppConnectionService), + false))); } return builder.build(); } @@ -923,35 +1142,60 @@ public class NotificationService { private void modifyForTextOnly(final Builder builder, final ArrayList messages) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { final Conversation conversation = (Conversation) messages.get(0).getConversation(); - final Person.Builder meBuilder = new Person.Builder().setName(mXmppConnectionService.getString(R.string.me)); + final Person.Builder meBuilder = + new Person.Builder().setName(mXmppConnectionService.getString(R.string.me)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - meBuilder.setIcon(IconCompat.createWithBitmap(mXmppConnectionService.getAvatarService().get(conversation.getAccount(), AvatarService.getSystemUiAvatarSize(mXmppConnectionService)))); + meBuilder.setIcon( + IconCompat.createWithBitmap( + mXmppConnectionService + .getAvatarService() + .get( + conversation.getAccount(), + AvatarService.getSystemUiAvatarSize( + mXmppConnectionService)))); } final Person me = meBuilder.build(); - NotificationCompat.MessagingStyle messagingStyle = new NotificationCompat.MessagingStyle(me); + NotificationCompat.MessagingStyle messagingStyle = + new NotificationCompat.MessagingStyle(me); final boolean multiple = conversation.getMode() == Conversation.MODE_MULTI; if (multiple) { messagingStyle.setConversationTitle(conversation.getName()); } for (Message message : messages) { - final Person sender = message.getStatus() == Message.STATUS_RECEIVED ? getPerson(message) : null; + final Person sender = + message.getStatus() == Message.STATUS_RECEIVED ? getPerson(message) : null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && isImageMessage(message)) { - final Uri dataUri = FileBackend.getMediaUri(mXmppConnectionService, mXmppConnectionService.getFileBackend().getFile(message)); - NotificationCompat.MessagingStyle.Message imageMessage = new NotificationCompat.MessagingStyle.Message(UIHelper.getMessagePreview(mXmppConnectionService, message).first, message.getTimeSent(), sender); + final Uri dataUri = + FileBackend.getMediaUri( + mXmppConnectionService, + mXmppConnectionService.getFileBackend().getFile(message)); + NotificationCompat.MessagingStyle.Message imageMessage = + new NotificationCompat.MessagingStyle.Message( + UIHelper.getMessagePreview(mXmppConnectionService, message) + .first, + message.getTimeSent(), + sender); if (dataUri != null) { imageMessage.setData(message.getMimeType(), dataUri); } messagingStyle.addMessage(imageMessage); } else { - messagingStyle.addMessage(UIHelper.getMessagePreview(mXmppConnectionService, message).first, message.getTimeSent(), sender); + messagingStyle.addMessage( + UIHelper.getMessagePreview(mXmppConnectionService, message).first, + message.getTimeSent(), + sender); } } messagingStyle.setGroupConversation(multiple); builder.setStyle(messagingStyle); } else { if (messages.get(0).getConversation().getMode() == Conversation.MODE_SINGLE) { - builder.setStyle(new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages))); - final CharSequence preview = UIHelper.getMessagePreview(mXmppConnectionService, messages.get(messages.size() - 1)).first; + builder.setStyle( + new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages))); + final CharSequence preview = + UIHelper.getMessagePreview( + mXmppConnectionService, messages.get(messages.size() - 1)) + .first; builder.setContentText(preview); builder.setTicker(preview); builder.setNumber(messages.size()); @@ -973,7 +1217,10 @@ public class NotificationService { builder.setContentText(styledString); builder.setTicker(styledString); } else { - final String text = mXmppConnectionService.getResources().getQuantityString(R.plurals.x_messages, count, count); + final String text = + mXmppConnectionService + .getResources() + .getQuantityString(R.plurals.x_messages, count, count); builder.setContentText(text); builder.setTicker(text); } @@ -996,7 +1243,8 @@ public class NotificationService { private Message getFirstDownloadableMessage(final Iterable messages) { for (final Message message : messages) { - if (message.getTransferable() != null || (message.getType() == Message.TYPE_TEXT && message.treatAsDownloadable())) { + if (message.getTransferable() != null + || (message.getType() == Message.TYPE_TEXT && message.treatAsDownloadable())) { return message; } } @@ -1024,27 +1272,37 @@ public class NotificationService { } private PendingIntent createShowLocationIntent(final Message message) { - Iterable intents = GeoHelper.createGeoIntentsFromMessage(mXmppConnectionService, message); - for (Intent intent : intents) { + Iterable intents = + GeoHelper.createGeoIntentsFromMessage(mXmppConnectionService, message); + for (final Intent intent : intents) { if (intent.resolveActivity(mXmppConnectionService.getPackageManager()) != null) { - return PendingIntent.getActivity(mXmppConnectionService, generateRequestCode(message.getConversation(), 18), intent, PendingIntent.FLAG_UPDATE_CURRENT); + return PendingIntent.getActivity( + mXmppConnectionService, + generateRequestCode(message.getConversation(), 18), + intent, + PendingIntent.FLAG_UPDATE_CURRENT); } } return null; } - private PendingIntent createContentIntent(final String conversationUuid, final String downloadMessageUuid) { - final Intent viewConversationIntent = new Intent(mXmppConnectionService, ConversationsActivity.class); + private PendingIntent createContentIntent( + final String conversationUuid, final String downloadMessageUuid) { + final Intent viewConversationIntent = + new Intent(mXmppConnectionService, ConversationsActivity.class); viewConversationIntent.setAction(ConversationsActivity.ACTION_VIEW_CONVERSATION); viewConversationIntent.putExtra(ConversationsActivity.EXTRA_CONVERSATION, conversationUuid); if (downloadMessageUuid != null) { - viewConversationIntent.putExtra(ConversationsActivity.EXTRA_DOWNLOAD_UUID, downloadMessageUuid); - return PendingIntent.getActivity(mXmppConnectionService, + viewConversationIntent.putExtra( + ConversationsActivity.EXTRA_DOWNLOAD_UUID, downloadMessageUuid); + return PendingIntent.getActivity( + mXmppConnectionService, generateRequestCode(conversationUuid, 8), viewConversationIntent, PendingIntent.FLAG_UPDATE_CURRENT); } else { - return PendingIntent.getActivity(mXmppConnectionService, + return PendingIntent.getActivity( + mXmppConnectionService, generateRequestCode(conversationUuid, 10), viewConversationIntent, PendingIntent.FLAG_UPDATE_CURRENT); @@ -1052,7 +1310,8 @@ public class NotificationService { } private int generateRequestCode(String uuid, int actionId) { - return (actionId * NOTIFICATION_ID_MULTIPLIER) + (uuid.hashCode() % NOTIFICATION_ID_MULTIPLIER); + return (actionId * NOTIFICATION_ID_MULTIPLIER) + + (uuid.hashCode() % NOTIFICATION_ID_MULTIPLIER); } private int generateRequestCode(Conversational conversation, int actionId) { @@ -1072,19 +1331,24 @@ public class NotificationService { intent.setAction(XmppConnectionService.ACTION_CLEAR_NOTIFICATION); if (conversation != null) { intent.putExtra("uuid", conversation.getUuid()); - return PendingIntent.getService(mXmppConnectionService, generateRequestCode(conversation, 20), intent, 0); + return PendingIntent.getService( + mXmppConnectionService, generateRequestCode(conversation, 20), intent, 0); } return PendingIntent.getService(mXmppConnectionService, 0, intent, 0); } - private PendingIntent createReplyIntent(final Conversation conversation, final String lastMessageUuid, final boolean dismissAfterReply) { + private PendingIntent createReplyIntent( + final Conversation conversation, + final String lastMessageUuid, + final boolean dismissAfterReply) { final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); intent.setAction(XmppConnectionService.ACTION_REPLY_TO_CONVERSATION); intent.putExtra("uuid", conversation.getUuid()); intent.putExtra("dismiss_notification", dismissAfterReply); intent.putExtra("last_message_uuid", lastMessageUuid); final int id = generateRequestCode(conversation, dismissAfterReply ? 12 : 14); - return PendingIntent.getService(mXmppConnectionService, id, intent, PendingIntent.FLAG_UPDATE_CURRENT); + return PendingIntent.getService( + mXmppConnectionService, id, intent, PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent createReadPendingIntent(Conversation conversation) { @@ -1092,7 +1356,11 @@ public class NotificationService { intent.setAction(XmppConnectionService.ACTION_MARK_AS_READ); intent.putExtra("uuid", conversation.getUuid()); intent.setPackage(mXmppConnectionService.getPackageName()); - return PendingIntent.getService(mXmppConnectionService, generateRequestCode(conversation, 16), intent, PendingIntent.FLAG_UPDATE_CURRENT); + return PendingIntent.getService( + mXmppConnectionService, + generateRequestCode(conversation, 16), + intent, + PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent createCallAction(String sessionId, final String action, int requestCode) { @@ -1100,7 +1368,8 @@ public class NotificationService { intent.setAction(action); intent.setPackage(mXmppConnectionService.getPackageName()); intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, sessionId); - return PendingIntent.getService(mXmppConnectionService, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + return PendingIntent.getService( + mXmppConnectionService, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent createSnoozeIntent(Conversation conversation) { @@ -1108,7 +1377,11 @@ public class NotificationService { intent.setAction(XmppConnectionService.ACTION_SNOOZE); intent.putExtra("uuid", conversation.getUuid()); intent.setPackage(mXmppConnectionService.getPackageName()); - return PendingIntent.getService(mXmppConnectionService, generateRequestCode(conversation, 22), intent, PendingIntent.FLAG_UPDATE_CURRENT); + return PendingIntent.getService( + mXmppConnectionService, + generateRequestCode(conversation, 22), + intent, + PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent createTryAgainIntent() { @@ -1147,8 +1420,7 @@ public class NotificationService { } private int getPixel(final int dp) { - final DisplayMetrics metrics = mXmppConnectionService.getResources() - .getDisplayMetrics(); + final DisplayMetrics metrics = mXmppConnectionService.getResources().getDisplayMetrics(); return ((int) (dp * metrics.density)); } @@ -1157,8 +1429,10 @@ public class NotificationService { } private boolean inMiniGracePeriod(final Account account) { - final int miniGrace = account.getStatus() == Account.State.ONLINE ? Config.MINI_GRACE_PERIOD - : Config.MINI_GRACE_PERIOD * 2; + final int miniGrace = + account.getStatus() == Account.State.ONLINE + ? Config.MINI_GRACE_PERIOD + : Config.MINI_GRACE_PERIOD * 2; return SystemClock.elapsedRealtime() < (this.mLastNotification + miniGrace); } @@ -1178,26 +1452,34 @@ public class NotificationService { } } } - mBuilder.setContentText(mXmppConnectionService.getString(R.string.connected_accounts, connected, enabled)); + mBuilder.setContentText( + mXmppConnectionService.getString(R.string.connected_accounts, connected, enabled)); final PendingIntent openIntent = createOpenConversationsIntent(); if (openIntent != null) { mBuilder.setContentIntent(openIntent); } - mBuilder.setWhen(0); - mBuilder.setPriority(Notification.PRIORITY_MIN); - mBuilder.setSmallIcon(connected > 0 ? R.drawable.ic_link_white_24dp : R.drawable.ic_link_off_white_24dp); + mBuilder.setWhen(0) + .setPriority(Notification.PRIORITY_MIN) + .setSmallIcon( + connected > 0 + ? R.drawable.ic_link_white_24dp + : R.drawable.ic_link_off_white_24dp) + .setLocalOnly(true); if (Compatibility.runsTwentySix()) { mBuilder.setChannelId("foreground"); } - return mBuilder.build(); } private PendingIntent createOpenConversationsIntent() { try { - return PendingIntent.getActivity(mXmppConnectionService, 0, new Intent(mXmppConnectionService, ConversationsActivity.class), 0); + return PendingIntent.getActivity( + mXmppConnectionService, + 0, + new Intent(mXmppConnectionService, ConversationsActivity.class), + 0); } catch (RuntimeException e) { return null; } @@ -1212,7 +1494,10 @@ public class NotificationService { final List errors = new ArrayList<>(); boolean torNotAvailable = false; for (final Account account : mXmppConnectionService.getAccounts()) { - if (account.hasErrorStatus() && account.showErrorNotification() && (showAllErrors || account.getLastErrorStatus() == Account.State.UNAUTHORIZED)) { + if (account.hasErrorStatus() + && account.showErrorNotification() + && (showAllErrors + || account.getLastErrorStatus() == Account.State.UNAUTHORIZED)) { errors.add(account); torNotAvailable |= account.getStatus() == Account.State.TOR_NOT_AVAILABLE; } @@ -1225,29 +1510,31 @@ public class NotificationService { cancel(ERROR_NOTIFICATION_ID); return; } else if (errors.size() == 1) { - mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.problem_connecting_to_account)); + mBuilder.setContentTitle( + mXmppConnectionService.getString(R.string.problem_connecting_to_account)); mBuilder.setContentText(errors.get(0).getJid().asBareJid().toEscapedString()); } else { - mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.problem_connecting_to_accounts)); + mBuilder.setContentTitle( + mXmppConnectionService.getString(R.string.problem_connecting_to_accounts)); mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_fix)); } - mBuilder.addAction(R.drawable.ic_autorenew_white_24dp, + mBuilder.addAction( + R.drawable.ic_autorenew_white_24dp, mXmppConnectionService.getString(R.string.try_again), - createTryAgainIntent() - ); + createTryAgainIntent()); if (torNotAvailable) { if (TorServiceUtils.isOrbotInstalled(mXmppConnectionService)) { mBuilder.addAction( R.drawable.ic_play_circle_filled_white_48dp, mXmppConnectionService.getString(R.string.start_orbot), - PendingIntent.getActivity(mXmppConnectionService, 147, TorServiceUtils.LAUNCH_INTENT, 0) - ); + PendingIntent.getActivity( + mXmppConnectionService, 147, TorServiceUtils.LAUNCH_INTENT, 0)); } else { mBuilder.addAction( R.drawable.ic_file_download_white_24dp, mXmppConnectionService.getString(R.string.install_orbot), - PendingIntent.getActivity(mXmppConnectionService, 146, TorServiceUtils.INSTALL_INTENT, 0) - ); + PendingIntent.getActivity( + mXmppConnectionService, 146, TorServiceUtils.INSTALL_INTENT, 0)); } } mBuilder.setDeleteIntent(createDismissErrorIntent()); @@ -1269,7 +1556,9 @@ public class NotificationService { intent.putExtra("jid", errors.get(0).getJid().asBareJid().toEscapedString()); intent.putExtra(EditAccountActivity.EXTRA_OPENED_FROM_NOTIFICATION, true); } - mBuilder.setContentIntent(PendingIntent.getActivity(mXmppConnectionService, 145, intent, PendingIntent.FLAG_UPDATE_CURRENT)); + mBuilder.setContentIntent( + PendingIntent.getActivity( + mXmppConnectionService, 145, intent, PendingIntent.FLAG_UPDATE_CURRENT)); if (Compatibility.runsTwentySix()) { mBuilder.setChannelId("error"); } @@ -1291,7 +1580,8 @@ public class NotificationService { } private void notify(String tag, int id, Notification notification) { - final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mXmppConnectionService); + final NotificationManagerCompat notificationManager = + NotificationManagerCompat.from(mXmppConnectionService); try { notificationManager.notify(tag, id, notification); } catch (RuntimeException e) { @@ -1300,7 +1590,8 @@ public class NotificationService { } public void notify(int id, Notification notification) { - final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mXmppConnectionService); + final NotificationManagerCompat notificationManager = + NotificationManagerCompat.from(mXmppConnectionService); try { notificationManager.notify(id, notification); } catch (RuntimeException e) { @@ -1309,7 +1600,8 @@ public class NotificationService { } public void cancel(int id) { - final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mXmppConnectionService); + final NotificationManagerCompat notificationManager = + NotificationManagerCompat.from(mXmppConnectionService); try { notificationManager.cancel(id); } catch (RuntimeException e) { @@ -1318,7 +1610,8 @@ public class NotificationService { } private void cancel(String tag, int id) { - final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mXmppConnectionService); + final NotificationManagerCompat notificationManager = + NotificationManagerCompat.from(mXmppConnectionService); try { notificationManager.cancel(tag, id); } catch (RuntimeException e) { @@ -1330,7 +1623,8 @@ public class NotificationService { @Override public void run() { - final Vibrator vibrator = (Vibrator) mXmppConnectionService.getSystemService(Context.VIBRATOR_SERVICE); + final Vibrator vibrator = + (Vibrator) mXmppConnectionService.getSystemService(Context.VIBRATOR_SERVICE); vibrator.vibrate(CALL_PATTERN, -1); } } From d8fd59394cad303245c781ba6e6ef716c2284737 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 1 Jul 2022 15:54:21 +0200 Subject: [PATCH 11/20] fix array out of bounds. fixes #4334 --- .../util/EditMessageActionModeCallback.java | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/util/EditMessageActionModeCallback.java b/src/main/java/eu/siacs/conversations/ui/util/EditMessageActionModeCallback.java index fca8ebbbc93344a9f2962906a4b8b4fb6babaf7a..a859e14f8576e3a1e8983eb913c5e6c1e7d1db28 100644 --- a/src/main/java/eu/siacs/conversations/ui/util/EditMessageActionModeCallback.java +++ b/src/main/java/eu/siacs/conversations/ui/util/EditMessageActionModeCallback.java @@ -48,17 +48,28 @@ public class EditMessageActionModeCallback implements ActionMode.Callback { public EditMessageActionModeCallback(EditMessage editMessage) { this.editMessage = editMessage; - this.clipboardManager = (ClipboardManager) editMessage.getContext().getSystemService(Context.CLIPBOARD_SERVICE); + this.clipboardManager = + (ClipboardManager) + editMessage.getContext().getSystemService(Context.CLIPBOARD_SERVICE); } @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { + public boolean onCreateActionMode(final ActionMode mode, final Menu menu) { final MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.edit_message_actions, menu); final MenuItem pasteAsQuote = menu.findItem(R.id.paste_as_quote); final ClipData primaryClip = clipboardManager.getPrimaryClip(); - if (primaryClip != null && primaryClip.getItemCount() >= 0) { - pasteAsQuote.setVisible(primaryClip.getDescription().getMimeType(0).startsWith("text/") && !TextUtils.isEmpty(primaryClip.getItemAt(0).getText())); + if (primaryClip != null && primaryClip.getItemCount() > 0) { + final String mimeType; + try { + mimeType = primaryClip.getDescription().getMimeType(0); + } catch (final Exception e) { + pasteAsQuote.setVisible(false); + return true; + } + pasteAsQuote.setVisible( + mimeType.startsWith("text/") + && !TextUtils.isEmpty(primaryClip.getItemAt(0).getText())); } else { pasteAsQuote.setVisible(false); } @@ -71,10 +82,10 @@ public class EditMessageActionModeCallback implements ActionMode.Callback { } @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) { if (item.getItemId() == R.id.paste_as_quote) { final ClipData primaryClip = clipboardManager.getPrimaryClip(); - if (primaryClip != null && primaryClip.getItemCount() >= 1) { + if (primaryClip != null && primaryClip.getItemCount() > 0) { editMessage.insertAsQuote(primaryClip.getItemAt(0).getText().toString()); return true; } @@ -83,7 +94,5 @@ public class EditMessageActionModeCallback implements ActionMode.Callback { } @Override - public void onDestroyActionMode(ActionMode mode) { - - } + public void onDestroyActionMode(ActionMode mode) {} } From b97e2deaa29dad374c936ca46c2ca0dbb210192c Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Wed, 17 Feb 2021 08:45:57 +0000 Subject: [PATCH 12/20] Show battery dialogue always --- .../conversations/ui/ConversationsActivity.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java index 6d0a03f8b3ebb1b038e2d9c6f5a2536694cafc4e..c31c3464be330771452fb1507d09d1e109895a44 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java @@ -221,8 +221,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio } private void openBatteryOptimizationDialogIfNeeded() { - if (hasAccountWithoutPush() - && isOptimizingBattery() + if (isOptimizingBattery() && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M && getPreferences().getBoolean(getBatteryOptimizationPreferenceKey(), true)) { AlertDialog.Builder builder = new AlertDialog.Builder(this); @@ -245,15 +244,6 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio } } - private boolean hasAccountWithoutPush() { - for (Account account : xmppConnectionService.getAccounts()) { - if (account.getStatus() == Account.State.ONLINE && !xmppConnectionService.getPushManagementService().available(account)) { - return true; - } - } - return false; - } - private void notifyFragmentOfBackendConnected(@IdRes int id) { final Fragment fragment = getFragmentManager().findFragmentById(id); if (fragment instanceof OnBackendConnected) { From 49851057116eb257ef2a2c02089ffc2a507846ad Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Wed, 17 Feb 2021 08:50:14 +0000 Subject: [PATCH 13/20] Here too ...but why was that function created elsewhere if here you just compare this? --- .../java/eu/siacs/conversations/ui/EditAccountActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index e9c0bce392eac39972882ae9521543f9cbef5097..fc21f62965a22906f54420b6232cced30e5990f7 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -1045,7 +1045,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat if (this.mAccount.isOnlineAndConnected() && !this.mFetchingAvatar) { Features features = this.mAccount.getXmppConnection().getFeatures(); this.binding.stats.setVisibility(View.VISIBLE); - boolean showBatteryWarning = !xmppConnectionService.getPushManagementService().available(mAccount) && isOptimizingBattery(); + boolean showBatteryWarning = isOptimizingBattery(); boolean showDataSaverWarning = isAffectedByDataSaver(); showOsOptimizationWarning(showBatteryWarning, showDataSaverWarning); this.binding.sessionEst.setText(UIHelper.readableTimeDifferenceFull(this, this.mAccount.getXmppConnection() From 2364d7c46d39e04f81ed83ae873e56d9457fa625 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 Jul 2022 10:56:24 +0200 Subject: [PATCH 14/20] pulled translations from transifex --- src/main/res/values-it/strings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index a665e79c7820c6f124b76da7b736c322b7e50cca..ffc63ac41d5e35c3b273ae47f03275ce7ee9548f 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -989,4 +989,6 @@ Documento di testo Le registrazioni di profili non sono supportate Nessun indirizzo XMPP trovato - + Errore di autenticazione temporaneo + + From e455ed4f1ae10ebb82d88d98102c7a6673c43a6f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 Jul 2022 14:45:59 +0200 Subject: [PATCH 15/20] fix orbot detection --- src/main/AndroidManifest.xml | 12 ++++---- .../conversations/utils/TorServiceUtils.java | 28 +++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index a3dd9822ae00acbd77b73731fe98c208e4a06919..458c8a7f4b63897547ced729b89a4005b090631e 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -50,27 +50,29 @@ android:required="false" /> - + + + - + - + diff --git a/src/main/java/eu/siacs/conversations/utils/TorServiceUtils.java b/src/main/java/eu/siacs/conversations/utils/TorServiceUtils.java index 9fc9f5082f66fb8fcca1c6241f72a49469dc84bd..4f0e6fc530154a06ede1150f393f27b0ef877f86 100644 --- a/src/main/java/eu/siacs/conversations/utils/TorServiceUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/TorServiceUtils.java @@ -6,41 +6,47 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; +import android.widget.Toast; import eu.siacs.conversations.R; import me.drakeet.support.toast.ToastCompat; public class TorServiceUtils { - private final static String URI_ORBOT = "org.torproject.android"; + private static final String URI_ORBOT = "org.torproject.android"; private static final Uri ORBOT_PLAYSTORE_URI = Uri.parse("market://details?id=" + URI_ORBOT); - private final static String ACTION_START_TOR = "org.torproject.android.START_TOR"; + private static final String ACTION_START_TOR = "org.torproject.android.START_TOR"; public static final Intent INSTALL_INTENT = new Intent(Intent.ACTION_VIEW, ORBOT_PLAYSTORE_URI); public static final Intent LAUNCH_INTENT = new Intent(ACTION_START_TOR); - public final static String ACTION_STATUS = "org.torproject.android.intent.action.STATUS"; - public final static String EXTRA_STATUS = "org.torproject.android.intent.extra.STATUS"; + public static final String ACTION_STATUS = "org.torproject.android.intent.action.STATUS"; + public static final String EXTRA_STATUS = "org.torproject.android.intent.extra.STATUS"; - public static boolean isOrbotInstalled(Context context) { + public static boolean isOrbotInstalled(final Context context) { try { context.getPackageManager().getPackageInfo(URI_ORBOT, PackageManager.GET_ACTIVITIES); return true; - } catch (PackageManager.NameNotFoundException e) { + } catch (final PackageManager.NameNotFoundException e) { return false; } } - public static void downloadOrbot(Activity activity, int requestCode) { try { activity.startActivityForResult(INSTALL_INTENT, requestCode); - } catch (ActivityNotFoundException e) { - ToastCompat.makeText(activity, R.string.no_market_app_installed, ToastCompat.LENGTH_SHORT).show(); + } catch (final ActivityNotFoundException e) { + ToastCompat.makeText( + activity, R.string.no_market_app_installed, ToastCompat.LENGTH_SHORT) + .show(); } } - public static void startOrbot(Activity activity, int requestCode) { - activity.startActivityForResult(LAUNCH_INTENT, requestCode); + public static void startOrbot(final Activity activity, final int requestCode) { + try { + activity.startActivityForResult(LAUNCH_INTENT, requestCode); + } catch (final ActivityNotFoundException e) { + Toast.makeText(activity, R.string.install_orbot, Toast.LENGTH_LONG).show(); + } } } From abfe1f1dbd85d9b8e88b3b4a7e86e0bcf92c0465 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 9 Jul 2022 14:46:18 +0200 Subject: [PATCH 16/20] do not show toast when activity is gone. fixes #4335 --- .../eu/siacs/conversations/ui/ConversationFragment.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 1b334e5d4421de4975a163f4834abe35559ff94c..2eb602257c4e99c6dad0ae4bf01109a6ec4a9e61 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -710,8 +710,12 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } @Override - public void error(final int error, Message message) { + public void error(final int error, final Message message) { hidePrepareFileToast(prepareFileToast); + final ConversationsActivity activity = ConversationFragment.this.activity; + if (activity == null) { + return; + } activity.runOnUiThread(() -> activity.replaceToast(getString(error))); } }); From 7d92ac365ddae026fc03cf66dbd2d1e96909f078 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 Jul 2022 10:46:49 +0200 Subject: [PATCH 17/20] version bump to 2.10.7 --- CHANGELOG.md | 6 ++++++ build.gradle | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 304fac6d97c9cb00922b127db2e726351c2f52c9..4e748a2cf7e46a19e89381c02d58a30d0e081d82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +### Version 2.10.7 + +* always ask for battery optimizations opt-out +* set local only flag on 'x connected accounts' notifications +* Minor bug fixes + ### Version 2.10.6 * Minor bug fixes diff --git a/build.gradle b/build.gradle index ad5a88b9c563cf05782d8e401cce0ebfa19773d3..b48ffb58e053a891801680b472f7c2a92966d45a 100644 --- a/build.gradle +++ b/build.gradle @@ -91,8 +91,8 @@ android { defaultConfig { minSdkVersion 21 targetSdkVersion 30 - versionCode 42032 - versionName "2.10.6" + versionCode 42033 + versionName "2.10.7" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" resValue "string", "applicationId", applicationId From 52e9b2c88eaa8585934489047db6542d25a1f870 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 Jul 2022 10:47:03 +0200 Subject: [PATCH 18/20] use signal protocol android --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index b48ffb58e053a891801680b472f7c2a92966d45a..23774bb76e5e810eb021894ce887c366e3e2bdbd 100644 --- a/build.gradle +++ b/build.gradle @@ -57,7 +57,7 @@ dependencies { implementation 'com.google.zxing:core:3.3.3' implementation 'de.measite.minidns:minidns-hla:0.2.4' implementation 'me.leolin:ShortcutBadger:1.1.22@aar' - implementation 'org.whispersystems:signal-protocol-java:2.6.2' + implementation 'org.whispersystems:signal-protocol-android:2.6.2' implementation 'com.makeramen:roundedimageview:2.3.0' implementation "com.wefika:flowlayout:0.4.1" implementation 'com.otaliastudios:transcoder:0.10.4' @@ -71,7 +71,7 @@ dependencies { implementation "com.squareup.retrofit2:retrofit:2.9.0" implementation "com.squareup.retrofit2:converter-gson:2.9.0" - implementation "com.squareup.okhttp3:okhttp:4.9.3" + implementation "com.squareup.okhttp3:okhttp:4.10.0" implementation 'com.google.guava:guava:30.1.1-android' quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.12.49' From 49c9584361f1c9ff3cb03361c82d0a10359dc67d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 Jul 2022 12:34:02 +0200 Subject: [PATCH 19/20] bump targetSdk to 32 --- build.gradle | 4 +- src/conversations/AndroidManifest.xml | 3 +- src/main/AndroidManifest.xml | 16 +++- .../services/NotificationService.java | 96 ++++++++++++++----- .../services/XmppConnectionService.java | 17 +++- .../conversations/utils/Compatibility.java | 4 + 6 files changed, 103 insertions(+), 37 deletions(-) diff --git a/build.gradle b/build.gradle index 23774bb76e5e810eb021894ce887c366e3e2bdbd..65d5f99fc945eb4b08554a1d312c37ccf54aee44 100644 --- a/build.gradle +++ b/build.gradle @@ -86,11 +86,11 @@ ext { android { namespace 'eu.siacs.conversations' - compileSdkVersion 31 + compileSdkVersion 32 defaultConfig { minSdkVersion 21 - targetSdkVersion 30 + targetSdkVersion 32 versionCode 42033 versionName "2.10.7" archivesBaseName += "-$versionName" diff --git a/src/conversations/AndroidManifest.xml b/src/conversations/AndroidManifest.xml index bf2297949f60c8fe268877ed4bca753a0b097169..d573b32d3dae88e55c506eeaf0d51ec065fca73c 100644 --- a/src/conversations/AndroidManifest.xml +++ b/src/conversations/AndroidManifest.xml @@ -26,7 +26,8 @@ + android:launchMode="singleTask" + android:exported="true"> diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 458c8a7f4b63897547ced729b89a4005b090631e..2a48da7a010653543fbaa7d85f2d1532fd90e6b2 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -83,7 +83,9 @@ - + @@ -107,6 +109,7 @@ android:label="@string/title_activity_show_location" /> @@ -127,6 +130,7 @@ android:windowSoftInputMode="stateAlwaysHidden" /> @@ -166,6 +170,7 @@ @@ -174,6 +179,7 @@ @@ -192,6 +198,7 @@ @@ -225,6 +232,7 @@ android:label="@string/group_chat_avatar" /> @@ -261,10 +269,6 @@ - - - - @@ -302,6 +307,7 @@ diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index abe6e9e11370833989844dd90bb23953c95c9e46..acac26cc091593340f98062e74600a83607b8adc 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -1,5 +1,7 @@ package eu.siacs.conversations.services; +import static eu.siacs.conversations.utils.Compatibility.s; + import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationChannelGroup; @@ -625,7 +627,9 @@ public class NotificationService { mXmppConnectionService, requestCode, fullScreenIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + s() + ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } public void cancelIncomingCallNotification() { @@ -759,7 +763,7 @@ public class NotificationService { && conversations != null && conversations.size() == 1; // if this check is changed to > 0 catchup messages will - // create one notification per conversation + // create one notification per conversation if (notifications.size() == 0) { cancel(NOTIFICATION_ID); @@ -835,9 +839,7 @@ public class NotificationService { } else { mBuilder.setLocalOnly(true); } - if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mBuilder.setCategory(Notification.CATEGORY_MESSAGE); - } + mBuilder.setCategory(Notification.CATEGORY_MESSAGE); mBuilder.setPriority( notify ? (headsup @@ -1280,7 +1282,9 @@ public class NotificationService { mXmppConnectionService, generateRequestCode(message.getConversation(), 18), intent, - PendingIntent.FLAG_UPDATE_CURRENT); + s() + ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } } return null; @@ -1299,13 +1303,17 @@ public class NotificationService { mXmppConnectionService, generateRequestCode(conversationUuid, 8), viewConversationIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + s() + ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } else { return PendingIntent.getActivity( mXmppConnectionService, generateRequestCode(conversationUuid, 10), viewConversationIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + s() + ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } } @@ -1332,9 +1340,20 @@ public class NotificationService { if (conversation != null) { intent.putExtra("uuid", conversation.getUuid()); return PendingIntent.getService( - mXmppConnectionService, generateRequestCode(conversation, 20), intent, 0); + mXmppConnectionService, + generateRequestCode(conversation, 20), + intent, + s() + ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } - return PendingIntent.getService(mXmppConnectionService, 0, intent, 0); + return PendingIntent.getService( + mXmppConnectionService, + 0, + intent, + s() + ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent createReplyIntent( @@ -1348,7 +1367,12 @@ public class NotificationService { intent.putExtra("last_message_uuid", lastMessageUuid); final int id = generateRequestCode(conversation, dismissAfterReply ? 12 : 14); return PendingIntent.getService( - mXmppConnectionService, id, intent, PendingIntent.FLAG_UPDATE_CURRENT); + mXmppConnectionService, + id, + intent, + s() + ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent createReadPendingIntent(Conversation conversation) { @@ -1360,7 +1384,9 @@ public class NotificationService { mXmppConnectionService, generateRequestCode(conversation, 16), intent, - PendingIntent.FLAG_UPDATE_CURRENT); + s() + ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent createCallAction(String sessionId, final String action, int requestCode) { @@ -1369,7 +1395,12 @@ public class NotificationService { intent.setPackage(mXmppConnectionService.getPackageName()); intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, sessionId); return PendingIntent.getService( - mXmppConnectionService, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT); + mXmppConnectionService, + requestCode, + intent, + s() + ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent createSnoozeIntent(Conversation conversation) { @@ -1381,19 +1412,33 @@ public class NotificationService { mXmppConnectionService, generateRequestCode(conversation, 22), intent, - PendingIntent.FLAG_UPDATE_CURRENT); + s() + ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent createTryAgainIntent() { final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); intent.setAction(XmppConnectionService.ACTION_TRY_AGAIN); - return PendingIntent.getService(mXmppConnectionService, 45, intent, 0); + return PendingIntent.getService( + mXmppConnectionService, + 45, + intent, + s() + ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } private PendingIntent createDismissErrorIntent() { final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class); intent.setAction(XmppConnectionService.ACTION_DISMISS_ERROR_NOTIFICATIONS); - return PendingIntent.getService(mXmppConnectionService, 69, intent, 0); + return PendingIntent.getService( + mXmppConnectionService, + 69, + intent, + s() + ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT); } private boolean wasHighlightedOrPrivate(final Message message) { @@ -1538,15 +1583,9 @@ public class NotificationService { } } mBuilder.setDeleteIntent(createDismissErrorIntent()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE); - mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp); - } else { - mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning); - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { - mBuilder.setLocalOnly(true); - } + mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE); + mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp); + mBuilder.setLocalOnly(true); mBuilder.setPriority(Notification.PRIORITY_LOW); final Intent intent; if (AccountUtils.MANAGE_ACCOUNT_ACTIVITY != null) { @@ -1558,7 +1597,12 @@ public class NotificationService { } mBuilder.setContentIntent( PendingIntent.getActivity( - mXmppConnectionService, 145, intent, PendingIntent.FLAG_UPDATE_CURRENT)); + mXmppConnectionService, + 145, + intent, + s() + ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT + : PendingIntent.FLAG_UPDATE_CURRENT)); if (Compatibility.runsTwentySix()) { mBuilder.setChannelId("error"); } diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 7965a4e31ea2d75ef938668afe3e86394262d4ae..a6823e6702925d38b39642ffb0d1616c6910fac4 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -36,6 +36,7 @@ import android.preference.PreferenceManager; import android.provider.ContactsContract; import android.security.KeyChain; import android.telephony.PhoneStateListener; +import android.telephony.TelephonyCallback; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.DisplayMetrics; @@ -1203,9 +1204,10 @@ public class XmppConnectionService extends Service { private void setupPhoneStateListener() { final TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); - if (telephonyManager != null) { - telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); + if (telephonyManager == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + return; } + telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); } public boolean isPhoneInCall() { @@ -1402,7 +1404,16 @@ public class XmppConnectionService extends Service { final Intent intent = new Intent(this, EventReceiver.class); intent.setAction("ping"); try { - PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, 0); + final PendingIntent pendingIntent; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + pendingIntent = + PendingIntent.getBroadcast( + this, requestCode, intent, PendingIntent.FLAG_IMMUTABLE); + } else { + pendingIntent = + PendingIntent.getBroadcast( + this, requestCode, intent, 0); + } alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, pendingIntent); } catch (RuntimeException e) { Log.e(Config.LOGTAG, "unable to schedule alarm for ping", e); diff --git a/src/main/java/eu/siacs/conversations/utils/Compatibility.java b/src/main/java/eu/siacs/conversations/utils/Compatibility.java index f181853c64a9a2cadc33d2922727090f54d08fdc..10854187e00b7d1355ac3920a1cfe08d765a0ddf 100644 --- a/src/main/java/eu/siacs/conversations/utils/Compatibility.java +++ b/src/main/java/eu/siacs/conversations/utils/Compatibility.java @@ -47,6 +47,10 @@ public class Compatibility { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; } + public static boolean s() { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S; + } + private static boolean runsTwentyFour() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N; } From 0beb1e901a879871d15746aec6134cfe342dde07 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 10 Jul 2022 13:00:34 +0200 Subject: [PATCH 20/20] every device is 21+ now --- .../eu/siacs/conversations/persistance/FileBackend.java | 8 ++++---- .../java/eu/siacs/conversations/ui/util/Attachment.java | 2 +- .../java/eu/siacs/conversations/utils/Compatibility.java | 4 ---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 821899eb7500589ff0a77cf3f296d1f574f52f00..faeca6308938e7ef997676d81c297a0b26220296 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -437,7 +437,7 @@ public class FileBackend { return bitmap; } final String mime = attachment.getMime(); - if ("application/pdf".equals(mime) && Compatibility.runsTwentyOne()) { + if ("application/pdf".equals(mime)) { bitmap = cropCenterSquarePdf(attachment.getUri(), size); drawOverlay( bitmap, @@ -961,7 +961,7 @@ public class FileBackend { } DownloadableFile file = getFile(message); final String mime = file.getMimeType(); - if ("application/pdf".equals(mime) && Compatibility.runsTwentyOne()) { + if ("application/pdf".equals(mime)) { thumbnail = getPdfDocumentPreview(file, size); } else if (mime.startsWith("video/")) { thumbnail = getVideoPreview(file, size); @@ -1507,12 +1507,12 @@ public class FileBackend { body.append(url); } body.append('|').append(file.getSize()); - if (image || video || (pdf && Compatibility.runsTwentyOne())) { + if (image || video || pdf) { try { final Dimensions dimensions; if (video) { dimensions = getVideoDimensions(file); - } else if (pdf && Compatibility.runsTwentyOne()) { + } else if (pdf) { dimensions = getPdfDocumentDimensions(file); } else { dimensions = getImageDimensions(file); diff --git a/src/main/java/eu/siacs/conversations/ui/util/Attachment.java b/src/main/java/eu/siacs/conversations/ui/util/Attachment.java index b539c70efca6aafc6de8b998f323abbf055b06a1..f994955d0d300c01f61c2f8697c4012b367fec28 100644 --- a/src/main/java/eu/siacs/conversations/ui/util/Attachment.java +++ b/src/main/java/eu/siacs/conversations/ui/util/Attachment.java @@ -179,7 +179,7 @@ public class Attachment implements Parcelable { private static boolean renderFileThumbnail(final String mime) { return mime.startsWith("video/") || isImage(mime) - || (Compatibility.runsTwentyOne() && "application/pdf".equals(mime)); + || "application/pdf".equals(mime); } public Uri getUri() { diff --git a/src/main/java/eu/siacs/conversations/utils/Compatibility.java b/src/main/java/eu/siacs/conversations/utils/Compatibility.java index 10854187e00b7d1355ac3920a1cfe08d765a0ddf..33eb68ba84c6ef362e3e01f19b759294aae65bc2 100644 --- a/src/main/java/eu/siacs/conversations/utils/Compatibility.java +++ b/src/main/java/eu/siacs/conversations/utils/Compatibility.java @@ -43,10 +43,6 @@ public class Compatibility { return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; } - public static boolean runsTwentyOne() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; - } - public static boolean s() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S; }