From ef98a24bf6f212bb06a212e804e6a339e303b809 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 12 Dec 2019 18:54:44 +0100 Subject: [PATCH 01/38] add .heic to list of known mime types fixes #3598 --- src/main/java/eu/siacs/conversations/utils/MimeUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/utils/MimeUtils.java b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java index aaaef8e0d..3040ce15e 100644 --- a/src/main/java/eu/siacs/conversations/utils/MimeUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/MimeUtils.java @@ -16,6 +16,7 @@ package eu.siacs.conversations.utils; import android.content.Context; import android.net.Uri; +import android.os.Build; import android.util.Log; import java.io.File; @@ -268,6 +269,7 @@ public final class MimeUtils { add("image/ico", "cur"); add("image/ico", "ico"); add("image/ief", "ief"); + add("image/heic","heic"); // add ".jpg" first so it will be the default for guessExtensionFromMimeType add("image/jpeg", "jpg"); add("image/jpeg", "jpeg"); From cae124d93fd5e55d6d92a83c632fd1b2687c3fed Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Fri, 20 Dec 2019 19:07:31 +0100 Subject: [PATCH 02/38] createOutputStream(): allow to disable decryption --- .../services/AbstractConnectionManager.java | 13 ++----------- .../conversations/xmpp/jingle/JingleConnection.java | 2 +- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java index 43c28b854..81f3f80bc 100644 --- a/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java +++ b/src/main/java/eu/siacs/conversations/services/AbstractConnectionManager.java @@ -53,20 +53,11 @@ public class AbstractConnectionManager { } } - - public static OutputStream createAppendedOutputStream(DownloadableFile file) { - return createOutputStream(file, true); - } - - public static OutputStream createOutputStream(DownloadableFile file) { - return createOutputStream(file, false); - } - - private static OutputStream createOutputStream(DownloadableFile file, boolean append) { + public static OutputStream createOutputStream(DownloadableFile file, boolean append, boolean decrypt) { FileOutputStream os; try { os = new FileOutputStream(file, append); - if (file.getKey() == null) { + if (file.getKey() == null || !decrypt) { return os; } } catch (FileNotFoundException e) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index 2596f9960..3b2909cc7 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -213,7 +213,7 @@ public class JingleConnection implements Transferable { } this.file.getParentFile().mkdirs(); this.file.createNewFile(); - this.mFileOutputStream = AbstractConnectionManager.createOutputStream(this.file); + this.mFileOutputStream = AbstractConnectionManager.createOutputStream(this.file, false, true); return this.mFileOutputStream; } From 92cf221a2b4448061d01043f7e60a453fd770306 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Fri, 20 Dec 2019 19:09:44 +0100 Subject: [PATCH 03/38] Implement download resumption for OMEMO encrypted files --- .../http/HttpDownloadConnection.java | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index 8c366558d..3723e06b2 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -4,7 +4,10 @@ import android.os.PowerManager; import android.support.annotation.Nullable; import android.util.Log; +import com.google.common.io.ByteStreams; + import java.io.BufferedInputStream; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -90,7 +93,12 @@ public class HttpDownloadConnection implements Transferable { ext = extension.main; } message.setRelativeFilePath(message.getUuid() + (ext != null ? ("." + ext) : "")); - this.file = mXmppConnectionService.getFileBackend().getFile(message, false); + if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { + this.file = new DownloadableFile(mXmppConnectionService.getCacheDir().getAbsolutePath() + "/" + message.getUuid()); + Log.d(Config.LOGTAG, "create temporary OMEMO encrypted file: " + this.file.getAbsolutePath() + "(" + message.getMimeType() + ")"); + } else { + this.file = mXmppConnectionService.getFileBackend().getFile(message, false); + } final String reference = mUrl.getRef(); if (reference != null && AesGcmURLStreamHandler.IV_KEY.matcher(reference).matches()) { this.file.setKeyAndIv(CryptoHelper.hexToBytes(reference)); @@ -131,7 +139,41 @@ public class HttpDownloadConnection implements Transferable { mHttpConnectionManager.updateConversationUi(true); } - private void finish() { + private void decryptOmemoFile() throws Exception { + final DownloadableFile outputFile = mXmppConnectionService.getFileBackend().getFile(message, true); + + if (outputFile.getParentFile().mkdirs()) { + Log.d(Config.LOGTAG, "created parent directories for " + outputFile.getAbsolutePath()); + } + + try { + outputFile.createNewFile(); + final InputStream is = new FileInputStream(this.file); + + outputFile.setKey(this.file.getKey()); + outputFile.setIv(this.file.getIv()); + final OutputStream os = AbstractConnectionManager.createOutputStream(outputFile, false, true); + + ByteStreams.copy(is, os); + + FileBackend.close(is); + FileBackend.close(os); + + if (!file.delete()) { + Log.w(Config.LOGTAG,"unable to delete temporary OMEMO encrypted file " + file.getAbsolutePath()); + } + + message.setRelativeFilePath(outputFile.getPath()); + } catch (IOException e) { + message.setEncryption(Message.ENCRYPTION_DECRYPTION_FAILED); + mXmppConnectionService.updateMessage(message); + } + } + + private void finish() throws Exception { + if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { + decryptOmemoFile(); + } message.setTransferable(null); mHttpConnectionManager.finishConnection(this); boolean notify = acceptedAutomatically && !message.isRead(); @@ -337,8 +379,8 @@ public class HttpDownloadConnection implements Transferable { try { changeStatus(STATUS_DOWNLOADING); download(); - updateImageBounds(); finish(); + updateImageBounds(); } catch (SSLHandshakeException e) { changeStatus(STATUS_OFFER); } catch (Exception e) { @@ -369,7 +411,7 @@ public class HttpDownloadConnection implements Transferable { connection.setUseCaches(false); connection.setRequestProperty("User-Agent", mXmppConnectionService.getIqGenerator().getUserAgent()); final long expected = file.getExpectedSize(); - final boolean tryResume = file.exists() && file.getKey() == null && file.getSize() > 0 && file.getSize() < expected; + final boolean tryResume = file.exists() && file.getSize() > 0 && file.getSize() < expected; long resumeSize = 0; if (tryResume) { @@ -388,7 +430,7 @@ public class HttpDownloadConnection implements Transferable { Log.d(Config.LOGTAG, "server resumed"); transmitted = file.getSize(); updateProgress(Math.round(((double) transmitted / expected) * 100)); - os = AbstractConnectionManager.createAppendedOutputStream(file); + os = AbstractConnectionManager.createOutputStream(file, true, false); if (os == null) { throw new FileWriterException(); } @@ -406,7 +448,7 @@ public class HttpDownloadConnection implements Transferable { if (!file.exists() && !file.createNewFile()) { throw new FileWriterException(); } - os = AbstractConnectionManager.createOutputStream(file); + os = AbstractConnectionManager.createOutputStream(file, false, false); } int count; byte[] buffer = new byte[4096]; From 5117956648b63708bfd5a2a9b69b4323cc8761e8 Mon Sep 17 00:00:00 2001 From: Marc Schink Date: Fri, 20 Dec 2019 19:10:07 +0100 Subject: [PATCH 04/38] Add missing space in debug output --- .../eu/siacs/conversations/http/HttpDownloadConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index 3723e06b2..ca0476b4e 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -416,7 +416,7 @@ public class HttpDownloadConnection implements Transferable { if (tryResume) { resumeSize = file.getSize(); - Log.d(Config.LOGTAG, "http download trying resume after" + resumeSize + " of " + expected); + Log.d(Config.LOGTAG, "http download trying resume after " + resumeSize + " of " + expected); connection.setRequestProperty("Range", "bytes=" + resumeSize + "-"); } connection.setConnectTimeout(Config.SOCKET_TIMEOUT * 1000); From c898486534b04a6ccf90206bc1456155db32d9df Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 22 Dec 2019 18:19:02 +0100 Subject: [PATCH 05/38] add request package install permission starting with api 26 an app needs to hold that permission to even show the app install screen --- src/main/AndroidManifest.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 31f33e5fd..347372013 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -17,6 +17,7 @@ + - + From 9bcef7a8e7768a95a6910cb7ef6e9533110c2ef0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 22 Dec 2019 19:30:58 +0100 Subject: [PATCH 06/38] display '#' in generated channel avatars --- .../http/HttpDownloadConnection.java | 4 ++++ .../conversations/services/AvatarService.java | 20 ++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index ca0476b4e..b7cf0947a 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -296,6 +296,10 @@ public class HttpDownloadConnection implements Transferable { retrieveFailed(e); return; } + //TODO at this stage we probably also want to persist the file size in the body of the + // message via a similar mechansim as updateFileParams() - essentially body needs to read + // "url|filesize" + // afterwards a file that failed to download mid way will not display 'check file size' anymore file.setExpectedSize(size); message.resetFileParams(); if (mHttpConnectionManager.hasStoragePermission() diff --git a/src/main/java/eu/siacs/conversations/services/AvatarService.java b/src/main/java/eu/siacs/conversations/services/AvatarService.java index ca2d534b2..8f7f8afb4 100644 --- a/src/main/java/eu/siacs/conversations/services/AvatarService.java +++ b/src/main/java/eu/siacs/conversations/services/AvatarService.java @@ -58,6 +58,8 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { private static final String PREFIX_ACCOUNT = "account"; private static final String PREFIX_GENERIC = "generic"; + private static final String CHANNEL_SYMBOL = "#"; + final private ArrayList sizes = new ArrayList<>(); final private HashMap> conversationDependentKeys = new HashMap<>(); @@ -95,7 +97,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { if (conversation != null) { return get(conversation,size,cacheOnly); } - return get(result.getName(), room != null ? room.asBareJid().toEscapedString() : result.getName(), size, cacheOnly); + return get(CHANNEL_SYMBOL, room != null ? room.asBareJid().toEscapedString() : result.getName(), size, cacheOnly); } private Bitmap get(final Contact contact, final int size, boolean cachedOnly) { @@ -339,12 +341,16 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { bitmap = mXmppConnectionService.getFileBackend().getAvatar(mucOptions.getAvatar(), size); if (bitmap == null) { - final List users = mucOptions.getUsersRelevantForNameAndAvatar(); - if (users.size() == 0) { - Conversation c = mucOptions.getConversation(); - bitmap = getImpl(c.getName().toString(), c.getJid().asBareJid().toString(), size); + Conversation c = mucOptions.getConversation(); + if (mucOptions.isPrivateAndNonAnonymous()) { + final List users = mucOptions.getUsersRelevantForNameAndAvatar(); + if (users.size() == 0) { + bitmap = getImpl(c.getName().toString(), c.getJid().asBareJid().toString(), size); + } else { + bitmap = getImpl(users, size); + } } else { - bitmap = getImpl(users, size); + bitmap = getImpl(CHANNEL_SYMBOL, c.getJid().asBareJid().toString(), size); } } @@ -628,7 +634,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded { private static boolean drawTile(Canvas canvas, String name, String seed, int left, int top, int right, int bottom) { if (name != null) { - final String letter = getFirstLetter(name); + final String letter = name.equals(CHANNEL_SYMBOL) ? name : getFirstLetter(name); final int color = UIHelper.getColorForName(seed == null ? name : seed); drawTile(canvas, letter, color, left, top, right, bottom); return true; From a60e29d4f488664049460452b54674e7a45eea86 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 26 Dec 2019 17:36:16 +0100 Subject: [PATCH 07/38] removed c style array --- src/main/java/eu/siacs/conversations/entities/Message.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index cc73222c5..1d34ec4ec 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -802,7 +802,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable if (this.transferable != null) { fileParams.size = this.transferable.getFileSize(); } - String parts[] = body == null ? new String[0] : body.split("\\|"); + final String[] parts = body == null ? new String[0] : body.split("\\|"); switch (parts.length) { case 1: try { From ed4a73e1c7925d3744542193579c0ea25e439eb4 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 26 Dec 2019 18:58:54 +0100 Subject: [PATCH 08/38] persist file size across aborts fixes #3601 --- .../siacs/conversations/entities/Message.java | 4 + .../http/HttpDownloadConnection.java | 27 +++-- .../persistance/FileBackend.java | 100 +++++++++--------- .../ui/ConversationFragment.java | 4 +- .../ui/adapter/MessageAdapter.java | 8 +- .../conversations/utils/MessageUtils.java | 4 + .../siacs/conversations/utils/UIHelper.java | 2 +- 7 files changed, 85 insertions(+), 64 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 1d34ec4ec..360103aa0 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -653,6 +653,10 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable } } + public boolean isOOb() { + return oob; + } + public static class MergeSeparator { } diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index b7cf0947a..bd52e8ad2 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -74,8 +74,11 @@ public class HttpDownloadConnection implements Transferable { public void init(boolean interactive) { this.message.setTransferable(this); try { + final Message.FileParams fileParams = message.getFileParams(); if (message.hasFileOnRemoteHost()) { - mUrl = CryptoHelper.toHttpsUrl(message.getFileParams().url); + mUrl = CryptoHelper.toHttpsUrl(fileParams.url); + } else if (message.isOOb() && fileParams.url != null && fileParams.size > 0) { + mUrl = fileParams.url; } else { mUrl = CryptoHelper.toHttpsUrl(new URL(message.getBody().split("\n")[0])); } @@ -139,7 +142,7 @@ public class HttpDownloadConnection implements Transferable { mHttpConnectionManager.updateConversationUi(true); } - private void decryptOmemoFile() throws Exception { + private void decryptOmemoFile() { final DownloadableFile outputFile = mXmppConnectionService.getFileBackend().getFile(message, true); if (outputFile.getParentFile().mkdirs()) { @@ -171,9 +174,6 @@ public class HttpDownloadConnection implements Transferable { } private void finish() throws Exception { - if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { - decryptOmemoFile(); - } message.setTransferable(null); mHttpConnectionManager.finishConnection(this); boolean notify = acceptedAutomatically && !message.isRead(); @@ -189,6 +189,12 @@ public class HttpDownloadConnection implements Transferable { }); } + private void decryptIfNeeded() { + if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { + decryptOmemoFile(); + } + } + private void changeStatus(int status) { this.mStatus = status; mHttpConnectionManager.updateConversationUi(true); @@ -296,10 +302,10 @@ public class HttpDownloadConnection implements Transferable { retrieveFailed(e); return; } - //TODO at this stage we probably also want to persist the file size in the body of the - // message via a similar mechansim as updateFileParams() - essentially body needs to read - // "url|filesize" - // afterwards a file that failed to download mid way will not display 'check file size' anymore + final Message.FileParams fileParams = message.getFileParams(); + FileBackend.updateFileParams(message, fileParams.url, size); + message.setOob(true); + mXmppConnectionService.databaseBackend.updateMessage(message, true); file.setExpectedSize(size); message.resetFileParams(); if (mHttpConnectionManager.hasStoragePermission() @@ -383,8 +389,9 @@ public class HttpDownloadConnection implements Transferable { try { changeStatus(STATUS_DOWNLOADING); download(); - finish(); + decryptIfNeeded(); updateImageBounds(); + finish(); } catch (SSLHandshakeException e) { changeStatus(STATUS_OFFER); } catch (Exception e) { diff --git a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java index 3c049bf48..48f3d4343 100644 --- a/src/main/java/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/FileBackend.java @@ -3,7 +3,6 @@ package eu.siacs.conversations.persistance; import android.annotation.TargetApi; import android.content.ContentResolver; import android.content.Context; -import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; @@ -74,10 +73,8 @@ public class FileBackend { private static final SimpleDateFormat IMAGE_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US); private static final String FILE_PROVIDER = ".files"; - - private XmppConnectionService mXmppConnectionService; - private static final float IGNORE_PADDING = 0.15f; + private XmppConnectionService mXmppConnectionService; public FileBackend(XmppConnectionService service) { this.mXmppConnectionService = service; @@ -158,7 +155,7 @@ public class FileBackend { } public static String getBackupDirectory(String app) { - return Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+app+"/Backup/"; + return Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + app + "/Backup/"; } private static Bitmap rotate(Bitmap bitmap, int degree) { @@ -257,31 +254,6 @@ public class FileBackend { return inSampleSize; } - public Bitmap getPreviewForUri(Attachment attachment, int size, boolean cacheOnly) { - final String key = "attachment_"+attachment.getUuid().toString()+"_"+String.valueOf(size); - final LruCache cache = mXmppConnectionService.getBitmapCache(); - Bitmap bitmap = cache.get(key); - if (bitmap != null || cacheOnly) { - return bitmap; - } - if (attachment.getMime() != null && attachment.getMime().startsWith("video/")) { - bitmap = cropCenterSquareVideo(attachment.getUri(), size); - drawOverlay(bitmap, paintOverlayBlack(bitmap) ? R.drawable.play_video_black : R.drawable.play_video_white, 0.75f); - } else { - bitmap = cropCenterSquare(attachment.getUri(), size); - if (bitmap != null && "image/gif".equals(attachment.getMime())) { - Bitmap withGifOverlay = bitmap.copy(Bitmap.Config.ARGB_8888, true); - drawOverlay(withGifOverlay, paintOverlayBlack(withGifOverlay) ? R.drawable.play_gif_black : R.drawable.play_gif_white, 1.0f); - bitmap.recycle(); - bitmap = withGifOverlay; - } - } - if (bitmap != null) { - cache.put(key, bitmap); - } - return bitmap; - } - private static Dimensions getVideoDimensions(Context context, Uri uri) throws NotAVideoFile { MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever(); try { @@ -421,19 +393,6 @@ public class FileBackend { } } - private void createNoMedia(File diretory) { - final File noMedia = new File(diretory, ".nomedia"); - if (!noMedia.exists()) { - try { - if (!noMedia.createNewFile()) { - Log.d(Config.LOGTAG, "created nomedia file " + noMedia.getAbsolutePath()); - } - } catch (Exception e) { - Log.d(Config.LOGTAG, "could not create nomedia file"); - } - } - } - public static Uri getMediaUri(Context context, File file) { final String filePath = file.getAbsolutePath(); final Cursor cursor; @@ -455,6 +414,50 @@ public class FileBackend { } } + public static void updateFileParams(Message message, URL url, long size) { + final StringBuilder body = new StringBuilder(); + body.append(url.toString()).append('|').append(size); + message.setBody(body.toString()); + } + + public Bitmap getPreviewForUri(Attachment attachment, int size, boolean cacheOnly) { + final String key = "attachment_" + attachment.getUuid().toString() + "_" + String.valueOf(size); + final LruCache cache = mXmppConnectionService.getBitmapCache(); + Bitmap bitmap = cache.get(key); + if (bitmap != null || cacheOnly) { + return bitmap; + } + if (attachment.getMime() != null && attachment.getMime().startsWith("video/")) { + bitmap = cropCenterSquareVideo(attachment.getUri(), size); + drawOverlay(bitmap, paintOverlayBlack(bitmap) ? R.drawable.play_video_black : R.drawable.play_video_white, 0.75f); + } else { + bitmap = cropCenterSquare(attachment.getUri(), size); + if (bitmap != null && "image/gif".equals(attachment.getMime())) { + Bitmap withGifOverlay = bitmap.copy(Bitmap.Config.ARGB_8888, true); + drawOverlay(withGifOverlay, paintOverlayBlack(withGifOverlay) ? R.drawable.play_gif_black : R.drawable.play_gif_white, 1.0f); + bitmap.recycle(); + bitmap = withGifOverlay; + } + } + if (bitmap != null) { + cache.put(key, bitmap); + } + return bitmap; + } + + private void createNoMedia(File diretory) { + final File noMedia = new File(diretory, ".nomedia"); + if (!noMedia.exists()) { + try { + if (!noMedia.createNewFile()) { + Log.d(Config.LOGTAG, "created nomedia file " + noMedia.getAbsolutePath()); + } + } catch (Exception e) { + Log.d(Config.LOGTAG, "could not create nomedia file"); + } + } + } + public void updateMediaScanner(File file) { updateMediaScanner(file, null); } @@ -472,7 +475,7 @@ public class FileBackend { if (callback != null && file.getAbsolutePath().equals(path)) { callback.run(); } else { - Log.d(Config.LOGTAG,"media scanner scanned wrong file"); + Log.d(Config.LOGTAG, "media scanner scanned wrong file"); if (callback != null) { callback.run(); } @@ -506,7 +509,7 @@ public class FileBackend { } public DownloadableFile getFileForPath(String path) { - return getFileForPath(path,MimeUtils.guessMimeTypeFromExtension(MimeUtils.extractRelevantExtension(path))); + return getFileForPath(path, MimeUtils.guessMimeTypeFromExtension(MimeUtils.extractRelevantExtension(path))); } public DownloadableFile getFileForPath(String path, String mime) { @@ -548,7 +551,7 @@ public class FileBackend { public List convertToAttachments(List relativeFilePaths) { List attachments = new ArrayList<>(); - for(DatabaseBackend.FilePath relativeFilePath : relativeFilePaths) { + for (DatabaseBackend.FilePath relativeFilePath : relativeFilePaths) { final String mime = MimeUtils.guessMimeTypeFromExtension(MimeUtils.extractRelevantExtension(relativeFilePath.path)); final File file = getFileForPath(relativeFilePath.path, mime); attachments.add(Attachment.of(relativeFilePath.uuid, file, mime)); @@ -988,7 +991,7 @@ public class FileBackend { avatar.height = bitmap.getHeight(); return avatar; } catch (OutOfMemoryError e) { - Log.d(Config.LOGTAG,"unable to convert avatar to base64 due to low memory"); + Log.d(Config.LOGTAG, "unable to convert avatar to base64 due to low memory"); return null; } catch (Exception e) { return null; @@ -1116,7 +1119,7 @@ public class FileBackend { return cropCenterSquare(input, size); } } catch (FileNotFoundException | SecurityException e) { - Log.d(Config.LOGTAG,"unable to open file "+image.toString(), e); + Log.d(Config.LOGTAG, "unable to open file " + image.toString(), e); return null; } finally { close(is); @@ -1228,7 +1231,6 @@ public class FileBackend { message.setType(privateMessage ? Message.TYPE_PRIVATE_FILE : (image ? Message.TYPE_IMAGE : Message.TYPE_FILE)); } - private int getMediaRuntime(File file) { try { MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever(); diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 1eaa1861f..724855ee7 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -1424,8 +1424,10 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke Log.d(Config.LOGTAG, "type: " + transferable.getClass().getName()); Toast.makeText(getActivity(), R.string.not_connected_try_again, Toast.LENGTH_SHORT).show(); } - } else if (message.treatAsDownloadable() || message.hasFileOnRemoteHost()) { + } else if (message.treatAsDownloadable() || message.hasFileOnRemoteHost() || MessageUtils.unInitiatedButKnownSize(message)) { createNewConnection(message); + } else { + Log.d(Config.LOGTAG,message.getConversation().getAccount()+": unable to start downloadable"); } } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index a8a93d4e8..e3afab37a 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -70,6 +70,7 @@ import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.EmojiWrapper; import eu.siacs.conversations.utils.Emoticons; import eu.siacs.conversations.utils.GeoHelper; +import eu.siacs.conversations.utils.MessageUtils; import eu.siacs.conversations.utils.StylingHelper; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.mam.MamReference; @@ -184,7 +185,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie final Transferable transferable = message.getTransferable(); boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI && message.getMergedStatus() <= Message.STATUS_RECEIVED; - if (message.isFileOrImage() || transferable != null) { + if (message.isFileOrImage() || transferable != null || MessageUtils.unInitiatedButKnownSize(message)) { FileParams params = message.getFileParams(); filesize = params.size > 0 ? UIHelper.filesizeToString(params.size) : null; if (transferable != null && (transferable.getStatus() == Transferable.STATUS_FAILED || transferable.getStatus() == Transferable.STATUS_CANCELLED)) { @@ -733,8 +734,9 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie }); final Transferable transferable = message.getTransferable(); - if (message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) { - if (transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) { + final boolean unInitiatedButKnownSize = MessageUtils.unInitiatedButKnownSize(message); + if (unInitiatedButKnownSize || message.isDeleted() || (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING)) { + if (unInitiatedButKnownSize || transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER) { displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message)), darkBackground); } else if (transferable != null && transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) { displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message)), darkBackground); diff --git a/src/main/java/eu/siacs/conversations/utils/MessageUtils.java b/src/main/java/eu/siacs/conversations/utils/MessageUtils.java index ca3416579..e5e4fbd97 100644 --- a/src/main/java/eu/siacs/conversations/utils/MessageUtils.java +++ b/src/main/java/eu/siacs/conversations/utils/MessageUtils.java @@ -91,4 +91,8 @@ public class MessageUtils { public static String filterLtrRtl(String body) { return LTR_RTL.matcher(body).replaceFirst(EMPTY_STRING); } + + public static boolean unInitiatedButKnownSize(Message message) { + return message.getType() == Message.TYPE_TEXT && message.getTransferable() == null && message.isOOb() && message.getFileParams().size > 0 && message.getFileParams().url != null; + } } diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index c99c1c1b2..47fec58c6 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -306,7 +306,7 @@ public class UIHelper { UIHelper.getMessageDisplayName(message) + " "), false); } else if (message.isGeoUri()) { return new Pair<>(context.getString(R.string.location), true); - } else if (message.treatAsDownloadable()) { + } else if (message.treatAsDownloadable() || MessageUtils.unInitiatedButKnownSize(message)) { return new Pair<>(context.getString(R.string.x_file_offered_for_download, getFileDescriptionString(context, message)), true); } else { From 2b375877eb05eef492651e53fa1beeadbf93979b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 29 Dec 2019 15:34:02 +0100 Subject: [PATCH 09/38] extend omemo auto expiry to 42 days (6 weeks) closes #3584 --- src/main/java/eu/siacs/conversations/Config.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index b86e2b65d..c106bf42b 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -94,7 +94,9 @@ public final class Config { public static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000; - public static final long OMEMO_AUTO_EXPIRY = 14 * MILLISECONDS_IN_DAY; + //remove *other* omemo devices from *your* device list announcement after not seeing any activity from them for 42 days. They will automatically add themselves after coming back online. + public static final long OMEMO_AUTO_EXPIRY = 42 * MILLISECONDS_IN_DAY; + public static final boolean REMOVE_BROKEN_DEVICES = false; public static final boolean OMEMO_PADDING = false; public static final boolean PUT_AUTH_TAG_INTO_KEY = true; From af3c106dc8c8f59b880dbb1768cde0bb2746cbd6 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 30 Dec 2019 00:14:52 +0100 Subject: [PATCH 10/38] reset file to normal message when attempting re-download after delete fixes: #3604 --- .../siacs/conversations/http/HttpDownloadConnection.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java index bd52e8ad2..b494c7ab0 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpDownloadConnection.java @@ -72,6 +72,15 @@ public class HttpDownloadConnection implements Transferable { } public void init(boolean interactive) { + if (message.isDeleted()) { + if (message.getType() == Message.TYPE_PRIVATE_FILE) { + message.setType(Message.TYPE_PRIVATE); + } else if (message.isFileOrImage()) { + message.setType(Message.TYPE_TEXT); + } + message.setDeleted(false); + mXmppConnectionService.updateMessage(message); + } this.message.setTransferable(this); try { final Message.FileParams fileParams = message.getFileParams(); From 42d69fd5e3d32423e3c00fa7809d6331b14c4451 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 30 Dec 2019 00:23:44 +0100 Subject: [PATCH 11/38] =?UTF-8?q?don=E2=80=99t=20crash=20when=20long=20pre?= =?UTF-8?q?ssing=20invalid=20geo-uris?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/eu/siacs/conversations/utils/GeoHelper.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java index 79600075a..9847236ef 100644 --- a/src/main/java/eu/siacs/conversations/utils/GeoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/GeoHelper.java @@ -125,9 +125,13 @@ public class GeoHelper { } public static boolean openInOsmAnd(Context context, Message message) { - final GeoPoint geoPoint = parseGeoPoint(message.getBody()); - final String label = getLabel(context, message); - return geoIntent(geoPoint,label).resolveActivity(context.getPackageManager()) != null; + try { + final GeoPoint geoPoint = parseGeoPoint(message.getBody()); + final String label = getLabel(context, message); + return geoIntent(geoPoint, label).resolveActivity(context.getPackageManager()) != null; + } catch (IllegalArgumentException e) { + return false; + } } private static String getLabel(Context context, Message message) { From 0315b3b5c259dd6e63d841c446ccd785c23b9412 Mon Sep 17 00:00:00 2001 From: Anjan Momi Date: Sat, 4 Jan 2020 19:44:05 +0000 Subject: [PATCH 12/38] added openstreetmap copyright notice to maps fixes #3588 --- .../conversations/ui/ShareLocationActivity.java | 4 ++++ src/main/res/layout/activity_share_location.xml | 12 ++++++++++++ src/main/res/values/colors.xml | 1 + src/main/res/values/strings.xml | 1 + 4 files changed, 18 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/ui/ShareLocationActivity.java b/src/main/java/eu/siacs/conversations/ui/ShareLocationActivity.java index 136e9d2b2..01050ad0d 100644 --- a/src/main/java/eu/siacs/conversations/ui/ShareLocationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ShareLocationActivity.java @@ -11,7 +11,9 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.design.widget.Snackbar; import android.support.v7.widget.Toolbar; +import android.text.method.LinkMovementMethod; import android.view.View; +import android.widget.TextView; import org.osmdroid.api.IGeoPoint; import org.osmdroid.util.GeoPoint; @@ -105,6 +107,8 @@ public class ShareLocationActivity extends LocationActivity implements LocationL } toggleFixedLocation(); }); + + binding.openstreetmapCredit.setMovementMethod(LinkMovementMethod.getInstance()); } @Override diff --git a/src/main/res/layout/activity_share_location.xml b/src/main/res/layout/activity_share_location.xml index 01249da55..9f25fa41f 100644 --- a/src/main/res/layout/activity_share_location.xml +++ b/src/main/res/layout/activity_share_location.xml @@ -26,6 +26,18 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> + + #deffffff #b2ffffff #1fffffff + #80FFFFFF #fffafafa #ffeeeeee #ffe0e0e0 diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index d9b957ec1..47d0e90ac 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -882,4 +882,5 @@ Channel discovery method Backup About + © OpenStreetMap contributors From 0ddfc51d6c23af91ad52526601a25ec7c2cd5de0 Mon Sep 17 00:00:00 2001 From: Anjan Momi Date: Sun, 5 Jan 2020 02:22:39 -0800 Subject: [PATCH 13/38] show number of participants in a MUC fixes #3447 --- .../eu/siacs/conversations/ui/ConferenceDetailsActivity.java | 1 + src/main/res/layout/activity_muc_details.xml | 5 +++-- src/main/res/values/strings.xml | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index 755a6b045..f3f4ded42 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -551,6 +551,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers this.mUserPreviewAdapter.submitList(MucOptions.sub(users, GridManager.getCurrentColumnCount(binding.users))); this.binding.invite.setVisibility(mucOptions.canInvite() ? View.VISIBLE : View.GONE); this.binding.showUsers.setVisibility(users.size() > 0 ? View.VISIBLE : View.GONE); + this.binding.showUsers.setText(getResources().getQuantityString(R.plurals.view_users, users.size(), users.size())); this.binding.usersWrapper.setVisibility(users.size() > 0 || mucOptions.canInvite() ? View.VISIBLE : View.GONE); if (users.size() == 0) { this.binding.noUsersHints.setText(mucOptions.isPrivateAndNonAnonymous() ? R.string.no_users_hint_group_chat : R.string.no_users_hint_channel); diff --git a/src/main/res/layout/activity_muc_details.xml b/src/main/res/layout/activity_muc_details.xml index 54d7081ab..0d67187e4 100644 --- a/src/main/res/layout/activity_muc_details.xml +++ b/src/main/res/layout/activity_muc_details.xml @@ -1,6 +1,7 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 47d0e90ac..fbac96230 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -753,7 +753,6 @@ Importance, Sound, Vibrate Video compression View media - View participants Participants Media browser File omitted due to security violation. @@ -882,5 +881,9 @@ Channel discovery method Backup About + + View %1$d Participant + View %1$d Participants + © OpenStreetMap contributors From 83e1d0d0a5acd87fe76658fb62f9f4269ece6240 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 5 Jan 2020 13:30:26 +0100 Subject: [PATCH 14/38] make checkmark icon more material --- .../ui/adapter/MessageAdapter.java | 2 + .../res/drawable-hdpi/ic_done_black_18dp.png | Bin 0 -> 149 bytes .../res/drawable-hdpi/ic_done_white_18dp.png | Bin 0 -> 157 bytes .../drawable-hdpi/ic_received_indicator.png | Bin 560 -> 0 bytes .../res/drawable-mdpi/ic_done_black_18dp.png | Bin 0 -> 138 bytes .../res/drawable-mdpi/ic_done_black_24dp.png | Bin 130 -> 0 bytes .../res/drawable-mdpi/ic_done_white_18dp.png | Bin 0 -> 144 bytes .../drawable-mdpi/ic_received_indicator.png | Bin 402 -> 0 bytes .../ic_done_black_18dp.png} | Bin .../res/drawable-xhdpi/ic_done_black_24dp.png | Bin 188 -> 0 bytes .../res/drawable-xhdpi/ic_done_white_18dp.png | Bin 0 -> 188 bytes .../drawable-xhdpi/ic_received_indicator.png | Bin 717 -> 0 bytes .../drawable-xxhdpi/ic_done_black_18dp.png | Bin 0 -> 199 bytes .../drawable-xxhdpi/ic_done_white_18dp.png | Bin 0 -> 217 bytes .../drawable-xxhdpi/ic_received_indicator.png | Bin 1016 -> 0 bytes .../ic_done_black_18dp.png} | Bin .../drawable-xxxhdpi/ic_done_black_24dp.png | Bin 277 -> 0 bytes .../drawable-xxxhdpi/ic_done_white_18dp.png | Bin 0 -> 255 bytes .../ic_received_indicator.png | Bin 1303 -> 0 bytes src/main/res/layout/message_sent.xml | 48 +++++++++--------- src/main/res/values/themes.xml | 2 - 21 files changed, 25 insertions(+), 27 deletions(-) create mode 100644 src/main/res/drawable-hdpi/ic_done_black_18dp.png create mode 100644 src/main/res/drawable-hdpi/ic_done_white_18dp.png delete mode 100644 src/main/res/drawable-hdpi/ic_received_indicator.png create mode 100644 src/main/res/drawable-mdpi/ic_done_black_18dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_done_black_24dp.png create mode 100644 src/main/res/drawable-mdpi/ic_done_white_18dp.png delete mode 100644 src/main/res/drawable-mdpi/ic_received_indicator.png rename src/main/res/{drawable-hdpi/ic_done_black_24dp.png => drawable-xhdpi/ic_done_black_18dp.png} (100%) delete mode 100644 src/main/res/drawable-xhdpi/ic_done_black_24dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_done_white_18dp.png delete mode 100644 src/main/res/drawable-xhdpi/ic_received_indicator.png create mode 100644 src/main/res/drawable-xxhdpi/ic_done_black_18dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_done_white_18dp.png delete mode 100644 src/main/res/drawable-xxhdpi/ic_received_indicator.png rename src/main/res/{drawable-xxhdpi/ic_done_black_24dp.png => drawable-xxxhdpi/ic_done_black_18dp.png} (100%) delete mode 100644 src/main/res/drawable-xxxhdpi/ic_done_black_24dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_done_white_18dp.png delete mode 100644 src/main/res/drawable-xxxhdpi/ic_received_indicator.png diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index e3afab37a..6867bbeb5 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -208,6 +208,8 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie break; case Message.STATUS_SEND_RECEIVED: case Message.STATUS_SEND_DISPLAYED: + viewHolder.indicatorReceived.setImageResource(darkBackground ? R.drawable.ic_done_white_18dp : R.drawable.ic_done_black_18dp); + viewHolder.indicatorReceived.setAlpha(darkBackground ? 0.7f : 0.57f); viewHolder.indicatorReceived.setVisibility(View.VISIBLE); break; case Message.STATUS_SEND_FAILED: diff --git a/src/main/res/drawable-hdpi/ic_done_black_18dp.png b/src/main/res/drawable-hdpi/ic_done_black_18dp.png new file mode 100644 index 0000000000000000000000000000000000000000..8d867ac01c83890e875a454a4d2d0a2a8b4e4dff GIT binary patch literal 149 zcmeAS@N?(olHy`uVBq!ia0vp^(jd&i0wmS%+S~(DF`h1tAr*|t5)1}hXC&{Oy!fT@ zA$v3T%US=7Z4v?`JZDKrzVWzz!AAo-}1>Xmj9PI zA?3-zvEvwzkTd_fkKCP(d{;fPY#dD|t>Ro2*p}kEn1SJi`^>-3wicKH?PKtC^>bP0 Hl+XkK93ntJ literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-hdpi/ic_received_indicator.png b/src/main/res/drawable-hdpi/ic_received_indicator.png deleted file mode 100644 index 6d842d6cbdebd202be9f2552d5b95080c43b7e38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 560 zcmV-00?+-4P)5nZU6uP8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10j)_yK~y-6t0oelbt&O`5up`ILG4i5hUD%!_2 z8GF*n0vHV|ig@a-Um}`5M*u>NI*Imp8kOlPs`Fn`#o5}r*$862vxZRS095$s92GOy zd+uD#+O%3k*zkvbGsEU9vUq_Z{;&YF1Bhy>FjhGJSDOG>OV$Gb=Z#aUEhch_VbD*2 zh_Yd)oYC9n8P=NhOd|Z0h<-pXKWP7Qe^k+&KkPTIapPUCuI4fTG=n_t$;Btm3#Fz~ zMxevL_L4niAJv1TbG@@UTru;&AW#<3m!jsrhx@rYfWKw4(sej~_`NO!5MPP68K&$3 zU4H%-5Cu?p?@T&l^^odnKyj-0Lp)LM|Wx`?Xy_yca;ZrhXFp8p{WQ y0PKl_9aYAGV*nA}?q+u@jX<|XY%vxI(tidu=Y#WO(tU>j0000 zDQABF|6k8&r`nUC%KKyL8CCz2^%wtF|9^dG>Y0OCr|N(H=l{3=-}-iU&WM>z5i<|| tzgcmYDePN!L-E2>QXK6Y4=m`&Vvv&c&N-+tM+RsGgQu&X%Q~loCIB9gP2NC8#zd%8G= zXiV(wGxTB(6mdQO+iy{8(_Rk6pOP<(!7^qgP08kUg$*K(ylpAJZ|OjavkAj_4&M z3l=aQv`E&DU}G`;S1G2%V%&M})4pQ4@E`74y{G;dd=D!=)cuotn{V{r6Z`E~oS1rW z%}J9R`M+IDU)nYt3X?e&n=ce&p?~IOdKIV65;yb73NM*_M2ei(HwJ_%dNe)xw*35@ z5IgOBZPaW|7%)WpAOi6WhuUnCsV&ROR&RMff zGpM?<`un`&Eb3JpJaY`q>r%dl++>fNdpYb{4C9B{M|n+`F`r@5a4D2%k8EOmaee-~ s5YBy(6G9g0ROoC=y`Gy=zRWP*=T^+M2L^`y!0==6boFyt=akR{0JWf-AOHXW diff --git a/src/main/res/drawable-hdpi/ic_done_black_24dp.png b/src/main/res/drawable-xhdpi/ic_done_black_18dp.png similarity index 100% rename from src/main/res/drawable-hdpi/ic_done_black_24dp.png rename to src/main/res/drawable-xhdpi/ic_done_black_18dp.png diff --git a/src/main/res/drawable-xhdpi/ic_done_black_24dp.png b/src/main/res/drawable-xhdpi/ic_done_black_24dp.png deleted file mode 100644 index 64a4944f7531ab9fb745fd34dd00c778cff1573f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0DW=|K#kP61P7xwZt8HzYxyd7xd z_anOJT=vF;=6o%TO%qmB2=N*^J(z8E{F3t0DRy@o7f;`BG-3LF`^uk20(J8L%76ab z`e&B#*^~M_=S=wbCso$$y|k0wldT1B8K8v!{z=h{y4_R}8rt40u`}^1XVn zvWkOUU-^j{pVq65HqD1Oi)r3+T*LWdLcQO)Q$gY0SWi# mI0*h{o5b;0Guz~Cq_l|d_dwzLnQwv4VeoYIb6Mw<&;$SqxI>Tt literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xhdpi/ic_received_indicator.png b/src/main/res/drawable-xhdpi/ic_received_indicator.png deleted file mode 100644 index 799593b24d7b69acfe4ccba5082fff6c4b460445..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 717 zcmV;;0y6!HP)u9DstG>7I zndkjI-}k*U1AAPuo3KzUbV@|ec@ROEH^qxty8*VJ*yU940JKBF5CFyVFo(^Z!oz*x zGB1~VE6~i^jZ7t7cZf9k)Gub4b$+a6>?eS+6MksU?()M01}n-B z)UU$xT4`nX*w;jPQ4mBvr{~iRshg>^-&az=iSA=3bA~YjROF@6<&{j`^!4dq8@+*t zT=lYQzo_*QIFgqZ48yFSY@bYR<_|oBeOc=vXe7T>QEf@ICKCVi2fCu;@tQLp@@cJ4 zpSw=7W2>H`PY`(>Ip`s=Rk*@;!?12`*H?7F;_~8spr#-w?TOaJ!ghTU?TlJ8hkx8f z<+Nw$qhwohaHGkN+fjib--h~KXW~LJ8#7XeQ%xXu5E=}XZoAh$^%^%^d)Fx+*9%hk9xr160SWD?xAj z{HmUG6$^*_8}WAzseYi*_h<;z1fo9egX_3W1SkVwxN|tWVr4G_qrT0aT@MEpeH8>= z2mqM6IyEaEjlLr=-=9l_Q4geVM7@zUbi@@)HoFW4o|CE6P0FqAfs|r_u+&aGI z-UNli7XPB!cx@f(ISQ4Cj<{{fdk9)e$ez|8Y>UWZ@171&00000NkvXXu0mjfZL~x= diff --git a/src/main/res/drawable-xxhdpi/ic_done_black_18dp.png b/src/main/res/drawable-xxhdpi/ic_done_black_18dp.png new file mode 100644 index 0000000000000000000000000000000000000000..1c4739e006b28c05b7a19e80f293b7b5f8c73ee1 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL0wmRZ7KH(+K2I0NkP61Pmp1Yq43u#FC@dy0 z^<4d?cHW)@Vb;$Qj`x&4dAcZX-xvRQ9&6p%g=?n-c}0J#z0!R0lB?*`$1T5#X6vom zk)RW@B4A-yjAZPU-bY721ZTe!`TCGAj;qYa%i^}!Y5ww(AdTls0?v7AmKT9oQ>uSy vJhYio5a(r~uR3SC&^a&8@@Mg0noG@(_deH~=DVI9=rRURS3j3^P6M7L)iaL`^Fl;m&EuUVkIj`gf`xk%7{i-Vh{ zTU?Ayz2oVjTlgq{Vj;ic*MpfWnU*gSvrwH{nDwf)dx6?J85hgvcm7K=E`2Acm~6A^ QAJDA~p00i_>zopr0MfryGynhq literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xxhdpi/ic_received_indicator.png b/src/main/res/drawable-xxhdpi/ic_received_indicator.png deleted file mode 100644 index 7ee61364e136e5f1e291422cf0f1c556faf92636..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1016 zcmVbYrTKxsm?pDFJ6B^ zgr|WAfXzTz;6mBj=hqbEj5<%KR8E218x+?Fk3`lClWRYqV!x?@`32-zFXNqGlM`}A z+n-aBPYLW<{Z`7+gKn=o3lM8H#^lU?g-?L0+fZT9%M|;NzZ)7_+|(WU_D8MCIUrtb z;i#MS`u#aA1MND#YkMVDz5v|q3t1JiUbic5JiwnOk9j=E7 z6_grGC8fd{V7)Ii7cIx0nK?4E&`6!oK#7fscYynS(<-8wLT{neXq`}c$ec6}i)Di9 zmw0F@>%Fp)T1}sj88&gLkPpE8n2fJ~bEWl~21!DXBJB1}TSN{{9+;e8alK|RPTqM? z)qaofbQF$xS?}f5)V$?{wtcwmu8xx(TN+6;!zQlQe&ojhKU-_xSPkYT$mGo)Cugq4 z*R{=ATPZqY&W^g73Em30Dg@r1?wS5|^&mw=bwuHw8(V3`o zrbbqa0f;!G&gOu>xF>h!cJ|atQjHD~@Eug;_3{4ka#Nt?w&g#7LRCa`z>J!-f7;~C zJ{2CTE+vy**892{3_zrGsI+KB_W*Og*ai{KI>()@HzrbpsicSw1Qk+rppkD?T@XOA zyXe`7?gRex#dm1TPMDl|2q3vJ*@w#ZfI3$;*-dAf#enY}a&ql2DH7C_D)56s8c0+Z z(LOg@d@l^pE$@(yURnRXQFQMOE?zw!mWgz;o z3%@Vz2hKOd5jh5ZMbX1+UN#!o<`C0k~Or!m2(Fa*luADFr?4-dQ{wHfTlvLtP_X>*nqJ m*2To)wbG%|wXiX_<@gIJEh>*Xb<}JC0000b^wD=lt6oW;%QS1o1=daUAyI8~(&3 zd|u96v#;i-{{JTZcp&}h>FMeJ8GvN{`tw#N{;ZEGUD<;p)-Lh7=#>`kZ6pLOOe=>Nw L`njxgN@xNAv*3Ko diff --git a/src/main/res/drawable-xxxhdpi/ic_done_white_18dp.png b/src/main/res/drawable-xxxhdpi/ic_done_white_18dp.png new file mode 100644 index 0000000000000000000000000000000000000000..0ebb55559b55f99df3270796763745a71f113078 GIT binary patch literal 255 zcmV=}0*5fKp)HP1G&I6Iqc zjKz5rgEVtukiIy2Qo_-K;J|?c2M!!K@i?}(lWik$uJ;4aeo|e|;mI*SsV?U@bDX5g zSJ{Te;g>S0!OODIPipkgGo)TTcRZxVWAGnIFqKOr(UM3=(~BhBSvit;g=R?Vjh>M7 zAB+M?!6}eboF615Cqq(m7NiKA4^kA)n-qydL_|cirW>R3em?os7vTT^002ovPDHLk FV1hF8Y9jyu literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xxxhdpi/ic_received_indicator.png b/src/main/res/drawable-xxxhdpi/ic_received_indicator.png deleted file mode 100644 index 0fb694c9f6528f2503d69280480e1d7a710bf5e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1303 zcmV+y1?c*TP)sj^QMXak-PvtSB+|x*Run=I zL?QT4st;OA&1RPbMX_S>$xTsFAzmBIX44B+N)?~HV3dN?TL~J)%R@6e6GOUD(1MMo zx$W-xeQ0XiBxiQ^Ua;TWp8q@F|NS#_=KN;=;f*k9mzndX~Z)6Fd z0R(Mmr%B3t6A|m^YQf4a;wVI_df^=aEou_~PC~oK=rVs)F+>ThIYMxq{yYQsDG9_A zTDt0Xqtj5D2P(7%^dWs4G2XSwe@Y1LjadvxWAo%9yNpetg!V>F>)2XfcjVJYb9t9$~PR3&Hc0R zY_akcy@1*)YkC3rRdFfMoqRGmSFC*JuhM(a0@HzZCcXs{)zI*T*=ZinMQo{28-Z$r zBz%wvnd%lg54Zrp7xS&vrp4y~ZzRUqvLt?OIMC4KbfL9H+gwv38HajzPYKeVE{^T< z5C9-F@i>5u%VO)RQd+N5p{e?lPXO4YiZdhTq`%J<0sx5l&Q+sCyYzkfmTV$=T(1X{ z-NHOASUA2IxnOA#Q=KBNLE@k{=5=Qg=>wqB0GRrWh;b@UkG42_2fznZ1OkF};AWc% z!-UN4OszISb1(p0tK>2c8DaC`;@Mr*&&AMVx_@aiy1Gzt3BJwhvPKKlvBQd1!i<;} zGqwU)EKvJIsm%k5UdRla$B20c0M1{U4(C7DIh4(u5w?ynA)2pnCX+dm@7!FF^-v!e z^bde2lB4QKB4lpP+f@$8+D?1;s>c9c_0zT*{C>WMaz)kxMkAvsuBEL2{p47bTpt!@ z%Q+k!Xv~MqzcVt^0pK?W^j}KRb*kX_L^d87pJa&+05i5kqP>Nh$^|(cDb0xay=1e-V5+M&6$m{c(S*2HGqEFMvfN`Yw@7d~)GGh?ntyz`xC5ceve=M-u=5 N002ovPDHLkV1gp!WugE8 diff --git a/src/main/res/layout/message_sent.xml b/src/main/res/layout/message_sent.xml index 29ac6fc65..ef6030cbc 100644 --- a/src/main/res/layout/message_sent.xml +++ b/src/main/res/layout/message_sent.xml @@ -1,49 +1,48 @@ - + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:paddingLeft="8dp" + android:paddingTop="3dp" + android:paddingRight="8dp" + android:paddingBottom="3dp"> + android:layout_alignParentEnd="true" + android:layout_alignParentRight="true" + android:layout_alignParentBottom="true" + android:orientation="vertical"> + + + android:layout_height="3dp" /> - + android:longClickable="true" + android:minHeight="53dp"> - + + android:textAppearance="@style/TextAppearance.Conversations.Caption" /> @@ -85,7 +85,6 @@ android:layout_width="?attr/TextSizeCaption" android:layout_height="?attr/TextSizeCaption" android:layout_gravity="center_vertical" - android:layout_marginLeft="4sp" android:alpha="0.54" android:gravity="center_vertical" android:src="@drawable/ic_mode_edit_black_18dp" /> @@ -95,10 +94,9 @@ android:layout_width="?attr/TextSizeCaption" android:layout_height="?attr/TextSizeCaption" android:layout_gravity="center_vertical" - android:layout_marginLeft="4sp" android:alpha="0.54" android:gravity="center_vertical" - android:src="@drawable/ic_received_indicator" /> + android:src="@drawable/ic_done_black_18dp" /> diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml index 6ebf7505c..219fb6702 100644 --- a/src/main/res/values/themes.xml +++ b/src/main/res/values/themes.xml @@ -87,7 +87,6 @@ @drawable/ic_edit_white_24dp @drawable/ic_edit_black_24dp @drawable/ic_save_black_24dp - @drawable/ic_done_black_24dp @drawable/ic_group_white_24dp @drawable/ic_add_white_24dp @drawable/ic_reply_white_24dp @@ -202,7 +201,6 @@ @drawable/ic_edit_white_24dp @drawable/ic_edit_white_24dp @drawable/ic_save_white_24dp - @drawable/ic_done_black_24dp @drawable/ic_group_white_24dp @drawable/ic_add_white_24dp @drawable/ic_reply_white_24dp From 31ba7fab2544b8cb2723a4899ccdd9120abb993a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 5 Jan 2020 13:53:04 +0100 Subject: [PATCH 15/38] make omemo setting default to 'always' on Quicksy --- src/quicksy/res/values/defaults.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/quicksy/res/values/defaults.xml b/src/quicksy/res/values/defaults.xml index 045e125f3..8f3617396 100644 --- a/src/quicksy/res/values/defaults.xml +++ b/src/quicksy/res/values/defaults.xml @@ -1,3 +1,4 @@ + always From 9ccb5fdb463b0f5b4e22c698fec46fcb4ab7654b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 5 Jan 2020 15:59:54 +0100 Subject: [PATCH 16/38] show edit display name in all flavors --- .../siacs/conversations/ui/EditAccountActivity.java | 1 - src/main/res/layout/activity_edit_account.xml | 11 +++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java index 1a24077ad..640ed2412 100644 --- a/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/EditAccountActivity.java @@ -604,7 +604,6 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat if (Config.DISALLOW_REGISTRATION_IN_UI) { this.binding.accountRegisterNew.setVisibility(View.GONE); } - this.binding.yourNameBox.setVisibility(QuickConversationsService.isQuicksy() ? View.VISIBLE : View.GONE); this.binding.actionEditYourName.setOnClickListener(this::onEditYourNameClicked); } diff --git a/src/main/res/layout/activity_edit_account.xml b/src/main/res/layout/activity_edit_account.xml index 1f8a8870e..4b7a03e8a 100644 --- a/src/main/res/layout/activity_edit_account.xml +++ b/src/main/res/layout/activity_edit_account.xml @@ -471,16 +471,11 @@ - - + android:layout_marginTop="12dp"> + android:layout_marginTop="12dp"> + android:layout_marginTop="12dp"> Date: Sun, 5 Jan 2020 16:00:11 +0100 Subject: [PATCH 17/38] increase size of checkmark --- src/main/res/layout/message_sent.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/res/layout/message_sent.xml b/src/main/res/layout/message_sent.xml index ef6030cbc..82d122ec8 100644 --- a/src/main/res/layout/message_sent.xml +++ b/src/main/res/layout/message_sent.xml @@ -91,8 +91,8 @@ Date: Sun, 5 Jan 2020 16:17:20 +0100 Subject: [PATCH 18/38] pulled translations from transifex --- src/conversations/res/values-bg/strings.xml | 8 +++++ src/main/res/values-hu/strings.xml | 10 +++--- src/main/res/values-pt-rBR/strings.xml | 2 +- src/main/res/values-ro-rRO/strings.xml | 32 ++++++++--------- src/quicksy/res/values-hu/strings.xml | 38 ++++++++++----------- 5 files changed, 49 insertions(+), 41 deletions(-) create mode 100644 src/conversations/res/values-bg/strings.xml diff --git a/src/conversations/res/values-bg/strings.xml b/src/conversations/res/values-bg/strings.xml new file mode 100644 index 000000000..e49eeb0c1 --- /dev/null +++ b/src/conversations/res/values-bg/strings.xml @@ -0,0 +1,8 @@ + + + Изберете вашият XMPP доставчик + Използвайте conversations.im + Създаване не нов профил + Имате ли вече XMPP профил? Това може да се случи, ако вече използвате друг клиент на XMPP или сте използвали преди това Conversations. Ако не, можете да създадете нов XMPP профил в момента.\nСъвет: Някои доставчици на имейл също предоставят XMPP профили. +  + \ No newline at end of file diff --git a/src/main/res/values-hu/strings.xml b/src/main/res/values-hu/strings.xml index da71c269c..44adbbc1f 100644 --- a/src/main/res/values-hu/strings.xml +++ b/src/main/res/values-hu/strings.xml @@ -21,7 +21,7 @@ Résztvevő tiltásának feloldása Fiókok kezelése Beállítások - Megosztás a Conversationnel + Megosztás a Conversations alkalmazással Beszélgetés indítása Partner kiválasztása Partnerek kiválasztása @@ -499,7 +499,7 @@ %s partnerrel megosztott képek %s partnerrel megosztott szöveg A Conversations alkalmazásnak hozzáférésre van szüksége a külső tárolóhoz - A Conversations alkalmazásnak hozzáférésre van szüksége a kamerához + A Conversations alkalmazásnak kamera-hozzáférésre van szüksége Szinkronizálás a partnerekkel A Conversations szeretné megfeleltetni a kiszolgáló oldali partnerlistát a helyi címjegyzékkel, hogy megjelenítse a partnerek teljes nevét és profilképét.\n\nA Conversations csak olvassa a névjegyeit, és helyileg felelteti meg őket, anélkül hogy feltöltené azokat a kiszolgálóra.\n\nMost arra fogják kérni, hogy adjon jogosultságot a névjegyek eléréséhez.
A telefonszámok másolatát nem fogjuk eltárolni.\n\nTovábbi információkért olvassa el az adatvédelmi irányelveinket.

Most arra fogják kérni, hogy adjon jogosultságot a névjegyek eléréséhez.]]>
@@ -678,7 +678,7 @@ Mindenképp szeretne csatlakozni? Tanúsítvány részletei: Egyszer - A QR-kód olvasónak kamerahozzáférésre van szüksége + A QR-kód olvasónak kamera-hozzáférésre van szüksége Görgessen az aljára Görgessen le egy üzenet elküldése után Állapotüzenet szerkesztése @@ -717,7 +717,7 @@ Megosztás Nem sikerült elindítani a rögzítést Kérem várjon… - A Conversations alkalmazásnak mikrofonhozzáférésre van szüksége + A Conversations alkalmazásnak mikrofon-hozzáférésre van szüksége Üzenetek keresése GIF Beszélgetés megtekintése @@ -739,7 +739,7 @@ Ezt a csoportos csevegést megszüntették Nem sikerült elmenteni a felvételt Előtér szolgáltatás - Ezt az értesítési kategóriát egy állandó értesítés megjelenítéséhez használják, beleértve azt is, hogy a Conversations fut. + Ezt az értesítési kategóriát egy állandó értesítés megjelenítéséhez használják, jelezve azt, hogy a Conversations fut. Állapotinformációk Kapcsolódási problémák Ezt az értesítési kategóriát egy értesítés megjelenítéséhez használják abban az esetben, ha probléma merül fel a fiókhoz való kapcsolódásnál. diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml index 659132c10..9e502563e 100644 --- a/src/main/res/values-pt-rBR/strings.xml +++ b/src/main/res/values-pt-rBR/strings.xml @@ -876,7 +876,7 @@ jabber.network Servidor local - A maioria dos usuários devem escolher \'jabber.network\' para melhores sugestões de toda rede pública do XMPP + A maioria dos usuários deve escolher \'jabber.network\' para melhores sugestões de toda rede pública do XMPP Método de descoberta de canais Backup Sobre diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index ee8f16dea..129966633 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -95,7 +95,7 @@ Trimite mesaj criptat cu OpenPGP Numele dumneavoastră a fost schimbat Trimite necriptat - Decriptarea a eșuat. Poate nu aveții cheia privată corectă. + Decriptarea a eșuat. Poate nu aveți cheia privată corectă. OpenKeychain Conversations utilizează o aplicație externă OpenKeychain pentru a cripta și decripta mesaje și a administra cheile publice.\n\nOpenKeychain este licențiat sub GPLv3 și se poate instala din F-Droid și Google Play.\n\n(Vă rugăm să reporniți Conversations după) Repornește @@ -175,11 +175,11 @@ Sigur doriți asta? Dacă vă ștergeți contul, întregul istoric de conversații va fi pierdut Înregistrare voce - Adresä XMPP + Adresă XMPP Blochează adresă XMPP numeutilizator@exemplu.ro Parolă - Acesta nu este o adresă XMPP valabilă + Aceasta nu este o adresă XMPP valabilă Memorie epuizată. Imaginea este prea mare. Vreți să adăugați pe %s în lista de contacte? Informații server @@ -231,7 +231,7 @@ Șterge semn de carte Distruge discuția de grup Distruge canal - Sigur doriți distrugerea acestei discuții de grup?\n\nAtenție: Discuția de grup v-a fi complet ștearsä de pe server. + Sigur doriți distrugerea acestei discuții de grup?\n\nAtenție: Discuția de grup v-a fi complet ștearsă de pe server. Sigur doriți distrugerea acestui canal public?\n\nAtenție: Canalul public v-a fi complet șters de pe server. Nu s-a putut distruge discuția de grup Nu s-a putut distruge canalul @@ -560,8 +560,8 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Intimitate Temă Selecție paletă culori interfață - Tema luminoasă - Tema întunecată + Luminoasă + Întunecată Fundal verde Pentru mesajele primite Nu s-a putut contacta OpenKeychain @@ -689,7 +689,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Detalii certificat: Doar o dată Scanerul de coduri QR are nevoie de acces la camera foto - Derulează în jos + Derulează până jos După trimiterea unui mesaj derulează până la sfârșit Editare mesaj de stare Editare mesaj de stare @@ -766,15 +766,15 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Vizualizare fișiere media Fișier omis ca urmare a unei probleme de securitate. Calitate video - O calitate micä înseamnă fișiere mai mici + O calitate mică înseamnă fișiere mai mici Medie (360p) Mare (720p) anulat Deja aveți ciorna unui mesaj. Opțiune neimplementată - Cod de țarä invalid - Alegeți o țarä - numär de telefon + Cod de țară invalid + Alegeți o țară + număr de telefon Verificare număr de telefon Quicksy va trimite un mesaj SMS (pot exista costuri în funcție de furnizor) pentru a vă verifica numărul de telefon. Introduceți codul țării dumneavoastră si numărul de telefon:
%s

Este în regulă sau ați dori să editați numărul?]]>
@@ -790,7 +790,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați %s înapoi S-a copiat automat un posibil cod din memorie - Vä rugăm să vă introduceți codul de 6 cifre. + Vă rugăm să vă introduceți codul de 6 cifre. Sigur doriți să anulați procedura de înregistrare? Da Nu @@ -799,7 +799,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Codul introdus este incorect. Codul pe care vi l-am trimis a expirat. Eroare de rețea necunoscută. - Räspuns necunoscut de la server. + Răspuns necunoscut de la server. Nu se poate face conexiunea la server. Nu se poate realiza o conexiune securizată. Nu se poate găsi serverul. @@ -815,7 +815,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Acest număr de telefon este momentan autentificat pe un alt dispozitiv. Vă rugăm să vă introduceți numele pentru a informa persoanele care nu vă au în agendă cine sunteți. Numele dumneavoastă - Introducețivä numele + Introducețivă numele Folosiți butonul de editare pentru a vă seta numele. Refuză cererea Instalare Orbot @@ -840,7 +840,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Creează discuție de grup privată Creează canal public Nume canal - Adresä XMPP + Adresă XMPP Vă rugăm să furnizați un nume pentru canal Vă rugăm să furnizați o adresă XMPP Aceasta este o adresă XMPP. Vă rugăm să furnizați un nume. @@ -877,7 +877,7 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Copie de siguranță Conversations Eveniment Deschide o copie de siguranță - Fișierul selectat nu este o copie de siguranța Conversations + Fișierul selectat nu este o copie de siguranță Conversations Acest cont a fost deja configurat Va rugăm să introduceți parola pentru acest cont Nu se poate realiza această acțiune diff --git a/src/quicksy/res/values-hu/strings.xml b/src/quicksy/res/values-hu/strings.xml index 45bfbb6c0..71b9d7129 100644 --- a/src/quicksy/res/values-hu/strings.xml +++ b/src/quicksy/res/values-hu/strings.xml @@ -1,26 +1,26 @@ A Quicksy összeomlott - A verem nyomkövetések beküldésével segíthet a Quicksy folyamatos fejlesztésében\nFigyelem: Ez az XMPP fiókját fogja használni az adatok fejlesztőhöz való elküldéshez. - A Quicksy egy harmadik fél által biztosított alkalmazást, az OpenKeychain-t használja az üzenetek titkosítására és a nyilvános kulcsok kezelésére.\n\nAz OpenKeychain GPLv3 engedélyes és letölthető az F-Droid-ról és a Google Play-ről.\n\n(Kérjük, ezután indítsa újra a Quicksy-t.) - A Quicksy nem tudja titkosítani az üzeneteit, mert a kapcsolata nem jelenti be a nyilvános kulcsát.\n\nKérje meg a kapcsolatát, hogy állítsa be az OpenPGP-t. - A Quicksy nem képes titkosítani az üzeneteket, mert az ismerősei nem jelentik be a nyilvános kulcsaikat.\n\n Kérje meg az ismerőseit, hogy állítsák be az OpenPGP-t. - A Quicksy csendben marad ennyi ideig, miután aktivitást észlelt másik eszközön - A verem nyomkövetések beküldésével segíthet a Quicksy folyamatos fejlesztésében - A Quicksy-nek hozzáférésre lenne szüksége a külső tárhelyhez - A Quicksy-nek hozzáférésre lenne szüksége a kamerához - A készülék erős akkumulátor optimalizálást végez a Quicksy programon, ami késleltetett értesítésekhez, vagy akár üzenetek elvesztéséhet is vezethet.\nJavasolt kikapcsolni ezt. - A készülék erős akkumulátor optimalizálást végez a Quicksy programon, ami késleltetett értesítésekhez, vagy akár üzenetek elvesztéséhet is vezethet.\nMost megkérnénk az optimalizáció letiltására. - Jelezze az ismerőseinek, hogy mikor használja a Quicksy-t - Az operációs rendszer korlátozza a Quicksy hozzáférését az internethez, amikor az a háttérben fut. Ahhoz, hogy értesítéseket kapjon az új üzenetekről aktív Adatspórolás esetén is, lehetővé kell tennie a Quicksy korlátlan hozzáférését.\nA Quicksy továbbra is arra törekszik, hogy spóroljon az adatforgalmon, ha ez lehetséges. - Az eszköze nem támogatja az adatspórolás letiltását. - Ha értesítést szeretne kapni, még akkor is, ha a képernyő ki van kapcsolva, hozzá kell adnia a Quicksy-t a védett alkalmazások listájához. - A Quicksy nem tud titkosított üzeneteket küldeni neki: %1$s. Ez azért történhetett, mert a kapcsolattartója olyan elavult kiszolgálót vagy ügyfélprogramot használ ami nem tudja kezelni az OMEMO-t. - A Quicksy-nek hozzáférésre lenne szüksége a mikrofonhoz - Ez az értesítési kategória állandó értesítést jelenít meg arról, hogy a Quicksy fut. + A veremkiíratások elküldésével segíti a Quicksy alkalmazás folyamatos fejlesztését\nFigyelmeztetés: Ez a XMPP-fiókját fogja használni a veremkövetés elküldéséhez a fejlesztő számára. + A Quicksy egy OpenKeychain nevű, harmadik fél által fejlesztett alkalmazást használ az üzenetek titkosításához és visszafejtéséhez, valamint a személyes kulcsai kezeléséhez.n\nAz OpenKeychain GPLv3 szerint licencelt, és elérhető az F-Droid és a Google Play szoftveráruházakban.\n\n(Ezután indítsa újra a Quicksy alkalmazást.) + A Quicksy nem tudja titkosítani az üzeneteit, mert a partnere nem közölte a nyilvános kulcsát.\n\nKérje meg a partnerét, hogy állítsa be az OpenPGP-t. + A Quicksy nem tudja titkosítani az üzeneteit, mert a partnerei nem közölték a nyilvános kulcsukat.\n\nKérje meg a partnereit, hogy állítsák be az OpenPGP-t. + A Quicksy csendben marad ennyi ideig, miután aktivitást észlelt egy másik eszközön + A veremkiíratások elküldésével segíti a Quicksy alkalmazás folyamatos fejlesztését + A Quicksy alkalmazásnak hozzáférésre van szüksége a külső tárolóhoz + A Quicksy alkalmazásnak kamera-hozzáférésre van szüksége + A készülék erős akkumulátor-optimalizálást végez a Quicksy programon, ami késleltetett értesítésekhez, vagy akár üzenetek elvesztéséhez is vezethet.\nAjánlott kikapcsolni ezeket. + A készülék erős akkumulátor-optimalizálást végez a Quicksy programon, ami késleltetett értesítésekhez, vagy akár üzenetek elvesztéséhez is vezethet.\nMost arra fogják kérni, hogy tiltsa le azokat. + Tudassa az összes partnerével, hogy a Quicksy alkalmazást használja + Az operációs rendszer korlátozza a Quicksy hozzáférését az internethez, amikor az a háttérben fut. Ahhoz, hogy értesítéseket kapjon az új üzenetekről aktív adatspórolás esetén is, lehetővé kell tennie a Quicksy korlátlan hozzáférését.\nA Quicksy továbbra is arra törekszik, hogy spóroljon az adatforgalmon, ahol lehetséges. + Az eszköze nem támogatja az adatspórolás letiltását a Quicksy alkalmazásnál. + Ha akkor is szeretne értesítéseket kapni, amikor a kijelző ki van kapcsolva, hozzá kell adnia a Quicksy alkalmazást a védett alkalmazások listájához. + A Quicksy nem tud titkosított üzeneteket küldeni %1$s részére. Ez amiatt lehet, hogy a partnere elavult kiszolgálót vagy kliensprogramot használ, amely nem tudja kezelni az OMEMO-t. + A Quicksy alkalmazásnak mikrofon-hozzáférésre van szüksége + Ezt az értesítési kategóriát egy állandó értesítés megjelenítéséhez használják, jelezve azt, hogy a Quicksy fut. Quicksy profilkép A Quicksy nem érhető el az Ön országában. - Nem sikerült ellenőrizni a szerver azonosságát. + Nem sikerült ellenőrizni a kiszolgáló személyazonosságát. Ismeretlen biztonsági hiba. - Időtúllépés történt a szerverhez való csatlakozás közben. + Időtúllépés a kiszolgálóhoz való csatlakozáskor. From 1dad70fbc3c85a68fd8954a7ffab30666c87cdff Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 5 Jan 2020 18:06:27 +0100 Subject: [PATCH 19/38] version bump to 2.6.2 + changelog --- CHANGELOG.md | 6 ++++++ build.gradle | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff2b7b07b..6bc09a43b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +### Version 2.6.2 +* let users set their own nick name +* resume download of OMEMO encrypted files +* Channels now use '#' as symbol in avatar +* Quicksy uses 'always' as OMEMO encryption default (hides lock icon) + ### Version 2.6.1 * fixes for Jingle IBB file transfer * fixes for repeated corrections filling up the database diff --git a/build.gradle b/build.gradle index 2275c90aa..f004f6d60 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:3.5.3' } } @@ -61,16 +61,16 @@ dependencies { implementation "com.wefika:flowlayout:0.4.1" implementation 'net.ypresto.androidtranscoder:android-transcoder:0.3.0' implementation project(':libs:xmpp-addr') - implementation 'org.osmdroid:osmdroid-android:6.1.0' + implementation 'org.osmdroid:osmdroid-android:6.1.5' implementation 'org.hsluv:hsluv:0.2' implementation 'org.conscrypt:conscrypt-android:2.2.1' implementation 'me.drakeet.support:toastcompat:1.1.0' implementation "com.leinardi.android:speed-dial:2.0.1" - implementation 'com.squareup.retrofit2:retrofit:2.6.1' - implementation 'com.squareup.retrofit2:converter-gson:2.6.1' - implementation 'com.squareup.okhttp3:okhttp:3.12.6' + implementation 'com.squareup.retrofit2:retrofit:2.7.1' + implementation 'com.squareup.retrofit2:converter-gson:2.7.1' + implementation 'com.squareup.okhttp3:okhttp:3.12.7' implementation 'com.google.guava:guava:27.1-android' - quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.10.16' + quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.11.1' } ext { @@ -84,8 +84,8 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 28 - versionCode 351 - versionName "2.6.1" + versionCode 352 + versionName "2.6.2" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" resValue "string", "applicationId", applicationId From 4e0f05f0a1c3517c596c4196ffd25f2be3b2e3f0 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 8 Jan 2020 10:51:18 +0100 Subject: [PATCH 20/38] refactored xmpp uri parsing to expose all params --- .../eu/siacs/conversations/utils/XmppUri.java | 131 ++++++++---------- 1 file changed, 60 insertions(+), 71 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/XmppUri.java b/src/main/java/eu/siacs/conversations/utils/XmppUri.java index de18aa596..8feae0b15 100644 --- a/src/main/java/eu/siacs/conversations/utils/XmppUri.java +++ b/src/main/java/eu/siacs/conversations/utils/XmppUri.java @@ -1,15 +1,19 @@ package eu.siacs.conversations.utils; import android.net.Uri; -import android.util.Log; +import android.support.annotation.NonNull; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Map; -import eu.siacs.conversations.Config; import rocks.xmpp.addr.Jid; public class XmppUri { @@ -17,9 +21,7 @@ public class XmppUri { protected Uri uri; protected String jid; private List fingerprints = new ArrayList<>(); - private String body; - private String name; - private String action; + private Map parameters = Collections.emptyMap(); private boolean safeSource = true; private static final String OMEMO_URI_PARAM = "omemo-sid-"; @@ -66,7 +68,6 @@ public class XmppUri { try { jid = Jid.of(lameUrlDecode(segments.get(1))).toString(); } catch (Exception e) { - Log.d(Config.LOGTAG, "parsing failed ", e); jid = null; } } else if (segments.size() >= 3) { @@ -74,33 +75,24 @@ public class XmppUri { jid = segments.get(1) + "@" + segments.get(2); } if (segments.size() > 1 && "j".equalsIgnoreCase(segments.get(0))) { - action = ACTION_JOIN; + this.parameters = ImmutableMap.of(ACTION_JOIN, ""); } - fingerprints = parseFingerprints(uri.getQuery(), '&'); + final Map parameters = parseParameters(uri.getQuery(), '&'); + this.fingerprints = parseFingerprints(parameters); } else if ("xmpp".equalsIgnoreCase(scheme)) { // sample: xmpp:foo@bar.com - - final String query = uri.getQuery(); - - if (hasAction(query, ACTION_JOIN)) { - this.action = ACTION_JOIN; - } else if (hasAction(query, ACTION_MESSAGE)) { - this.action = ACTION_MESSAGE; - } - + this.parameters = parseParameters(uri.getQuery(), ';'); if (uri.getAuthority() != null) { jid = uri.getAuthority(); } else { - String[] parts = uri.getSchemeSpecificPart().split("\\?"); + final String[] parts = uri.getSchemeSpecificPart().split("\\?"); if (parts.length > 0) { jid = parts[0]; } else { return; } } - this.fingerprints = parseFingerprints(uri.getQuery()); - this.body = parseParameter("body", uri.getQuery()); - this.name = parseParameter("name", uri.getQuery()); + this.fingerprints = parseFingerprints(parameters); } else if ("imto".equalsIgnoreCase(scheme)) { // sample: imto://xmpp/foo@bar.com try { @@ -117,6 +109,35 @@ public class XmppUri { } } + + private static Map parseParameters(final String query, final char seperator) { + final ImmutableMap.Builder builder = new ImmutableMap.Builder<>(); + final String[] pairs = query == null ? new String[0] : query.split(String.valueOf(seperator)); + for (String pair : pairs) { + final String[] parts = pair.split("=", 2); + if (parts.length == 0) { + continue; + } + final String key = parts[0].toLowerCase(Locale.US); + final String value; + if (parts.length == 2) { + String decoded; + try { + decoded = URLDecoder.decode(parts[1],"UTF-8"); + } catch (UnsupportedEncodingException e) { + decoded = ""; + } + value = decoded; + } else { + value = ""; + } + builder.put(key, value); + } + return builder.build(); + } + + @Override + @NonNull public String toString() { if (uri != null) { return uri.toString(); @@ -124,58 +145,25 @@ public class XmppUri { return ""; } - private List parseFingerprints(String query) { - return parseFingerprints(query, ';'); - } - - private List parseFingerprints(String query, char seperator) { - List fingerprints = new ArrayList<>(); - String[] pairs = query == null ? new String[0] : query.split(String.valueOf(seperator)); - for (String pair : pairs) { - String[] parts = pair.split("=", 2); - if (parts.length == 2) { - String key = parts[0].toLowerCase(Locale.US); - String value = parts[1].toLowerCase(Locale.US); - if (key.startsWith(OMEMO_URI_PARAM)) { - try { - int id = Integer.parseInt(key.substring(OMEMO_URI_PARAM.length())); - fingerprints.add(new Fingerprint(FingerprintType.OMEMO, value, id)); - } catch (Exception e) { - //ignoring invalid device id - } - } - } - } - return fingerprints; - } - - private String parseParameter(String key, String query) { - for (String pair : query == null ? new String[0] : query.split(";")) { - final String[] parts = pair.split("=", 2); - if (parts.length == 2 && key.equals(parts[0].toLowerCase(Locale.US))) { + private static List parseFingerprints(Map parameters) { + ImmutableList.Builder builder = new ImmutableList.Builder<>(); + for (Map.Entry parameter : parameters.entrySet()) { + final String key = parameter.getKey(); + final String value = parameter.getValue().toLowerCase(Locale.US); + if (key.startsWith(OMEMO_URI_PARAM)) { try { - return URLDecoder.decode(parts[1], "UTF-8"); - } catch (UnsupportedEncodingException e) { - return null; + final int id = Integer.parseInt(key.substring(OMEMO_URI_PARAM.length())); + builder.add(new Fingerprint(FingerprintType.OMEMO, value, id)); + } catch (Exception e) { + //ignoring invalid device id } } } - return null; - } - - private boolean hasAction(String query, String action) { - for (String pair : query == null ? new String[0] : query.split(";")) { - final String[] parts = pair.split("=", 2); - if (parts.length == 1 && parts[0].toLowerCase(Locale.US).startsWith(action)) { - return true; - } - } - return false; + return builder.build(); } public boolean isAction(final String action) { - return this.action != null && this.action.equals(action); - + return parameters.containsKey(action); } public Jid getJid() { @@ -199,11 +187,11 @@ public class XmppUri { } public String getBody() { - return body; + return parameters.get("body"); } public String getName() { - return name; + return parameters.get("name"); } public List getFingerprints() { @@ -218,7 +206,7 @@ public class XmppUri { OMEMO } - public static String getFingerprintUri(String base, List fingerprints, char seperator) { + public static String getFingerprintUri(String base, List fingerprints, char separator) { StringBuilder builder = new StringBuilder(base); builder.append('?'); for (int i = 0; i < fingerprints.size(); ++i) { @@ -230,7 +218,7 @@ public class XmppUri { builder.append('='); builder.append(fingerprints.get(i).fingerprint); if (i != fingerprints.size() - 1) { - builder.append(seperator); + builder.append(separator); } } return builder.toString(); @@ -247,9 +235,10 @@ public class XmppUri { this.deviceId = deviceId; } + @NonNull @Override public String toString() { - return type.toString() + ": " + fingerprint + (deviceId != 0 ? " " + String.valueOf(deviceId) : ""); + return type.toString() + ": " + fingerprint + (deviceId != 0 ? " " + deviceId : ""); } } From 471b02ce868fa8e61cb59fe05769d866ec3dfa2c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 8 Jan 2020 11:07:15 +0100 Subject: [PATCH 21/38] explicity set okhttp to 3.12.x --- build.gradle | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index f004f6d60..391f15193 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ dependencies { exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' } implementation 'org.sufficientlysecure:openpgp-api:10.0' - implementation ('com.theartofdev.edmodo:android-image-cropper:2.7.+') { + implementation('com.theartofdev.edmodo:android-image-cropper:2.7.+') { exclude group: 'com.android.support', module: 'appcompat-v7' exclude group: 'com.android.support', module: 'exifinterface' } @@ -66,8 +66,12 @@ dependencies { implementation 'org.conscrypt:conscrypt-android:2.2.1' implementation 'me.drakeet.support:toastcompat:1.1.0' implementation "com.leinardi.android:speed-dial:2.0.1" - implementation 'com.squareup.retrofit2:retrofit:2.7.1' - implementation 'com.squareup.retrofit2:converter-gson:2.7.1' + implementation("com.squareup.retrofit2:retrofit:2.7.1") { + exclude group: "com.squareup.okhttp3", "module": "okhttp" + } + implementation("com.squareup.retrofit2:converter-gson:2.7.1") { + exclude group: "com.squareup.okhttp3", "module": "okhttp" + } implementation 'com.squareup.okhttp3:okhttp:3.12.7' implementation 'com.google.guava:guava:27.1-android' quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.11.1' @@ -199,7 +203,6 @@ android { } - if (new File("signing.properties").exists()) { Properties props = new Properties() props.load(new FileInputStream(file("signing.properties"))) From 05c3e047f6c9b8e789f182d2c9455cf0240d5835 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 8 Jan 2020 19:02:29 +0100 Subject: [PATCH 22/38] fix retrofit to 2.6.x --- build.gradle | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 391f15193..c720c19e6 100644 --- a/build.gradle +++ b/build.gradle @@ -66,12 +66,10 @@ dependencies { implementation 'org.conscrypt:conscrypt-android:2.2.1' implementation 'me.drakeet.support:toastcompat:1.1.0' implementation "com.leinardi.android:speed-dial:2.0.1" - implementation("com.squareup.retrofit2:retrofit:2.7.1") { - exclude group: "com.squareup.okhttp3", "module": "okhttp" - } - implementation("com.squareup.retrofit2:converter-gson:2.7.1") { - exclude group: "com.squareup.okhttp3", "module": "okhttp" - } + //retrofit needs to stick with 2.6.x (https://github.com/square/retrofit/blob/master/CHANGELOG.md) + implementation "com.squareup.retrofit2:retrofit:2.6.4" + implementation "com.squareup.retrofit2:converter-gson:2.6.4" + //okhttp needs to stick with 3.12.x implementation 'com.squareup.okhttp3:okhttp:3.12.7' implementation 'com.google.guava:guava:27.1-android' quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.11.1' From 80e83f77a7d983e48da631bf7b53dfa54cdb2b3b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 8 Jan 2020 19:05:12 +0100 Subject: [PATCH 23/38] pulled translations from transifex --- src/main/java/eu/siacs/conversations/Config.java | 1 + .../conversations/crypto/axolotl/XmppAxolotlMessage.java | 4 ++-- .../eu/siacs/conversations/http/HttpUploadConnection.java | 2 +- src/main/res/values-ar/strings.xml | 1 - src/main/res/values-de/strings.xml | 1 - src/main/res/values-el/strings.xml | 1 - src/main/res/values-es/strings.xml | 1 - src/main/res/values-eu/strings.xml | 1 - src/main/res/values-fr/strings.xml | 1 - src/main/res/values-gl/strings.xml | 1 - src/main/res/values-hu/strings.xml | 1 - src/main/res/values-it/strings.xml | 1 - src/main/res/values-nl/strings.xml | 1 - src/main/res/values-pl/strings.xml | 8 +++++++- src/main/res/values-pt-rBR/strings.xml | 1 - src/main/res/values-ro-rRO/strings.xml | 7 ++++++- src/main/res/values-uk/strings.xml | 1 - src/main/res/values-zh-rCN/strings.xml | 1 - 18 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index c106bf42b..f231cc4d5 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -100,6 +100,7 @@ public final class Config { public static final boolean REMOVE_BROKEN_DEVICES = false; public static final boolean OMEMO_PADDING = false; public static final boolean PUT_AUTH_TAG_INTO_KEY = true; + public static final boolean TWELVE_BYTE_IV = false; public static final boolean USE_BOOKMARKS2 = false; diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java index 853dc4bab..5a85e1157 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/XmppAxolotlMessage.java @@ -165,8 +165,8 @@ public class XmppAxolotlMessage { } private static byte[] generateIv() { - SecureRandom random = new SecureRandom(); - byte[] iv = new byte[16]; + final SecureRandom random = new SecureRandom(); + byte[] iv = new byte[Config.TWELVE_BYTE_IV ? 12 : 16]; random.nextBytes(iv); return iv; } diff --git a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java index daa0c20c7..08fae1bc5 100644 --- a/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java +++ b/src/main/java/eu/siacs/conversations/http/HttpUploadConnection.java @@ -109,7 +109,7 @@ public class HttpUploadConnection implements Transferable { if (Config.ENCRYPT_ON_HTTP_UPLOADED || message.getEncryption() == Message.ENCRYPTION_AXOLOTL || message.getEncryption() == Message.ENCRYPTION_OTR) { - this.key = new byte[48]; + this.key = new byte[Config.TWELVE_BYTE_IV ? 44 : 48]; mXmppConnectionService.getRNG().nextBytes(this.key); this.file.setKeyAndIv(this.key); } diff --git a/src/main/res/values-ar/strings.xml b/src/main/res/values-ar/strings.xml index c09fcb195..25f653038 100644 --- a/src/main/res/values-ar/strings.xml +++ b/src/main/res/values-ar/strings.xml @@ -657,7 +657,6 @@ الأهمية ، الصوت ، الإهتزاز ضغط الفيديو اعرض الوسائط - اعرض المشارِكين المشارِكون جودة الفيديو متوسط (360ب) diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index a1076e8f2..9c2822015 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -751,7 +751,6 @@ Wichtigkeit, Klang, Vibrationen Video komprimieren Medien anzeigen - Teilnehmer anzeigen Teilnehmer Medienbrowser Datei wurde aufgrund von Sicherheitsverletzungen ausgelassen. diff --git a/src/main/res/values-el/strings.xml b/src/main/res/values-el/strings.xml index 8395311ac..2453932b2 100644 --- a/src/main/res/values-el/strings.xml +++ b/src/main/res/values-el/strings.xml @@ -747,7 +747,6 @@ Σημασία, Ήχος, Δόνηση Συμπίεση βίντεο Εμφάνιση μέσου - Εμφάνιση συμμετεχόντων Συμμετέχοντες Περιηγητης μέσων Το αρχείο παραλείπεται λόγω παραβίασης ασφάλειας. diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 02fd7f855..9ef58cda8 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -751,7 +751,6 @@ Importancia, Sonido, Vibración Compresión de video Ver galería - Ver participantes Participantes Galería Fichero omitido por violación de seguridad diff --git a/src/main/res/values-eu/strings.xml b/src/main/res/values-eu/strings.xml index 247d0e13a..6366f3809 100644 --- a/src/main/res/values-eu/strings.xml +++ b/src/main/res/values-eu/strings.xml @@ -746,7 +746,6 @@ Garrantzia, soinua, dardara Bideoen konprimatzea Ikusi multimedia - Parte-hartzaileak ikusi Parte-hartzaileak Multimedia nabigatzailea Fitxategia alde batera utzita segurtasun hauste bategatik. diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index 5cbaa6e69..aeadabaf2 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -749,7 +749,6 @@ Importance, son, vibration Compression vidéo Voir les média - Voir les participants Participants Navigateur de média Fichier omis en raison d\'une violation de la sécurité. diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 53cb075e5..c26851121 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -751,7 +751,6 @@ Importancia, Son, Vibrar Compresión de vídeo Ver medios - Ver participantes Participantes Navegador de medios Ficheiro omitido debido a transgresión da seguridade. diff --git a/src/main/res/values-hu/strings.xml b/src/main/res/values-hu/strings.xml index 44adbbc1f..7dd041b14 100644 --- a/src/main/res/values-hu/strings.xml +++ b/src/main/res/values-hu/strings.xml @@ -751,7 +751,6 @@ Fontosság, hang, rezgés Videó tömörítése Média megtekintése - Résztvevők megtekintése Résztvevők Médiaböngésző A fájl ki lett hagyva a biztonság megsértése miatt. diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index 105179733..2f46b3017 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -751,7 +751,6 @@ Importanza, suono, vibrazione Compressione video Vedi i media - Vedi i partecipanti Partecipanti Browser multimediale File omesso per violazione di sicurezza. diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index bf7da9372..3f2dcb4db 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -748,7 +748,6 @@ Belang, geluid, trillen Videocompressie Media bekijken - Deelnemers bekijken Deelnemers Mediabrowser Bestand weggelaten wegens beveiligingsovertreding. diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 797bc1fca..cb386b427 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -769,7 +769,6 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż Ważność, Dźwięk, Wibracja Kompresja wideo Pokaż media - Pokaż członków Uczestnicy Przeglądarka mediów Plik pominięty w związku z naruszeniem bezpieczeństwa. @@ -898,4 +897,11 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż Metoda odkrywania kanałów Kopia zapasowa O aplikacji + + Pokaż %1$d uczestnika + Pokaż %1$d uczestników + Pokaż %1$d uczestników + Pokaż %1$d uczestników + + © autorzy OpenStreetMap diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml index 9e502563e..f91a0a4b2 100644 --- a/src/main/res/values-pt-rBR/strings.xml +++ b/src/main/res/values-pt-rBR/strings.xml @@ -751,7 +751,6 @@ Importância, som, vibração. Compressão de vídeo Ver mídia - Ver participantes Participantes Navegador de mídia Arquivo omitido devido a violação de segurança diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index 129966633..21b92b5c5 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -761,7 +761,6 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Importanță, sunete, vibrații Compresie video Vizualizare fișiere media - Arată participanții Participanți Vizualizare fișiere media Fișier omis ca urmare a unei probleme de securitate. @@ -890,4 +889,10 @@ sau chiar pierderea mesajelor.\nÎn continuare veți fi rugați să dezactivați Metoda de descoperire a canalelor Copie de siguranță Despre + + Arată %1$d participant + Arată %1$d participanți + Arată %1$d de participanți + + © Colaboratorii OpenStreetMap diff --git a/src/main/res/values-uk/strings.xml b/src/main/res/values-uk/strings.xml index 8750b4860..1c8b2e762 100644 --- a/src/main/res/values-uk/strings.xml +++ b/src/main/res/values-uk/strings.xml @@ -761,7 +761,6 @@ Важливість, звук, вібрація Стиснення відео Перегляд медіа - Переглянути учасників Учасники Переглядач медіа Файл пропущено через порушення безпеки. diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index 85a37fe86..0bb284ed2 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -740,7 +740,6 @@ 重要性,声音,振动 视频压缩 查看媒体文件 - 查看成员 成员 媒体浏览器 文件由于违反安全策略而被删除。 From 7803a073ec4ca57dfc34edbcc06c26cd08ac798f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Jan 2020 10:10:22 +0100 Subject: [PATCH 24/38] bump version code --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c720c19e6..f68542d54 100644 --- a/build.gradle +++ b/build.gradle @@ -86,7 +86,7 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 28 - versionCode 352 + versionCode 353 versionName "2.6.2" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" From 387e32cf8e7e56d8aefd98a134b1b3d460597c07 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Jan 2020 17:41:37 +0100 Subject: [PATCH 25/38] pulled translations from transifex --- src/main/res/values-de/strings.xml | 5 +++++ src/main/res/values-gl/strings.xml | 13 +++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index 9c2822015..2e7d24102 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -879,4 +879,9 @@ Channelsuchmethode Sicherungskopie Über + + %1$d Teilnehmer anzeigen + %1$d Teilnehmer anzeigen + + © OpenStreetMap Beitragende diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index c26851121..58141e1a8 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -285,7 +285,7 @@ Sincronizar cos marcadores Unirse e deixar conversas de grupo de acordo coa marca auto-unirse nos seus marcadores. Copiouse a pegada dixital OMEMO ao portapapeis! - Vostede non pode acceder a esta conversa en grupo + Non podes acceder a esta conversa en grupo Esta conversa en grupo é so para membros Restrición do recurso Xa foi expulsado de esta conversa en grupo @@ -387,7 +387,7 @@ Privada, só para membros Facer os enderezos XMPP visibles para calquera Establecer canal como moderado - Vostede non está a participar + Non estás a participar ¡Opcións da conversa en grupo modificadas! Non se puideron modificar as opcións da conversa en grupo Nunca @@ -525,7 +525,7 @@ Fallo na seguridade: Acceso non válido ao ficheiro Non se atopou un aplicativo para compartir URI Compartir URI con... -
Pode rexistrarse co seu número de teléfono e Quicksy suxeriralle automáticamente —tomando os números da súa libreta de enderezos como referencia— posibles contactos para vostede.

Ao rexistarse vostede acepta a nosa política de intimidade.]]>
+
Podes rexistrarte co teu número de teléfono e Quicksy suxerillache automáticamente —tomando os números da túa libreta de enderezos como referencia— posibles contactos para ti.

Ao rexistrarte aceptas a nosa política de intimidade.]]>
Aceptar & continuar Guiarémola a través do proceso de creación de unha conta en conversations.im.¹\nAo escoller a conversations.im como fornecedor poderá comunicar con usuarias de outros fornecedores proporcionándolles o seu enderezo XMPP completo. O seu enderezo XMPP completo será: %s @@ -802,7 +802,7 @@ Está a utilizar unha versión desactualizada de esta app. Actualizar Este número de teléfono está actualmente ligado a outro dispositivo. - Por favor, introduza o seu nome para permitir que a xente que non o ten na axenda de enderezos sepa quen é vostede. + Por favor, escribe o teu nome para permitir que a xente que non te ten na axenda de enderezos sepa quen es. O seu nome Introduza o seu nome Utilice o botón editar para escribir o seu nome. @@ -879,4 +879,9 @@ Método de descubrimento de canles Respaldo Acerca de + + Ver %1$d Participante + Ver %1$d Participantes + + © contribuíntes OpenStreetMap From d039c4870f4ac3e48fb597690db732d96faa0d72 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Jan 2020 14:13:05 +0100 Subject: [PATCH 26/38] support registration via pars tokens --- .../conversations/ui/MagicCreateActivity.java | 184 ++++++++++-------- .../conversations/utils/SignupUtils.java | 12 ++ src/conversations/res/layout/magic_create.xml | 181 +++++++++-------- src/conversations/res/values/strings.xml | 2 +- .../siacs/conversations/entities/Account.java | 4 + .../conversations/ui/EditAccountActivity.java | 13 ++ .../conversations/ui/UriHandlerActivity.java | 14 ++ .../eu/siacs/conversations/utils/XmppUri.java | 5 + .../eu/siacs/conversations/xml/Namespace.java | 2 + .../conversations/xmpp/XmppConnection.java | 27 ++- src/main/res/values/strings.xml | 1 + 11 files changed, 280 insertions(+), 165 deletions(-) diff --git a/src/conversations/java/eu/siacs/conversations/ui/MagicCreateActivity.java b/src/conversations/java/eu/siacs/conversations/ui/MagicCreateActivity.java index 52c067258..bc9b06d5f 100644 --- a/src/conversations/java/eu/siacs/conversations/ui/MagicCreateActivity.java +++ b/src/conversations/java/eu/siacs/conversations/ui/MagicCreateActivity.java @@ -2,7 +2,9 @@ package eu.siacs.conversations.ui; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.databinding.DataBindingUtil; import android.os.Bundle; +import android.support.v7.widget.Toolbar; import android.text.Editable; import android.text.TextWatcher; import android.view.View; @@ -15,102 +17,124 @@ import java.security.SecureRandom; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; +import eu.siacs.conversations.databinding.MagicCreateBinding; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.utils.CryptoHelper; import rocks.xmpp.addr.Jid; public class MagicCreateActivity extends XmppActivity implements TextWatcher { - private TextView mFullJidDisplay; - private EditText mUsername; + public static final String EXTRA_DOMAIN = "domain"; + public static final String EXTRA_PRE_AUTH = "pre_auth"; - @Override - protected void refreshUiReal() { + private MagicCreateBinding binding; + private String domain; + private String preAuth; - } + @Override + protected void refreshUiReal() { - @Override - void onBackendConnected() { + } - } + @Override + void onBackendConnected() { - @Override - public void onStart() { - super.onStart(); - final int theme = findTheme(); - if (this.mTheme != theme) { - recreate(); - } - } + } - @Override - protected void onCreate(final Bundle savedInstanceState) { - if (getResources().getBoolean(R.bool.portrait_only)) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); - } - super.onCreate(savedInstanceState); - setContentView(R.layout.magic_create); - setSupportActionBar(findViewById(R.id.toolbar)); - configureActionBar(getSupportActionBar()); - mFullJidDisplay = findViewById(R.id.full_jid); - mUsername = findViewById(R.id.username); - Button next = findViewById(R.id.create_account); - next.setOnClickListener(v -> { - try { - String username = mUsername.getText().toString(); - Jid jid = Jid.of(username.toLowerCase(), Config.MAGIC_CREATE_DOMAIN, null); - if (!jid.getEscapedLocal().equals(jid.getLocal())|| username.length() < 3) { - mUsername.setError(getString(R.string.invalid_username)); - mUsername.requestFocus(); - } else { - mUsername.setError(null); - Account account = xmppConnectionService.findAccountByJid(jid); - if (account == null) { - account = new Account(jid, CryptoHelper.createPassword(new SecureRandom())); - account.setOption(Account.OPTION_REGISTER, true); - account.setOption(Account.OPTION_DISABLED, true); - account.setOption(Account.OPTION_MAGIC_CREATE, true); - xmppConnectionService.createAccount(account); - } - Intent intent = new Intent(MagicCreateActivity.this, EditAccountActivity.class); - intent.putExtra("jid", account.getJid().asBareJid().toString()); - intent.putExtra("init", true); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - Toast.makeText(MagicCreateActivity.this, R.string.secure_password_generated, Toast.LENGTH_SHORT).show(); - StartConversationActivity.addInviteUri(intent, getIntent()); - startActivity(intent); - } - } catch (IllegalArgumentException e) { - mUsername.setError(getString(R.string.invalid_username)); - mUsername.requestFocus(); - } - }); - mUsername.addTextChangedListener(this); - } + @Override + public void onStart() { + super.onStart(); + final int theme = findTheme(); + if (this.mTheme != theme) { + recreate(); + } + } - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { + @Override + protected void onCreate(final Bundle savedInstanceState) { + final Intent data = getIntent(); + this.domain = data == null ? null : data.getStringExtra(EXTRA_DOMAIN); + this.preAuth = data == null ? null : data.getStringExtra(EXTRA_PRE_AUTH); + if (getResources().getBoolean(R.bool.portrait_only)) { + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + super.onCreate(savedInstanceState); + this.binding = DataBindingUtil.setContentView(this, R.layout.magic_create); + setSupportActionBar((Toolbar) this.binding.toolbar); + configureActionBar(getSupportActionBar(), this.domain == null); + if (domain != null) { + binding.instructions.setText(getString(R.string.magic_create_text_on_x, domain)); + binding.finePrint.setVisibility(View.INVISIBLE); + } + binding.createAccount.setOnClickListener(v -> { + try { + final String username = binding.username.getText().toString(); + final Jid jid; + if (this.domain == null) { + jid = Jid.ofLocalAndDomain(username, Config.MAGIC_CREATE_DOMAIN); + } else { + jid = Jid.ofLocalAndDomain(username, this.domain); + } + if (!jid.getEscapedLocal().equals(jid.getLocal()) || username.length() < 3) { + binding.username.setError(getString(R.string.invalid_username)); + binding.username.requestFocus(); + } else { + binding.username.setError(null); + Account account = xmppConnectionService.findAccountByJid(jid); + if (account == null) { + account = new Account(jid, CryptoHelper.createPassword(new SecureRandom())); + account.setOption(Account.OPTION_REGISTER, true); + account.setOption(Account.OPTION_DISABLED, true); + account.setOption(Account.OPTION_MAGIC_CREATE, true); + if (this.preAuth != null) { + account.setKey(Account.PRE_AUTH_REGISTRATION_TOKEN, this.preAuth); + } + xmppConnectionService.createAccount(account); + } + Intent intent = new Intent(MagicCreateActivity.this, EditAccountActivity.class); + intent.putExtra("jid", account.getJid().asBareJid().toString()); + intent.putExtra("init", true); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + Toast.makeText(MagicCreateActivity.this, R.string.secure_password_generated, Toast.LENGTH_SHORT).show(); + StartConversationActivity.addInviteUri(intent, getIntent()); + startActivity(intent); + } + } catch (IllegalArgumentException e) { + binding.username.setError(getString(R.string.invalid_username)); + binding.username.requestFocus(); + } + }); + binding.username.addTextChangedListener(this); + } - } + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { + } - } + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { - @Override - public void afterTextChanged(Editable s) { - if (s.toString().trim().length() > 0) { - try { - mFullJidDisplay.setVisibility(View.VISIBLE); - Jid jid = Jid.of(s.toString().toLowerCase(), Config.MAGIC_CREATE_DOMAIN, null); - mFullJidDisplay.setText(getString(R.string.your_full_jid_will_be, jid.toEscapedString())); - } catch (IllegalArgumentException e) { - mFullJidDisplay.setVisibility(View.INVISIBLE); - } + } - } else { - mFullJidDisplay.setVisibility(View.INVISIBLE); - } - } + @Override + public void afterTextChanged(Editable s) { + if (s.toString().trim().length() > 0) { + try { + binding.fullJid.setVisibility(View.VISIBLE); + final Jid jid; + if (this.domain == null) { + jid = Jid.ofLocalAndDomain(s.toString(), Config.MAGIC_CREATE_DOMAIN); + } else { + jid = Jid.ofLocalAndDomain(s.toString(), this.domain); + } + binding.fullJid.setText(getString(R.string.your_full_jid_will_be, jid.toEscapedString())); + } catch (IllegalArgumentException e) { + binding.fullJid.setVisibility(View.INVISIBLE); + } + + } else { + binding.fullJid.setVisibility(View.INVISIBLE); + } + } } diff --git a/src/conversations/java/eu/siacs/conversations/utils/SignupUtils.java b/src/conversations/java/eu/siacs/conversations/utils/SignupUtils.java index fc5d874d3..f03a9a7bc 100644 --- a/src/conversations/java/eu/siacs/conversations/utils/SignupUtils.java +++ b/src/conversations/java/eu/siacs/conversations/utils/SignupUtils.java @@ -8,6 +8,7 @@ import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.ui.ConversationsActivity; import eu.siacs.conversations.ui.EditAccountActivity; +import eu.siacs.conversations.ui.MagicCreateActivity; import eu.siacs.conversations.ui.ManageAccountActivity; import eu.siacs.conversations.ui.PickServerActivity; import eu.siacs.conversations.ui.StartConversationActivity; @@ -15,6 +16,17 @@ import eu.siacs.conversations.ui.WelcomeActivity; public class SignupUtils { + public static boolean isSupportTokenRegistry() { + return true; + } + + public static Intent getTokenRegistrationIntent(final Activity activity, String domain, String preauth) { + final Intent intent = new Intent(activity, MagicCreateActivity.class); + intent.putExtra(MagicCreateActivity.EXTRA_DOMAIN, domain); + intent.putExtra(MagicCreateActivity.EXTRA_PRE_AUTH, preauth); + return intent; + } + public static Intent getSignUpIntent(final Activity activity) { return getSignUpIntent(activity, false); } diff --git a/src/conversations/res/layout/magic_create.xml b/src/conversations/res/layout/magic_create.xml index e08dd84c8..51ef104ea 100644 --- a/src/conversations/res/layout/magic_create.xml +++ b/src/conversations/res/layout/magic_create.xml @@ -1,97 +1,112 @@ - + - + - + + + + + android:fillViewport="true"> - - - - - - -