From 07f4d99246d44910534080f396c3eb0cc850e04f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 4 Feb 2025 14:26:34 +0100 Subject: [PATCH 01/60] add better state tracking to SASL --- .../conversations/crypto/sasl/Anonymous.java | 19 +- .../conversations/crypto/sasl/DigestMd5.java | 241 ++++++++++++------ .../conversations/crypto/sasl/External.java | 17 +- .../conversations/crypto/sasl/Plain.java | 32 ++- .../crypto/sasl/SaslMechanism.java | 23 +- .../crypto/sasl/ScramMechanism.java | 1 - .../conversations/xmpp/XmppConnection.java | 17 +- 7 files changed, 237 insertions(+), 113 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/Anonymous.java b/src/main/java/eu/siacs/conversations/crypto/sasl/Anonymous.java index 6fc4b11ceed745cec500ff0e62759359d49792ba..0c8d9fb31ef92c02232e5d2898a920bee2ca312f 100644 --- a/src/main/java/eu/siacs/conversations/crypto/sasl/Anonymous.java +++ b/src/main/java/eu/siacs/conversations/crypto/sasl/Anonymous.java @@ -1,8 +1,9 @@ package eu.siacs.conversations.crypto.sasl; -import javax.net.ssl.SSLSocket; - +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import eu.siacs.conversations.entities.Account; +import javax.net.ssl.SSLSocket; public class Anonymous extends SaslMechanism { @@ -24,6 +25,20 @@ public class Anonymous extends SaslMechanism { @Override public String getClientFirstMessage(final SSLSocket sslSocket) { + Preconditions.checkState( + this.state == State.INITIAL, "Calling getClientFirstMessage from invalid state"); + this.state = State.AUTH_TEXT_SENT; return ""; } + + @Override + public String getResponse(final String challenge, final SSLSocket sslSocket) + throws AuthenticationException { + checkState(State.AUTH_TEXT_SENT); + if (Strings.isNullOrEmpty(challenge)) { + this.state = State.VALID_SERVER_RESPONSE; + return null; + } + throw new AuthenticationException("Unexpected server response"); + } } diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/DigestMd5.java b/src/main/java/eu/siacs/conversations/crypto/sasl/DigestMd5.java index b75d0883fd4a5bdbf6634a2cddf5054c40c02e26..0916b953f35a20021c39a991a5e5de239c3616a9 100644 --- a/src/main/java/eu/siacs/conversations/crypto/sasl/DigestMd5.java +++ b/src/main/java/eu/siacs/conversations/crypto/sasl/DigestMd5.java @@ -1,20 +1,25 @@ package eu.siacs.conversations.crypto.sasl; -import android.util.Base64; - -import java.nio.charset.Charset; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -import javax.net.ssl.SSLSocket; - +import android.util.Log; +import androidx.annotation.NonNull; +import com.google.common.base.Preconditions; +import com.google.common.base.Splitter; +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableMap; +import com.google.common.hash.Hashing; +import com.google.common.io.BaseEncoding; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.utils.CryptoHelper; +import java.nio.charset.Charset; +import java.util.Map; +import javax.net.ssl.SSLSocket; public class DigestMd5 extends SaslMechanism { public static final String MECHANISM = "DIGEST-MD5"; private State state = State.INITIAL; + private String precalculatedRSPAuth; public DigestMd5(final Account account) { super(account); @@ -31,84 +36,150 @@ public class DigestMd5 extends SaslMechanism { } @Override - public String getResponse(final String challenge, final SSLSocket sslSocket) + public String getClientFirstMessage(final SSLSocket sslSocket) { + Preconditions.checkState( + this.state == State.INITIAL, "Calling getClientFirstMessage from invalid state"); + this.state = State.AUTH_TEXT_SENT; + return ""; + } + + @Override + public String getResponse(final String challenge, final SSLSocket socket) + throws AuthenticationException { + return switch (state) { + case AUTH_TEXT_SENT -> processChallenge(challenge, socket); + case RESPONSE_SENT -> validateServerResponse(challenge); + case VALID_SERVER_RESPONSE -> validateUnnecessarySuccessMessage(challenge); + default -> throw new InvalidStateException(state); + }; + } + + // ejabberd sends the RSPAuth response as a challenge and then an empty success + // technically this is allowed as per https://datatracker.ietf.org/doc/html/rfc2222#section-5.2 + // although it says to do that only if the profile of the protocol does not allow data to be put + // into success. which xmpp does allow. obviously + private String validateUnnecessarySuccessMessage(final String challenge) + throws AuthenticationException { + if (Strings.isNullOrEmpty(challenge)) { + return ""; + } + throw new AuthenticationException("Success message must be empty"); + } + + private String validateServerResponse(final String challenge) throws AuthenticationException { + Log.d(Config.LOGTAG, "DigestMd5.validateServerResponse(" + challenge + ")"); + final var attributes = messageToAttributes(challenge); + Log.d(Config.LOGTAG, "attributes: " + attributes); + final var rspauth = attributes.get("rspauth"); + if (Strings.isNullOrEmpty(rspauth)) { + throw new AuthenticationException("no rspauth in server finish message"); + } + final var expected = this.precalculatedRSPAuth; + if (Strings.isNullOrEmpty(expected) || !this.precalculatedRSPAuth.equals(rspauth)) { + throw new AuthenticationException("RSPAuth mismatch"); + } + this.state = State.VALID_SERVER_RESPONSE; + return ""; + } + + private String processChallenge(final String challenge, final SSLSocket socket) throws AuthenticationException { - switch (state) { - case INITIAL: - state = State.RESPONSE_SENT; - final String encodedResponse; - try { - final Tokenizer tokenizer = - new Tokenizer(Base64.decode(challenge, Base64.DEFAULT)); - String nonce = ""; - for (final String token : tokenizer) { - final String[] parts = token.split("=", 2); - if (parts[0].equals("nonce")) { - nonce = parts[1].replace("\"", ""); - } else if (parts[0].equals("rspauth")) { - return ""; - } - } - final String digestUri = "xmpp/" + account.getServer(); - final String nonceCount = "00000001"; - final String x = - account.getUsername() - + ":" - + account.getServer() - + ":" - + account.getPassword(); - final MessageDigest md = MessageDigest.getInstance("MD5"); - final byte[] y = md.digest(x.getBytes(Charset.defaultCharset())); - final String cNonce = CryptoHelper.random(100); - final byte[] a1 = - CryptoHelper.concatenateByteArrays( - y, - (":" + nonce + ":" + cNonce) - .getBytes(Charset.defaultCharset())); - final String a2 = "AUTHENTICATE:" + digestUri; - final String ha1 = CryptoHelper.bytesToHex(md.digest(a1)); - final String ha2 = - CryptoHelper.bytesToHex( - md.digest(a2.getBytes(Charset.defaultCharset()))); - final String kd = - ha1 + ":" + nonce + ":" + nonceCount + ":" + cNonce + ":auth:" + ha2; - final String response = - CryptoHelper.bytesToHex( - md.digest(kd.getBytes(Charset.defaultCharset()))); - final String saslString = - "username=\"" - + account.getUsername() - + "\",realm=\"" - + account.getServer() - + "\",nonce=\"" - + nonce - + "\",cnonce=\"" - + cNonce - + "\",nc=" - + nonceCount - + ",qop=auth,digest-uri=\"" - + digestUri - + "\",response=" - + response - + ",charset=utf-8"; - encodedResponse = - Base64.encodeToString( - saslString.getBytes(Charset.defaultCharset()), Base64.NO_WRAP); - } catch (final NoSuchAlgorithmException e) { - throw new AuthenticationException(e); - } - - return encodedResponse; - case RESPONSE_SENT: - state = State.VALID_SERVER_RESPONSE; - break; - case VALID_SERVER_RESPONSE: - if (challenge == null) { - return null; // everything is fine - } - default: - throw new InvalidStateException(state); + Log.d(Config.LOGTAG, "DigestMd5.processChallenge()"); + this.state = State.RESPONSE_SENT; + final var attributes = messageToAttributes(challenge); + + final var nonce = attributes.get("nonce"); + + if (Strings.isNullOrEmpty(nonce)) { + throw new AuthenticationException("Server nonce missing"); + } + final String digestUri = "xmpp/" + account.getServer(); + final String nonceCount = "00000001"; + final String x = + account.getUsername() + ":" + account.getServer() + ":" + account.getPassword(); + final byte[] y = Hashing.md5().hashBytes(x.getBytes(Charset.defaultCharset())).asBytes(); + final String cNonce = CryptoHelper.random(100); + final byte[] a1 = + CryptoHelper.concatenateByteArrays( + y, (":" + nonce + ":" + cNonce).getBytes(Charset.defaultCharset())); + final String a2 = "AUTHENTICATE:" + digestUri; + final String ha1 = CryptoHelper.bytesToHex(Hashing.md5().hashBytes(a1).asBytes()); + final String ha2 = + CryptoHelper.bytesToHex( + Hashing.md5().hashBytes(a2.getBytes(Charset.defaultCharset())).asBytes()); + final String kd = ha1 + ":" + nonce + ":" + nonceCount + ":" + cNonce + ":auth:" + ha2; + + final String a2ForResponse = ":" + digestUri; + final String ha2ForResponse = + CryptoHelper.bytesToHex( + Hashing.md5() + .hashBytes(a2ForResponse.getBytes(Charset.defaultCharset())) + .asBytes()); + final String kdForResponseInput = + ha1 + ":" + nonce + ":" + nonceCount + ":" + cNonce + ":auth:" + ha2ForResponse; + + this.precalculatedRSPAuth = + CryptoHelper.bytesToHex( + Hashing.md5() + .hashBytes(kdForResponseInput.getBytes(Charset.defaultCharset())) + .asBytes()); + + final String response = + CryptoHelper.bytesToHex( + Hashing.md5().hashBytes(kd.getBytes(Charset.defaultCharset())).asBytes()); + + final String saslString = + "username=\"" + + account.getUsername() + + "\",realm=\"" + + account.getServer() + + "\",nonce=\"" + + nonce + + "\",cnonce=\"" + + cNonce + + "\",nc=" + + nonceCount + + ",qop=auth,digest-uri=\"" + + digestUri + + "\",response=" + + response + + ",charset=utf-8"; + return BaseEncoding.base64().encode(saslString.getBytes()); + } + + private static Map messageToAttributes(final String message) + throws AuthenticationException { + byte[] asBytes; + try { + asBytes = BaseEncoding.base64().decode(message); + } catch (final IllegalArgumentException e) { + throw new AuthenticationException("Unable to decode server challenge", e); + } + try { + return splitToAttributes(new String(asBytes)); + } catch (final IllegalArgumentException e) { + throw new AuthenticationException("Duplicate attributes"); + } + } + + private static Map splitToAttributes(final String message) { + final ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + for (final String token : Splitter.on(',').split(message)) { + final var tuple = Splitter.on('=').limit(2).splitToList(token); + if (tuple.size() == 2) { + final var value = tuple.get(1); + builder.put(tuple.get(0), trimQuotes(value)); + } + } + return builder.buildOrThrow(); + } + + public static String trimQuotes(@NonNull final String input) { + if (input.length() >= 2 + && input.charAt(0) == '"' + && input.charAt(input.length() - 1) == '"') { + return input.substring(1, input.length() - 1); } - return null; + return input; } } diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/External.java b/src/main/java/eu/siacs/conversations/crypto/sasl/External.java index 2e8adf1892d5332340e2a9fb28872223807f34df..056f022d1a091e47d5da91b0e083a7e2adf1654c 100644 --- a/src/main/java/eu/siacs/conversations/crypto/sasl/External.java +++ b/src/main/java/eu/siacs/conversations/crypto/sasl/External.java @@ -1,6 +1,7 @@ package eu.siacs.conversations.crypto.sasl; -import android.util.Base64; +import com.google.common.base.Preconditions; +import com.google.common.io.BaseEncoding; import eu.siacs.conversations.entities.Account; import javax.net.ssl.SSLSocket; @@ -24,7 +25,17 @@ public class External extends SaslMechanism { @Override public String getClientFirstMessage(final SSLSocket sslSocket) { - return Base64.encodeToString( - account.getJid().asBareJid().toString().getBytes(), Base64.NO_WRAP); + Preconditions.checkState( + this.state == State.INITIAL, "Calling getClientFirstMessage from invalid state"); + this.state = State.AUTH_TEXT_SENT; + final String message = account.getJid().asBareJid().toString(); + return BaseEncoding.base64().encode(message.getBytes()); + } + + @Override + public String getResponse(String challenge, SSLSocket sslSocket) + throws AuthenticationException { + // TODO check that state is in auth text sent and move to finished + return ""; } } diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java b/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java index 2be5d0bcb2a09482653b88df5ce4427adc6fe2ec..7ec4c2faab4f466c7bcb04470b692cfed16d41a1 100644 --- a/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java +++ b/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java @@ -1,12 +1,10 @@ package eu.siacs.conversations.crypto.sasl; -import android.util.Base64; - -import java.nio.charset.Charset; - -import javax.net.ssl.SSLSocket; - +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import com.google.common.io.BaseEncoding; import eu.siacs.conversations.entities.Account; +import javax.net.ssl.SSLSocket; public class Plain extends SaslMechanism { @@ -16,11 +14,6 @@ public class Plain extends SaslMechanism { super(account); } - public static String getMessage(String username, String password) { - final String message = '\u0000' + username + '\u0000' + password; - return Base64.encodeToString(message.getBytes(Charset.defaultCharset()), Base64.NO_WRAP); - } - @Override public int getPriority() { return 10; @@ -33,6 +26,21 @@ public class Plain extends SaslMechanism { @Override public String getClientFirstMessage(final SSLSocket sslSocket) { - return getMessage(account.getUsername(), account.getPassword()); + Preconditions.checkState( + this.state == State.INITIAL, "Calling getClientFirstMessage from invalid state"); + this.state = State.AUTH_TEXT_SENT; + final String message = '\u0000' + account.getUsername() + '\u0000' + account.getPassword(); + return BaseEncoding.base64().encode(message.getBytes()); + } + + @Override + public String getResponse(final String challenge, final SSLSocket sslSocket) + throws AuthenticationException { + checkState(State.AUTH_TEXT_SENT); + if (Strings.isNullOrEmpty(challenge)) { + this.state = State.VALID_SERVER_RESPONSE; + return null; + } + throw new AuthenticationException("Unexpected server response"); } } diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/SaslMechanism.java b/src/main/java/eu/siacs/conversations/crypto/sasl/SaslMechanism.java index 40f48a2392d6523ab4a6d573c1b116033b652f7a..d601f21023665f5e93dd7dba5827d8a19532ccb0 100644 --- a/src/main/java/eu/siacs/conversations/crypto/sasl/SaslMechanism.java +++ b/src/main/java/eu/siacs/conversations/crypto/sasl/SaslMechanism.java @@ -16,6 +16,8 @@ public abstract class SaslMechanism { protected final Account account; + protected State state = State.INITIAL; + protected SaslMechanism(final Account account) { this.account = account; } @@ -39,14 +41,10 @@ public abstract class SaslMechanism { public abstract String getMechanism(); - public String getClientFirstMessage(final SSLSocket sslSocket) { - return ""; - } + public abstract String getClientFirstMessage(final SSLSocket sslSocket); - public String getResponse(final String challenge, final SSLSocket sslSocket) - throws AuthenticationException { - return ""; - } + public abstract String getResponse(final String challenge, final SSLSocket sslSocket) + throws AuthenticationException; public enum State { INITIAL, @@ -55,6 +53,17 @@ public abstract class SaslMechanism { VALID_SERVER_RESPONSE, } + protected void checkState(final State expected) throws InvalidStateException { + final var current = this.state; + if (current == null) { + throw new InvalidStateException("Current state is null. Implementation problem"); + } + if (current != expected) { + throw new InvalidStateException( + String.format("State was %s. Expected %s", current, expected)); + } + } + public enum Version { SASL, SASL_2; diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/ScramMechanism.java b/src/main/java/eu/siacs/conversations/crypto/sasl/ScramMechanism.java index 0ee9b879c40fce893ab391d1182e727c8e9a86f7..db6f717033d6549b02a21bd1c24e99acea4dc487 100644 --- a/src/main/java/eu/siacs/conversations/crypto/sasl/ScramMechanism.java +++ b/src/main/java/eu/siacs/conversations/crypto/sasl/ScramMechanism.java @@ -48,7 +48,6 @@ public abstract class ScramMechanism extends SaslMechanism { protected final ChannelBinding channelBinding; private final String gs2Header; private final String clientNonce; - protected State state = State.INITIAL; private final String clientFirstMessageBare; private byte[] serverSignature = null; private DowngradeProtection downgradeProtection = null; diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index d02d533cadaf246a1390aa6edb9c42501ca31008..136904a17bdb764e20a208c3ba74b3de9dc91644 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -775,7 +775,9 @@ public class XmppConnection implements Runnable { throws IOException, XmlPullParserException { final LoginInfo currentLoginInfo = this.loginInfo; final SaslMechanism currentSaslMechanism = LoginInfo.mechanism(currentLoginInfo); - if (currentLoginInfo == null || currentSaslMechanism == null) { + if (currentLoginInfo == null + || LoginInfo.isSuccess(currentLoginInfo) + || currentSaslMechanism == null) { throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); } final SaslMechanism.Version version; @@ -987,9 +989,15 @@ public class XmppConnection implements Runnable { } catch (final IllegalArgumentException e) { throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); } + + final LoginInfo currentLoginInfo = this.loginInfo; + if (currentLoginInfo == null || LoginInfo.isSuccess(currentLoginInfo)) { + throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); + } + Log.d(Config.LOGTAG, failure.toString()); Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": login failure " + version); - if (SaslMechanism.hashedToken(LoginInfo.mechanism(this.loginInfo))) { + if (SaslMechanism.hashedToken(LoginInfo.mechanism(currentLoginInfo))) { Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": resetting token"); account.resetFastToken(); mXmppConnectionService.databaseBackend.updateAccount(account); @@ -1026,7 +1034,7 @@ public class XmppConnection implements Runnable { } } } - if (SaslMechanism.hashedToken(LoginInfo.mechanism(this.loginInfo))) { + if (SaslMechanism.hashedToken(LoginInfo.mechanism(currentLoginInfo))) { Log.d( Config.LOGTAG, account.getJid().asBareJid() @@ -2913,6 +2921,9 @@ public class XmppConnection implements Runnable { public void success(final String challenge, final SSLSocket sslSocket) throws SaslMechanism.AuthenticationException { + if (Thread.currentThread().isInterrupted()) { + throw new SaslMechanism.AuthenticationException("Race condition during auth"); + } final var response = this.saslMechanism.getResponse(challenge, sslSocket); if (!Strings.isNullOrEmpty(response)) { throw new SaslMechanism.AuthenticationException( From 8c8ac62fb96156798411cadc25c0033609ea2097 Mon Sep 17 00:00:00 2001 From: Ricky-Tigg Date: Wed, 5 Feb 2025 11:49:23 +0000 Subject: [PATCH 02/60] Translated using Weblate (Finnish) Currently translated at 80.4% (852 of 1059 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/fi/ --- src/main/res/values-fi/strings.xml | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/main/res/values-fi/strings.xml b/src/main/res/values-fi/strings.xml index eb29b28470c2891528ac3b4df5aec4dc61bee6a6..8734a2b9daae7173927c95d5852659019723e22d 100644 --- a/src/main/res/values-fi/strings.xml +++ b/src/main/res/values-fi/strings.xml @@ -119,13 +119,13 @@ Rauhanaika Kuinka pitkäksi aikaa ilmoitukset hiljennetään kun jollain toisella laitteillasi tehdään jotain. Edistyneet - Vikailmoituksia lähettämällä autat kehitystyötä - Lukukuittaus + Lähettämällä pinojälkiä autat Quicksyn jatkuvaa kehitystä + Vahvista viestit Ilmoita lähettäjälle kun olet vastaanottanut ja lukenut viestin Estä kuvankaappaukset Piilota sovelluksen sisältö sovellusvaihtajassa ja estä ruutukaappaukset Käyttöliittymä - OpenKeychain-virhe + OpenKeychain tuotti virheen. Avain ei kelpaa salaamiseen. Hyväksy Virhe tapahtui @@ -178,7 +178,7 @@ käyttäjä@esimerkki.fi Salasana Tämä ei ole kunnollinen XMPP-osoite - Muisti loppui. Kuva on liian suuri. + Muisti loppu. Kuva liian iso Lisätäänkö %s osoitekirjaan? Tietoa palvelimesta XEP-0313: MAM @@ -265,7 +265,7 @@ Kirjoita salasana Pyydä yhteystietoa ensin lähettämään tilapäivityksiä.\n\nTätä käytetään sen tunnistamiseen mitä sovellusta tämä käyttää. Pyydä nyt - Ohita + Jätä huomioimatta Varoitus: Tämän lähettäminen ilman molemminpuolisia tilapäivityksiä voi aiheuttaa odottamattomia ongelmia.\n\nMene \"Yhteystiedon tietoihin\" tarkistaaksesi tilapäivitysten tilauksesi. Turvallisuus Salli viestien korjaaminen @@ -484,10 +484,7 @@ Salli %1$s:n käyttää ulkoista tallennustilaa Salli %1$s:n käyttää kameraa Synkronoi yhteystietojen kanssa - %1$s haluaa pääsyn osoitekirjaasi yhdistääkseen sen XMPP-yhteystietojesi kanssa. -\nTämä näyttää yhteystietojesi koko nimen ja kuvan. -\n -\n%1$s pelkästään lukee osoitekirjaasi ja vertailee niitä paikallisesti, lähettämättä mitään palvelimelle. + %1$s käsittelee yhteystietoluettelosi paikallisesti laitteellasi näyttääkseen sinulle nimet ja profiilikuvat vastaavista XMPP-yhteystiedoista.\n\nMikään yhteystietoluettelo ei koskaan poistu laitteestasi! Ilmoita kaikista uusista viesteistä Ilmoita vain kun minut mainitaan Ilmoitukset pois käytöstä @@ -762,7 +759,7 @@ e-kirja Alkuperäinen (pakkaamaton) Avaa sovelluksella… - Conversations-profiilikuva + Keskustelun profiilikuva Valitse tili Palauta varmuuskopiosta Palauta @@ -929,4 +926,5 @@ Äänikirja Hiljaiset viestit Vaihdetaanko videopuheluun\? + Kanavahaku käyttää kolmannen osapuolen palvelua nimeltä <a href=https://search.jabber.network>search.jabber.network</a>.<br><br>Tämän ominaisuuden käyttäminen lähettää IP-osoitteesi ja hakutermit kyseiseen palveluun. Katso lisätietoja niiden <a href=https://search.jabber.network/privacy>tietosuojakäytännöstään</a>. \ No newline at end of file From 0634e767108baa307cb11ab7e8e5312c6543ffa7 Mon Sep 17 00:00:00 2001 From: Ricky-Tigg Date: Wed, 5 Feb 2025 11:41:15 +0000 Subject: [PATCH 03/60] Translated using Weblate (Finnish) Currently translated at 100.0% (9 of 9 strings) Translation: Conversations/Android App (Quicksy) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-quicksy/fi/ --- src/quicksy/res/values-fi/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/quicksy/res/values-fi/strings.xml b/src/quicksy/res/values-fi/strings.xml index 9a988a15db678f4e9df6f9968f143c15690945b1..505494d3cbfbd8bda9f0cc8eae19f4af8ca7cdf4 100644 --- a/src/quicksy/res/values-fi/strings.xml +++ b/src/quicksy/res/values-fi/strings.xml @@ -1,7 +1,7 @@ Kuinka kauan Quicksy pysyy hiljaa nähtyään toisella laitteellasi toimintaa - Lähettämällä virheenkorjaustietoja autat Quicksyn kehittäjiä + Lähettämällä pinojälkiä autat Quicksyn jatkuvaa kehitystä Kerro kaikille yhteystiedoillesi kun käytät Quicksya Saadaksesi ilmoituksia silloinkin kun näyttö on sammutettu, Quicksy pitää lisätä suojattujen sovellusten luetteloon. Quicksy-profiilikuva @@ -9,4 +9,4 @@ Palvelimen identiteetin varmennus epäonnistui. Tuntematon turvallisuusvirhe. Palvelimeen yhdistäminen aikakatkaistiin. - + \ No newline at end of file From 4ff4e4560208da20fa3409519d31bb16e33a5355 Mon Sep 17 00:00:00 2001 From: SomeTr Date: Thu, 6 Feb 2025 13:08:02 +0000 Subject: [PATCH 04/60] Translated using Weblate (Ukrainian) Currently translated at 100.0% (82 of 82 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/uk/ --- fastlane/metadata/android/uk/changelogs/4213204.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 fastlane/metadata/android/uk/changelogs/4213204.txt diff --git a/fastlane/metadata/android/uk/changelogs/4213204.txt b/fastlane/metadata/android/uk/changelogs/4213204.txt new file mode 100644 index 0000000000000000000000000000000000000000..02085584c6b1ce2f4da0bf6219240c1d2706fa7e --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/4213204.txt @@ -0,0 +1,4 @@ +* Можливість призупиняти аудіозапис, натискаючи на таймер +* Виправлено реакції у приватних повідомлень MUC +* Припинено прийом «резервних повідомлень» для реакцій, звітів та маркерів показу +* Додано ще кілька значків попереднього перегляду медіафайлів From b5ff8a1584cfcd6275d1ba24433c0e43c48dd083 Mon Sep 17 00:00:00 2001 From: Umeaman Date: Sat, 8 Feb 2025 15:34:13 +0000 Subject: [PATCH 05/60] Translated using Weblate (Swedish) Currently translated at 41.4% (34 of 82 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/sv/ --- fastlane/metadata/android/sv-SE/changelogs/42013.txt | 1 + fastlane/metadata/android/sv-SE/changelogs/42050.txt | 1 + 2 files changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/sv-SE/changelogs/42013.txt create mode 100644 fastlane/metadata/android/sv-SE/changelogs/42050.txt diff --git a/fastlane/metadata/android/sv-SE/changelogs/42013.txt b/fastlane/metadata/android/sv-SE/changelogs/42013.txt new file mode 100644 index 0000000000000000000000000000000000000000..b496bcf7fb8551fabe83dc20384bd1cb7af6dce4 --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/42013.txt @@ -0,0 +1 @@ +* Fixade problemen med 'Ingen anslutbarhet' i Android 7.1 diff --git a/fastlane/metadata/android/sv-SE/changelogs/42050.txt b/fastlane/metadata/android/sv-SE/changelogs/42050.txt new file mode 100644 index 0000000000000000000000000000000000000000..2e1bfb48446e68c364817b6642f83cc65a8ae36f --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/42050.txt @@ -0,0 +1 @@ +* Öka hörnradien på profilbilder From 5562a8b8aaef324de15c169ab97d848d233a9e13 Mon Sep 17 00:00:00 2001 From: tygyh Date: Sat, 8 Feb 2025 14:27:09 +0000 Subject: [PATCH 06/60] Translated using Weblate (Swedish) Currently translated at 100.0% (2 of 2 strings) Translation: Conversations/App Store Metadata (Conversations) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata-conversations/sv/ --- .../fastlane/metadata/android/sv-SE/full_description.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conversations/fastlane/metadata/android/sv-SE/full_description.txt b/src/conversations/fastlane/metadata/android/sv-SE/full_description.txt index c02bd4912c0f7ad4a8487a5f1360fd11f9d13c19..ca7864c971aaf60e383313a10151be2eb2ec8a95 100644 --- a/src/conversations/fastlane/metadata/android/sv-SE/full_description.txt +++ b/src/conversations/fastlane/metadata/android/sv-SE/full_description.txt @@ -28,7 +28,7 @@ Conversations fungerar med alla XMPP-servrar. Men XMPP är ett utbyggbart protok De XEP-tillägg som stöds är: -* XEP-0065: SOCKS5 Bytestreams (or mod_proxy65). Används för filöverföring om båda parter är bakom en brandvägg (NAT). +* XEP-0065: SOCKS5 Bytestreams (or mod_proxy65). Används för filöverföring om båda parter är bakom en brandvägg eller NAT. * XEP-0163: Personal Eventing Protocol för avatarer * XEP-0191: Blocking command låter dig svartlista spammare eller blocka kontakter utan att ta bort dem * XEP-0198: Stream Management låter XMPP att klara av mindre nätverksavbrott och förändringar i den underliggande TCP-anslutningen From b681e412bb1f5f7e2302cb904a9b0c9b2e00f963 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 11 Feb 2025 11:39:52 +0100 Subject: [PATCH 07/60] add force P2P menu item to failed HTTP uploads --- .../services/XmppConnectionService.java | 34 ++++++++++++------- .../ui/ConversationFragment.java | 29 +++++++++++----- src/main/res/menu/message_context.xml | 3 ++ src/main/res/values/strings.xml | 1 + 4 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 0ff7dbe6fceb11fd24763ee7b8cfb8b3785da4e2..7a177262013ac97db7ca6e1232b1da8a99b179fd 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -1816,11 +1816,15 @@ public class XmppConnectionService extends Service { } } - private void sendFileMessage(final Message message, final boolean delay) { - Log.d(Config.LOGTAG, "send file message"); - final Account account = message.getConversation().getAccount(); - if (account.httpUploadAvailable(fileBackend.getFile(message, false).getSize()) - || message.getConversation().getMode() == Conversation.MODE_MULTI) { + private void sendFileMessage( + final Message message, final boolean delay, final boolean forceP2P) { + final var account = message.getConversation().getAccount(); + Log.d( + Config.LOGTAG, + account.getJid().asBareJid() + ": send file message. forceP2P=" + forceP2P); + if ((account.httpUploadAvailable(fileBackend.getFile(message, false).getSize()) + || message.getConversation().getMode() == Conversation.MODE_MULTI) + && !forceP2P) { mHttpConnectionManager.createNewUploadConnection(message, delay); } else { mJingleConnectionManager.startJingleFileTransfer(message); @@ -1828,10 +1832,14 @@ public class XmppConnectionService extends Service { } public void sendMessage(final Message message) { - sendMessage(message, false, false); + sendMessage(message, false, false, false); } - private void sendMessage(final Message message, final boolean resend, final boolean delay) { + private void sendMessage( + final Message message, + final boolean resend, + final boolean delay, + final boolean forceP2P) { final Account account = message.getConversation().getAccount(); if (account.setShowErrorNotification(true)) { databaseBackend.updateAccount(account); @@ -1878,7 +1886,7 @@ public class XmppConnectionService extends Service { fileBackend.getFile(message, false).getSize()) || conversation.getMode() == Conversation.MODE_MULTI || message.fixCounterpart()) { - this.sendFileMessage(message, delay); + this.sendFileMessage(message, delay, forceP2P); } else { break; } @@ -1893,7 +1901,7 @@ public class XmppConnectionService extends Service { fileBackend.getFile(message, false).getSize()) || conversation.getMode() == Conversation.MODE_MULTI || message.fixCounterpart()) { - this.sendFileMessage(message, delay); + this.sendFileMessage(message, delay, forceP2P); } else { break; } @@ -1908,7 +1916,7 @@ public class XmppConnectionService extends Service { fileBackend.getFile(message, false).getSize()) || conversation.getMode() == Conversation.MODE_MULTI || message.fixCounterpart()) { - this.sendFileMessage(message, delay); + this.sendFileMessage(message, delay, forceP2P); } else { break; } @@ -2030,7 +2038,7 @@ public class XmppConnectionService extends Service { } public void resendMessage(final Message message, final boolean delay) { - sendMessage(message, true, delay); + sendMessage(message, true, delay, false); } public void requestEasyOnboardingInvite( @@ -5992,10 +6000,10 @@ public class XmppConnectionService extends Service { return this.mHttpConnectionManager; } - public void resendFailedMessages(final Message message) { + public void resendFailedMessages(final Message message, final boolean forceP2P) { message.setTime(System.currentTimeMillis()); markMessage(message, Message.STATUS_WAITING); - this.resendMessage(message, false); + this.sendMessage(message, true, false, forceP2P); if (message.getConversation() instanceof Conversation c) { c.sort(); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 20ed93c058fa244fd90ba8a61eb08c4940ec7ce9..498b08773cbfc37e7f9024a27bbb967bb2b5169b 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -1305,6 +1305,7 @@ public class ConversationFragment extends XmppFragment final MenuItem correctMessage = menu.findItem(R.id.correct_message); final MenuItem shareWith = menu.findItem(R.id.share_with); final MenuItem sendAgain = menu.findItem(R.id.send_again); + final MenuItem retryAsP2P = menu.findItem(R.id.send_again_as_p2p); final MenuItem copyUrl = menu.findItem(R.id.copy_url); final MenuItem downloadFile = menu.findItem(R.id.download_file); final MenuItem cancelTransmission = menu.findItem(R.id.cancel_transmission); @@ -1372,6 +1373,12 @@ public class ConversationFragment extends XmppFragment } if (m.getStatus() == Message.STATUS_SEND_FAILED) { sendAgain.setVisible(true); + final var fileNotUploaded = m.isFileOrImage() && !m.hasFileOnRemoteHost(); + final var isPeerOnline = + conversational.getMode() == Conversation.MODE_SINGLE + && (conversational instanceof Conversation c) + && !c.getContact().getPresences().isEmpty(); + retryAsP2P.setVisible(fileNotUploaded && isPeerOnline); } if (m.hasFileOnRemoteHost() || m.isGeoUri() @@ -1438,7 +1445,10 @@ public class ConversationFragment extends XmppFragment quoteMessage(selectedMessage); return true; case R.id.send_again: - resendMessage(selectedMessage); + resendMessage(selectedMessage, false); + return true; + case R.id.send_again_as_p2p: + resendMessage(selectedMessage, true); return true; case R.id.copy_url: ShareUtil.copyUrlToClipboard(activity, selectedMessage); @@ -2195,12 +2205,11 @@ public class ConversationFragment extends XmppFragment builder.create().show(); } - private void resendMessage(final Message message) { + private void resendMessage(final Message message, final boolean forceP2P) { if (message.isFileOrImage()) { - if (!(message.getConversation() instanceof Conversation)) { + if (!(message.getConversation() instanceof Conversation conversation)) { return; } - final Conversation conversation = (Conversation) message.getConversation(); final DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); if ((file.exists() && file.canRead()) || message.hasFileOnRemoteHost()) { @@ -2208,14 +2217,16 @@ public class ConversationFragment extends XmppFragment if (!message.hasFileOnRemoteHost() && xmppConnection != null && conversation.getMode() == Conversational.MODE_SINGLE - && !xmppConnection - .getFeatures() - .httpUpload(message.getFileParams().getSize())) { + && (!xmppConnection + .getFeatures() + .httpUpload(message.getFileParams().getSize()) + || forceP2P)) { activity.selectPresence( conversation, () -> { message.setCounterpart(conversation.getNextCounterpart()); - activity.xmppConnectionService.resendFailedMessages(message); + activity.xmppConnectionService.resendFailedMessages( + message, forceP2P); new Handler() .post( () -> { @@ -2238,7 +2249,7 @@ public class ConversationFragment extends XmppFragment return; } } - activity.xmppConnectionService.resendFailedMessages(message); + activity.xmppConnectionService.resendFailedMessages(message, false); new Handler() .post( () -> { diff --git a/src/main/res/menu/message_context.xml b/src/main/res/menu/message_context.xml index 831808db20be6e2000067d64355ce5fca351b849..aa572bcdf712b74c8732a15197269e80b48ac352 100644 --- a/src/main/res/menu/message_context.xml +++ b/src/main/res/menu/message_context.xml @@ -55,6 +55,9 @@ android:id="@+id/send_again" android:title="@string/send_again" android:visible="false" /> + Paste as quote Copy original URL Send again + Retry with P2P File URL Copied URL to clipboard Copied XMPP address to clipboard From 711543038f4fba5e9686f50dfe9bba6c7b62c185 Mon Sep 17 00:00:00 2001 From: Ricky-Tigg Date: Mon, 10 Feb 2025 13:34:25 +0000 Subject: [PATCH 08/60] Translated using Weblate (Finnish) Currently translated at 95.4% (1011 of 1059 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/fi/ --- src/main/res/values-fi/strings.xml | 186 ++++++++++++++++++++++++----- 1 file changed, 158 insertions(+), 28 deletions(-) diff --git a/src/main/res/values-fi/strings.xml b/src/main/res/values-fi/strings.xml index 8734a2b9daae7173927c95d5852659019723e22d..bcbf296e46109a7cd88c3eb9795e107e188b54f4 100644 --- a/src/main/res/values-fi/strings.xml +++ b/src/main/res/values-fi/strings.xml @@ -26,8 +26,8 @@ minuutti sitten %d minuuttia sitten - %d lukematon keskustelu - %d lukematonta keskustelua + %d lukematon pikakeskustelu + %d lukematonta pikakeskustelua lähettää… Puretaan viestin salausta. Odota hetki… @@ -39,7 +39,7 @@ Moderaattori Osallistuja Vierailija - Poistetaanko %s yhteystiedoistasi? Keskustelujasi hänen kanssaan ei poisteta. + Poistetaanko %s yhteystiedoistasi? Pikakeskustelujasi hänen kanssaan ei poisteta. Estetäänkö %s lähettämästä viestejä sinulle? Perutaanko %s:n esto lähettää viestejä sinulle? Estetäänkö kaikki yhteydet verkkotunnuksesta %s? @@ -76,7 +76,7 @@ Valmistaudutaan lähettämään kuvat Jaetaan tiedostoja. Odota hetki… Pyyhi historia - Pyyhi keskusteluhistoria + Pyyhi pikakeskusteluhistoria Poistetaanko kaikki keskustelun viestit? \n \nVaroitus: Muilla laitteilla tai palvelimilla säilytettyjä kopioita ei poisteta. @@ -85,12 +85,12 @@ \n \nVaroitus: Muilla laitteilla tai palvelimilla olevia kopioita ei poisteta. Valitse laite - Lähetä salaamaton viesti + Lähetä selkeä tekstiviesti Lähetä viesti Lähetä viesti henkilölle %s Lähetä v\\OMEMO-salattu viesti Uusi nimimerkki on jo varattu - Lähetä salaamaton + Lähetä selkeää tekstiä Salauksen purku epäonnistui. Sinulle ei varmaan ole oikeaa salaista avainta. OpenKeychain OpenKeychainia viestien salaamiseeen ja salauksen purkamiseen, sekä julkisten avaintesi hallinointiin.

Se on GPLv3+-lisensoitu ja saatavilla F-Droidista sekä Google Playsta.

(Käynnistä %1$s uudelleen asennettuasi sovelluksen.)]]>
@@ -159,7 +159,7 @@ TLS-kättely epäonnistui Verkkotunnuksen varmentaminen epäonnistui Yhteensopimaton palvelin - Salaamaton + Selkeä teksti OTR OpenPGP OMEMO @@ -171,7 +171,7 @@ Haluatko varmasti poistaa OpenPGP-avaimesi tilamainostuksistasi?\nYhteystietosi eivät voi enää lähettää sinulle OpenPGP-salattuja viestejä. OpenPGP julkinen avain julkaistu. Ota tunnus käyttöön - Haluatko varmasti poistaa tilisi? Tilin poistaminen pyyhkii koko keskusteluhistoriasi + Oletko varma, että haluat poistaa tilisi? Tilin poistaminen poistaa koko pikakeskusteluhistoriasi Nauhoita ääntä XMPP-osoite Estä XMPP-osoite @@ -268,7 +268,7 @@ Jätä huomioimatta Varoitus: Tämän lähettäminen ilman molemminpuolisia tilapäivityksiä voi aiheuttaa odottamattomia ongelmia.\n\nMene \"Yhteystiedon tietoihin\" tarkistaaksesi tilapäivitysten tilauksesi. Turvallisuus - Salli viestien korjaaminen + Viestin korjaus Mahdollistaa muiden muokata sinulle lähettämiään viestejä jälkikäteen Edistyneet asetukset Ole varovainen näiden kanssa @@ -302,8 +302,8 @@ XMPP-osoite kopioitu leikepöydälle Vikailmoitus kopioitu leikepöydälle web-osoite - Lue 2D-viivakoodi - Näytä 2D-viivakoodi + Skannaa QR-koodi + Näytä QR-koodi Näytä estolista Tilitiedot Vahvista @@ -438,7 +438,7 @@ Lataus epöonnistui: Isäntään ei saatu yhteyttä Lataus epäonnistui: Tiedoston tallennus epäonnistui Tor-verkkoa ei saavutettu - Palvelin ei vastaa tästä verkkotunnuksesta + Ei vastuussa toimialueesta Rikki Saatavuus Poissa kun laite on lukittu @@ -447,8 +447,8 @@ Näytä minut kiireisenä kun laite on äänettömänä Kohtele vain värinä -tilaa äänettömän lailla Näytä minut kiireisenä kun laite on vain värinä -tilassa - Laajemmat yhteysasetukset - Näytä isäntänimen ja portin valinta tiliä lisätessä + Isäntänimi ja portti + Näytä laajennetut yhteysasetukset tilin määrittämisen yhteydessä xmpp.esimerkki.fi Kirjaudu varmenteella Varmenteen jäsennys epäonnistui @@ -483,7 +483,7 @@ Kuvat jaettu %s:n kanssa Salli %1$s:n käyttää ulkoista tallennustilaa Salli %1$s:n käyttää kameraa - Synkronoi yhteystietojen kanssa + Yhteystietolistan integrointi %1$s käsittelee yhteystietoluettelosi paikallisesti laitteellasi näyttääkseen sinulle nimet ja profiilikuvat vastaavista XMPP-yhteystiedoista.\n\nMikään yhteystietoluettelo ei koskaan poistu laitteestasi! Ilmoita kaikista uusista viesteistä Ilmoita vain kun minut mainitaan @@ -528,7 +528,7 @@ Lyhyt Keskipitkä Pitkä - Kertoo yhteystiedoillesi milloin käytät Conversationsia + Anna yhteyshenkilöillesi nähdä, milloin viimeksi käytit sovellusta Yksityisyys Teema Valitse väripaletti @@ -575,7 +575,7 @@ Luota uusiin laitteisiin varmistamattomilta yhteystiedoilta, mutta vaadi varmistettujen yhteystietojen uusien laitteiden manuaalinen hyväksyminen. OMEMO-avaimiin luotetaan sokeasti, eli ne voivat olla jonkun muun tai joku voi salakuunnella. Ei luotettu - Viallinen 2D-viivakoodi + Virheellinen QR-koodi Tyhjennä välimuisti (kamerasovelluksen käyttämä) Tyhjennä välimuisti Siivoa yksityinen tallennustila @@ -657,7 +657,7 @@ Poista käytöstä nyt Luonnos: OMEMO-salaus - Uusissa keskusteluissa OMEMO otetaan oletuksena käyttöön. + Uusissa pikakeskusteluissa OMEMO otetaan oletuksena käyttöön. Luo pikakuvake Käytössä oletuksena Oletuksena pois käytöstä @@ -674,13 +674,13 @@ Odota hetki… Salli %1$s:n käyttää mikrofonia GIF - Näytä keskustelu + Näytä pikakeskustelu Sijainnin jako -lisäosa Käytä lisäosaa sisäänrakennetun kartan sijaan Kopioi web-osoite Kopioi XMPP-osoite Tiedostonjako HTTP:llä S3:een - \'Aloita keskustelu\' -näytöllä avaa näppäimistö ja siirrä kursori hakukenttään + \'Uusi pikakeskustelu\' -näytön esiintymisen yhteydessä, avaa näppäimistö ja aseta kohdistin hakukenttään Ryhmän kuvake Isäntäpalvelin ei tue ryhmäkeskustelun kuvakkeita Vain omistaja voi vaihtaa kuvakkeen @@ -722,20 +722,20 @@ Varmista %s %s.]]> Lähetimme sinulle uuden viestin 6-numeroisella koodilla. - Kirjoita 6-numeroinen PIN-koodi alapuolelle. + Syötä kuusinumeroinen PIN-koodi alle. Lähetä uusi tekstiviesti Lähetä uusi tekstivieti (%s) Odota (%s) - takaisin + Takaisin Mahdollinen PIN-koodi liitettiin leikepöydältä automaattisesti. - Syötä 6-numeroinen PIN-koodisi. + Syötä kuusinumeroinen PIN-koodisi. Haluatko varmasti perua rekisteröintiprosessin? Kyllä Ei Varmistetaan… Pyydetään tekstiviestiä… Syöttämäsi PIN-koodi on väärä. - Lähettämämme PIN-koodi on vanhentunut. + Sinulle lähettämämme PIN-koodi on vanhentunut. Tuntematon verkkovirhe. Tuntematon vastaus palvelimelta. Palvelimeen ei saatu yhteyttä. @@ -858,8 +858,8 @@ Irrota GPX-reitti Viestin korjaaminen epäonnistui - Kaikki keskustelut - Tämä keskustelu + Kaikki pikakeskustelut + Tämä pikakeskustelu Profiilikuvasi %s:n profiilikuva OMEMO-salattu @@ -890,7 +890,7 @@ Perustekstiasiakirja OMEMO:a käytetään aina kaikissa yksityisissä keskusteluissa. Etsi yhteystiedoista - OMEMO täytyy ottaa käyttöön käsin uusissa keskusteluissa. + OMEMO on otettava nimenomaisesti käyttöön uusille pikakeskusteluille. Ryhmäkeskustelut Etsi ryhmäkeskusteluista Suoraan hakuun @@ -905,7 +905,7 @@ Synkronoi kirjanmerkit Lähtevä puhelu (%s) · %s Lataus epäonnistui: Kelvoton tiedosto - Julkaise käyttö + Viimeksi nähty Jatka Kirjautunut ulos @@ -927,4 +927,134 @@ Hiljaiset viestit Vaihdetaanko videopuheluun\? Kanavahaku käyttää kolmannen osapuolen palvelua nimeltä <a href=https://search.jabber.network>search.jabber.network</a>.<br><br>Tämän ominaisuuden käyttäminen lähettää IP-osoitteesi ja hakutermit kyseiseen palveluun. Katso lisätietoja niiden <a href=https://search.jabber.network/privacy>tietosuojakäytännöstään</a>. + Opas on laadittu tilin luomista varten conversations.imissa.\nKun valitset palveluntarjoajaksi conversations.im, voit kommunikoida muiden palveluntarjoajien käyttäjien kanssa antamalla heille koko XMPP-osoitteesi. + Lähetä kaatumisraportit + Yhteyshenkilö pyytää läsnäolotilausta + Viivakoodi ei sisällä sormenjälkiä tälle pikakeskustelulle. + Vastaavat pikakeskustelut arkistoitu. + Viestien ilmoitusasetukset + Sinuun sovelletaan käyttörajoitus + Lisätäänkö lisää säikeitä? + Ulkoasu + Vaalea/tumma tila + Yhteyden aikakatkaisu + Käytännön rikkomus + Yhteensopimaton asiakas + Virtavirhe + Virran avaamisvirhe + Aseta \"autojoin\" -lippu, kun tulet MUC:hen tai poistut siitä ja reagoi muiden asiakkaiden tekemiin muutoksiin. + Poistuit tästä ryhmäpikakeskustelusta teknisistä syistä + %s:n sidossuhdetta ei voitu muuttaa + multimediatiedosto + Sidonnan epäonnistuminen + Laitteesi käyttää raskasta akun optimointia kohteelle %1$s, mikä voi johtaa viivästyneisiin ilmoituksiin tai jopa viestien katoamiseen.\n\nSinua pyydetään nyt poistamaan ne käytöstä. + Liity Conversationiin + Erilliset taustavärit lähetetyille ja vastaanotetuille viesteille + Epäluotettava laite + Viestejä ei noudeta paikallisen säilytysajan vuoksi. + Järjestelmän värit (Material You) + Ei kiinteä asento + Tätä ilmoitusluokkaa käytetään näyttämään pysyvä ilmoitus, joka ilmaisee, että %1$s on käynnissä. + Virheellinen käyttäjän syöte + Älä yritä palauttaa varmuuskopioita, joita et ole itse luonut! + Etsi osallistujat + Yhteyshenkilö ei ole saatavilla + Vaihda pikakeskusteluun + Tilin rekisteröintiä ei tueta + Poista avatar + Hylkää siirtyminen videopyyntöön + Siirry videoon + Työntö-palvelin + Ei mitään (poistettu käytöstä) + Hylkää + Poista tili palvelimelta + Tiliä ei voitu poistaa palvelimelta + Piilota ilmoitus + Kirjaudu ulos + Yhteystietosi käyttää vahvistamattomia laitteita. Skannaa heidän QR-koodinsa suorittaaksesi vahvistuksen ja estääksesi aktiiviset MITM-hyökkäykset. + Käytät vahvistamattomia laitteita. Skannaa QR-koodi muilla laitteillasi vahvistaaksesi ja estääksesi aktiiviset MITM-hyökkäykset. + Ilmoita roskapostista + Ilmoita roskapostista ja estä roskapostittaja + Puheluintegraatio ei ole saatavilla! + Poista ja arkistoi pikakeskustelu + Aloita pikakeskustelu + Käyttöliittymä + Teema, värit, kuvakaappaukset, syöttö + Turvallisuus + E2E-salaus, sokea luottamus ennen vahvistusta, MITM-tunnistus + Ilmoitusvälitys UnifiedPush-yhteensopiville kolmannen osapuolen sovelluksille + Ilmoitukset + Salli kuvakaappaukset + Päästä päähän -salaus + Varmenneviranomaiset + Luota järjestelmän CA-varmenteisiin + Edellyttää kanavan sidontaa + Kanavan sidonta voi havaita joitain koneen välissä olevia hyökkäyksiä + Palvelinyhteys + Kirjoitusilmoitukset, viimeksi nähty, saatavuus + Isäntänimi ja portti, Tor + Sitoutumisilmoitukset + Haluatko poistaa kirjanmerkin kohteesta %s? + Haluatko poistaa %s:n kirjanmerkin ja arkistoida pikakeskustelun? + Keskustelujen varmuuskopio + Yrität tuoda vanhentunutta varmuuskopiotiedostomuotoa + Piilota ei-aktiivinen + Laitteesi käyttää raskasta akun optimointia kohteelle %1$s, mikä voi johtaa viivästyneisiin ilmoituksiin tai jopa viestien katoamiseen.\nOn suositeltavaa poistaa ne käytöstä. + Ei lupaa puhelun soittamiseen + Tätä ilmoitusryhmää käytetään näyttämään ilmoituksia, joiden ei pitäisi laukaista ääntä. Esimerkiksi ollessasi aktiivinen toisella laitteella (armoaika). + Syötä nimesi, jotta ihmiset, joiden osoitekirjassa ei ole sinua, tietävät kuka olet. + Videota ei voitu poistaa käytöstä. + Quicksy pyytää suostumustasi tietojesi käyttöön + Uusi pikakeskustelu + Tälle yhteyshenkilölle ei ole käytettävissä avaimia.\nVarmista, että teillä molemmilla on läsnäolotilaus. + Tämä ei ole kelvollinen käyttäjänimi + Näytä ei-aktiivinen + Turvavirhe: Virheellinen tiedoston käyttöoikeus! + Tervetuloa Quicksyyn! + Dynaamiset värit + Isäntänimi ja portti, Tor, kanavan löytö + Näytä sovelluksen sisältö sovelluksen vaihtajassa ja salli kuvakaappausten ottaminen + Oletko varma, että haluat poistaa tämän laitteen vahvistuksen?\nTämä laite ja sen viestit merkitään \"Epäluotettava\":ksi. + Puhelut on poistettu käytöstä Toria käytettäessä + Asiakasvarmennetta ei ole valittu! + Tietosuojakäytäntö + Etsi maita + Yhteystietolistan integrointi ei ole saatavilla + Ei sidossuhdetta + Teksti jaettu %s:n kanssa + Huomioi ilmoitukset + Näytä huomioidut ilmoitukset + Kiinteä asento + Tallentamista ei voitu aloittaa + Tätä ilmoitusluokkaa käytetään näyttämään ilmoitus, jos tiliin yhdistämisessä on ongelma. + Käynnissä olevat puhelut + Tiedosto jätetty pois tietoturvarikkomuksen vuoksi. + Kirjaudu sisään + Jaa kanssa… + Värikkäät pikakeskustelukuplat + Arkistoi pikakeskustelu + Jaa kanssa… + Poista pikakeskustelu jälkeenpäin + Lähetä salattu viesti + Suorita toiminto kanssa + Vastaanotetaan + Automaattinen lataus + Käyttöjärjestelmä + Näppäimistö + Tiedoston koko, kuvan pakkaus, videon laatu + Armonaika, soittoääni, värinä, muukalaiset + Lähetetään + XMPP-osoitetta ei löytynyt + Väliaikainen todennuksen epäonnistuminen + XMPP-tili + Tili, jonka kautta työntöviestit vastaanotetaan. + Pikakeskustelu arkistoitu + Sinun avatarisi. Napauta valitaksesi uuden avatarin galleriasta. + XEP-0388: laajennettava SASL-profiili + Tälle yhteyshenkilölle ei ole käytettävissä avaimia.\nUusia avaimia ei voitu noutaa palvelimelta. Ehkä yhteystietosi palvelimessa on jotain vikaa? + Yhdistä uudelleen toiseen isäntään + Olet vahvistamassa oman tilisi OMEMO-avaimet. Tämä on turvallista vain, jos seurasit tätä linkkiä luotettavasta lähteestä, jossa vain sinä olisit voinut julkaista tämän linkin. + Sovellus + Vuorovaikutus + Laitteella \ No newline at end of file From 8211da59b43a3c32e7c0abd22c71c7fdbfff0902 Mon Sep 17 00:00:00 2001 From: Ricky-Tigg Date: Mon, 10 Feb 2025 13:01:43 +0000 Subject: [PATCH 09/60] Translated using Weblate (Finnish) Currently translated at 100.0% (2 of 2 strings) Translation: Conversations/App Store Metadata (Quicksy) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata-quicksy/fi/ --- .../metadata/android/fi-FI/full_description.txt | 14 ++++++++++++++ .../metadata/android/fi-FI/short_description.txt | 1 + 2 files changed, 15 insertions(+) create mode 100644 src/quicksy/fastlane/metadata/android/fi-FI/full_description.txt create mode 100644 src/quicksy/fastlane/metadata/android/fi-FI/short_description.txt diff --git a/src/quicksy/fastlane/metadata/android/fi-FI/full_description.txt b/src/quicksy/fastlane/metadata/android/fi-FI/full_description.txt new file mode 100644 index 0000000000000000000000000000000000000000..5030837b499c0cf1c524106486c7410c9d6ba908 --- /dev/null +++ b/src/quicksy/fastlane/metadata/android/fi-FI/full_description.txt @@ -0,0 +1,14 @@ +Quicksy on suositun Jabber/XMPP-asiakaskeskustelujen spin off, jossa on automaattinen yhteystietojen etsintä. + +Rekisteröidyt puhelinnumerollasi ja Quicksy ehdottaa sinulle automaattisesti mahdollisia yhteystietoja osoitekirjassasi olevien puhelinnumeroiden perusteella. + +Kotelon alla Quicksy on täysimittainen Jabber-asiakasohjelma, jonka avulla voit kommunikoida minkä tahansa käyttäjän kanssa millä tahansa julkisesti liitetyllä palvelimella. Samoin Quicksyn käyttäjiin voidaan ottaa yhteyttä ulkopuolelta yksinkertaisesti lisäämällä +puhelinnumero@quicksy.im yhteystietoluetteloosi. + +Yhteystietojen synkronoinnin lisäksi käyttöliittymä on tarkoituksella mahdollisimman lähellä keskusteluja. Tämän ansiosta käyttäjät voivat lopulta siirtyä Quicksystä Conversationsiin ilman, että heidän tarvitsee opetella uudelleen sovelluksen toimintaa. + +Ehdotetut yhteystiedot koostuvat muista Quicksy-käyttäjistä ja tavallisista Jabber/XMPP-käyttäjistä, jotka ovat syöttäneet Jabber-tunnuksensa Quicksy-hakemistoon (https://quicksy.im/#get-listed). + +Huomautus: Voit kirjoittaa (https://quicksy.im/enter/) Jabber-tunnuksesi Quicksyyn +Hakemistoon vaaditaan kertaluonteinen rekisteröintimaksu. + +Lue lisää tietosuojakäytännöstä (https://quicksy.im/#privacy). diff --git a/src/quicksy/fastlane/metadata/android/fi-FI/short_description.txt b/src/quicksy/fastlane/metadata/android/fi-FI/short_description.txt new file mode 100644 index 0000000000000000000000000000000000000000..9482dfa8200858b1c73a4d960d2943bb9d2ffdde --- /dev/null +++ b/src/quicksy/fastlane/metadata/android/fi-FI/short_description.txt @@ -0,0 +1 @@ +Jabber/XMPP helpolla syötyksellä ja helpolla löytämisellä From ea5ca035cdf531b8ae650b998af303ef87619988 Mon Sep 17 00:00:00 2001 From: Ricky-Tigg Date: Tue, 11 Feb 2025 13:21:56 +0000 Subject: [PATCH 10/60] Translated using Weblate (Finnish) Currently translated at 99.7% (1056 of 1059 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/fi/ --- src/main/res/values-fi/strings.xml | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/main/res/values-fi/strings.xml b/src/main/res/values-fi/strings.xml index bcbf296e46109a7cd88c3eb9795e107e188b54f4..4463331cf52f2762017dccad8668e4be1d153c49 100644 --- a/src/main/res/values-fi/strings.xml +++ b/src/main/res/values-fi/strings.xml @@ -1057,4 +1057,49 @@ Sovellus Vuorovaikutus Laitteella + Luo yksikertainen, ajoita toistuva + Luo yksikertainen varmuuskopio + Puhelussa käytetään langallisia kuulokkeita + Puhelussa käytetään kaiutinta. Napauta vaihtaaksesi kuulokkeisiin. + Puhelussa käytetään kaiutinta. + Puhelussa käytetään bluetoothia. + Käännä kamera + Video on kytketty päälle. Poista käytöstä napauttamalla. + Video on poistettu käytöstä. Ota käyttöön napauttamalla. + Sisäänkirjautumismekanismi + Taustaväri, kirjasinkoko, avatarit + Haluatko poistaa avatarisi? Jotkut asiakkaat saattavat edelleen näyttää avatarisi välimuistissa olevan kopion. + Suurenna viestikuplien kirjasinkokoa + Otetaanko mukautetut ilmoitusasetukset (tärkeys, ääni, värinä) käyttöön tälle keskustelulle? + Puhelua ei voitu muokata + Hyväksy kutsut ryhmäpikakeskusteluihin tuntemattomilta + Kutsut tuntemattomilta + Salli yksityisviestit + Suuri fontti + Toimintoa ei tueta + Muokkaa lempinimeä + Poista OpenPGP-avain + Muokkaa nimeä ja aihetta + Muuta kokoonpanoa + Muuta ilmoitusasetuksia + Puhelussa käytetään kuuloketta. Napauta vaihtaaksesi kaiuttimeen. + Toistuva varmuuskopio + Koko näyttö -ilmoitukset + Salli tämän sovelluksen näyttää saapuvien puhelujen ilmoitukset, jotka täyttävät koko näytön, kun laite on lukittuna. + Puhelussa käytetään kuulokkeita. + Yhteyshenkilösi XMPP-asiakasohjelma ei ehkä tue audio-/videopuheluita. + Reaktiota ei voitu lisätä + Lisää reaktio… + Puheluintegraatio + Tämän sovelluksen puhelut ovat vuorovaikutuksessa tavallisten puheluiden kanssa, kuten puhelun lopettaminen toisen alkaessa. + Vasemmalle tasatut viestit + Näytä kaikki viestit, mukaan lukien lähetetyt, vasemmalla puolella yhtenäisen pikakeskustelu-asettelun saavuttamiseksi. + Mukautetut ilmoitukset + Näytä vain yhteyshenkilöille + Lisää reaktio + Lisää reaktioita + Näytä avatarit viestillesi ja kahdenkeskisissä pikakeskusteluissa ryhmäpikakeskustelujen lisäksi. + Pikakeskustelukuplat + Näytä avatarit + Pikakeskustelukuplat \ No newline at end of file From a2f3287ae6eb0b3594e9c3c1884828d62638be82 Mon Sep 17 00:00:00 2001 From: solokot Date: Tue, 11 Feb 2025 20:40:41 +0000 Subject: [PATCH 11/60] Translated using Weblate (Russian) Currently translated at 100.0% (1059 of 1059 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/ru/ --- src/main/res/values-ru/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index a3ac3320c402eda6045ca0b3f858e9ef83ce701b..93586dd3cc95988c31faa9388bba33cb455f65bc 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -676,7 +676,7 @@ Автоматически удалять сообщения с этого устройства по прошествии заданного времени. Зашифровать сообщение Сообщения не загружаются в соответствии с локальным сроком хранения. - Сжимание видео + Сжатие видео Контакт заблокирован. Уведомления от неизвестных контактов Уведомлять о сообщениях и звонках от неизвестных контактов From 5db53f6124e642b05d83b287ad3b637fe806240c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Mon, 10 Feb 2025 21:48:26 +0000 Subject: [PATCH 12/60] Translated using Weblate (Estonian) Currently translated at 53.6% (44 of 82 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/et/ --- fastlane/metadata/android/et/changelogs/42042.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/42042.txt diff --git a/fastlane/metadata/android/et/changelogs/42042.txt b/fastlane/metadata/android/et/changelogs/42042.txt new file mode 100644 index 0000000000000000000000000000000000000000..82b99e472a3f3da9ac7018502b697e7e25680f59 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/42042.txt @@ -0,0 +1,2 @@ +* Parandasime kordussaatmise tsükli serverites, millel on vaid sm:2 tugi +* Näitame „Lülita ümber videole“ nuppu vaid siis, kui teine osapool toetab videovestlust From 0e6d4d8d56f7300a75b19d328c0a4c6dc07a3770 Mon Sep 17 00:00:00 2001 From: random_r Date: Wed, 12 Feb 2025 15:22:25 +0000 Subject: [PATCH 13/60] Translated using Weblate (Italian) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/it/ --- src/main/res/values-it/strings.xml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index be2a7f0660d624667f9cf161f22a04ff63154d00..71321b0bab64e56dc26b410a657b64b8d00a54f2 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -461,7 +461,7 @@ Scaricamento fallito: file non valido Rete Tor non disponibile Bind fallito - Il server non è responsabile per questo dominio + Non responsabile per il dominio Rotto Disponibilità \"Non disponibile\" a dispositivo bloccato @@ -1107,4 +1107,21 @@ Aggiungi reazione… Aggiungi reazione Altre reazioni + Connessione scaduta + Mostra solo ai contatti + Riprova con P2P + Impossibile modificare la chiamata + Il client XMPP del tuo contatto potrebbe non supportare le chiamate audio/video. + Integrazione di chiamate + Le chiamate da questa app interagiscono con le normali chiamate telefoniche, come terminare una chiamata quando un\'altra inizia. + Messaggi allineati a sinistra + Mostra gli avatar + Mostra gli avatar per i tuoi messaggi e nelle chat 1:1, in aggiunta alle chat di gruppo. + Attivare le impostazioni di notifica personalizzate (importanza, suono, vibrazione) per questa conversazione? + Mostra tutti i messaggi, inclusi quelli inviati, sul lato sinistro per una disposizione uniforme della chat. + Notifiche personalizzate + Vuoi eliminare il tuo avatar? Alcuni client potrebbero continuare a mostrare una copia in cache del tuo avatar. + Messaggi di chat + Colore di sfondo, dimensione caratteri, avatar + Messaggi di chat \ No newline at end of file From de7838cec9be31cff76e12c38e324d9c8b26c16d Mon Sep 17 00:00:00 2001 From: SomeTr Date: Wed, 12 Feb 2025 15:44:58 +0000 Subject: [PATCH 14/60] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/uk/ --- src/main/res/values-uk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-uk/strings.xml b/src/main/res/values-uk/strings.xml index a1935c2d9f79bbb30874da97580e532ec4561d56..f1389563dd717d42490104de894a1dcf1bba574b 100644 --- a/src/main/res/values-uk/strings.xml +++ b/src/main/res/values-uk/strings.xml @@ -1157,4 +1157,5 @@ Показувати лише контактам Бажаєте видалити свій аватар? Деякі клієнти можуть продовжувати відображати копію Вашого аватара з кешу. Час очікування з\'єднання вичерпано + Повторити спробу з P2P \ No newline at end of file From fa45c6508fbdb1f31b17b79ba8cf3abbf703c807 Mon Sep 17 00:00:00 2001 From: licaon-kter Date: Wed, 12 Feb 2025 13:01:42 +0000 Subject: [PATCH 15/60] Translated using Weblate (Romanian) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/ro/ --- src/main/res/values-ro-rRO/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index ccaca3d230b0240175cad6f77d90bc5b431aeba1..50d6c822c2d8c7f9152a1a3a6b8c85bdae28892c 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -1128,4 +1128,5 @@ Ați dori să vă ștergeți avatarul? Unii clienți ar putea să continue să arate o copie a avatarului. Arată doar contactelor Timp limită de conectare expirat + Reîncearcă cu P2P \ No newline at end of file From 3faa74c4827a6148fc489fc8587d8c689b3a8c6b Mon Sep 17 00:00:00 2001 From: Outbreak2096 Date: Wed, 12 Feb 2025 12:51:59 +0000 Subject: [PATCH 16/60] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/zh_Hans/ --- src/main/res/values-zh-rCN/strings.xml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index fbe2e682ba3003995dcd94b2399e118fc6a5657b..5731c8dd88b2a91f95ffd33e9c27f5b750e52d8f 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -414,7 +414,7 @@ 回复 标记为已读 输入 - Enter 即发送 + Enter 键发送 使用 Enter 键发送消息。即使禁用此选项,始终可以使用 Ctrl+Enter 发送消息。 显示 Enter 键 将表情符号键替换为 Enter 键 @@ -455,7 +455,7 @@ 以快捷操作替代“发送”按钮 快捷操作 - 最近使用 + 最近用过 选择快捷操作 搜索联系人 发送私信 @@ -617,9 +617,9 @@ 清理缓存 清理私人存储空间 清理保存文件的私人存储(可从服务器重新下载) - 我从可信来源收到此链接 - 点击链接后,您将验证 %1$s 的 OMEMO 密钥。只有从可信来源(只有 %2$s 可以发布此链接)收到此链接才是安全的。 - 您将验证自己账号的 OMEMO 密钥。只有从可信来源(只有您可以发布此链接)收到此链接才是安全的。 + 我从可信来源获得此链接 + 点击链接后,您将验证 %1$s 的 OMEMO 密钥。只有从可信来源(只有 %2$s 可以发布此链接)获得此链接才是安全的。 + 您将验证自己账号的 OMEMO 密钥。只有从可信来源(只有您可以发布此链接)获得此链接才是安全的。 继续 验证 OMEMO 密钥 显示非活动设备 @@ -662,8 +662,8 @@ 服务器要求在网站上注册 打开网站 未找到可以打开网站的应用 - 顶部通知 - 显示顶部通知 + 提醒式通知 + 显示提醒式通知 今天 昨天 用 DNSSEC 验证主机名 @@ -772,7 +772,7 @@ 电话号码 验证您的电话号码 Quicksy 将发送短信(运营商可能收费)来验证电话号码。请输入您的国家/地区代码和电话号码: -
%s

可以吗?是否编辑号码?]]>
+
%s

是否正确,或者编辑号码?]]>
%s 不是有效的电话号码。 请输入您的电话号码。 搜索国家/地区 @@ -785,7 +785,7 @@ 请稍候 (%s) 返回 已自动从剪贴板粘贴可能的 PIN 码。 - 请输入您的 6 位 PIN 码。 + 请输入六位数的 PIN 码。 是否确定要中止注册过程? @@ -1006,7 +1006,7 @@ 是否移除 %s 的书签并归档对话? 是否移除 %s 的书签? 删除并归档对话 - 频道发现使用称为 <a href=https://search.jabber.network>search.jabber.network</a> 的第三方服务。<br><br>使用此功能会将您的 IP 地址和搜索词传输到此服务。请参阅其 <a href=https://search.jabber.network/privacy>隐私政策</a> 以获取更多信息。 + 频道发现使用称为 <a href=https://search.jabber.network>search.jabber.network</a> 的第三方服务。<br><br>使用此功能会将您的 IP 地址和搜索词传输到此服务。如需更多信息,请参阅其<a href=https://search.jabber.network/privacy>隐私政策</a>。 开始对话 分享至… 为发送和接收的消息使用不同的背景颜色 @@ -1056,7 +1056,7 @@ 兼容 UnifiedPush 的第三方应用的通知转发器 发送加密消息 大字体 - 增加消息气泡中的字体大小 + 增大消息气泡中的字体大小 陌生人的邀请 接受来自陌生人的群聊邀请 创建一次性备份 @@ -1095,7 +1095,7 @@ 背景颜色、字体大小、头像 消息气泡 消息气泡 - 在群聊和一对一聊天中为您的消息显示头像。 + 在群聊和一对一聊天中为消息显示头像。 通话集成 自定义通知 是否为此对话启用自定义通知(重要程度、声音、振动)设置? @@ -1105,4 +1105,5 @@ 是否删除头像?某些客户端可能会继续显示您头像的缓存副本。 仅显示给联系人 连接超时 + 使用 P2P 重试 \ No newline at end of file From 6b814220b038c2d94bc248a56065535aebd0ba39 Mon Sep 17 00:00:00 2001 From: random_r Date: Wed, 12 Feb 2025 15:29:44 +0000 Subject: [PATCH 17/60] Translated using Weblate (Italian) Currently translated at 100.0% (82 of 82 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/it/ --- fastlane/metadata/android/it-IT/changelogs/4212404.txt | 2 ++ fastlane/metadata/android/it-IT/changelogs/4212504.txt | 1 + fastlane/metadata/android/it-IT/changelogs/4212604.txt | 2 ++ fastlane/metadata/android/it-IT/changelogs/4212704.txt | 1 + fastlane/metadata/android/it-IT/changelogs/4212804.txt | 3 +++ fastlane/metadata/android/it-IT/changelogs/4212904.txt | 2 ++ fastlane/metadata/android/it-IT/changelogs/4213104.txt | 2 ++ fastlane/metadata/android/it-IT/changelogs/4213204.txt | 4 ++++ 8 files changed, 17 insertions(+) create mode 100644 fastlane/metadata/android/it-IT/changelogs/4212404.txt create mode 100644 fastlane/metadata/android/it-IT/changelogs/4212504.txt create mode 100644 fastlane/metadata/android/it-IT/changelogs/4212604.txt create mode 100644 fastlane/metadata/android/it-IT/changelogs/4212704.txt create mode 100644 fastlane/metadata/android/it-IT/changelogs/4212804.txt create mode 100644 fastlane/metadata/android/it-IT/changelogs/4212904.txt create mode 100644 fastlane/metadata/android/it-IT/changelogs/4213104.txt create mode 100644 fastlane/metadata/android/it-IT/changelogs/4213204.txt diff --git a/fastlane/metadata/android/it-IT/changelogs/4212404.txt b/fastlane/metadata/android/it-IT/changelogs/4212404.txt new file mode 100644 index 0000000000000000000000000000000000000000..f553324498ea3b3f1947f3a279bd3c89c3f9a6c8 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/4212404.txt @@ -0,0 +1,2 @@ +* Mostra sempre il pulsante di chiamata +* Varie correzioni di errori diff --git a/fastlane/metadata/android/it-IT/changelogs/4212504.txt b/fastlane/metadata/android/it-IT/changelogs/4212504.txt new file mode 100644 index 0000000000000000000000000000000000000000..e904c43f2d2f1ca2fad8bb29e61603a8e7a148a8 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/4212504.txt @@ -0,0 +1 @@ +* migliorata la gestione di alcune reazioni con emoji diff --git a/fastlane/metadata/android/it-IT/changelogs/4212604.txt b/fastlane/metadata/android/it-IT/changelogs/4212604.txt new file mode 100644 index 0000000000000000000000000000000000000000..bc300b00c49fbe9dc86129e0cbd73b02a76df133 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/4212604.txt @@ -0,0 +1,2 @@ +* Spostati i messaggi più vicini tra di loro invece di unirli +* Aggiunta possibilità di nascondere gli avatar nelle chat quando non strettamente necessario (Impostazioni -> Interfaccia -> Messaggi di chat -> Mostra avatar) diff --git a/fastlane/metadata/android/it-IT/changelogs/4212704.txt b/fastlane/metadata/android/it-IT/changelogs/4212704.txt new file mode 100644 index 0000000000000000000000000000000000000000..3c532a0d2e2620c9c08f17fafad1fac4cacdeac8 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/4212704.txt @@ -0,0 +1 @@ +* Aggiunta possibilità di mostrare i messaggi allineati a sinistra diff --git a/fastlane/metadata/android/it-IT/changelogs/4212804.txt b/fastlane/metadata/android/it-IT/changelogs/4212804.txt new file mode 100644 index 0000000000000000000000000000000000000000..f8b3ac15aa1c5e3b5421677b4fb494f47fff6d2c --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/4212804.txt @@ -0,0 +1,3 @@ +* Accesso più facile a suoni di notifica personalizzati via Dettagli del contatto -> Menu -> Notifiche personalizzate +* Corretto destinatari delle condivisioni dirette sulle nuove versioni di Android +* Possibilità di limitare la visibilità degli avatar ai soli contatti diff --git a/fastlane/metadata/android/it-IT/changelogs/4212904.txt b/fastlane/metadata/android/it-IT/changelogs/4212904.txt new file mode 100644 index 0000000000000000000000000000000000000000..ec9bb831ee2ce91269921d094231e1dbcb8e6f06 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/4212904.txt @@ -0,0 +1,2 @@ +* Corretti alcuni errori minori dell'interfaccia +* Corretti problemi di connessione con domini .onion su porte non predefinite diff --git a/fastlane/metadata/android/it-IT/changelogs/4213104.txt b/fastlane/metadata/android/it-IT/changelogs/4213104.txt new file mode 100644 index 0000000000000000000000000000000000000000..63b2ef9824fc0a3ffad7c1d92615a7c24323976c --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/4213104.txt @@ -0,0 +1,2 @@ +* Utilizzo di SASL SCRAM Downgrade Protection (XEP-0474) +* Invio di reazioni a messaggi privati in gruppi al JID corretto diff --git a/fastlane/metadata/android/it-IT/changelogs/4213204.txt b/fastlane/metadata/android/it-IT/changelogs/4213204.txt new file mode 100644 index 0000000000000000000000000000000000000000..f152707bedaf558307521cd477396be3518a61dd --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/4213204.txt @@ -0,0 +1,4 @@ +* Consenti di mettere in pausa registrazioni audio toccando il timer +* Corrette reazioni in messaggi privati dei gruppi +* Non accettare più 'messaggi di ripiego' per le reazioni, ricevute e display markers +* Aggiunte ulteriori icone di anteprime media From 9c084c569b8390f5b5c1729c770790f9d9b4ab3e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 14 Feb 2025 08:29:18 +0100 Subject: [PATCH 18/60] write migration to store raw localparts in account table --- .../persistance/DatabaseBackend.java | 79 ++++++++++++++----- 1 file changed, 59 insertions(+), 20 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 0ff55672cff82c01c0ad574cc62799fc0d91bc5e..efbc1d7227ea3531b426b7405c4a42c1e6f325dc 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -48,6 +48,8 @@ import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; import org.json.JSONException; import org.json.JSONObject; +import org.jxmpp.jid.parts.Localpart; +import org.jxmpp.stringprep.XmppStringprepException; import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKeyPair; import org.whispersystems.libsignal.InvalidKeyException; @@ -59,7 +61,7 @@ import org.whispersystems.libsignal.state.SignedPreKeyRecord; public class DatabaseBackend extends SQLiteOpenHelper { private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 52; + private static final int DATABASE_VERSION = 53; private static boolean requiresMessageIndexRebuild = false; private static DatabaseBackend instance = null; @@ -1053,6 +1055,37 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Message.REACTIONS + " TEXT"); } + if (oldVersion < 53 && newVersion >= 53) { + try (final Cursor cursor = + db.query( + Account.TABLENAME, + new String[] {Account.UUID, Account.USERNAME}, + null, + null, + null, + null, + null)) { + while (cursor != null && cursor.moveToNext()) { + final var uuid = cursor.getString(0); + final var username = cursor.getString(1); + final Localpart localpart; + try { + localpart = Localpart.fromUnescaped(username); + } catch (final XmppStringprepException e) { + Log.d(Config.LOGTAG, "unable to parse jid"); + continue; + } + final var contentValues = new ContentValues(); + contentValues.putNull(Account.ROSTERVERSION); + contentValues.put(Account.USERNAME, localpart.toString()); + db.update( + Account.TABLENAME, + contentValues, + Account.UUID + "=?", + new String[] {uuid}); + } + } + } } private void canonicalizeJids(SQLiteDatabase db) { @@ -1064,21 +1097,24 @@ public class DatabaseBackend extends SQLiteOpenHelper { String newJid; try { newJid = - Jid.of(cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID))) + Jid.of( + cursor.getString( + cursor.getColumnIndexOrThrow( + Conversation.CONTACTJID))) .toString(); - } catch (IllegalArgumentException ignored) { + } catch (final IllegalArgumentException e) { Log.e( Config.LOGTAG, "Failed to migrate Conversation CONTACTJID " - + cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID)) - + ": " - + ignored - + ". Skipping..."); + + cursor.getString( + cursor.getColumnIndexOrThrow(Conversation.CONTACTJID)) + + ". Skipping...", + e); continue; } final String[] updateArgs = { - newJid, cursor.getString(cursor.getColumnIndex(Conversation.UUID)), + newJid, cursor.getString(cursor.getColumnIndexOrThrow(Conversation.UUID)), }; db.execSQL( "update " @@ -1098,12 +1134,14 @@ public class DatabaseBackend extends SQLiteOpenHelper { while (cursor.moveToNext()) { String newJid; try { - newJid = Jid.of(cursor.getString(cursor.getColumnIndex(Contact.JID))).toString(); + newJid = + Jid.of(cursor.getString(cursor.getColumnIndexOrThrow(Contact.JID))) + .toString(); } catch (final IllegalArgumentException e) { Log.e( Config.LOGTAG, "Failed to migrate Contact JID " - + cursor.getString(cursor.getColumnIndex(Contact.JID)) + + cursor.getString(cursor.getColumnIndexOrThrow(Contact.JID)) + ": Skipping...", e); continue; @@ -1111,8 +1149,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { final String[] updateArgs = { newJid, - cursor.getString(cursor.getColumnIndex(Contact.ACCOUNT)), - cursor.getString(cursor.getColumnIndex(Contact.JID)), + cursor.getString(cursor.getColumnIndexOrThrow(Contact.ACCOUNT)), + cursor.getString(cursor.getColumnIndexOrThrow(Contact.JID)), }; db.execSQL( "update " @@ -1137,24 +1175,25 @@ public class DatabaseBackend extends SQLiteOpenHelper { try { newServer = Jid.of( - cursor.getString(cursor.getColumnIndex(Account.USERNAME)), - cursor.getString(cursor.getColumnIndex(Account.SERVER)), + cursor.getString( + cursor.getColumnIndexOrThrow(Account.USERNAME)), + cursor.getString( + cursor.getColumnIndexOrThrow(Account.SERVER)), null) .getDomain() .toString(); - } catch (IllegalArgumentException ignored) { + } catch (final IllegalArgumentException e) { Log.e( Config.LOGTAG, "Failed to migrate Account SERVER " - + cursor.getString(cursor.getColumnIndex(Account.SERVER)) - + ": " - + ignored - + ". Skipping..."); + + cursor.getString(cursor.getColumnIndexOrThrow(Account.SERVER)) + + ". Skipping...", + e); continue; } String[] updateArgs = { - newServer, cursor.getString(cursor.getColumnIndex(Account.UUID)), + newServer, cursor.getString(cursor.getColumnIndexOrThrow(Account.UUID)), }; db.execSQL( "update " From fe0e3a10648ea2cf6643421d2dc04406bd94220f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 14 Feb 2025 08:29:36 +0100 Subject: [PATCH 19/60] add some extra hostname validation --- .../java/eu/siacs/conversations/xmpp/Jid.java | 17 +++++++++++++---- src/main/res/values/strings.xml | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/Jid.java b/src/main/java/eu/siacs/conversations/xmpp/Jid.java index c6b26903f32bea1deb59182cda9938112bf4bbc2..a83c762872b18f9b6f9a17a2662016ecd64c4297 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/Jid.java +++ b/src/main/java/eu/siacs/conversations/xmpp/Jid.java @@ -1,9 +1,10 @@ package eu.siacs.conversations.xmpp; import androidx.annotation.NonNull; -import com.google.common.base.CharMatcher; +import eu.siacs.conversations.utils.IP; import im.conversations.android.xmpp.model.stanza.Stanza; import java.io.Serializable; +import java.util.regex.Pattern; import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.parts.Domainpart; import org.jxmpp.jid.parts.Localpart; @@ -12,6 +13,10 @@ import org.jxmpp.stringprep.XmppStringprepException; public abstract class Jid implements Comparable, Serializable, CharSequence { + private static final Pattern HOSTNAME_PATTERN = + Pattern.compile( + "^(?=.{1,253}$)(?=.{1,253}$)(?!-)(?!.*--)(?!.*-$)[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)*$"); + public static Jid of( final CharSequence local, final CharSequence domain, final CharSequence resource) { if (local == null) { @@ -77,10 +82,14 @@ public abstract class Jid implements Comparable, Serializable, CharSequence public static Jid ofUserInput(final CharSequence input) { final var jid = of(input); - if (CharMatcher.is('@').matchesAnyOf(jid.getDomain())) { - throw new IllegalArgumentException("Domain should not contain @"); + final var domain = jid.getDomain().toString(); + if (domain.isEmpty()) { + throw new IllegalArgumentException("Domain can not be empty"); + } + if (HOSTNAME_PATTERN.matcher(domain).matches() || IP.matches(domain)) { + return jid; } - return jid; + throw new IllegalArgumentException("Invalid hostname"); } public static Jid ofOrInvalid(final String input) { diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index d10e1b7aa6d1c55328d4492fb1fd01e227b28818..e143b167cc19d9189fd545eebf32737505493109 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -171,6 +171,7 @@ Incompatible client Stream error Stream opening error + Channel binding unavailable Clear text OTR OpenPGP From 021f39375f1747ced9c39a97f6d61732f1383852 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 14 Feb 2025 08:46:25 +0100 Subject: [PATCH 20/60] introduce dedicated channel binding error state --- src/main/java/eu/siacs/conversations/entities/Account.java | 3 +++ src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index f55618fe2baeded03cbe51bd7e298d084011ce50..4d4c4e8d3bd5996f972cb489d6b1d320e571dc90 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -793,6 +793,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable REGISTRATION_PASSWORD_TOO_WEAK(true, false), TLS_ERROR, TLS_ERROR_DOMAIN, + CHANNEL_BINDING, INCOMPATIBLE_SERVER, INCOMPATIBLE_CLIENT, TOR_NOT_AVAILABLE, @@ -871,6 +872,8 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable return R.string.account_status_incompatible_server; case INCOMPATIBLE_CLIENT: return R.string.account_status_incompatible_client; + case CHANNEL_BINDING: + return R.string.account_status_channel_binding; case TOR_NOT_AVAILABLE: return R.string.account_status_tor_unavailable; case BIND_FAILURE: diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 136904a17bdb764e20a208c3ba74b3de9dc91644..2d7e0e52125121be8c8fe97b618c9eacb9881bc3 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -1696,7 +1696,7 @@ public class XmppConnection implements Runnable { return; } Log.d(Config.LOGTAG, account.getJid() + ": server did not offer channel binding"); - throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); + throw new StateChangingException(Account.State.CHANNEL_BINDING); } } From d81675224ae21a5f948fa57a3f9f2f821d883982 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 14 Feb 2025 08:53:56 +0100 Subject: [PATCH 21/60] remove special treatment for nimbuzz --- .../java/eu/siacs/conversations/crypto/sasl/SaslMechanism.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/SaslMechanism.java b/src/main/java/eu/siacs/conversations/crypto/sasl/SaslMechanism.java index d601f21023665f5e93dd7dba5827d8a19532ccb0..0aa147f95908d87beee26721118b03a089d0941d 100644 --- a/src/main/java/eu/siacs/conversations/crypto/sasl/SaslMechanism.java +++ b/src/main/java/eu/siacs/conversations/crypto/sasl/SaslMechanism.java @@ -129,8 +129,7 @@ public abstract class SaslMechanism { return new ScramSha256(account); } else if (mechanisms.contains(ScramSha1.MECHANISM)) { return new ScramSha1(account); - } else if (mechanisms.contains(Plain.MECHANISM) - && !account.getServer().equals("nimbuzz.com")) { + } else if (mechanisms.contains(Plain.MECHANISM)) { return new Plain(account); } else if (mechanisms.contains(DigestMd5.MECHANISM)) { return new DigestMd5(account); From 98b84f320a9a301d10e24a93b3ecde9ae09b67ef Mon Sep 17 00:00:00 2001 From: nautilusx Date: Wed, 12 Feb 2025 18:01:19 +0000 Subject: [PATCH 22/60] Translated using Weblate (German) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/de/ --- src/main/res/values-de/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 8925c0e35094d6a2af6ce7ca8487505e9b1574f9..2e349cafb2f3d8214c01349e635e28c4f38290a0 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -1109,4 +1109,5 @@ Möchtest du deinen Profilbild löschen? Einige Clients zeigen möglicherweise weiterhin eine zwischengespeicherte Kopie deines Profilbildes an. Nur für Kontakte anzeigen Zeitüberschreitung beim Verbinden + Erneut mit P2P versuchen \ No newline at end of file From 27866d45ade76f8aaa2c85dda691b0600868fa0d Mon Sep 17 00:00:00 2001 From: ghose Date: Thu, 13 Feb 2025 07:04:36 +0000 Subject: [PATCH 23/60] Translated using Weblate (Galician) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/gl/ --- src/main/res/values-gl/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 057c9eb5a24179a63574df143b64e84804d6f55f..621b2688499c553cca0c110eb31bd0623e3a6c51 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -1109,4 +1109,5 @@ Queres eliminar o teu avatar? Algúns clientes poderían continuar mostrando unha copia almacenada do teu avatar. Mostrar só aos contactos Caducidade da conexión + Reintentar con P2P \ No newline at end of file From b7dc3adb4678c66bbf5e2deed66306e5bc3fe67e Mon Sep 17 00:00:00 2001 From: Stephan-P Date: Thu, 13 Feb 2025 03:00:08 +0000 Subject: [PATCH 24/60] Translated using Weblate (Dutch) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/nl/ --- src/main/res/values-nl/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index 48f137cfd19fda1a0675743a6d83c53ccf975795..4416699e27bb31dadd1064444a4631c37ad72ca3 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -1125,4 +1125,5 @@ Alleen weergeven aan contacten Wil je je avatar verwijderen? Sommige clients kunnen nog steeds een kopie van jouw avatar in de cache weergeven. Time-out voor verbinding + Opnieuw proberen met P2P \ No newline at end of file From ab44d92c89be70ffedc1a20e3a3cbc704b004146 Mon Sep 17 00:00:00 2001 From: Grzegorz Szymaszek Date: Thu, 13 Feb 2025 14:20:33 +0000 Subject: [PATCH 25/60] Translated using Weblate (Polish) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/pl/ --- src/main/res/values-pl/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 975674a18ebd4a14d599995f4ec5a129b53e601e..f875158e509dbe96ef9295392aba157c764c1931 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -1141,4 +1141,5 @@ Czy chcesz usunąć swój awatar? Niektórzy klienci mogą nadal pokazywać zachowaną kopię. Pokazuj wyłącznie kontaktom Limit czasu połączenia + Spróbuj ponownie używając P2P \ No newline at end of file From 3d54804cd7860a7fca832cb1845935b75bf4d86d Mon Sep 17 00:00:00 2001 From: solokot Date: Thu, 13 Feb 2025 17:09:55 +0000 Subject: [PATCH 26/60] Translated using Weblate (Russian) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/ru/ --- src/main/res/values-ru/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index 93586dd3cc95988c31faa9388bba33cb455f65bc..edf4082e75290018175874c7e07b9e51201665c0 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -1156,4 +1156,5 @@ Хотите удалить свой аватар? Некоторые клиенты могут продолжать отображать кэшированную копию вашего аватара. Показывать только контактам Истекло время ожидания подключения + Повторить через P2P \ No newline at end of file From db39d60fdcc41dcdf76402afa14713e613c2da57 Mon Sep 17 00:00:00 2001 From: "lucasmz.dev" Date: Thu, 13 Feb 2025 04:27:45 +0000 Subject: [PATCH 27/60] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/pt_BR/ --- src/main/res/values-pt-rBR/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml index e299526a916bac6ef2e71bf1da83dc3ffe57df43..aa72a9ec3286e871455f600df176c816be0eacab 100644 --- a/src/main/res/values-pt-rBR/strings.xml +++ b/src/main/res/values-pt-rBR/strings.xml @@ -1127,4 +1127,5 @@ Mostrar somente para contatos Você gostaria de excluir seu avatar? Alguns clientes podem continuar mostrando uma cópia em cache do seu avatar. Conexão demorou muito + Tentar novamente com P2P \ No newline at end of file From 13d86023dc9b3c2d7924521e83e7a76632871da0 Mon Sep 17 00:00:00 2001 From: Besnik_b Date: Thu, 13 Feb 2025 09:42:54 +0000 Subject: [PATCH 28/60] Translated using Weblate (Albanian) Currently translated at 99.1% (1051 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/sq/ --- src/main/res/values-sq-rAL/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-sq-rAL/strings.xml b/src/main/res/values-sq-rAL/strings.xml index 4dbaba482ea931331449890164621c661876d213..b8c64aba80be703b19ccb5b5d8ca0941584fbd73 100644 --- a/src/main/res/values-sq-rAL/strings.xml +++ b/src/main/res/values-sq-rAL/strings.xml @@ -1120,4 +1120,5 @@ Shfaqja vetëm kontakteve Doni të fshihet avatari jua? Disa klientë mund të vazhdojnë të shfaqin një kopje të ruajtur në fshehtinat e tyre të avatarit tuaj. Mbarim kohe për lidhjen + Riprovo me P2P \ No newline at end of file From 129c0532ebb6568afa357cbd4574a69578f71d30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 12 Feb 2025 21:37:09 +0000 Subject: [PATCH 29/60] Translated using Weblate (Estonian) Currently translated at 100.0% (1060 of 1060 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/et/ --- src/main/res/values-et/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-et/strings.xml b/src/main/res/values-et/strings.xml index 6ced340fc2890d092fe33c8f2299cf883eaf7c95..e4fbb81f23fa865b773ba96616fc310efdf6e324 100644 --- a/src/main/res/values-et/strings.xml +++ b/src/main/res/values-et/strings.xml @@ -1129,4 +1129,5 @@ Kas sa sooviksid oma tunnuspildi kustutada? Palun arvesta, et mitmed klientrakendused võivad jätkata vana puhverdatud pildi kasutamist. Näita vaid kontaktidele Ühenduse on aegunud + Proovi uuesti võrdõigusvõrguga \ No newline at end of file From a04976601fcdf13a8162eab293e7230a2cdfab8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 12 Feb 2025 21:49:07 +0000 Subject: [PATCH 30/60] Translated using Weblate (Estonian) Currently translated at 57.3% (47 of 82 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/et/ --- fastlane/metadata/android/et/changelogs/360.txt | 1 + fastlane/metadata/android/et/changelogs/362.txt | 1 + fastlane/metadata/android/et/changelogs/397.txt | 3 +++ 3 files changed, 5 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/360.txt create mode 100644 fastlane/metadata/android/et/changelogs/362.txt create mode 100644 fastlane/metadata/android/et/changelogs/397.txt diff --git a/fastlane/metadata/android/et/changelogs/360.txt b/fastlane/metadata/android/et/changelogs/360.txt new file mode 100644 index 0000000000000000000000000000000000000000..4323c8142b4cf6b1e8323dea565efb6e78c3486b --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/360.txt @@ -0,0 +1 @@ +* Uute XMPP uri parameetrite tugi: ?register ja ?register;preauth diff --git a/fastlane/metadata/android/et/changelogs/362.txt b/fastlane/metadata/android/et/changelogs/362.txt new file mode 100644 index 0000000000000000000000000000000000000000..1988e6517563ab94af14e3f5b5fb8dbe55c234bf --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/362.txt @@ -0,0 +1 @@ +* Kujunduse automaatse vahetamise tugi Android 10 puhul diff --git a/fastlane/metadata/android/et/changelogs/397.txt b/fastlane/metadata/android/et/changelogs/397.txt new file mode 100644 index 0000000000000000000000000000000000000000..23faa3aebc2b94d99fc4e454bbc41a01aaf6ab07 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/397.txt @@ -0,0 +1,3 @@ +* GPX-failide tugi +* Parandasime varukoopia taastamise jõudlust +* Veaparaandused From 5a19a0c2dfc576b7ab238cc883ae592d60613e44 Mon Sep 17 00:00:00 2001 From: Stephan-P Date: Sat, 15 Feb 2025 21:57:06 +0000 Subject: [PATCH 31/60] Translated using Weblate (Dutch) Currently translated at 100.0% (1061 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/nl/ --- src/main/res/values-nl/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index 4416699e27bb31dadd1064444a4631c37ad72ca3..78066be4bb75f711dfd0a8ea1e26e168ebc165a8 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -1126,4 +1126,5 @@ Wil je je avatar verwijderen? Sommige clients kunnen nog steeds een kopie van jouw avatar in de cache weergeven. Time-out voor verbinding Opnieuw proberen met P2P + Kanaalbinding onbeschikbaar \ No newline at end of file From 8bb2f35e49faa54f7b97f01a604499bee4a4363a Mon Sep 17 00:00:00 2001 From: SomeTr Date: Sat, 15 Feb 2025 16:55:59 +0000 Subject: [PATCH 32/60] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1061 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/uk/ --- src/main/res/values-uk/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-uk/strings.xml b/src/main/res/values-uk/strings.xml index f1389563dd717d42490104de894a1dcf1bba574b..e4ad25d4678d71592b86af7b919b5ed03af52f5c 100644 --- a/src/main/res/values-uk/strings.xml +++ b/src/main/res/values-uk/strings.xml @@ -1158,4 +1158,5 @@ Бажаєте видалити свій аватар? Деякі клієнти можуть продовжувати відображати копію Вашого аватара з кешу. Час очікування з\'єднання вичерпано Повторити спробу з P2P + Прив\'язка каналу недоступна \ No newline at end of file From 007822336641cb3ed87c2cf48ffec8babf212007 Mon Sep 17 00:00:00 2001 From: Outbreak2096 Date: Sat, 15 Feb 2025 15:46:28 +0000 Subject: [PATCH 33/60] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (1061 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/zh_Hans/ --- src/main/res/values-zh-rCN/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 5731c8dd88b2a91f95ffd33e9c27f5b750e52d8f..851fa8bc37ece158463cf9c87c9efdc274f9c190 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -150,7 +150,7 @@ \n请使用其他文件管理器选择图片用来分享此文件的应用未提供足够的权限。 未知 - 暂时禁用 + 已暂时禁用 在线 正在连接… 离线 @@ -1106,4 +1106,5 @@ 仅显示给联系人 连接超时 使用 P2P 重试 + 不支持通道绑定 \ No newline at end of file From 68bb4d4a177b32482fcacdb3657c659fe185226f Mon Sep 17 00:00:00 2001 From: otf31 Date: Sun, 16 Feb 2025 16:56:53 +0000 Subject: [PATCH 34/60] Translated using Weblate (Spanish) Currently translated at 99.9% (1060 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/es/ --- src/main/res/values-es/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 9bb2b1da335beb6376fa559e7de3697fff89db75..abfb73c7e5c3370200d57aa140d08e934bab1a10 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -1123,4 +1123,5 @@ ¿Quieres eliminar tu imagen de perfil? Algunos clientes podrían seguir mostrando una copia en caché de tu avatar. Mostrar sólo a contactos Se agotó el tiempo de espera de la conexión + Reintentar con P2P \ No newline at end of file From d3123db511f88c89c955fc00bc6f2a72acc8fb28 Mon Sep 17 00:00:00 2001 From: ghose Date: Mon, 17 Feb 2025 07:05:40 +0000 Subject: [PATCH 35/60] Translated using Weblate (Galician) Currently translated at 100.0% (1061 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/gl/ --- src/main/res/values-gl/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 621b2688499c553cca0c110eb31bd0623e3a6c51..732c874d5e0e00cad8e8236e9db216ec5c0408e6 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -1110,4 +1110,5 @@ Mostrar só aos contactos Caducidade da conexión Reintentar con P2P + Non está dispoñible a vinculación de canles \ No newline at end of file From 042e0e8bef4bb2c547fa0036d8794987fc74fe5b Mon Sep 17 00:00:00 2001 From: user11 Date: Sun, 16 Feb 2025 14:04:53 +0000 Subject: [PATCH 36/60] Translated using Weblate (Serbian) Currently translated at 100.0% (1061 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/sr/ --- src/main/res/values-sr/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/res/values-sr/strings.xml b/src/main/res/values-sr/strings.xml index 1d014e4063e63d530932e4dba8df2f07412e944b..4558a2aa2c3c5e973bacaaf7b66198b3f6029b85 100644 --- a/src/main/res/values-sr/strings.xml +++ b/src/main/res/values-sr/strings.xml @@ -1143,4 +1143,6 @@ Желиш да обришеш свој аватар? Неки клијенти ће можда наставити да приказују кеширану копију твог аватара. Приказуј само контактима Истекла веза + Покушај поново са P2P + Везивање канала недоступно \ No newline at end of file From bc2a9b8fc0cf00d40b7e4ebcb252c9cf3dbede67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Sun, 16 Feb 2025 07:59:12 +0000 Subject: [PATCH 37/60] Translated using Weblate (Estonian) Currently translated at 100.0% (1061 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/et/ --- src/main/res/values-et/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/res/values-et/strings.xml b/src/main/res/values-et/strings.xml index e4fbb81f23fa865b773ba96616fc310efdf6e324..c1e8c9b859b921f50df527d62d23cd2ffe68615c 100644 --- a/src/main/res/values-et/strings.xml +++ b/src/main/res/values-et/strings.xml @@ -1083,7 +1083,7 @@ Automaatne allalaadimine Välimus Hele või tume kujundus - Nõua kanaliga sidumist + Nõua edastuskanaliga sidumist Edastuskanaliga sidumine võib aidata vahendusrünnete tuvastamisel Ühendus serveriga Operatsioonisüsteem @@ -1130,4 +1130,5 @@ Näita vaid kontaktidele Ühenduse on aegunud Proovi uuesti võrdõigusvõrguga + Edastuskanaliga sidumine pole võimalik \ No newline at end of file From b525b4ac061bed001ef87b2aa0715acd1275974a Mon Sep 17 00:00:00 2001 From: random_r Date: Mon, 17 Feb 2025 10:05:01 +0000 Subject: [PATCH 38/60] Translated using Weblate (Italian) Currently translated at 100.0% (1061 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/it/ --- src/main/res/values-it/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index 71321b0bab64e56dc26b410a657b64b8d00a54f2..236920610056ef78b75f1d1d9d6c31fa883f0987 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -460,7 +460,7 @@ Scaricamento fallito: scrittura del file impossibile Scaricamento fallito: file non valido Rete Tor non disponibile - Bind fallito + Associazione fallita Non responsabile per il dominio Rotto Disponibilità @@ -1124,4 +1124,5 @@ Messaggi di chat Colore di sfondo, dimensione caratteri, avatar Messaggi di chat + Associazione dei canali non disponibile \ No newline at end of file From 8222b90f7e8545acb14ea212a8a31fc88291e89a Mon Sep 17 00:00:00 2001 From: solokot Date: Mon, 17 Feb 2025 10:28:32 +0000 Subject: [PATCH 39/60] Translated using Weblate (Russian) Currently translated at 100.0% (1061 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/ru/ --- src/main/res/values-ru/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index edf4082e75290018175874c7e07b9e51201665c0..d5283e4be491cf0c167f44bcdcd60af48d877338 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -1157,4 +1157,5 @@ Показывать только контактам Истекло время ожидания подключения Повторить через P2P + Привязка канала недоступна \ No newline at end of file From a41f5bcab9ee2e608dc036883ca040845046a0cc Mon Sep 17 00:00:00 2001 From: "lucasmz.dev" Date: Mon, 17 Feb 2025 09:46:52 +0000 Subject: [PATCH 40/60] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (1061 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/pt_BR/ --- src/main/res/values-pt-rBR/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml index aa72a9ec3286e871455f600df176c816be0eacab..20ef84f34425ddce5f4a0a20e6d82f2b5eb2326a 100644 --- a/src/main/res/values-pt-rBR/strings.xml +++ b/src/main/res/values-pt-rBR/strings.xml @@ -1128,4 +1128,5 @@ Você gostaria de excluir seu avatar? Alguns clientes podem continuar mostrando uma cópia em cache do seu avatar. Conexão demorou muito Tentar novamente com P2P + Vínculo de canal indisponível \ No newline at end of file From 868c7c3940cd7f3841c79c9cc1bb0e9b56eb1d5a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 14 Feb 2025 08:57:03 +0100 Subject: [PATCH 41/60] version bump to 2.17.11 --- CHANGELOG.md | 4 ++++ build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/4213304.txt | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/4213304.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a991842efe4354883a8e783147f3926f687c810..c340ed768a0ebcded2f9d70a5c3b93fa34a53b41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### Version 2.17.11 + +* minor bug fixes + ### Version 2.17.10 * Allow audio recording to be pause by tapping the timer diff --git a/build.gradle b/build.gradle index 73e3aa833a1810eda12827a485d3d7ee126fcab9..db90c6bb86750702cab77af4400c16ea3ced2b23 100644 --- a/build.gradle +++ b/build.gradle @@ -113,8 +113,8 @@ android { defaultConfig { minSdkVersion 23 targetSdkVersion 34 - versionCode 42132 - versionName "2.17.10" + versionCode 42133 + versionName "2.17.11" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" resValue "string", "applicationId", applicationId diff --git a/fastlane/metadata/android/en-US/changelogs/4213304.txt b/fastlane/metadata/android/en-US/changelogs/4213304.txt new file mode 100644 index 0000000000000000000000000000000000000000..928fa5f5fab22711cadc2fc4a99f5b0322b9df02 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/4213304.txt @@ -0,0 +1 @@ +* minor bug fixes From cf416d6f66d7a51509a0b11c8342764ce57f2f3d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 15 Feb 2025 15:53:30 +0100 Subject: [PATCH 42/60] use material switches --- .../ui/adapter/AccountAdapter.java | 4 ++-- src/main/res/layout/item_account.xml | 20 +++++++++---------- .../res/layout/preference_material_switch.xml | 8 ++++++++ src/main/res/values-night/themes.xml | 1 + src/main/res/values/themes.xml | 9 +++++++++ 5 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 src/main/res/layout/preference_material_switch.xml diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java index b52280181c71bde8928b32aea05f55962b960c21..b33d1c2be16a10d2501aefa727a0c7df09b93940 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/AccountAdapter.java @@ -85,8 +85,8 @@ public class AccountAdapter extends ArrayAdapter { } viewHolder.binding.tglAccountStatus.setOnCheckedChangeListener( (compoundButton, b) -> { - if (b == isDisabled && activity instanceof OnTglAccountState) { - ((OnTglAccountState) activity).onClickTglAccountState(account, b); + if (b == isDisabled && activity instanceof OnTglAccountState tglAccountState) { + tglAccountState.onClickTglAccountState(account, b); } }); return view; diff --git a/src/main/res/layout/item_account.xml b/src/main/res/layout/item_account.xml index eebd434dc47dbaca60e74136f50d21af9fc897f2..6caff80ed51c8ca4c7323be20002015f530b2a44 100644 --- a/src/main/res/layout/item_account.xml +++ b/src/main/res/layout/item_account.xml @@ -8,8 +8,8 @@ android:layout_height="wrap_content" android:background="?selectableItemBackground" android:paddingStart="8dp" - android:paddingBottom="8dp" - android:paddingTop="8dp"> + android:paddingTop="8dp" + android:paddingBottom="8dp"> + android:layout_toStartOf="@+id/tgl_account_status" + android:layout_toEndOf="@+id/account_image" + android:orientation="vertical"> + android:textAppearance="?textAppearanceBodyLarge" + tools:text="juliet@example.com" /> - + android:focusable="false" + android:padding="16dp" /> \ No newline at end of file diff --git a/src/main/res/layout/preference_material_switch.xml b/src/main/res/layout/preference_material_switch.xml new file mode 100644 index 0000000000000000000000000000000000000000..a18e2a48cef36c70d7e7ca381bec55517eb60a05 --- /dev/null +++ b/src/main/res/layout/preference_material_switch.xml @@ -0,0 +1,8 @@ + + diff --git a/src/main/res/values-night/themes.xml b/src/main/res/values-night/themes.xml index 18591c59eb87bdea65a4dad8caa15cb63fd0b23f..c6a2926e8ff2443987133d14d2f26e69e5141a9e 100644 --- a/src/main/res/values-night/themes.xml +++ b/src/main/res/values-night/themes.xml @@ -28,6 +28,7 @@ @color/md_theme_dark_inverseOnSurface @color/md_theme_dark_inverseSurface @color/md_theme_dark_inversePrimary + @style/MaterialPreferenceThemeOverlay + + + + \ No newline at end of file From 22a8092a1ded7c689e1729cfdae63da05f66f80f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 17 Feb 2025 10:53:41 +0100 Subject: [PATCH 43/60] ensure that account exists when restoring from DB --- .../services/XmppConnectionService.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 7a177262013ac97db7ca6e1232b1da8a99b179fd..058e37edc3fef322f8cad31e22aa5cf069c95e27 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -2862,15 +2862,15 @@ public class XmppConnectionService extends Service { if (existing == null) { return null; } - Log.d( - Config.LOGTAG, - existing.getJid().asBareJid() - + ": restoring conversation with " - + existing.getJid() - + " from DB"); + Log.d(Config.LOGTAG, "restoring conversation with " + existing.getJid() + " from DB"); final Map accounts = ImmutableMap.copyOf(Maps.uniqueIndex(this.accounts, Account::getUuid)); - existing.setAccount(accounts.get(existing.getAccountUuid())); + final var account = accounts.get(existing.getAccountUuid()); + if (account == null) { + Log.d(Config.LOGTAG, "could not find account " + existing.getAccountUuid()); + return null; + } + existing.setAccount(account); final var loadMessagesFromDb = restoreFromArchive(existing); mDatabaseReaderExecutor.execute( () -> From 24900a3dc48c559a9deccd6e15af7af0943f2e9d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 17 Feb 2025 17:02:29 +0100 Subject: [PATCH 44/60] code clean up in stream feature parsing --- .../conversations/xmpp/XmppConnection.java | 69 ++++++++++++------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 2d7e0e52125121be8c8fe97b618c9eacb9881bc3..4c64ce11fc3d5b17cfc1d80aa1af83f930b12986 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -97,6 +97,7 @@ import im.conversations.android.xmpp.model.sm.StreamManagement; import im.conversations.android.xmpp.model.stanza.Iq; import im.conversations.android.xmpp.model.stanza.Presence; import im.conversations.android.xmpp.model.stanza.Stanza; +import im.conversations.android.xmpp.model.streams.Features; import im.conversations.android.xmpp.model.streams.StreamError; import im.conversations.android.xmpp.model.tls.Proceed; import im.conversations.android.xmpp.model.tls.StartTls; @@ -288,6 +289,7 @@ public class XmppConnection implements Runnable { mXmppConnectionService.resetSendingToWaiting(account); } Log.d(Config.LOGTAG, account.getJid().asBareJid().toString() + ": connecting"); + this.streamFeatures = null; this.pendingResumeId.clear(); this.loginInfo = null; this.features.encryptionEnabled = false; @@ -615,6 +617,9 @@ public class XmppConnection implements Runnable { } else if (nextTag.isStart("features", Namespace.STREAMS)) { processStreamFeatures(nextTag); } else if (nextTag.isStart("proceed", Namespace.TLS)) { + if (this.socket instanceof SSLSocket) { + throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); + } switchOverToTls(nextTag); } else if (nextTag.isStart("failure", Namespace.TLS)) { throw new StateChangingException(Account.State.TLS_ERROR); @@ -1040,6 +1045,7 @@ public class XmppConnection implements Runnable { account.getJid().asBareJid() + ": fast authentication failed. falling back to regular" + " authentication"); + this.loginInfo = null; authenticate(); } else { throw new StateChangingException(Account.State.UNAUTHORIZED); @@ -1268,7 +1274,10 @@ public class XmppConnection implements Runnable { account.getJid().asBareJid() + "Not processing iq. Thread was interrupted"); return; } - if (packet.hasExtension(Jingle.class) && packet.getType() == Iq.Type.SET && isBound) { + if (packet.hasExtension(Jingle.class) + && packet.getType() == Iq.Type.SET + && isBound + && LoginInfo.isSuccess(this.loginInfo)) { if (this.jingleListener != null) { this.jingleListener.onJinglePacketReceived(account, packet); } @@ -1295,7 +1304,7 @@ public class XmppConnection implements Runnable { final boolean isRequest = stanza.getType() == Iq.Type.GET || stanza.getType() == Iq.Type.SET; if (isRequest) { - if (isBound) { + if (isBound && LoginInfo.isSuccess(this.loginInfo)) { return this.unregisteredIqListener; } else { throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); @@ -1443,13 +1452,33 @@ public class XmppConnection implements Runnable { } private void processStreamFeatures(final Tag currentTag) throws IOException { - this.streamFeatures = + final var streamFeatures = tagReader.readElement( currentTag, im.conversations.android.xmpp.model.streams.Features.class); final boolean isSecure = isSecure(); + if (streamFeatures.hasExtension(StartTls.class) && !features.encryptionEnabled) { + sendStartTLS(); + return; + } + if (isSecure) { + processSecureStreamFeatures(streamFeatures); + } else { + Log.d( + Config.LOGTAG, + account.getJid().asBareJid() + + ": STARTTLS not available " + + XmlHelper.printElementNames(streamFeatures)); + throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); + } + } + + private void processSecureStreamFeatures( + final im.conversations.android.xmpp.model.streams.Features streamFeatures) + throws IOException { + this.streamFeatures = streamFeatures; final boolean needsBinding = !isBound && !account.isOptionSet(Account.OPTION_REGISTER); if (this.quickStartInProgress) { - if (this.streamFeatures.hasStreamFeature(Authentication.class)) { + if (streamFeatures.hasStreamFeature(Authentication.class)) { Log.d( Config.LOGTAG, account.getJid().asBareJid() @@ -1476,33 +1505,21 @@ public class XmppConnection implements Runnable { mXmppConnectionService.databaseBackend.updateAccount(account); throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); } - if (this.streamFeatures.hasExtension(StartTls.class) && !features.encryptionEnabled) { - sendStartTLS(); - } else if (this.streamFeatures.hasChild("register", Namespace.REGISTER_STREAM_FEATURE) + if (streamFeatures.hasChild("register", Namespace.REGISTER_STREAM_FEATURE) && account.isOptionSet(Account.OPTION_REGISTER)) { - if (isSecure) { - register(); - } else { - Log.d( - Config.LOGTAG, - account.getJid().asBareJid() - + ": unable to find STARTTLS for registration process " - + XmlHelper.printElementNames(this.streamFeatures)); - throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); - } - } else if (!this.streamFeatures.hasChild("register", Namespace.REGISTER_STREAM_FEATURE) + register(); + } else if (!streamFeatures.hasChild("register", Namespace.REGISTER_STREAM_FEATURE) && account.isOptionSet(Account.OPTION_REGISTER)) { throw new StateChangingException(Account.State.REGISTRATION_NOT_SUPPORTED); - } else if (this.streamFeatures.hasStreamFeature(Authentication.class) + } else if (streamFeatures.hasStreamFeature(Authentication.class) && shouldAuthenticate - && isSecure) { + && this.loginInfo == null) { authenticate(SaslMechanism.Version.SASL_2); - } else if (this.streamFeatures.hasStreamFeature(Mechanisms.class) + } else if (streamFeatures.hasStreamFeature(Mechanisms.class) && shouldAuthenticate - && isSecure) { + && this.loginInfo == null) { authenticate(SaslMechanism.Version.SASL); - } else if (this.streamFeatures.streamManagement() - && isSecure + } else if (streamFeatures.streamManagement() && LoginInfo.isSuccess(loginInfo) && streamId != null && !inSmacksSession) { @@ -1519,7 +1536,6 @@ public class XmppConnection implements Runnable { this.tagWriter.writeStanzaAsync(resume); } else if (needsBinding) { if (this.streamFeatures.hasChild("bind", Namespace.BIND) - && isSecure && LoginInfo.isSuccess(loginInfo)) { sendBindRequest(); } else { @@ -1555,6 +1571,9 @@ public class XmppConnection implements Runnable { } private void authenticate(final SaslMechanism.Version version) throws IOException { + if (this.loginInfo != null) { + throw new StateChangingException(Account.State.INCOMPATIBLE_SERVER); + } final AuthenticationStreamFeature authElement; if (version == SaslMechanism.Version.SASL) { authElement = this.streamFeatures.getExtension(Mechanisms.class); From 948edd851af1179b18d9aec5d21a999a171dc769 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 17 Feb 2025 17:15:45 +0100 Subject: [PATCH 45/60] fix formatting in gl and fi strings --- src/main/res/values-fi/strings.xml | 2 +- src/main/res/values-gl/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/res/values-fi/strings.xml b/src/main/res/values-fi/strings.xml index 4463331cf52f2762017dccad8668e4be1d153c49..9ad951c5bfe8cbec95ac6600e7e79981a75d5b24 100644 --- a/src/main/res/values-fi/strings.xml +++ b/src/main/res/values-fi/strings.xml @@ -324,7 +324,7 @@ Poista %s tiedosto Avaa %s - lähetetään (%1$d% % valmiina) + lähetetään (%1$d%% valmiina) Valmistellaan tiedoston lähettämistä %s tarjottu ladattavaksi Peru siirto diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 732c874d5e0e00cad8e8236e9db216ec5c0408e6..1d31d8f311a26b64d8d9995b7902694c06b6f7cf 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -334,7 +334,7 @@ Eliminar %s ficheiro Abrir %s - enviando (%1$d %% completado) + enviando (%1$d%% completado) Preparándose para compartir o ficheiro Ofreceuse %s para descargar Cancelar a transmisión From 8e51872c9709fbc7467c74dd2b381740f4e1ae54 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 18 Feb 2025 10:20:43 +0100 Subject: [PATCH 46/60] bump dependencies --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index db90c6bb86750702cab77af4400c16ea3ced2b23..941f8dc1735bc17b8f1f3cab6fca897775423977 100644 --- a/build.gradle +++ b/build.gradle @@ -42,7 +42,7 @@ spotless { dependencies { - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.3' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.4' implementation project(':libs:annotation') annotationProcessor project(':libs:annotation-processor') @@ -66,7 +66,7 @@ dependencies { implementation 'androidx.cardview:cardview:1.0.0' implementation "androidx.preference:preference:1.2.1" implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'com.google.android.material:material:1.13.0-alpha09' + implementation 'com.google.android.material:material:1.13.0-alpha10' implementation 'androidx.work:work-runtime:2.9.1' implementation "androidx.emoji2:emoji2:1.5.0" From 3026f7d1227ec8650968facef02dea1e3b66deac Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 18 Feb 2025 10:51:03 +0100 Subject: [PATCH 47/60] use material switch for device fingerprints --- .../ui/ContactDetailsActivity.java | 4 +- .../siacs/conversations/ui/OmemoActivity.java | 412 ++++++++++-------- ...ct_key.xml => item_device_fingerprint.xml} | 4 +- src/main/res/values/dimens.xml | 2 - 4 files changed, 229 insertions(+), 193 deletions(-) rename src/main/res/layout/{contact_key.xml => item_device_fingerprint.xml} (96%) diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index 3738f86415f9c6c2a9160a1efc4d575015f411b7..a21fd5360e77f618d75e1a80f87eb45f1609e57e 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -570,7 +570,9 @@ public class ContactDetailsActivity extends OmemoActivity } if (Config.supportOpenPgp() && contact.getPgpKeyId() != 0) { hasKeys = true; - View view = inflater.inflate(R.layout.contact_key, binding.detailsContactKeys, false); + View view = + inflater.inflate( + R.layout.item_device_fingerprint, binding.detailsContactKeys, false); TextView key = view.findViewById(R.id.key); TextView keyType = view.findViewById(R.id.key_type); keyType.setText(R.string.openpgp_key_id); diff --git a/src/main/java/eu/siacs/conversations/ui/OmemoActivity.java b/src/main/java/eu/siacs/conversations/ui/OmemoActivity.java index ac7559769d4f7c0a11170095c8b38c1571410065..7ed58127c0eb7700e64fa0598c833f5f19efdd34 100644 --- a/src/main/java/eu/siacs/conversations/ui/OmemoActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/OmemoActivity.java @@ -7,205 +7,241 @@ import android.view.View; import android.widget.CompoundButton; import android.widget.LinearLayout; import android.widget.Toast; - -import androidx.appcompat.app.AlertDialog; import androidx.databinding.DataBindingUtil; - import com.google.android.material.color.MaterialColors; import com.google.android.material.dialog.MaterialAlertDialogBuilder; - import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.axolotl.FingerprintStatus; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; -import eu.siacs.conversations.databinding.ContactKeyBinding; +import eu.siacs.conversations.databinding.ItemDeviceFingerprintBinding; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.XmppUri; public abstract class OmemoActivity extends XmppActivity { - private Account mSelectedAccount; - private String mSelectedFingerprint; - - protected XmppUri mPendingFingerprintVerificationUri = null; - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - Object account = v.getTag(R.id.TAG_ACCOUNT); - Object fingerprint = v.getTag(R.id.TAG_FINGERPRINT); - Object fingerprintStatus = v.getTag(R.id.TAG_FINGERPRINT_STATUS); - if (account instanceof Account - && fingerprint instanceof String - && fingerprintStatus instanceof FingerprintStatus) { - getMenuInflater().inflate(R.menu.omemo_key_context, menu); - MenuItem distrust = menu.findItem(R.id.distrust_key); - MenuItem verifyScan = menu.findItem(R.id.verify_scan); - if (this instanceof TrustKeysActivity) { - distrust.setVisible(false); - verifyScan.setVisible(false); - } else { - FingerprintStatus status = (FingerprintStatus) fingerprintStatus; - if (!status.isActive() || status.isVerified()) { - verifyScan.setVisible(false); - } - distrust.setVisible(status.isVerified() || (!status.isActive() && status.isTrusted())); - } - this.mSelectedAccount = (Account) account; - this.mSelectedFingerprint = (String) fingerprint; - } - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.distrust_key: - showPurgeKeyDialog(mSelectedAccount, mSelectedFingerprint); - break; - case R.id.copy_omemo_key: - copyOmemoFingerprint(mSelectedFingerprint); - break; - case R.id.verify_scan: - ScanActivity.scan(this); - break; - } - return true; - } - - @Override - public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) { - super.onActivityResult(requestCode, resultCode, intent); - if (requestCode == ScanActivity.REQUEST_SCAN_QR_CODE && resultCode == RESULT_OK) { - String result = intent.getStringExtra(ScanActivity.INTENT_EXTRA_RESULT); - XmppUri uri = new XmppUri(result == null ? "" : result); - if (xmppConnectionServiceBound) { - processFingerprintVerification(uri); - } else { - this.mPendingFingerprintVerificationUri = uri; - } - } - } - - protected abstract void processFingerprintVerification(XmppUri uri); - - protected void copyOmemoFingerprint(String fingerprint) { - if (copyTextToClipboard(CryptoHelper.prettifyFingerprint(fingerprint.substring(2)), R.string.omemo_fingerprint)) { - Toast.makeText( - this, - R.string.toast_message_omemo_fingerprint, - Toast.LENGTH_SHORT).show(); - } - } - - protected void addFingerprintRow(LinearLayout keys, final XmppAxolotlSession session, boolean highlight) { - final Account account = session.getAccount(); - final String fingerprint = session.getFingerprint(); - addFingerprintRowWithListeners(keys, - session.getAccount(), - fingerprint, - highlight, - session.getTrust(), - true, - true, - (buttonView, isChecked) -> account.getAxolotlService().setFingerprintTrust(fingerprint, FingerprintStatus.createActive(isChecked))); - } - - protected void addFingerprintRowWithListeners(LinearLayout keys, final Account account, - final String fingerprint, - boolean highlight, - FingerprintStatus status, - boolean showTag, - boolean undecidedNeedEnablement, - CompoundButton.OnCheckedChangeListener - onCheckedChangeListener) { - ContactKeyBinding binding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.contact_key, keys, true); - binding.tglTrust.setVisibility(View.VISIBLE); - registerForContextMenu(binding.getRoot()); - binding.getRoot().setTag(R.id.TAG_ACCOUNT, account); - binding.getRoot().setTag(R.id.TAG_FINGERPRINT, fingerprint); - binding.getRoot().setTag(R.id.TAG_FINGERPRINT_STATUS, status); - boolean x509 = Config.X509_VERIFICATION && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509; - final View.OnClickListener toast; - binding.tglTrust.setChecked(status.isTrusted()); - - if (status.isActive()) { - binding.key.setTextColor(MaterialColors.getColor(binding.key, com.google.android.material.R.attr.colorOnSurface)); - binding.keyType.setTextColor(MaterialColors.getColor(binding.keyType, com.google.android.material.R.attr.colorOnSurface)); - if (status.isVerified()) { - binding.verifiedFingerprint.setVisibility(View.VISIBLE); - binding.verifiedFingerprint.setAlpha(1.0f); - binding.tglTrust.setVisibility(View.GONE); - binding.verifiedFingerprint.setOnClickListener(v -> replaceToast(getString(R.string.this_device_has_been_verified), false)); - toast = null; - } else { - binding.verifiedFingerprint.setVisibility(View.GONE); - binding.tglTrust.setVisibility(View.VISIBLE); - binding.tglTrust.setOnCheckedChangeListener(onCheckedChangeListener); - if (status.getTrust() == FingerprintStatus.Trust.UNDECIDED && undecidedNeedEnablement) { - binding.buttonEnableDevice.setVisibility(View.VISIBLE); - binding.buttonEnableDevice.setOnClickListener(v -> { - account.getAxolotlService().setFingerprintTrust(fingerprint, FingerprintStatus.createActive(false)); - binding.buttonEnableDevice.setVisibility(View.GONE); - binding.tglTrust.setVisibility(View.VISIBLE); - }); - binding.tglTrust.setVisibility(View.GONE); - } else { - binding.tglTrust.setOnClickListener(null); - binding.tglTrust.setEnabled(true); - } - toast = v -> hideToast(); - } - } else { - binding.key.setTextColor(MaterialColors.getColor(binding.key, com.google.android.material.R.attr.colorOnSurfaceVariant)); - binding.keyType.setTextColor(MaterialColors.getColor(binding.keyType, com.google.android.material.R.attr.colorOnSurfaceVariant)); - toast = v -> replaceToast(getString(R.string.this_device_is_no_longer_in_use), false); - if (status.isVerified()) { - binding.tglTrust.setVisibility(View.GONE); - binding.verifiedFingerprint.setVisibility(View.VISIBLE); - binding.verifiedFingerprint.setAlpha(0.4368f); - binding.verifiedFingerprint.setOnClickListener(toast); - } else { - binding.tglTrust.setVisibility(View.VISIBLE); - binding.verifiedFingerprint.setVisibility(View.GONE); - binding.tglTrust.setEnabled(false); - } - } - - binding.getRoot().setOnClickListener(toast); - binding.key.setOnClickListener(toast); - binding.keyType.setOnClickListener(toast); - if (showTag) { - binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); - } else { - binding.keyType.setVisibility(View.GONE); - } - if (highlight) { - binding.keyType.setTextColor(MaterialColors.getColor(binding.keyType, com.google.android.material.R.attr.colorPrimaryVariant)); - binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509_selected_message : R.string.omemo_fingerprint_selected_message)); - } else { - binding.keyType.setText(getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); - } - - binding.key.setText(CryptoHelper.prettifyFingerprint(fingerprint.substring(2))); - } - - public void showPurgeKeyDialog(final Account account, final String fingerprint) { - final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); - builder.setTitle(R.string.distrust_omemo_key); - builder.setMessage(R.string.distrust_omemo_key_text); - builder.setNegativeButton(getString(R.string.cancel), null); - builder.setPositiveButton(R.string.confirm, - (dialog, which) -> { - account.getAxolotlService().distrustFingerprint(fingerprint); - refreshUi(); - }); - builder.create().show(); - } - - @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - ScanActivity.onRequestPermissionResult(this, requestCode, grantResults); - } + private Account mSelectedAccount; + private String mSelectedFingerprint; + + protected XmppUri mPendingFingerprintVerificationUri = null; + + @Override + public void onCreateContextMenu( + ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + Object account = v.getTag(R.id.TAG_ACCOUNT); + Object fingerprint = v.getTag(R.id.TAG_FINGERPRINT); + Object fingerprintStatus = v.getTag(R.id.TAG_FINGERPRINT_STATUS); + if (account instanceof Account + && fingerprint instanceof String + && fingerprintStatus instanceof FingerprintStatus) { + getMenuInflater().inflate(R.menu.omemo_key_context, menu); + MenuItem distrust = menu.findItem(R.id.distrust_key); + MenuItem verifyScan = menu.findItem(R.id.verify_scan); + if (this instanceof TrustKeysActivity) { + distrust.setVisible(false); + verifyScan.setVisible(false); + } else { + FingerprintStatus status = (FingerprintStatus) fingerprintStatus; + if (!status.isActive() || status.isVerified()) { + verifyScan.setVisible(false); + } + distrust.setVisible( + status.isVerified() || (!status.isActive() && status.isTrusted())); + } + this.mSelectedAccount = (Account) account; + this.mSelectedFingerprint = (String) fingerprint; + } + } + + @Override + public boolean onContextItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.distrust_key: + showPurgeKeyDialog(mSelectedAccount, mSelectedFingerprint); + break; + case R.id.copy_omemo_key: + copyOmemoFingerprint(mSelectedFingerprint); + break; + case R.id.verify_scan: + ScanActivity.scan(this); + break; + } + return true; + } + + @Override + public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) { + super.onActivityResult(requestCode, resultCode, intent); + if (requestCode == ScanActivity.REQUEST_SCAN_QR_CODE && resultCode == RESULT_OK) { + String result = intent.getStringExtra(ScanActivity.INTENT_EXTRA_RESULT); + XmppUri uri = new XmppUri(result == null ? "" : result); + if (xmppConnectionServiceBound) { + processFingerprintVerification(uri); + } else { + this.mPendingFingerprintVerificationUri = uri; + } + } + } + + protected abstract void processFingerprintVerification(XmppUri uri); + + protected void copyOmemoFingerprint(String fingerprint) { + if (copyTextToClipboard( + CryptoHelper.prettifyFingerprint(fingerprint.substring(2)), + R.string.omemo_fingerprint)) { + Toast.makeText(this, R.string.toast_message_omemo_fingerprint, Toast.LENGTH_SHORT) + .show(); + } + } + + protected void addFingerprintRow( + LinearLayout keys, final XmppAxolotlSession session, boolean highlight) { + final Account account = session.getAccount(); + final String fingerprint = session.getFingerprint(); + addFingerprintRowWithListeners( + keys, + session.getAccount(), + fingerprint, + highlight, + session.getTrust(), + true, + true, + (buttonView, isChecked) -> + account.getAxolotlService() + .setFingerprintTrust( + fingerprint, FingerprintStatus.createActive(isChecked))); + } + + protected void addFingerprintRowWithListeners( + LinearLayout keys, + final Account account, + final String fingerprint, + boolean highlight, + FingerprintStatus status, + boolean showTag, + boolean undecidedNeedEnablement, + CompoundButton.OnCheckedChangeListener onCheckedChangeListener) { + ItemDeviceFingerprintBinding binding = + DataBindingUtil.inflate( + getLayoutInflater(), R.layout.item_device_fingerprint, keys, true); + binding.tglTrust.setVisibility(View.VISIBLE); + registerForContextMenu(binding.getRoot()); + binding.getRoot().setTag(R.id.TAG_ACCOUNT, account); + binding.getRoot().setTag(R.id.TAG_FINGERPRINT, fingerprint); + binding.getRoot().setTag(R.id.TAG_FINGERPRINT_STATUS, status); + boolean x509 = + Config.X509_VERIFICATION + && status.getTrust() == FingerprintStatus.Trust.VERIFIED_X509; + final View.OnClickListener toast; + binding.tglTrust.setChecked(status.isTrusted()); + binding.tglTrust.jumpDrawablesToCurrentState(); + + if (status.isActive()) { + binding.key.setTextColor( + MaterialColors.getColor( + binding.key, com.google.android.material.R.attr.colorOnSurface)); + binding.keyType.setTextColor( + MaterialColors.getColor( + binding.keyType, com.google.android.material.R.attr.colorOnSurface)); + if (status.isVerified()) { + binding.verifiedFingerprint.setVisibility(View.VISIBLE); + binding.verifiedFingerprint.setAlpha(1.0f); + binding.tglTrust.setVisibility(View.GONE); + binding.verifiedFingerprint.setOnClickListener( + v -> + replaceToast( + getString(R.string.this_device_has_been_verified), false)); + toast = null; + } else { + binding.verifiedFingerprint.setVisibility(View.GONE); + binding.tglTrust.setVisibility(View.VISIBLE); + binding.tglTrust.setOnCheckedChangeListener(onCheckedChangeListener); + if (status.getTrust() == FingerprintStatus.Trust.UNDECIDED + && undecidedNeedEnablement) { + binding.buttonEnableDevice.setVisibility(View.VISIBLE); + binding.buttonEnableDevice.setOnClickListener( + v -> { + account.getAxolotlService() + .setFingerprintTrust( + fingerprint, FingerprintStatus.createActive(false)); + binding.buttonEnableDevice.setVisibility(View.GONE); + binding.tglTrust.setVisibility(View.VISIBLE); + }); + binding.tglTrust.setVisibility(View.GONE); + } else { + binding.tglTrust.setOnClickListener(null); + binding.tglTrust.setEnabled(true); + } + toast = v -> hideToast(); + } + } else { + binding.key.setTextColor( + MaterialColors.getColor( + binding.key, com.google.android.material.R.attr.colorOnSurfaceVariant)); + binding.keyType.setTextColor( + MaterialColors.getColor( + binding.keyType, + com.google.android.material.R.attr.colorOnSurfaceVariant)); + toast = v -> replaceToast(getString(R.string.this_device_is_no_longer_in_use), false); + if (status.isVerified()) { + binding.tglTrust.setVisibility(View.GONE); + binding.verifiedFingerprint.setVisibility(View.VISIBLE); + binding.verifiedFingerprint.setAlpha(0.4368f); + binding.verifiedFingerprint.setOnClickListener(toast); + } else { + binding.tglTrust.setVisibility(View.VISIBLE); + binding.verifiedFingerprint.setVisibility(View.GONE); + binding.tglTrust.setEnabled(false); + } + } + + binding.getRoot().setOnClickListener(toast); + binding.key.setOnClickListener(toast); + binding.keyType.setOnClickListener(toast); + if (showTag) { + binding.keyType.setText( + getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); + } else { + binding.keyType.setVisibility(View.GONE); + } + if (highlight) { + binding.keyType.setTextColor( + MaterialColors.getColor( + binding.keyType, + com.google.android.material.R.attr.colorPrimaryVariant)); + binding.keyType.setText( + getString( + x509 + ? R.string.omemo_fingerprint_x509_selected_message + : R.string.omemo_fingerprint_selected_message)); + } else { + binding.keyType.setText( + getString(x509 ? R.string.omemo_fingerprint_x509 : R.string.omemo_fingerprint)); + } + + binding.key.setText(CryptoHelper.prettifyFingerprint(fingerprint.substring(2))); + } + + public void showPurgeKeyDialog(final Account account, final String fingerprint) { + final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this); + builder.setTitle(R.string.distrust_omemo_key); + builder.setMessage(R.string.distrust_omemo_key_text); + builder.setNegativeButton(getString(R.string.cancel), null); + builder.setPositiveButton( + R.string.confirm, + (dialog, which) -> { + account.getAxolotlService().distrustFingerprint(fingerprint); + refreshUi(); + }); + builder.create().show(); + } + + @Override + public void onRequestPermissionsResult( + int requestCode, String[] permissions, int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + ScanActivity.onRequestPermissionResult(this, requestCode, grantResults); + } } diff --git a/src/main/res/layout/contact_key.xml b/src/main/res/layout/item_device_fingerprint.xml similarity index 96% rename from src/main/res/layout/contact_key.xml rename to src/main/res/layout/item_device_fingerprint.xml index 447396ab503b70de0d439d6c96864f6a539fe04d..56c148f30c4d0deaa4478d62d6e6926e4bc06190 100644 --- a/src/main/res/layout/contact_key.xml +++ b/src/main/res/layout/item_device_fingerprint.xml @@ -36,7 +36,7 @@ - 8dp 8dp 12dp - 48dp - 11sp 224dp 224dp From 1f256cccb81c32878ba9e8abf5da972c7d1f1f3c Mon Sep 17 00:00:00 2001 From: SomeTr Date: Mon, 17 Feb 2025 19:15:00 +0000 Subject: [PATCH 48/60] Translated using Weblate (Ukrainian) Currently translated at 100.0% (83 of 83 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/uk/ --- fastlane/metadata/android/uk/changelogs/4213304.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 fastlane/metadata/android/uk/changelogs/4213304.txt diff --git a/fastlane/metadata/android/uk/changelogs/4213304.txt b/fastlane/metadata/android/uk/changelogs/4213304.txt new file mode 100644 index 0000000000000000000000000000000000000000..5055677c66cce09d060052a9941d17aecf3e6621 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/4213304.txt @@ -0,0 +1 @@ +* Незначні виправлення помилок From 0cdc923949da9a686ac3bc1b8cab4f4aed132aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Mon, 17 Feb 2025 17:25:31 +0000 Subject: [PATCH 49/60] Translated using Weblate (Estonian) Currently translated at 62.6% (52 of 83 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/et/ --- fastlane/metadata/android/et/changelogs/397.txt | 2 +- fastlane/metadata/android/et/changelogs/404.txt | 1 + fastlane/metadata/android/et/changelogs/42015.txt | 1 + fastlane/metadata/android/et/changelogs/42038.txt | 2 ++ fastlane/metadata/android/et/changelogs/42041.txt | 5 +++++ fastlane/metadata/android/et/changelogs/4213304.txt | 1 + 6 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 fastlane/metadata/android/et/changelogs/404.txt create mode 100644 fastlane/metadata/android/et/changelogs/42015.txt create mode 100644 fastlane/metadata/android/et/changelogs/42038.txt create mode 100644 fastlane/metadata/android/et/changelogs/42041.txt create mode 100644 fastlane/metadata/android/et/changelogs/4213304.txt diff --git a/fastlane/metadata/android/et/changelogs/397.txt b/fastlane/metadata/android/et/changelogs/397.txt index 23faa3aebc2b94d99fc4e454bbc41a01aaf6ab07..1656798be6346be41f56d4f1df31a171b69ea9f8 100644 --- a/fastlane/metadata/android/et/changelogs/397.txt +++ b/fastlane/metadata/android/et/changelogs/397.txt @@ -1,3 +1,3 @@ * GPX-failide tugi * Parandasime varukoopia taastamise jõudlust -* Veaparaandused +* Veaparandused diff --git a/fastlane/metadata/android/et/changelogs/404.txt b/fastlane/metadata/android/et/changelogs/404.txt new file mode 100644 index 0000000000000000000000000000000000000000..e1a8ed181d560db32d4aadcc12fc7adf2b347bbd --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/404.txt @@ -0,0 +1 @@ +* väikesed stabiilsusega seotud veaparandused audio/video funktsionaalsuses diff --git a/fastlane/metadata/android/et/changelogs/42015.txt b/fastlane/metadata/android/et/changelogs/42015.txt new file mode 100644 index 0000000000000000000000000000000000000000..41971b0dee5971719547ddefe6a979759984cef6 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/42015.txt @@ -0,0 +1 @@ +* väikesed veaparandused audio/video funktsionaalsuses diff --git a/fastlane/metadata/android/et/changelogs/42038.txt b/fastlane/metadata/android/et/changelogs/42038.txt new file mode 100644 index 0000000000000000000000000000000000000000..c8b0b4406c9db6808200485e4911b8137471933d --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/42038.txt @@ -0,0 +1,2 @@ +* Väikesed veaparandused +* Taastasime võimaluse helistada välja JMP ja muude teenuste abil (Playstore'i versioonis) diff --git a/fastlane/metadata/android/et/changelogs/42041.txt b/fastlane/metadata/android/et/changelogs/42041.txt new file mode 100644 index 0000000000000000000000000000000000000000..c7a8e60c87c76229be20a6e0e8eeee7ddcfc5531 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/42041.txt @@ -0,0 +1,5 @@ +* Ühenduste kiirema taastamise nimel võtsime kasutusele Extensible SASL Profile, Bind 2.0 ja Fast protokollid +* Võtsime kasutusele ühenduskanalite sidumise +* Lisasime võimaluse lülituda häälkõnel ümber videokõnele +* Lisasime võimaluse oma tunnuspildi kustutamiseks +* Lisasime märkamata jäänud kõnede teavituse diff --git a/fastlane/metadata/android/et/changelogs/4213304.txt b/fastlane/metadata/android/et/changelogs/4213304.txt new file mode 100644 index 0000000000000000000000000000000000000000..a0571dea82198717c9e2096ead3c152460df6c50 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/4213304.txt @@ -0,0 +1 @@ +* väikesed veaparandused From ffe9a915d618e884d44ffda5cb3d26a217720368 Mon Sep 17 00:00:00 2001 From: Stefan Haan Date: Tue, 18 Feb 2025 13:49:52 +0100 Subject: [PATCH 50/60] update conversations.doap --- conversations.doap | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conversations.doap b/conversations.doap index 838a248d0634881d7a600a8d182173d78bc2253b..89132d021139da15ac127e11e0864754d730c742 100644 --- a/conversations.doap +++ b/conversations.doap @@ -514,9 +514,9 @@ - 2.14.0 - 2024-03-22 - + 2.17.10 + 2025-02-04 + From f4e642c3aea7fa19096f36df051189a034a3030e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Tue, 18 Feb 2025 16:03:51 +0100 Subject: [PATCH 51/60] run Tor connection via hostname only if extended connection ui is visible --- .../siacs/conversations/entities/Account.java | 5 +++++ .../conversations/xmpp/XmppConnection.java | 17 ++++++++++++++--- src/main/res/menu/message_context.xml | 5 +++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 4d4c4e8d3bd5996f972cb489d6b1d320e571dc90..294d27df6088ad77d99edba45f629553f4ad2bcf 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -317,6 +317,11 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable return server != null && server.endsWith(".onion"); } + public boolean isDirectToOnion() { + final var hostname = Strings.nullToEmpty(this.hostname).trim(); + return isOnion() && (hostname.isEmpty() || hostname.endsWith(".onion")); + } + public int getPort() { return this.port; } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 4c64ce11fc3d5b17cfc1d80aa1af83f930b12986..0fbdf57f80c1d88712ddd05f83cc304dc61f9307 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -304,8 +304,9 @@ public class XmppConnection implements Runnable { Socket localSocket; shouldAuthenticate = !account.isOptionSet(Account.OPTION_REGISTER); this.changeStatus(Account.State.CONNECTING); - final boolean useTor = mXmppConnectionService.useTorToConnect() || account.isOnion(); + final boolean useTorSetting = mXmppConnectionService.useTorToConnect(); final boolean extended = mXmppConnectionService.showExtendedConnectionOptions(); + final boolean useTor = useTorSetting || account.isOnion(); // TODO collapse Tor usage into normal connection code path if (useTor) { final var seeOtherHost = this.seeOtherHostResolverResult; @@ -323,7 +324,15 @@ public class XmppConnection implements Runnable { Resolver.fromHardCoded( account.getServer(), Resolver.XMPP_PORT_STARTTLS)); } else { - viaTor = Iterables.getOnlyElement(Resolver.fromHardCoded(hostname, port)); + if (useTorSetting || extended) { + // if the hostname configuration is showing we can take it + viaTor = Iterables.getOnlyElement(Resolver.fromHardCoded(hostname, port)); + } else { + viaTor = + Iterables.getOnlyElement( + Resolver.fromHardCoded( + account.getServer(), Resolver.XMPP_PORT_STARTTLS)); + } this.verifiedHostname = hostname; } @@ -1567,7 +1576,9 @@ public class XmppConnection implements Runnable { } private boolean isSecure() { - return features.encryptionEnabled || Config.ALLOW_NON_TLS_CONNECTIONS || account.isOnion(); + return (features.encryptionEnabled && this.socket instanceof SSLSocket) + || Config.ALLOW_NON_TLS_CONNECTIONS + || account.isDirectToOnion(); } private void authenticate(final SaslMechanism.Version version) throws IOException { diff --git a/src/main/res/menu/message_context.xml b/src/main/res/menu/message_context.xml index aa572bcdf712b74c8732a15197269e80b48ac352..2d0d118de2110521deca41d42cfac05acf8511cd 100644 --- a/src/main/res/menu/message_context.xml +++ b/src/main/res/menu/message_context.xml @@ -55,9 +55,10 @@ android:id="@+id/send_again" android:title="@string/send_again" android:visible="false" /> - + android:visible="false" /> Date: Tue, 18 Feb 2025 16:06:00 +0100 Subject: [PATCH 52/60] version bump to 2.17.12 --- CHANGELOG.md | 4 ++++ build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/4213404.txt | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/4213404.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index c340ed768a0ebcded2f9d70a5c3b93fa34a53b41..d048e41491a2b6c7be8e58ad7a8d07f6375b7782 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +### Version 2.17.12 + +* Fix crash on file transfer in fi translation + ### Version 2.17.11 * minor bug fixes diff --git a/build.gradle b/build.gradle index 941f8dc1735bc17b8f1f3cab6fca897775423977..c014e6e74df3965b2fea41a7a7232ccd82eb9d22 100644 --- a/build.gradle +++ b/build.gradle @@ -113,8 +113,8 @@ android { defaultConfig { minSdkVersion 23 targetSdkVersion 34 - versionCode 42133 - versionName "2.17.11" + versionCode 42134 + versionName "2.17.12" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" resValue "string", "applicationId", applicationId diff --git a/fastlane/metadata/android/en-US/changelogs/4213404.txt b/fastlane/metadata/android/en-US/changelogs/4213404.txt new file mode 100644 index 0000000000000000000000000000000000000000..607f1d08026b376edfab14f1400972a44c6ce22f --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/4213404.txt @@ -0,0 +1 @@ +* Fix crash on file transfer in fi translation From 89f3356c25d0bd4a4ca7bc42ec206f0bb5b5575b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 23 Feb 2025 10:59:47 +0100 Subject: [PATCH 53/60] resetting hostname when extended connection settings and tor is disabled --- .../eu/siacs/conversations/AppSettings.java | 10 ++++++- .../siacs/conversations/entities/Account.java | 3 +- .../services/XmppConnectionService.java | 6 ---- .../settings/ConnectionSettingsFragment.java | 28 +++++++++++++++---- .../conversations/xmpp/XmppConnection.java | 7 ++--- 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/AppSettings.java b/src/main/java/eu/siacs/conversations/AppSettings.java index 4287d694f69fc51fe3ba976fcc32e39ad0aecdf2..45cd9a0a1e35dc3766ed4c8086d5aaa768e23ba0 100644 --- a/src/main/java/eu/siacs/conversations/AppSettings.java +++ b/src/main/java/eu/siacs/conversations/AppSettings.java @@ -7,6 +7,7 @@ import androidx.annotation.BoolRes; import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; import com.google.common.base.Strings; +import eu.siacs.conversations.services.QuickConversationsService; import java.security.SecureRandom; public class AppSettings { @@ -121,7 +122,14 @@ public class AppSettings { } public boolean isUseTor() { - return getBooleanPreference(USE_TOR, R.bool.use_tor); + return QuickConversationsService.isConversations() + && getBooleanPreference(USE_TOR, R.bool.use_tor); + } + + public boolean isExtendedConnectionOptions() { + return QuickConversationsService.isConversations() + && getBooleanPreference( + AppSettings.SHOW_CONNECTION_OPTIONS, R.bool.show_connection_options); } public boolean isAcceptInvitesFromStrangers() { diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index 294d27df6088ad77d99edba45f629553f4ad2bcf..ef5e4152d6be0b700ea10b6d4acb743565cfb0e8 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -20,6 +20,7 @@ import eu.siacs.conversations.crypto.sasl.HashedTokenSha512; import eu.siacs.conversations.crypto.sasl.SaslMechanism; import eu.siacs.conversations.services.AvatarService; import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.utils.Resolver; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.XmppUri; import eu.siacs.conversations.xmpp.Jid; @@ -116,7 +117,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable null, null, null, - 5222, + Resolver.XMPP_PORT_STARTTLS, Presence.Status.ONLINE, null, null, diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 058e37edc3fef322f8cad31e22aa5cf069c95e27..a27886f5e3851da778eaa84407adf9e77989558e 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -5433,12 +5433,6 @@ public class XmppConnectionService extends Service { && getBooleanPreference("use_tor", R.bool.use_tor); } - public boolean showExtendedConnectionOptions() { - return QuickConversationsService.isConversations() - && getBooleanPreference( - AppSettings.SHOW_CONNECTION_OPTIONS, R.bool.show_connection_options); - } - public boolean broadcastLastActivity() { return getBooleanPreference(AppSettings.BROADCAST_LAST_ACTIVITY, R.bool.last_activity); } diff --git a/src/main/java/eu/siacs/conversations/ui/fragment/settings/ConnectionSettingsFragment.java b/src/main/java/eu/siacs/conversations/ui/fragment/settings/ConnectionSettingsFragment.java index 61843bd93c6e946ee327680a453feb672c57b1e3..ab8caa5c984118b18faf9d3e54f71b1105ca61a1 100644 --- a/src/main/java/eu/siacs/conversations/ui/fragment/settings/ConnectionSettingsFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/fragment/settings/ConnectionSettingsFragment.java @@ -1,17 +1,18 @@ package eu.siacs.conversations.ui.fragment.settings; import android.os.Bundle; +import android.util.Log; import android.widget.Toast; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import com.google.common.base.Strings; - import eu.siacs.conversations.AppSettings; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; +import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.services.QuickConversationsService; +import eu.siacs.conversations.utils.Resolver; +import java.util.Arrays; public class ConnectionSettingsFragment extends XmppPreferenceFragment { @@ -59,9 +60,26 @@ public class ConnectionSettingsFragment extends XmppPreferenceFragment { reconnectAccounts(); requireService().reinitializeMuclumbusService(); } - case AppSettings.SHOW_CONNECTION_OPTIONS -> { - reconnectAccounts(); + case AppSettings.SHOW_CONNECTION_OPTIONS -> reconnectAccounts(); + } + if (Arrays.asList(AppSettings.USE_TOR, AppSettings.SHOW_CONNECTION_OPTIONS).contains(key)) { + final var appSettings = new AppSettings(requireContext()); + if (appSettings.isUseTor() || appSettings.isExtendedConnectionOptions()) { + return; } + resetUserDefinedHostname(); + } + } + + private void resetUserDefinedHostname() { + final var service = requireService(); + for (final Account account : service.getAccounts()) { + Log.d( + Config.LOGTAG, + account.getJid().asBareJid() + ": resetting hostname and port to defaults"); + account.setHostname(null); + account.setPort(Resolver.XMPP_PORT_STARTTLS); + service.databaseBackend.updateAccount(account); } } diff --git a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java index 0fbdf57f80c1d88712ddd05f83cc304dc61f9307..654a7e7e8b52e7a975dd9c7da6980a21a10732cc 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java @@ -304,8 +304,8 @@ public class XmppConnection implements Runnable { Socket localSocket; shouldAuthenticate = !account.isOptionSet(Account.OPTION_REGISTER); this.changeStatus(Account.State.CONNECTING); - final boolean useTorSetting = mXmppConnectionService.useTorToConnect(); - final boolean extended = mXmppConnectionService.showExtendedConnectionOptions(); + final boolean useTorSetting = appSettings.isUseTor(); + final boolean extended = appSettings.isExtendedConnectionOptions(); final boolean useTor = useTorSetting || account.isOnion(); // TODO collapse Tor usage into normal connection code path if (useTor) { @@ -1885,8 +1885,7 @@ public class XmppConnection implements Runnable { is = null; } } else { - final boolean useTor = - mXmppConnectionService.useTorToConnect() || account.isOnion(); + final boolean useTor = this.appSettings.isUseTor() || account.isOnion(); try { final String url = data.getValue("url"); final String fallbackUrl = data.getValue("captcha-fallback-url"); From 38754f5dbcbd1bea5f2d33526eaa794070765e1a Mon Sep 17 00:00:00 2001 From: Outbreak2096 Date: Tue, 18 Feb 2025 10:49:49 +0000 Subject: [PATCH 54/60] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (83 of 83 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/zh_Hans/ --- fastlane/metadata/android/zh-CN/changelogs/4213304.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 fastlane/metadata/android/zh-CN/changelogs/4213304.txt diff --git a/fastlane/metadata/android/zh-CN/changelogs/4213304.txt b/fastlane/metadata/android/zh-CN/changelogs/4213304.txt new file mode 100644 index 0000000000000000000000000000000000000000..9d049011e09872903f007ac9248a9b5ab7f131e1 --- /dev/null +++ b/fastlane/metadata/android/zh-CN/changelogs/4213304.txt @@ -0,0 +1 @@ +* 小错误修复 From fcc875b63ed46d5d03e3ebba97256e82832e8dbf Mon Sep 17 00:00:00 2001 From: licaon-kter Date: Wed, 19 Feb 2025 12:14:24 +0000 Subject: [PATCH 55/60] Translated using Weblate (Romanian) Currently translated at 100.0% (1061 of 1061 strings) Translation: Conversations/Android App (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/android-app-shared/ro/ --- src/main/res/values-ro-rRO/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index 50d6c822c2d8c7f9152a1a3a6b8c85bdae28892c..caade01e552aa02b6c5fb6a7364509df943a818a 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -1129,4 +1129,5 @@ Arată doar contactelor Timp limită de conectare expirat Reîncearcă cu P2P + Channel binding indisponibil \ No newline at end of file From 09512c15fe347b2d3827864a908d101bb3897944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Sat, 22 Feb 2025 09:59:55 +0000 Subject: [PATCH 56/60] Translated using Weblate (Estonian) Currently translated at 72.2% (60 of 83 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/et/ --- fastlane/metadata/android/et/changelogs/349.txt | 4 ++++ fastlane/metadata/android/et/changelogs/351.txt | 3 +++ fastlane/metadata/android/et/changelogs/353.txt | 4 ++++ fastlane/metadata/android/et/changelogs/364.txt | 2 ++ fastlane/metadata/android/et/changelogs/367.txt | 2 ++ fastlane/metadata/android/et/changelogs/379.txt | 1 + fastlane/metadata/android/et/changelogs/381.txt | 2 ++ fastlane/metadata/android/et/changelogs/382.txt | 2 ++ 8 files changed, 20 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/349.txt create mode 100644 fastlane/metadata/android/et/changelogs/351.txt create mode 100644 fastlane/metadata/android/et/changelogs/353.txt create mode 100644 fastlane/metadata/android/et/changelogs/364.txt create mode 100644 fastlane/metadata/android/et/changelogs/367.txt create mode 100644 fastlane/metadata/android/et/changelogs/379.txt create mode 100644 fastlane/metadata/android/et/changelogs/381.txt create mode 100644 fastlane/metadata/android/et/changelogs/382.txt diff --git a/fastlane/metadata/android/et/changelogs/349.txt b/fastlane/metadata/android/et/changelogs/349.txt new file mode 100644 index 0000000000000000000000000000000000000000..166160ba9cfe4d200d42eb96280667b20b38501a --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/349.txt @@ -0,0 +1,4 @@ +* Lisasime seadistuse asjatundjatele, kes soovivad teha kanalite tuvastamist search.jabber.network asemel kohalikus serveris +* Kohaletoimetamise märkeruudud on nüüd vaikimisi kasutusel ja eemaldasime vastava seadistuse +* Lülitasime „Saatmisnupp näitab olekut“ vakimisi sisse ja eemaldasime vastava seadistuse +* Tõstsime Varunduse ja Esiplaani teenuse seadistused põhivaatesse diff --git a/fastlane/metadata/android/et/changelogs/351.txt b/fastlane/metadata/android/et/changelogs/351.txt new file mode 100644 index 0000000000000000000000000000000000000000..5981723dbc1b1fa58ba2b1cced218ac4d0510a38 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/351.txt @@ -0,0 +1,3 @@ +* parandused failide edastamisel Jingle IBB abil +* parandused, kus korduvad sõnumite muutmised ummistasid andmebaasi +* võtsime kasutusele „Last Message Correction“ versiooni 1.1 diff --git a/fastlane/metadata/android/et/changelogs/353.txt b/fastlane/metadata/android/et/changelogs/353.txt new file mode 100644 index 0000000000000000000000000000000000000000..e815c62fcc48fe95e668694ce9bce51df65d93f7 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/353.txt @@ -0,0 +1,4 @@ +* kasutajad saavad nüüs ise oma hüüdnime lisada +* jälle on võimalik alla laadida faile, kasutades OMEMO krüptimist +* kanalite tunnuspildid kasutavad nüüd # sümbolit +* Quicksy kasutab vaikimisi „alati“ OMEMO krüptimist (sellega läheb peitu ka luku ikoon) diff --git a/fastlane/metadata/android/et/changelogs/364.txt b/fastlane/metadata/android/et/changelogs/364.txt new file mode 100644 index 0000000000000000000000000000000000000000..171c3db84039fab4d22cce6c00d9cc86106cb832 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/364.txt @@ -0,0 +1,2 @@ +* pdf-failide eelvaade Androidi versioonis 5 ja uuemas +* kasutame OMEMO puhul 12-baidiseid IV-sid diff --git a/fastlane/metadata/android/et/changelogs/367.txt b/fastlane/metadata/android/et/changelogs/367.txt new file mode 100644 index 0000000000000000000000000000000000000000..35fcae076d078398af9b688825772b498fb7af2e --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/367.txt @@ -0,0 +1,2 @@ +* Parandasime tunnuspiltide valimise mõnedes Android 10 seadmetes +* Parandasime suuremate failide edastamise vead diff --git a/fastlane/metadata/android/et/changelogs/379.txt b/fastlane/metadata/android/et/changelogs/379.txt new file mode 100644 index 0000000000000000000000000000000000000000..495bb0be00b5eae69a9309863bafe60bd4c8770d --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/379.txt @@ -0,0 +1 @@ +* Lisasime hääl- ja videokõnede võimaluse (eeldab, et server oskab kasutada STUN ja TURN servereid, mis on leitavad XEP-0215 alusel) diff --git a/fastlane/metadata/android/et/changelogs/381.txt b/fastlane/metadata/android/et/changelogs/381.txt new file mode 100644 index 0000000000000000000000000000000000000000..5e124e02998b72454ce1900766c8abb78d92585c --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/381.txt @@ -0,0 +1,2 @@ +* Kuuldav tagasiside (helistame, kõne algas, kõne lõppes) häälkõnede puhul. +* Parandsime vea, mis tekkis ebaõnnestunud videokõne kordamisel diff --git a/fastlane/metadata/android/et/changelogs/382.txt b/fastlane/metadata/android/et/changelogs/382.txt new file mode 100644 index 0000000000000000000000000000000000000000..2ce7697b623709fbe75707baaf0b4f6ff7f59fe5 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/382.txt @@ -0,0 +1,2 @@ +* Lisasime nupu kaamera vahetamiseks videokõne ajal +* Parandasime häälkõnede toimimise tahvelarvutites From 99f9c584fb9c83fe9e730d59cd7a695357d85fbb Mon Sep 17 00:00:00 2001 From: SomeTr Date: Sun, 23 Feb 2025 10:07:42 +0000 Subject: [PATCH 57/60] Translated using Weblate (Ukrainian) Currently translated at 100.0% (84 of 84 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/uk/ --- fastlane/metadata/android/uk/changelogs/4213404.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 fastlane/metadata/android/uk/changelogs/4213404.txt diff --git a/fastlane/metadata/android/uk/changelogs/4213404.txt b/fastlane/metadata/android/uk/changelogs/4213404.txt new file mode 100644 index 0000000000000000000000000000000000000000..80b025364194ad37c00235572579c092c9430b64 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/4213404.txt @@ -0,0 +1 @@ +* Виправлено збій під час передавання файлів, якщо мовою додатка вибрано фінську From c8d51ad06b2e7d92d8cf0821c9fde1e1b2255b32 Mon Sep 17 00:00:00 2001 From: Outbreak2096 Date: Sun, 23 Feb 2025 15:04:01 +0000 Subject: [PATCH 58/60] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (84 of 84 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/zh_Hans/ --- fastlane/metadata/android/zh-CN/changelogs/4213404.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 fastlane/metadata/android/zh-CN/changelogs/4213404.txt diff --git a/fastlane/metadata/android/zh-CN/changelogs/4213404.txt b/fastlane/metadata/android/zh-CN/changelogs/4213404.txt new file mode 100644 index 0000000000000000000000000000000000000000..d35b0abef410381b283c55fce79afc52990fe3e9 --- /dev/null +++ b/fastlane/metadata/android/zh-CN/changelogs/4213404.txt @@ -0,0 +1 @@ +* 修复在芬兰语翻译中文件传输的崩溃问题 From d4ca03c81ab9baa7eeada0322a3f730f07f1f122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Sun, 23 Feb 2025 22:55:36 +0000 Subject: [PATCH 59/60] Translated using Weblate (Estonian) Currently translated at 73.8% (62 of 84 strings) Translation: Conversations/App Store Metadata (shared) Translate-URL: https://translate.codeberg.org/projects/conversations/app-store-metadata/et/ --- fastlane/metadata/android/et/changelogs/405.txt | 1 + fastlane/metadata/android/et/changelogs/4213404.txt | 1 + 2 files changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/et/changelogs/405.txt create mode 100644 fastlane/metadata/android/et/changelogs/4213404.txt diff --git a/fastlane/metadata/android/et/changelogs/405.txt b/fastlane/metadata/android/et/changelogs/405.txt new file mode 100644 index 0000000000000000000000000000000000000000..12e754dad2c24073e934e6557352a96546c97d2a --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/405.txt @@ -0,0 +1 @@ +* Quicksy: lisandus kinnituseks saadetud SMS'ide automaatne vastuvõtmine diff --git a/fastlane/metadata/android/et/changelogs/4213404.txt b/fastlane/metadata/android/et/changelogs/4213404.txt new file mode 100644 index 0000000000000000000000000000000000000000..55ed1677e8e1c604f4c69d681696dbd4b99eeb63 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/4213404.txt @@ -0,0 +1 @@ +* Parandasime kokkujooksmise failide edastamisel soomekeelse tõlkega rakenduses From 71001ce8ce41ed6689fc8a4a880fb2d87a8628e8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 24 Feb 2025 09:14:44 +0100 Subject: [PATCH 60/60] fix quicksy registration --- src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java b/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java index 7ec4c2faab4f466c7bcb04470b692cfed16d41a1..9729abed5f51fc39df98d8a162e4bb7cb8b75974 100644 --- a/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java +++ b/src/main/java/eu/siacs/conversations/crypto/sasl/Plain.java @@ -29,7 +29,11 @@ public class Plain extends SaslMechanism { Preconditions.checkState( this.state == State.INITIAL, "Calling getClientFirstMessage from invalid state"); this.state = State.AUTH_TEXT_SENT; - final String message = '\u0000' + account.getUsername() + '\u0000' + account.getPassword(); + return getMessage(account.getUsername(), account.getPassword()); + } + + public static String getMessage(final String username, final String password) { + final String message = '\u0000' + username + '\u0000' + password; return BaseEncoding.base64().encode(message.getBytes()); }