From 14bb8b0cf1720bc82de469cd203d3538e537b409 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 1 Jul 2020 15:36:53 +0200 Subject: [PATCH 01/18] Fix typo (#3814) camea -> camera --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cf05cfaa..feb9f314e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,7 @@ ### Version 2.8.2 -* Add button to switch camea during video call +* Add button to switch camera during video call * Fixed voice calls on tablets ### Version 2.8.1 From 71a56002fee0410de47075217ae7f600a0c5f813 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Jul 2020 17:43:30 +0200 Subject: [PATCH 02/18] fix emojis not rendering correctly with trailing variant selector. fixes #3819 --- .../siacs/conversations/utils/Emoticons.java | 455 +++++++++--------- 1 file changed, 228 insertions(+), 227 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/utils/Emoticons.java b/src/main/java/eu/siacs/conversations/utils/Emoticons.java index 6abcf9b02..26dc205b4 100644 --- a/src/main/java/eu/siacs/conversations/utils/Emoticons.java +++ b/src/main/java/eu/siacs/conversations/utils/Emoticons.java @@ -29,280 +29,281 @@ package eu.siacs.conversations.utils; +import android.support.annotation.NonNull; import android.util.LruCache; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.regex.Pattern; public class Emoticons { - private static final UnicodeRange MISC_SYMBOLS_AND_PICTOGRAPHS = new UnicodeRange(0x1F300,0x1F5FF); - private static final UnicodeRange SUPPLEMENTAL_SYMBOLS = new UnicodeRange(0x1F900,0x1F9FF); - private static final UnicodeRange EMOTICONS = new UnicodeRange(0x1F600,0x1F64F); - private static final UnicodeRange TRANSPORT_SYMBOLS = new UnicodeRange(0x1F680,0x1F6FF); - private static final UnicodeRange MISC_SYMBOLS = new UnicodeRange(0x2600,0x26FF); - private static final UnicodeRange DINGBATS = new UnicodeRange(0x2700,0x27BF); - private static final UnicodeRange ENCLOSED_ALPHANUMERIC_SUPPLEMENT = new UnicodeRange(0x1F100,0x1F1FF); - private static final UnicodeRange ENCLOSED_IDEOGRAPHIC_SUPPLEMENT = new UnicodeRange(0x1F200,0x1F2FF); - private static final UnicodeRange REGIONAL_INDICATORS = new UnicodeRange(0x1F1E6,0x1F1FF); - private static final UnicodeRange GEOMETRIC_SHAPES = new UnicodeRange(0x25A0,0x25FF); - private static final UnicodeRange LATIN_SUPPLEMENT = new UnicodeRange(0x80,0xFF); - private static final UnicodeRange MISC_TECHNICAL = new UnicodeRange(0x2300,0x23FF); - private static final UnicodeRange TAGS = new UnicodeRange(0xE0020,0xE007F); - private static final UnicodeList CYK_SYMBOLS_AND_PUNCTUATION = new UnicodeList(0x3030,0x303D); - private static final UnicodeList LETTERLIKE_SYMBOLS = new UnicodeList(0x2122,0x2139); + private static final UnicodeRange MISC_SYMBOLS_AND_PICTOGRAPHS = new UnicodeRange(0x1F300, 0x1F5FF); + private static final UnicodeRange SUPPLEMENTAL_SYMBOLS = new UnicodeRange(0x1F900, 0x1F9FF); + private static final UnicodeRange EMOTICONS = new UnicodeRange(0x1F600, 0x1F64F); + private static final UnicodeRange TRANSPORT_SYMBOLS = new UnicodeRange(0x1F680, 0x1F6FF); + private static final UnicodeRange MISC_SYMBOLS = new UnicodeRange(0x2600, 0x26FF); + private static final UnicodeRange DINGBATS = new UnicodeRange(0x2700, 0x27BF); + private static final UnicodeRange ENCLOSED_ALPHANUMERIC_SUPPLEMENT = new UnicodeRange(0x1F100, 0x1F1FF); + private static final UnicodeRange ENCLOSED_IDEOGRAPHIC_SUPPLEMENT = new UnicodeRange(0x1F200, 0x1F2FF); + private static final UnicodeRange REGIONAL_INDICATORS = new UnicodeRange(0x1F1E6, 0x1F1FF); + private static final UnicodeRange GEOMETRIC_SHAPES = new UnicodeRange(0x25A0, 0x25FF); + private static final UnicodeRange LATIN_SUPPLEMENT = new UnicodeRange(0x80, 0xFF); + private static final UnicodeRange MISC_TECHNICAL = new UnicodeRange(0x2300, 0x23FF); + private static final UnicodeRange TAGS = new UnicodeRange(0xE0020, 0xE007F); + private static final UnicodeList CYK_SYMBOLS_AND_PUNCTUATION = new UnicodeList(0x3030, 0x303D); + private static final UnicodeList LETTERLIKE_SYMBOLS = new UnicodeList(0x2122, 0x2139); - private static final UnicodeBlocks KEYCAP_COMBINEABLE = new UnicodeBlocks(new UnicodeList(0x23),new UnicodeList(0x2A),new UnicodeRange(0x30,0x39)); + private static final UnicodeBlocks KEYCAP_COMBINEABLE = new UnicodeBlocks(new UnicodeList(0x23), new UnicodeList(0x2A), new UnicodeRange(0x30, 0x39)); - private static final UnicodeBlocks SYMBOLIZE = new UnicodeBlocks( - GEOMETRIC_SHAPES, - LATIN_SUPPLEMENT, - CYK_SYMBOLS_AND_PUNCTUATION, - LETTERLIKE_SYMBOLS, - KEYCAP_COMBINEABLE); - private static final UnicodeBlocks EMOJIS = new UnicodeBlocks( - MISC_SYMBOLS_AND_PICTOGRAPHS, - SUPPLEMENTAL_SYMBOLS, - EMOTICONS, - TRANSPORT_SYMBOLS, - MISC_SYMBOLS, - DINGBATS, - ENCLOSED_ALPHANUMERIC_SUPPLEMENT, - ENCLOSED_IDEOGRAPHIC_SUPPLEMENT, - MISC_TECHNICAL); + private static final UnicodeBlocks SYMBOLIZE = new UnicodeBlocks( + GEOMETRIC_SHAPES, + LATIN_SUPPLEMENT, + CYK_SYMBOLS_AND_PUNCTUATION, + LETTERLIKE_SYMBOLS, + KEYCAP_COMBINEABLE); + private static final UnicodeBlocks EMOJIS = new UnicodeBlocks( + MISC_SYMBOLS_AND_PICTOGRAPHS, + SUPPLEMENTAL_SYMBOLS, + EMOTICONS, + TRANSPORT_SYMBOLS, + MISC_SYMBOLS, + DINGBATS, + ENCLOSED_ALPHANUMERIC_SUPPLEMENT, + ENCLOSED_IDEOGRAPHIC_SUPPLEMENT, + MISC_TECHNICAL); - private static final int MAX_EMOIJS = 42; + private static final int MAX_EMOIJS = 42; - private static final int ZWJ = 0x200D; - private static final int VARIATION_16 = 0xFE0F; - private static final int COMBINING_ENCLOSING_KEYCAP = 0x20E3; - private static final int BLACK_FLAG = 0x1F3F4; - private static final UnicodeRange FITZPATRICK = new UnicodeRange(0x1F3FB,0x1F3FF); + private static final int ZWJ = 0x200D; + private static final int VARIATION_16 = 0xFE0F; + private static final int COMBINING_ENCLOSING_KEYCAP = 0x20E3; + private static final int BLACK_FLAG = 0x1F3F4; + private static final UnicodeRange FITZPATRICK = new UnicodeRange(0x1F3FB, 0x1F3FF); - private static final LruCache CACHE = new LruCache<>(256); + private static final LruCache CACHE = new LruCache<>(256); - private static List parse(String input) { - List symbols = new ArrayList<>(); - Builder builder = new Builder(); - boolean needsFinalBuild = false; - for (int cp, i = 0; i < input.length(); i += Character.charCount(cp)) { - cp = input.codePointAt(i); - if (builder.offer(cp)) { - needsFinalBuild = true; - } else { - symbols.add(builder.build()); - builder = new Builder(); - if (builder.offer(cp)) { - needsFinalBuild = true; - } - } - } - if (needsFinalBuild) { - symbols.add(builder.build()); - } - return symbols; - } + private static List parse(String input) { + List symbols = new ArrayList<>(); + Builder builder = new Builder(); + boolean needsFinalBuild = false; + for (int cp, i = 0; i < input.length(); i += Character.charCount(cp)) { + cp = input.codePointAt(i); + if (builder.offer(cp)) { + needsFinalBuild = true; + } else { + symbols.add(builder.build()); + builder = new Builder(); + if (builder.offer(cp)) { + needsFinalBuild = true; + } + } + } + if (needsFinalBuild) { + symbols.add(builder.build()); + } + return symbols; + } - public static Pattern getEmojiPattern(CharSequence input) { - Pattern pattern = CACHE.get(input); - if (pattern == null) { - pattern = generatePattern(input); - CACHE.put(input, pattern); - } - return pattern; - } + public static Pattern getEmojiPattern(final CharSequence input) { + Pattern pattern = CACHE.get(input); + if (pattern == null) { + pattern = generatePattern(input); + CACHE.put(input, pattern); + } + return pattern; + } - private static Pattern generatePattern(CharSequence input) { - final HashSet emojis = new HashSet<>(); - int i = 0; - for(Symbol symbol : parse(input.toString())) { - if (symbol instanceof Emoji) { - emojis.add(symbol.toString()); - if (++i >= MAX_EMOIJS) { - return Pattern.compile(""); - } - } - } - final StringBuilder pattern = new StringBuilder(); - for(String emoji : emojis) { - if (pattern.length() != 0) { - pattern.append('|'); - } - pattern.append(Pattern.quote(emoji)); - } - return Pattern.compile(pattern.toString()); - } + private static Pattern generatePattern(CharSequence input) { + final HashSet emojis = new HashSet<>(); + int i = 0; + for (final Symbol symbol : parse(input.toString())) { + if (symbol instanceof Emoji) { + emojis.add(symbol.toString()); + if (++i >= MAX_EMOIJS) { + return Pattern.compile(""); + } + } + } + final StringBuilder pattern = new StringBuilder(); + for (String emoji : emojis) { + if (pattern.length() != 0) { + pattern.append('|'); + } + pattern.append(Pattern.quote(emoji)); + } + return Pattern.compile(pattern.toString()); + } - public static boolean isEmoji(String input) { - List symbols = parse(input); - return symbols.size() == 1 && symbols.get(0).isEmoji(); - } + public static boolean isEmoji(String input) { + List symbols = parse(input); + return symbols.size() == 1 && symbols.get(0).isEmoji(); + } - public static boolean isOnlyEmoji(String input) { - List symbols = parse(input); - for(Symbol symbol : symbols) { - if (!symbol.isEmoji()) { - return false; - } - } - return symbols.size() > 0; - } + public static boolean isOnlyEmoji(String input) { + List symbols = parse(input); + for (Symbol symbol : symbols) { + if (!symbol.isEmoji()) { + return false; + } + } + return symbols.size() > 0; + } - private static abstract class Symbol { + private static abstract class Symbol { - private final String value; + private final String value; - public Symbol(List codepoints) { - StringBuilder builder = new StringBuilder(); - for(Integer codepoint : codepoints) { - builder.appendCodePoint(codepoint); - } - this.value = builder.toString(); - } + Symbol(List codepoints) { + final StringBuilder builder = new StringBuilder(); + for (final Integer codepoint : codepoints) { + builder.appendCodePoint(codepoint); + } + this.value = builder.toString(); + } - abstract boolean isEmoji(); + abstract boolean isEmoji(); - @Override - public String toString() { - return value; - } - } + @NonNull + @Override + public String toString() { + return value; + } + } - public static class Emoji extends Symbol { + public static class Emoji extends Symbol { - public Emoji(List codepoints) { - super(codepoints); - } + Emoji(List codepoints) { + super(codepoints); + } - @Override - boolean isEmoji() { - return true; - } - } + @Override + boolean isEmoji() { + return true; + } + } - public static class Other extends Symbol { + public static class Other extends Symbol { - public Other(List codepoints) { - super(codepoints); - } + public Other(List codepoints) { + super(codepoints); + } - @Override - boolean isEmoji() { - return false; - } - } + @Override + boolean isEmoji() { + return false; + } + } - private static class Builder { - private final List codepoints = new ArrayList<>(); + private static class Builder { + private final List codepoints = new ArrayList<>(); - public boolean offer(int codepoint) { - boolean add = false; - if (this.codepoints.size() == 0) { - if (SYMBOLIZE.contains(codepoint)) { - add = true; - } else if (REGIONAL_INDICATORS.contains(codepoint)) { - add = true; - } else if (EMOJIS.contains(codepoint) && !FITZPATRICK.contains(codepoint) && codepoint != ZWJ) { - add = true; - } - } else { - int previous = codepoints.get(codepoints.size() -1); - if (codepoints.get(0) == BLACK_FLAG) { - add = TAGS.contains(codepoint); - } else if (COMBINING_ENCLOSING_KEYCAP == codepoint) { - add = KEYCAP_COMBINEABLE.contains(previous) || previous == VARIATION_16; - } else if (SYMBOLIZE.contains(previous)) { - add = codepoint == VARIATION_16; - } else if (REGIONAL_INDICATORS.contains(previous) && REGIONAL_INDICATORS.contains(codepoint)) { - add = codepoints.size() == 1; - } else if (previous == VARIATION_16) { - add = isMerger(codepoint); - } else if (FITZPATRICK.contains(previous)) { - add = codepoint == ZWJ; - } else if (ZWJ == previous) { - add = EMOJIS.contains(codepoint); - } else if (isMerger(codepoint)) { - add = true; - } else if (codepoint == VARIATION_16 && EMOJIS.contains(previous)) { - add = true; - } - } - if (add) { - codepoints.add(codepoint); - return true; - } else { - return false; - } - } + public boolean offer(int codepoint) { + boolean add = false; + if (this.codepoints.size() == 0) { + if (SYMBOLIZE.contains(codepoint)) { + add = true; + } else if (REGIONAL_INDICATORS.contains(codepoint)) { + add = true; + } else if (EMOJIS.contains(codepoint) && !FITZPATRICK.contains(codepoint) && codepoint != ZWJ) { + add = true; + } + } else { + int previous = codepoints.get(codepoints.size() - 1); + if (codepoints.get(0) == BLACK_FLAG) { + add = TAGS.contains(codepoint); + } else if (COMBINING_ENCLOSING_KEYCAP == codepoint) { + add = KEYCAP_COMBINEABLE.contains(previous) || previous == VARIATION_16; + } else if (SYMBOLIZE.contains(previous)) { + add = codepoint == VARIATION_16; + } else if (REGIONAL_INDICATORS.contains(previous) && REGIONAL_INDICATORS.contains(codepoint)) { + add = codepoints.size() == 1; + } else if (previous == VARIATION_16) { + add = isMerger(codepoint) || codepoint == VARIATION_16; + } else if (FITZPATRICK.contains(previous)) { + add = codepoint == ZWJ; + } else if (ZWJ == previous) { + add = EMOJIS.contains(codepoint); + } else if (isMerger(codepoint)) { + add = true; + } else if (codepoint == VARIATION_16 && EMOJIS.contains(previous)) { + add = true; + } + } + if (add) { + codepoints.add(codepoint); + return true; + } else { + return false; + } + } - private static boolean isMerger(int codepoint) { - return codepoint == ZWJ || FITZPATRICK.contains(codepoint); - } + private static boolean isMerger(int codepoint) { + return codepoint == ZWJ || FITZPATRICK.contains(codepoint); + } - public Symbol build() { - if (codepoints.size() > 0 && SYMBOLIZE.contains(codepoints.get(codepoints.size() - 1))) { - return new Other(codepoints); - } else if (codepoints.size() > 1 && KEYCAP_COMBINEABLE.contains(codepoints.get(0)) && codepoints.get(codepoints.size() - 1) != COMBINING_ENCLOSING_KEYCAP) { - return new Other(codepoints); - } - return codepoints.size() == 0 ? new Other(codepoints): new Emoji(codepoints); - } - } + public Symbol build() { + if (codepoints.size() > 0 && SYMBOLIZE.contains(codepoints.get(codepoints.size() - 1))) { + return new Other(codepoints); + } else if (codepoints.size() > 1 && KEYCAP_COMBINEABLE.contains(codepoints.get(0)) && codepoints.get(codepoints.size() - 1) != COMBINING_ENCLOSING_KEYCAP) { + return new Other(codepoints); + } + return codepoints.size() == 0 ? new Other(codepoints) : new Emoji(codepoints); + } + } - public static class UnicodeBlocks implements UnicodeSet { - final UnicodeSet[] unicodeSets; + public static class UnicodeBlocks implements UnicodeSet { + final UnicodeSet[] unicodeSets; - public UnicodeBlocks(UnicodeSet... sets) { - this.unicodeSets = sets; - } + UnicodeBlocks(final UnicodeSet... sets) { + this.unicodeSets = sets; + } - @Override - public boolean contains(int codepoint) { - for(UnicodeSet unicodeSet : unicodeSets) { - if (unicodeSet.contains(codepoint)) { - return true; - } - } - return false; - } - } + @Override + public boolean contains(int codepoint) { + for (UnicodeSet unicodeSet : unicodeSets) { + if (unicodeSet.contains(codepoint)) { + return true; + } + } + return false; + } + } - public interface UnicodeSet { - boolean contains(int codepoint); - } + public interface UnicodeSet { + boolean contains(int codepoint); + } - public static class UnicodeList implements UnicodeSet { + public static class UnicodeList implements UnicodeSet { - private final List list; + private final List list; - public UnicodeList(Integer... codes) { - this.list = Arrays.asList(codes); - } + UnicodeList(final Integer... codes) { + this.list = Arrays.asList(codes); + } - @Override - public boolean contains(int codepoint) { - return this.list.contains(codepoint); - } - } + @Override + public boolean contains(int codepoint) { + return this.list.contains(codepoint); + } + } - public static class UnicodeRange implements UnicodeSet { + public static class UnicodeRange implements UnicodeSet { - private final int lower; - private final int upper; + private final int lower; + private final int upper; - UnicodeRange(int lower, int upper) { - this.lower = lower; - this.upper = upper; - } + UnicodeRange(int lower, int upper) { + this.lower = lower; + this.upper = upper; + } - public boolean contains(int codePoint) { - return codePoint >= lower && codePoint <= upper; - } - } + public boolean contains(int codePoint) { + return codePoint >= lower && codePoint <= upper; + } + } } From 9ab0fbe48c4bb4b602b4fbf35c109e509f99e381 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Jul 2020 18:52:46 +0200 Subject: [PATCH 03/18] provide progress bar for import backup. fixes #3809 --- .../services/ImportBackupService.java | 109 +++++++++++++----- 1 file changed, 81 insertions(+), 28 deletions(-) diff --git a/src/conversations/java/eu/siacs/conversations/services/ImportBackupService.java b/src/conversations/java/eu/siacs/conversations/services/ImportBackupService.java index 8596b1c3f..e50179c8d 100644 --- a/src/conversations/java/eu/siacs/conversations/services/ImportBackupService.java +++ b/src/conversations/java/eu/siacs/conversations/services/ImportBackupService.java @@ -1,5 +1,6 @@ package eu.siacs.conversations.services; +import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; @@ -10,9 +11,21 @@ import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.os.Binder; import android.os.IBinder; +import android.provider.OpenableColumns; import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationManagerCompat; import android.util.Log; +import com.google.common.base.Charsets; +import com.google.common.io.CountingInputStream; + +import org.bouncycastle.crypto.engines.AESEngine; +import org.bouncycastle.crypto.io.CipherInputStream; +import org.bouncycastle.crypto.modes.AEADBlockCipher; +import org.bouncycastle.crypto.modes.GCMBlockCipher; +import org.bouncycastle.crypto.params.AEADParameters; +import org.bouncycastle.crypto.params.KeyParameter; + import java.io.BufferedReader; import java.io.DataInputStream; import java.io.File; @@ -33,10 +46,6 @@ import java.util.zip.GZIPInputStream; import java.util.zip.ZipException; import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.CipherInputStream; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; @@ -44,14 +53,9 @@ import eu.siacs.conversations.persistance.DatabaseBackend; import eu.siacs.conversations.persistance.FileBackend; import eu.siacs.conversations.ui.ManageAccountActivity; import eu.siacs.conversations.utils.BackupFileHeader; -import eu.siacs.conversations.utils.Compatibility; import eu.siacs.conversations.utils.SerialSingleThreadExecutor; import eu.siacs.conversations.xmpp.Jid; -import static eu.siacs.conversations.services.ExportBackupService.CIPHERMODE; -import static eu.siacs.conversations.services.ExportBackupService.KEYTYPE; -import static eu.siacs.conversations.services.ExportBackupService.PROVIDER; - public class ImportBackupService extends Service { private static final int NOTIFICATION_ID = 21; @@ -117,9 +121,9 @@ public class ImportBackupService extends Service { return running.get(); } - public void loadBackupFiles(OnBackupFilesLoaded onBackupFilesLoaded) { + public void loadBackupFiles(final OnBackupFilesLoaded onBackupFilesLoaded) { executor.execute(() -> { - List accounts = mDatabaseBackend.getAccountJids(false); + final List accounts = mDatabaseBackend.getAccountJids(false); final ArrayList backupFiles = new ArrayList<>(); final Set apps = new HashSet<>(Arrays.asList("Conversations", "Quicksy", getString(R.string.app_name))); for (String app : apps) { @@ -128,7 +132,12 @@ public class ImportBackupService extends Service { Log.d(Config.LOGTAG, "directory not found: " + directory.getAbsolutePath()); continue; } - for (File file : directory.listFiles()) { + final File[] files = directory.listFiles(); + if (files == null) { + onBackupFilesLoaded.onBackupFilesLoaded(backupFiles); + return; + } + for (final File file : files) { if (file.isFile() && file.getName().endsWith(".ceb")) { try { final BackupFile backupFile = BackupFile.read(file); @@ -149,24 +158,67 @@ public class ImportBackupService extends Service { } private void startForegroundService() { + startForeground(NOTIFICATION_ID, createImportBackupNotification(1, 0)); + } + + private void updateImportBackupNotification(final long total, final long current) { + final int max; + final int progress; + if (total == 0) { + max = 1; + progress = 0; + } else { + max = 100; + progress = (int) (current * 100 / total); + } + final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); + try { + notificationManager.notify(NOTIFICATION_ID, createImportBackupNotification(max, progress)); + } catch (final RuntimeException e) { + Log.d(Config.LOGTAG, "unable to make notification", e); + } + } + + private Notification createImportBackupNotification(final int max, final int progress) { NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getBaseContext(), "backup"); mBuilder.setContentTitle(getString(R.string.restoring_backup)) .setSmallIcon(R.drawable.ic_unarchive_white_24dp) - .setProgress(1, 0, true); - startForeground(NOTIFICATION_ID, mBuilder.build()); + .setProgress(max, progress, max == 1 && progress == 0); + return mBuilder.build(); } - private boolean importBackup(Uri uri, String password) { + private boolean importBackup(final Uri uri, final String password) { Log.d(Config.LOGTAG, "importing backup from " + uri); try { - SQLiteDatabase db = mDatabaseBackend.getWritableDatabase(); + final SQLiteDatabase db = mDatabaseBackend.getWritableDatabase(); final InputStream inputStream; - if ("file".equals(uri.getScheme())) { - inputStream = new FileInputStream(new File(uri.getPath())); + final String path = uri.getPath(); + final long fileSize; + if ("file".equals(uri.getScheme()) && path != null) { + final File file = new File(path); + inputStream = new FileInputStream(file); + fileSize = file.length(); } else { + final Cursor returnCursor = getContentResolver().query(uri, null, null, null, null); + if (returnCursor == null) { + fileSize = 0; + } else { + returnCursor.moveToFirst(); + fileSize = returnCursor.getLong(returnCursor.getColumnIndex(OpenableColumns.SIZE)); + returnCursor.close(); + } inputStream = getContentResolver().openInputStream(uri); } - final DataInputStream dataInputStream = new DataInputStream(inputStream); + if (inputStream == null) { + synchronized (mOnBackupProcessedListeners) { + for (final OnBackupProcessed l : mOnBackupProcessedListeners) { + l.onBackupRestoreFailed(); + } + } + return false; + } + final CountingInputStream countingInputStream = new CountingInputStream(inputStream); + final DataInputStream dataInputStream = new DataInputStream(countingInputStream); final BackupFileHeader backupFileHeader = BackupFileHeader.read(dataInputStream); Log.d(Config.LOGTAG, backupFileHeader.toString()); @@ -179,15 +231,14 @@ public class ImportBackupService extends Service { return false; } - final Cipher cipher = Compatibility.twentyEight() ? Cipher.getInstance(CIPHERMODE) : Cipher.getInstance(CIPHERMODE, PROVIDER); - byte[] key = ExportBackupService.getKey(password, backupFileHeader.getSalt()); - SecretKeySpec keySpec = new SecretKeySpec(key, KEYTYPE); - IvParameterSpec ivSpec = new IvParameterSpec(backupFileHeader.getIv()); - cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); - CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher); + final byte[] key = ExportBackupService.getKey(password, backupFileHeader.getSalt()); - GZIPInputStream gzipInputStream = new GZIPInputStream(cipherInputStream); - BufferedReader reader = new BufferedReader(new InputStreamReader(gzipInputStream, "UTF-8")); + AEADBlockCipher cipher = new GCMBlockCipher(new AESEngine()); + cipher.init(false, new AEADParameters(new KeyParameter(key), 128, backupFileHeader.getIv())); + final CipherInputStream cipherInputStream = new CipherInputStream(countingInputStream, cipher); + + final GZIPInputStream gzipInputStream = new GZIPInputStream(cipherInputStream); + BufferedReader reader = new BufferedReader(new InputStreamReader(gzipInputStream, Charsets.UTF_8)); String line; StringBuilder multiLineQuery = null; while ((line = reader.readLine()) != null) { @@ -198,10 +249,12 @@ public class ImportBackupService extends Service { if (count % 2 == 1) { db.execSQL(multiLineQuery.toString()); multiLineQuery = null; + updateImportBackupNotification(fileSize, countingInputStream.getCount()); } } else { if (count % 2 == 0) { db.execSQL(line); + updateImportBackupNotification(fileSize, countingInputStream.getCount()); } else { multiLineQuery = new StringBuilder(line); } @@ -220,7 +273,7 @@ public class ImportBackupService extends Service { } } return true; - } catch (Exception e) { + } catch (final Exception e) { Throwable throwable = e.getCause(); final boolean reasonWasCrypto = throwable instanceof BadPaddingException || e instanceof ZipException; synchronized (mOnBackupProcessedListeners) { From 6a6c9fb3bf5d8cbf6571d32dfb62886578ae395b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Jul 2020 19:14:28 +0200 Subject: [PATCH 04/18] ignore race condition when toggling fixes #3822 --- .../siacs/conversations/ui/RtpSessionActivity.java | 14 ++++++++------ .../xmpp/jingle/JingleRtpConnection.java | 4 ++-- .../conversations/xmpp/jingle/WebRTCWrapper.java | 11 +++++++++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index 5db8dfc6d..9bff9ff98 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -910,15 +910,17 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } private void disableMicrophone(View view) { - JingleRtpConnection rtpConnection = requireRtpConnection(); - rtpConnection.setMicrophoneEnabled(false); - updateInCallButtonConfiguration(); + final JingleRtpConnection rtpConnection = requireRtpConnection(); + if (rtpConnection.setMicrophoneEnabled(false)) { + updateInCallButtonConfiguration(); + } } private void enableMicrophone(View view) { - JingleRtpConnection rtpConnection = requireRtpConnection(); - rtpConnection.setMicrophoneEnabled(true); - updateInCallButtonConfiguration(); + final JingleRtpConnection rtpConnection = requireRtpConnection(); + if (rtpConnection.setMicrophoneEnabled(true)) { + updateInCallButtonConfiguration(); + } } private void switchToEarpiece(View view) { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java index 28f7c738b..830695831 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleRtpConnection.java @@ -1085,8 +1085,8 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web return webRTCWrapper.isMicrophoneEnabled(); } - public void setMicrophoneEnabled(final boolean enabled) { - webRTCWrapper.setMicrophoneEnabled(enabled); + public boolean setMicrophoneEnabled(final boolean enabled) { + return webRTCWrapper.setMicrophoneEnabled(enabled); } public boolean isVideoEnabled() { diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java index ff7e6a677..98ce37a4e 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java @@ -370,12 +370,19 @@ public class WebRTCWrapper { } } - void setMicrophoneEnabled(final boolean enabled) { + boolean setMicrophoneEnabled(final boolean enabled) { final AudioTrack audioTrack = this.localAudioTrack; if (audioTrack == null) { throw new IllegalStateException("Local audio track does not exist (yet)"); } - audioTrack.setEnabled(enabled); + try { + audioTrack.setEnabled(enabled); + return true; + } catch (final IllegalStateException e) { + Log.d(Config.LOGTAG, "unable to toggle microphone", e); + //ignoring race condition in case MediaStreamTrack has been disposed + return false; + } } boolean isVideoEnabled() { From 1107529f5633b0356bc2f32da71a431c139f622b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Jul 2020 20:03:02 +0200 Subject: [PATCH 05/18] ask for contact permission before adding to contact to phone book. fixes #3808 --- .../ui/ContactDetailsActivity.java | 95 ++++++++++++------- 1 file changed, 60 insertions(+), 35 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java index 15190d08c..6c5496650 100644 --- a/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ContactDetailsActivity.java @@ -1,16 +1,20 @@ package eu.siacs.conversations.ui; +import android.Manifest; import android.content.ActivityNotFoundException; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.databinding.DataBindingUtil; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.provider.ContactsContract.CommonDataKinds; import android.provider.ContactsContract.Contacts; import android.provider.ContactsContract.Intents; +import android.support.annotation.NonNull; import android.support.v7.app.AlertDialog; import android.support.v7.widget.Toolbar; import android.text.Spannable; @@ -57,15 +61,15 @@ import eu.siacs.conversations.utils.IrregularUnicodeDetector; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.utils.XmppUri; import eu.siacs.conversations.xml.Namespace; +import eu.siacs.conversations.xmpp.Jid; import eu.siacs.conversations.xmpp.OnKeyStatusUpdated; import eu.siacs.conversations.xmpp.OnUpdateBlocklist; import eu.siacs.conversations.xmpp.XmppConnection; -import eu.siacs.conversations.xmpp.Jid; public class ContactDetailsActivity extends OmemoActivity implements OnAccountUpdate, OnRosterUpdate, OnUpdateBlocklist, OnKeyStatusUpdated, OnMediaLoaded { public static final String ACTION_VIEW_CONTACT = "view_contact"; + private final int REQUEST_SYNC_CONTACTS = 0x28cf; ActivityContactDetailsBinding binding; - private MediaAdapter mMediaAdapter; private Contact contact; @@ -110,47 +114,41 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp private boolean showInactiveOmemo = false; private String messageFingerprint; - private DialogInterface.OnClickListener addToPhonebook = new DialogInterface.OnClickListener() { + private void checkContactPermissionAndShowAddDialog() { + if (hasContactsPermission()) { + showAddToPhoneBookDialog(); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + requestPermissions(new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_SYNC_CONTACTS); + } + } - @Override - public void onClick(DialogInterface dialog, int which) { - Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT); + private boolean hasContactsPermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + return checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED; + } else { + return true; + } + } + + private void showAddToPhoneBookDialog() { + final AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(getString(R.string.action_add_phone_book)); + builder.setMessage(getString(R.string.add_phone_book_text, contact.getJid().toEscapedString())); + builder.setNegativeButton(getString(R.string.cancel), null); + builder.setPositiveButton(getString(R.string.add), (dialog, which) -> { + final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT); intent.setType(Contacts.CONTENT_ITEM_TYPE); intent.putExtra(Intents.Insert.IM_HANDLE, contact.getJid().toEscapedString()); intent.putExtra(Intents.Insert.IM_PROTOCOL, CommonDataKinds.Im.PROTOCOL_JABBER); intent.putExtra("finishActivityOnSaveCompleted", true); try { - ContactDetailsActivity.this.startActivityForResult(intent, 0); + startActivityForResult(intent, 0); } catch (ActivityNotFoundException e) { Toast.makeText(ContactDetailsActivity.this, R.string.no_application_found_to_view_contact, Toast.LENGTH_SHORT).show(); } - } - }; - - private OnClickListener onBadgeClick = new OnClickListener() { - - @Override - public void onClick(View v) { - Uri systemAccount = contact.getSystemAccount(); - if (systemAccount == null) { - AlertDialog.Builder builder = new AlertDialog.Builder( - ContactDetailsActivity.this); - builder.setTitle(getString(R.string.action_add_phone_book)); - builder.setMessage(getString(R.string.add_phone_book_text, contact.getJid().toEscapedString())); - builder.setNegativeButton(getString(R.string.cancel), null); - builder.setPositiveButton(getString(R.string.add), addToPhonebook); - builder.create().show(); - } else { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(systemAccount); - try { - startActivity(intent); - } catch (ActivityNotFoundException e) { - Toast.makeText(ContactDetailsActivity.this, R.string.no_application_found_to_view_contact, Toast.LENGTH_SHORT).show(); - } - } - } - }; + }); + builder.create().show(); + } @Override public void onRosterUpdate() { @@ -233,6 +231,18 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp mMediaAdapter.setAttachments(Collections.emptyList()); } + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) { + if (grantResults.length > 0) + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + if (requestCode == REQUEST_SYNC_CONTACTS && xmppConnectionServiceBound) { + showAddToPhoneBookDialog(); + xmppConnectionService.loadPhoneContacts(); + xmppConnectionService.startContactObserver(); + } + } + } + @Override public boolean onOptionsItemSelected(final MenuItem menuItem) { if (MenuDoubleTabUtil.shouldIgnoreTap()) { @@ -417,7 +427,7 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp } binding.detailsAccount.setText(getString(R.string.using_account, account)); AvatarWorkerTask.loadAvatar(contact, binding.detailsContactBadge, R.dimen.avatar_on_details_screen_size); - binding.detailsContactBadge.setOnClickListener(this.onBadgeClick); + binding.detailsContactBadge.setOnClickListener(this::onBadgeClick); binding.detailsContactKeys.removeAllViews(); boolean hasKeys = false; @@ -496,6 +506,21 @@ public class ContactDetailsActivity extends OmemoActivity implements OnAccountUp } } + private void onBadgeClick(View view) { + final Uri systemAccount = contact.getSystemAccount(); + if (systemAccount == null) { + checkContactPermissionAndShowAddDialog(); + } else { + final Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(systemAccount); + try { + startActivity(intent); + } catch (final ActivityNotFoundException e) { + Toast.makeText(this, R.string.no_application_found_to_view_contact, Toast.LENGTH_SHORT).show(); + } + } + } + public void onBackendConnected() { if (accountJid != null && contactJid != null) { Account account = xmppConnectionService.findAccountByJid(accountJid); From bf85a55930bde3f713e808a8b0ccf32ff93ba1c4 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 9 Jul 2020 20:11:09 +0200 Subject: [PATCH 06/18] catch NPE when detecting camera facing. fixes #3820 --- .../siacs/conversations/xmpp/jingle/WebRTCWrapper.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java index 98ce37a4e..58dfa4e5f 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/WebRTCWrapper.java @@ -509,7 +509,7 @@ public class WebRTCWrapper { final CameraEnumerator enumerator = getCameraEnumerator(); final Set deviceNames = ImmutableSet.copyOf(enumerator.getDeviceNames()); for (final String deviceName : deviceNames) { - if (enumerator.isFrontFacing(deviceName)) { + if (isFrontFacing(enumerator, deviceName)) { final CapturerChoice capturerChoice = of(enumerator, deviceName, deviceNames); if (capturerChoice == null) { return Optional.absent(); @@ -525,6 +525,14 @@ public class WebRTCWrapper { } } + private static boolean isFrontFacing(final CameraEnumerator cameraEnumerator, final String deviceName) { + try { + return cameraEnumerator.isFrontFacing(deviceName); + } catch (final NullPointerException e) { + return false; + } + } + public PeerConnection.PeerConnectionState getState() { return requirePeerConnection().connectionState(); } From 7ff56a508701d0004d3646bcb9fa82820982467e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2020 15:33:31 +0200 Subject: [PATCH 07/18] upgrade to libwebrtc m84. fixes #3824 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a7442d886..42c1246be 100644 --- a/build.gradle +++ b/build.gradle @@ -80,7 +80,7 @@ dependencies { implementation 'com.squareup.okhttp3:okhttp:3.12.12' implementation 'com.google.guava:guava:27.1-android' quicksyImplementation 'io.michaelrocks:libphonenumber-android:8.11.1' - implementation fileTree(include: ['libwebrtc-m83.aar'], dir: 'libs') + implementation fileTree(include: ['libwebrtc-m84.aar'], dir: 'libs') } ext { From bab9dd48932f4a78b8b3710c29b121afeafd462a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2020 16:10:40 +0200 Subject: [PATCH 08/18] make sure intent is only set to retracted if something was retracted. fixes #3826 --- .../eu/siacs/conversations/ui/RtpSessionActivity.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index 9bff9ff98..cf0e01db4 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -308,6 +308,7 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe return; } final Account account = extractAccount(intent); + final String action = intent.getAction(); final Jid with = Jid.ofEscaped(intent.getStringExtra(EXTRA_WITH)); final String sessionId = intent.getStringExtra(EXTRA_SESSION_ID); if (sessionId != null) { @@ -320,6 +321,9 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe requestPermissionsAndAcceptCall(); resetIntent(intent.getExtras()); } + } else if (asList(ACTION_MAKE_VIDEO_CALL, ACTION_MAKE_VOICE_CALL).contains(action)) { + proposeJingleRtpSession(account, with, actionToMedia(action)); + binding.with.setText(account.getRoster().getContact(with).getDisplayName()); } else { throw new IllegalStateException("received onNewIntent without sessionId"); } @@ -437,7 +441,11 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe return; } } - retractSessionProposal(); + //TODO apparently this method is not getting called on Android 10 when using the task switcher + final boolean emptyReference = rtpConnectionReference == null || rtpConnectionReference.get() == null; + if (emptyReference && xmppConnectionService != null) { + retractSessionProposal(); + } } @RequiresApi(api = Build.VERSION_CODES.O) From fffa65988134e555ffab2a3d7edc2acdd3b7a9a9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2020 16:29:20 +0200 Subject: [PATCH 09/18] download libwebrtc-m84 for travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d2392afab..247e8fd9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ android: - '.+' before_script: - mkdir libs - - wget -O libs/libwebrtc-m83.aar http://gultsch.de/files/libwebrtc-m83.aar + - wget -O libs/libwebrtc-m84.aar http://gultsch.de/files/libwebrtc-m84.aar script: - ./gradlew assembleConversationsFreeSystemRelease - ./gradlew assembleQuicksyFreeCompatRelease From c3fa1d5d30f097658d81333cc5a254a068e5505c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 Jul 2020 19:30:16 +0200 Subject: [PATCH 10/18] show switch to chat button during audio call. fixes #3825 --- .../conversations/ui/RtpSessionActivity.java | 27 ++++++++++++++++-- .../ic_question_answer_white_24dp.png | Bin 0 -> 192 bytes .../ic_question_answer_white_24dp.png | Bin 0 -> 137 bytes .../ic_question_answer_white_24dp.png | Bin 0 -> 195 bytes .../ic_question_answer_white_24dp.png | Bin 0 -> 256 bytes .../ic_question_answer_white_24dp.png | Bin 0 -> 320 bytes src/main/res/menu/activity_rtp_session.xml | 9 ++++-- src/main/res/values/attrs.xml | 1 + src/main/res/values/strings.xml | 1 + src/main/res/values/themes.xml | 2 ++ 10 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 src/main/res/drawable-hdpi/ic_question_answer_white_24dp.png create mode 100644 src/main/res/drawable-mdpi/ic_question_answer_white_24dp.png create mode 100644 src/main/res/drawable-xhdpi/ic_question_answer_white_24dp.png create mode 100644 src/main/res/drawable-xxhdpi/ic_question_answer_white_24dp.png create mode 100644 src/main/res/drawable-xxxhdpi/ic_question_answer_white_24dp.png diff --git a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java index cf0e01db4..33835119f 100644 --- a/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/RtpSessionActivity.java @@ -88,6 +88,10 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe RtpEndUserState.APPLICATION_ERROR, RtpEndUserState.CONNECTIVITY_ERROR ); + private static final List STATES_SHOWING_SWITCH_TO_CHAT = Arrays.asList( + RtpEndUserState.CONNECTING, + RtpEndUserState.CONNECTED + ); private static final String PROXIMITY_WAKE_LOCK_TAG = "conversations:in-rtp-session"; private static final int REQUEST_ACCEPT_CALL = 0x1111; private WeakReference rtpConnectionReference; @@ -135,7 +139,9 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe public boolean onCreateOptionsMenu(final Menu menu) { getMenuInflater().inflate(R.menu.activity_rtp_session, menu); final MenuItem help = menu.findItem(R.id.action_help); + final MenuItem gotoChat = menu.findItem(R.id.action_goto_chat); help.setVisible(isHelpButtonVisible()); + gotoChat.setVisible(isSwitchToConversationVisible()); return super.onCreateOptionsMenu(menu); } @@ -153,10 +159,25 @@ public class RtpSessionActivity extends XmppActivity implements XmppConnectionSe } } + private boolean isSwitchToConversationVisible() { + final JingleRtpConnection connection = this.rtpConnectionReference != null ? this.rtpConnectionReference.get() : null; + return connection != null && STATES_SHOWING_SWITCH_TO_CHAT.contains(connection.getEndUserState()); + } + + private void switchToConversation() { + final Contact contact = getWith(); + final Conversation conversation = xmppConnectionService.findOrCreateConversation(contact.getAccount(), contact.getJid(), false, true); + switchToConversation(conversation); + } + public boolean onOptionsItemSelected(final MenuItem item) { - if (item.getItemId() == R.id.action_help) { - launchHelpInBrowser(); - return true; + switch (item.getItemId()) { + case R.id.action_help: + launchHelpInBrowser(); + break; + case R.id.action_goto_chat: + switchToConversation(); + break; } return super.onOptionsItemSelected(item); } diff --git a/src/main/res/drawable-hdpi/ic_question_answer_white_24dp.png b/src/main/res/drawable-hdpi/ic_question_answer_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..247b7f11d2cdc53a988ec51e63d7678627dd750a GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K8yQhm|NCo5DGlpD;0%V#$KKGqt z6Q=)Y(#{Hv{-E<0?U#sfa`4Mf)LC?Pd&;k^^X2n(s;WO6y0$#{OS!D$d>-}`rw98U z&2c`z)^dsLg?Puw?7BxbbgHvQRiqV5IV2T%@T__FUcs>UUzLXsU+2x$ELFMBW;y4b kP;8Y6f)cEbmGNA;-wkgV*Yg-p20Dqs)78&qol`;+05tPPR{#J2 literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-mdpi/ic_question_answer_white_24dp.png b/src/main/res/drawable-mdpi/ic_question_answer_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..dad29526ae38bae2ccea06618caec7e2aae05c6d GIT binary patch literal 137 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+i08bakkP619rwzFp5_p^+%GpjA zezj65g6021&PW%7{1=zj-{S%;9qx k{a7pnAGkCKGwZRl2S4EAmlFCB0W_Pz)78&qol`;+03PivF#rGn literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xhdpi/ic_question_answer_white_24dp.png b/src/main/res/drawable-xhdpi/ic_question_answer_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..dbb131aab6765bfa19ff1e833f63b82d92299dc9 GIT binary patch literal 195 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0DE>9Q7kP61PmkqfNI|w)j#v07H zlhOD3t7@H>#F20!imhrDdLIXQvjdUbKm{dXo zBij$-2WObn*YgFe*qFN@KuBW>3zur+r~UVB12i~AyqH=y9r(V^q+mmnL-JHMpCb&y th6h}D3UUwFj>nQX`O{?urOrevmrhK&zq zI28COSg2i?yLshvAT1yx%+bfma-5|}nZfo(DzmTji-r)j3#;au38+YOOyXrZ$<~y@ s?6|2>;ikic90d=AuoNTfm-UYJ*R<0D!ftKT0eXqS)78&qol`;+01X{npa1{> literal 0 HcmV?d00001 diff --git a/src/main/res/drawable-xxxhdpi/ic_question_answer_white_24dp.png b/src/main/res/drawable-xxxhdpi/ic_question_answer_white_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..9b26c13a08b1733bb7c0792e4fcbc921d6eda543 GIT binary patch literal 320 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD0wg^q?%&M7z{u|D;uuoF`1bn2OlC)s=0wxv zWxk!X7X`{(}HdGO#nzGGGg zo^(C4Ixtz=>N?}PRSisB8Vf+ggVjv;{_`d>G&E1-ZJ5btahdUtu>&KkNB{~k=Ve2+ z*@Nb2y$4Uu@xEn}_gTe~DWM4fmtS}| literal 0 HcmV?d00001 diff --git a/src/main/res/menu/activity_rtp_session.xml b/src/main/res/menu/activity_rtp_session.xml index 540a9def9..04756490a 100644 --- a/src/main/res/menu/activity_rtp_session.xml +++ b/src/main/res/menu/activity_rtp_session.xml @@ -1,11 +1,16 @@ + xmlns:app="http://schemas.android.com/apk/res-auto"> + app:showAsAction="always" /> + \ No newline at end of file diff --git a/src/main/res/values/attrs.xml b/src/main/res/values/attrs.xml index 1f78fb09b..e67517049 100644 --- a/src/main/res/values/attrs.xml +++ b/src/main/res/values/attrs.xml @@ -97,6 +97,7 @@ + diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 75d839f0b..734a015c3 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -918,6 +918,7 @@ Audio call Video call Help + Switch to conversation Your microphone is unavailable You can only have one call at a time. Return to ongoing call diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml index 50262913f..8def180d8 100644 --- a/src/main/res/values/themes.xml +++ b/src/main/res/values/themes.xml @@ -115,6 +115,7 @@ @drawable/ic_delete_black_24dp @drawable/ic_search_white_24dp @drawable/ic_help_white_24dp + @drawable/ic_question_answer_white_24dp @drawable/ic_lock_open_white_24dp @drawable/ic_settings_black_24dp @drawable/ic_share_white_24dp @@ -269,6 +270,7 @@ @drawable/ic_delete_white_24dp @drawable/ic_search_white_24dp @drawable/ic_help_white_24dp + @drawable/ic_question_answer_white_24dp @drawable/ic_lock_open_white_24dp @drawable/ic_settings_white_24dp @drawable/ic_share_white_24dp From aa47e53584d8f3820ee275a052531639aba695de Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 11 Jul 2020 12:48:20 +0200 Subject: [PATCH 11/18] pulled translations from transifex --- src/conversations/res/values-de/strings.xml | 1 + src/conversations/res/values-el/strings.xml | 2 +- src/conversations/res/values-es/strings.xml | 2 +- src/conversations/res/values-fr/strings.xml | 2 +- src/conversations/res/values-gl/strings.xml | 1 + src/conversations/res/values-hu/strings.xml | 2 +- src/conversations/res/values-it/strings.xml | 2 +- src/conversations/res/values-nl/strings.xml | 2 +- src/conversations/res/values-pl/strings.xml | 2 +- .../res/values-pt-rBR/strings.xml | 2 +- .../res/values-ro-rRO/strings.xml | 2 +- src/conversations/res/values-ru/strings.xml | 5 +- src/conversations/res/values-uk/strings.xml | 2 +- .../res/values-zh-rCN/strings.xml | 2 +- src/main/res/values-de/strings.xml | 1 + src/main/res/values-ru/strings.xml | 55 +++++++++++++++---- src/quicksy/res/values-ru/strings.xml | 26 +++++++++ 17 files changed, 89 insertions(+), 22 deletions(-) create mode 100644 src/quicksy/res/values-ru/strings.xml diff --git a/src/conversations/res/values-de/strings.xml b/src/conversations/res/values-de/strings.xml index 92f0d955d..4f10f4cb4 100644 --- a/src/conversations/res/values-de/strings.xml +++ b/src/conversations/res/values-de/strings.xml @@ -8,4 +8,5 @@ Du wurdest zu %1$s eingeladen. Wir führen dich durch den Prozess der Kontoerstellung.\nWenn du %1$s als Provider wählst, kannst du mit Nutzern anderer Anbieter kommunizieren, indem du ihnen deine vollständige XMPP-Adresse gibst. Du wurdest zu %1$seingeladen. Ein Benutzername ist bereits für dich ausgewählt worden. Wir führen dich durch den Prozess der Kontoerstellung.\nDu kannst mit Nutzern anderer Anbieter kommunizieren, indem du ihnen deine vollständige XMPP-Adresse gibst. Deine Einladung für den Server + Falsch formatierter Provisionierungscode \ No newline at end of file diff --git a/src/conversations/res/values-el/strings.xml b/src/conversations/res/values-el/strings.xml index 64a05095f..8850f9d73 100644 --- a/src/conversations/res/values-el/strings.xml +++ b/src/conversations/res/values-el/strings.xml @@ -8,4 +8,4 @@ Έχετε προσκληθεί στο %1$s. Ένα όνομα χρήστη έχει ήδη επιλεγεί για εσάς. Θα σας καθοδηγήσουμε στη διαδικασία δημιουργίας λογαριασμού.\nΕπιλέγοντας τον %1$s ως πάροχο θα μπορείτε να επικοινωνείτε με χρήστες άλλων παρόχων δίνοντάς τους την πλήρη διεύθυνση XMPP σας. Έχετε προσκληθεί στο %1$s. Ένα όνομα χρήστη έχει ήδη επιλεγεί για εσάς. Θα σας καθοδηγήσουμε στη διαδικασία δημιουργίας λογαριασμού.\nΘα μπορείτε να επικοινωνείτε με χρήστες άλλων παρόχων δίνοντάς τους την πλήρη διεύθυνση XMPP σας. Η πρόσκλησή σας στον διακομιστή - \ No newline at end of file + \ No newline at end of file diff --git a/src/conversations/res/values-es/strings.xml b/src/conversations/res/values-es/strings.xml index 534a778f7..8d952a7a2 100644 --- a/src/conversations/res/values-es/strings.xml +++ b/src/conversations/res/values-es/strings.xml @@ -8,4 +8,4 @@ Has sido invitado a %1$s. Te guiaremos durante el proceso de creación de la cuenta.\nCuando selecciones %1$s como proveedor podrás comunicarte con usuarios de otros servidores proporcionándoles tu dirección XMPP completa. Has sido invitado a %1$s. Un nombre de usuario ya ha sido escogido para ti. Te guiaremos durante el proceso de creación de la cuenta.\nPodrás comunicarte con otros usuarios de otros servidores proporcionándoles tu dirección XMPP completa. Tu invitación al servidor - \ No newline at end of file + \ No newline at end of file diff --git a/src/conversations/res/values-fr/strings.xml b/src/conversations/res/values-fr/strings.xml index 0ea5ca4f1..7e616d601 100644 --- a/src/conversations/res/values-fr/strings.xml +++ b/src/conversations/res/values-fr/strings.xml @@ -8,4 +8,4 @@ Vous avez été invité à %1$s. Nous allons vous guider à travers le processus de création d’un compte.\nEn choisissant %1$s comme fournisseur, vous pourrez communiquer avec les utilisateurs des autres fournisseurs en leur donnant votre adresse XMPP complète. Vous avez été invité à %1$s. Un nom d’utilisateur a déjà été choisi pour vous. Nous allons vous guider à travers le processus de création d’un compte.\nVous pourrez communiquer avec les utilisateurs des autres fournisseurs en leur donnant votre adresse XMPP complète. Votre invitation au serveur - \ No newline at end of file + \ No newline at end of file diff --git a/src/conversations/res/values-gl/strings.xml b/src/conversations/res/values-gl/strings.xml index 4a889ed51..95a5e6b85 100644 --- a/src/conversations/res/values-gl/strings.xml +++ b/src/conversations/res/values-gl/strings.xml @@ -8,4 +8,5 @@ Convidáronte a %1$s. Guiarémoste no proceso para crear unha conta.\nAo escoller %1$s como provedor poderás comunicarte con usuarias de outros provedores cando lles deas o teu enderezo XMPP completo. Convidáronte a %1$s. Escollemos un nome de usuaria por ti. Guiarémoste no proceso de crear unha conta.\nPoderás comunicarte con usuarias de outros provedores cando lles digas o teu enderezo XMPP completo. O convite do teu servidor + Código de aprovisionamento con formato non válido \ No newline at end of file diff --git a/src/conversations/res/values-hu/strings.xml b/src/conversations/res/values-hu/strings.xml index c48b4c7c7..28438fe16 100644 --- a/src/conversations/res/values-hu/strings.xml +++ b/src/conversations/res/values-hu/strings.xml @@ -8,4 +8,4 @@ Meghívást kapott a(z) %1$s kiszolgálóra. Végig fogjuk vezetni egy fiók létrehozásának folyamatán.\nHa a(z) %1$s kiszolgálót választja szolgáltatóként, akkor képes lesz más szolgáltatók felhasználóival is kommunikálni, ha megadja nekik a teljes XMPP-címét. Meghívást kapott a(z) %1$s kiszolgálóra. Már kiválasztottak Önnek egy felhasználónevet. Végig fogjuk vezetni egy fiók létrehozásának folyamatán.\nKépes lesz más szolgáltatók felhasználóival is kommunikálni, ha megadja nekik a teljes XMPP-címét. Az Ön kiszolgálómeghívása - \ No newline at end of file + \ No newline at end of file diff --git a/src/conversations/res/values-it/strings.xml b/src/conversations/res/values-it/strings.xml index 4e38ab9aa..ccaf6889d 100644 --- a/src/conversations/res/values-it/strings.xml +++ b/src/conversations/res/values-it/strings.xml @@ -10,4 +10,4 @@ In ogni caso per facilitare puoi creare facilmente un account su conversations.i Sei stato invitato su %1$s. Ti guideremo nel procedimento per creare un account.\nQuando scegli %1$s come fornitore sarai in grado di comunicare con utenti di altri fornitori dando loro l\'indirizzo XMPP completo. Sei stato invitato su %1$s. È già stato scelto un nome utente per te. Ti guideremo nel procedimento per creare un account.\nSarai in grado di comunicare con utenti di altri fornitori dando loro l\'indirizzo XMPP completo. Il tuo invito al server - \ No newline at end of file + \ No newline at end of file diff --git a/src/conversations/res/values-nl/strings.xml b/src/conversations/res/values-nl/strings.xml index 9ab739372..a92dca5b2 100644 --- a/src/conversations/res/values-nl/strings.xml +++ b/src/conversations/res/values-nl/strings.xml @@ -8,4 +8,4 @@ Je ontving een uitnodiging voor %1$s. We zullen je helpen een account aan te maken.\nWanneer je %1$s als je provider kiest kan je met gebruikers van andere providers communiceren door hen je volledige XMPP-adres te geven. Je ontving een uitnodiging voor %1$s. Er werd reeds een gebruikersnaam voor jou gekozen. We zullen je helpen een account aan te maken.\nJe zal met gebruikers van andere providers communiceren door hen je volledige XMPP-adres te geven. Je server uitnodiging - \ No newline at end of file + \ No newline at end of file diff --git a/src/conversations/res/values-pl/strings.xml b/src/conversations/res/values-pl/strings.xml index d98df9180..bf72b7668 100644 --- a/src/conversations/res/values-pl/strings.xml +++ b/src/conversations/res/values-pl/strings.xml @@ -8,4 +8,4 @@ Zostałeś zaproszony do %1$s. Poprowadzimy ciebie przez proces tworzenia konta.\nWybierając %1$s jako dostawcę będziesz mógł komunikować się z innymi użytkownikami podając swój pełny adres XMPP. Zostałeś zaproszony do %1$s. Nazwa użytkownika została już dla ciebie wybrana. Poprowadzimy ciebie przez proces tworzenia konta.\nBęziesz mógł komunikować się z innymi użytkownikami podając swój adres XMPP. Zaproszenie twojego serwera - \ No newline at end of file + \ No newline at end of file diff --git a/src/conversations/res/values-pt-rBR/strings.xml b/src/conversations/res/values-pt-rBR/strings.xml index 4321fefc7..d2cacc255 100644 --- a/src/conversations/res/values-pt-rBR/strings.xml +++ b/src/conversations/res/values-pt-rBR/strings.xml @@ -8,4 +8,4 @@ Você foi convidado para %1$s. Nós iremos guiá-lo ao longo do processo de criação de uma conta.\nAo escolher %1$s como um provedor você conseguirá se comunicar com usuários de outros provedores dando a eles seu endereço XMPP completo. Você foi convidado para %1$s. Um nome de usuário já foi escolhido para você. Nós iremos guiá-lo ao longo do processo de criação de uma conta.\nVocê conseguirá se comunicar com usuários de outros provedores dando a eles seu endereço XMPP completo. Seu convite do servidor - \ No newline at end of file + \ No newline at end of file diff --git a/src/conversations/res/values-ro-rRO/strings.xml b/src/conversations/res/values-ro-rRO/strings.xml index 6cfd35fc9..7764e1b7a 100644 --- a/src/conversations/res/values-ro-rRO/strings.xml +++ b/src/conversations/res/values-ro-rRO/strings.xml @@ -8,4 +8,4 @@ Ați fost invitați la %1$s. Vă vom ghida prin procesul de creare al unui cont.\nCând alegeți %1$s ca furnizor veți putea comunica cu utilizatorii altor furnizori oferindu-le adresa dumneavoastră completă XMPP. Ați fost invitați la %1$s. Un nume de utilizator a fost deja ales pentru dumneavoastră. Vă vom ghida prin procesul de creare al unui cont.\nVeți putea comunica cu utilizatorii altor furnizori oferindu-le adresa dumneavoastră completă XMPP. Invitația serverului dumneavoastră - \ No newline at end of file + \ No newline at end of file diff --git a/src/conversations/res/values-ru/strings.xml b/src/conversations/res/values-ru/strings.xml index 2c0f0de60..49a3a5ecb 100644 --- a/src/conversations/res/values-ru/strings.xml +++ b/src/conversations/res/values-ru/strings.xml @@ -4,5 +4,8 @@ Использовать conversations.im Создать новый аккаунт У вас есть аккаунт XMPP? Если вы использовали Conversations или другой XMPP-клиент в прошлом, то скорее всего, он у вас есть. Если у вас нет аккаунта, вы можете создать его прямо сейчас.\nНекоторые провайдеры электронной почты также регистрируют аккаунты XMPP. - XMPP - это независимая сеть обмена сообщениями. Conversations позволяет вам подключиться к любому XMPP-серверу на ваш выбор.\nЕсли у вас нет сервера, предлагаем вам зарегистрировать аккаунт на conversations.im, сервер, специально предназначеный для работы с приложением Conversations. + XMPP - это независимая сеть обмена сообщениями. Conversations позволяет вам подключиться к любому XMPP-серверу на ваш выбор.\nЕсли у вас нет сервера, предлагаем вам зарегистрировать аккаунт на conversations.im, сервере, специально предназначенном для работы с Conversations. + Вас пригласили на %1$s. Мы проведём вас через процесс создания аккаунта. Аккаунт на %1$s позволит вам общаться с пользователями и на этом, и на других серверах, используя ваш полный XMPP-адрес. + Вас пригласили на %1$s. Вам уже назначили имя пользователя. Мы проведём вас через процесс создания аккаунта. Этот аккаунт позволит вам общаться с пользователями и на этом, и на других серверах, используя ваш полный XMPP-адрес. + Ваше приглашение \ No newline at end of file diff --git a/src/conversations/res/values-uk/strings.xml b/src/conversations/res/values-uk/strings.xml index 8a1a85bec..9d95077bd 100644 --- a/src/conversations/res/values-uk/strings.xml +++ b/src/conversations/res/values-uk/strings.xml @@ -8,4 +8,4 @@ Вас запросили до %1$s. Ми проведемо вас крок за кроком, щоб створити обліковий запис.\nОбираючи %1$s в якості свого постачальника, ви зможете спілкуватися з користувачами інших постачальників, для цього повідомте їм свою повну адресу XMPP. Вас запросили до %1$s. Для вас створено ім\'я користувача. Ми проведемо вас крок за кроком, щоб створити обліковий запис.\nВи зможете спілкуватися з користувачами інших постачальників, для цього повідомите їм свою повну адресу XMPP. Ваше запрошення до сервера - \ No newline at end of file + \ No newline at end of file diff --git a/src/conversations/res/values-zh-rCN/strings.xml b/src/conversations/res/values-zh-rCN/strings.xml index 66f21b7a9..0457d02b4 100644 --- a/src/conversations/res/values-zh-rCN/strings.xml +++ b/src/conversations/res/values-zh-rCN/strings.xml @@ -8,4 +8,4 @@ 您已受邀参加%1$s。 我们将指导您完成创建帐户的过程。\n选择%1$s作为提供者后,您可以通过提供其他人的完整XMPP地址与其他提供者的用户进行交流。 您已受邀参加%1$s。 已经为您选择了一个用户名。 我们将指导您完成创建帐户的过程。\n您可以通过向其他提供商的用户提供完整的XMPP地址来与他们进行交流。 你的服务器邀请 - \ No newline at end of file + \ No newline at end of file diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index eea90eeac..cc06fd1be 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -916,6 +916,7 @@ Audioanruf Videoanruf Hilfe + Zur Unterhaltung wechseln Dein Mikrofon ist nicht verfügbar Du kannst immer nur einen Anruf zur gleichen Zeit machen. Zurück zum laufenden Aufruf diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index a5e07707e..3c73ece40 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -121,11 +121,15 @@ Звук уведомления о новых сообщениях Мелодия входящего звонка Грейс-период + Время, на которое уведомления будут отключены, когда вы пользуетесь аккаунтом на другом устройстве. Дополнительно Не отправлять отчёты об ошибках + Отправляя отчеты об ошибках, вы помогаете разработке этого приложения Отчёты о получении Позволяет вашим контактам видеть, когда вы получили и прочитали их сообщения Интерфейс + OpenKeychain вызвал ошибку. + Неподходящий ключ для шифрования. Принять Произошла ошибка Ошибка @@ -137,8 +141,10 @@ Сделать снимок Удовлетворять запросы на подписки Выбранный файл не является изображением + Не удалось конвертировать изображение Файл не найден Общая ошибка ввода/вывода. Возможно, на устройстве недостаточно свободного места? + У приложения, которым вы выбрали это изображение, недостаточно прав, чтобы прочитать этот файл.\n\nПожалуйста, используйте другой файловый менеджер, чтобы выбрать это изображение. Неизвестен Временно отключён В сети @@ -150,6 +156,8 @@ Регистрация не удалась Имя пользователя уже используется Регистрация завершена + Сервер не поддерживает возможность регистрации + Неправильный токен регистрации Не удалось согласовать TLS Нарушение правил Несовместимый сервер @@ -165,14 +173,17 @@ Анонсировать OpenPGP ключ Удалить открытый ключ OpenPGP Вы действительно хотите удалить ваш OpenPGP публичный ключ из опубликованных?\nВаши собеседники не смогут больше отправлять вам зашифрованные OpenPGP сообщения. + Публичный ключ OpenPGP опубликован. Включить аккаунт Вы уверены? + Удаление аккаунта также удалит всю историю вашей переписки Запись голоса XMPP-адрес Заблокировать XMPP-адрес username@example.com Пароль Недопустимый XMPP-адрес + Нехватка памяти. Изображение слишком большое Вы хотите добавить %s в вашу адресную книгу? Информация о сервере XEP-0313: Архив сообщений @@ -181,6 +192,7 @@ XEP-0191: Команда блокирования XEP-0237: Версии списков XEP-0198: Управление потоками + XEP-0215: Обнаружение внешних служб XEP-0163: PEP (Аватары / OMEMO) XEP-0363: Загрузка по HTTP XEP-0357: Push-уведомления @@ -188,9 +200,14 @@ недоступно Отсутствие анонсирования открытых ключей Присутствие: только что + Присутствие: одну минуту назад Присутствие: %d мин. назад + Присутствие: один час назад Присутствие: %d час. назад + Присутствие: один день назад Присутствие: %d дн. назад + Зашифрованное сообщение. Пожалуйста, установите OpenKeychain для дешифрования. + Найдены новые OpenPGP зашифрованые сообщения ID OpenPGP ключа OMEMO отпечаток v\\OMEMO отпечаток @@ -212,10 +229,14 @@ Выбрать Контакт уже существует Присоединиться + канал@конференция.пример.com/никнейм + канал@конференция.пример.com Сохранить закладку Удалить закладку Уничтожить конференцию Уничтожить канал + Вы уверены, что хотите распустить эту конференцию?\n\nПредупреждение:Конференция будет полностью удалена с сервера. + Вы уверены, что хотите закрыть этот публичный канал?\n\nПредупреждение: Канал будет полностью удален с сервера. Не удалось уничтожить конференцию Не удалось уничтожить канал Редактировать тему конференции @@ -393,7 +414,7 @@ Скрыть пользователей вне сети %s печатает… %s прекратил набор - %s печатают... + %s печатают… %s перестали печатать Оповещения о наборе Позволяет вашим контактам видеть, когда вы пишете им новое сообщение @@ -440,11 +461,11 @@ Повреждено Доступность \"Отошёл\" когда экран выключен - Отмечает ваш ресурс как «отошёл» когда экран выключен + Устанавливает статус \"Отошёл\", когда экран выключен \"Не беспокоить\" в беззвучном режиме - Помечать ресурс как \"Не беспокоить\", когда устройство в беззвучном режиме + Устанавливает статус \"Не беспокоить\", когда устройство в беззвучном режиме Не доступен в режиме вибрации - Помечать ресурс как \"Не беспокоить\", когда устройство на вибрации + Устанавливает статус \"Не беспокоить\", когда устройство на вибрации Расширенные настройки подключения Показывать имя сервера и порт в настройках аккаунтов xmpp.example.com @@ -674,6 +695,7 @@ Серверу не удалось аутентифицироваться в качестве \"%s\". Сертификат подходит только для: Вы все равно хотите подключиться? Детали сертификата: + Один раз Сканеру QR-кода необходим доступ к камере Прокручивать вниз Прокручивать вниз после отправки сообщения @@ -707,6 +729,7 @@ Открепить позицию Копировать местоположение Поделиться местоположением + Направления Поделиться местоположением Показать местоположение Поделиться @@ -782,8 +805,8 @@ Вы уверены, что хотите прервать процедуру регистрации? Да Нет - Подтверждение... - Запрос SMS... + Подтверждение… + Запрос SMS… Введенный вами код некорректен. Отправленный вам код просрочен. Неизвестная ошибка сети. @@ -799,6 +822,7 @@ У вас есть ограничение скорости Слишком много попыток Вы используете устаревшую версию приложения + Обновить Этот номер телефона в данный момент авторизирован на другом устройстве. Пожалуйста, введите ваше имя, чтобы другие люди, у которых нет вас в списке контактов, знали кто вы. Ваше имя @@ -811,7 +835,7 @@ Этот канал сделает ваш XMPP-адрес публичным Электронная книга Оригинал (без сжатия) - Открыть с помощью... + Открыть с помощью… Картинка профиля Conversations Выбрать аккаунт Восстановить из резервной копии @@ -831,7 +855,7 @@ Пожалуйста, предоставьте имя для канала Пожалуйста, предоставьте XMPP-адрес Это XMPP-адрес. Пожалуйста, предоставьте имя. - Создание публичного канала... + Создание публичного канала… Этот канал уже существует Вы присоединились к существующему каналу Не удалось сохранить настройки канала @@ -868,11 +892,12 @@ Эта учетная запись уже настроена Пожалуйста, введите пароль этой учетной записи Не удалось совершить это действие - Присоединиться к публичному каналу... + Присоединиться к публичному каналу… + Приложение для обмена не предоставило право доступа к этому файлу. jabber.network Локальный сервер - Большиству пользователей следует выбрать ‘jabber.network’ для лучших предложений от всей публичной экосистемы XMPP. + Большиству пользователей следует выбрать ‘jabber.network’ для получения наиболее подходящих предложений от всей публичной экосистемы XMPP. Способ поиска каналов Резервное копирование О @@ -890,6 +915,8 @@ Вызов Занято Не удалось установить соединение + Соединение потеряно + Вызов отклонен Ошибка приложения Завершить Активный звонок @@ -902,9 +929,17 @@ Пропущен вызов Аудиозвонок Видеозвонок + Помощь Микрофон недоступен + Нельзя одновременно совершать больше одного звонка. Вернуться к текущему звонку Не удалось переключить камеру Добавить в избранные Убрать из избранных + + Просмотр %1$d участника + Просмотр %1$d участников + Просмотр %1$d участников + Просмотр %1$d участников + diff --git a/src/quicksy/res/values-ru/strings.xml b/src/quicksy/res/values-ru/strings.xml new file mode 100644 index 000000000..f36a8771a --- /dev/null +++ b/src/quicksy/res/values-ru/strings.xml @@ -0,0 +1,26 @@ + + + В Quicksy произошёл сбой + Отправляя отчёты об ошибках, вы помогаете исправить и улучшить Quicksy\nПредупреждение: Отчёт будет отправлен разработчику с вашего XMPP аккаунта. + Conversations использует стороннее приложение под названием OpenKeychain для шифровки и расшифровки сообщений и управления открытыми ключами.\nПрограмма OpenKeychain распространяется под лицензией GPLv3 и доступна через F-Droid или Google Play.\n\n(Пожалуйста, перезапустите Quicksy после установки.) + Quicksy не может зашифровать сообщение, потому что ваш собеседник не анонсирует свой открытый ключ.\n\nПожалуйста, попросите вашего собеседника настроить OpenPGP. + Quicksy не может зашифровать сообщение, потому что ваши собеседники не анонсируют их открытые ключи.\n\nПожалуйста, попросите ваших собеседников настроить OpenPGP. + Время, на которое уведомления от Quicksy будут отключены, когда вы пользуетесь аккаунтом на другом устройстве. + Отправляя отчёты об ошибках, вы помогаете в разработке Quicksy + Quicksy требуется доступ к основной файловой системе + Quicksy требуется доступ к камере + Ваше устройство использует агрессивную оптимизацию энергопотребления Quicksy, что может привести к задержке уведомлений и даже потере сообщений.\nРекомендуем ее отключить. + Ваше устройство использует агрессивную оптимизацию энергопотребления Quicksy, что может привести к задержке уведомлений и даже потере сообщений.\nСейчас появится предложение ее отключить. + Извещать собеседников, когда вы пользуетесь Quicksy + Ваша операционная система не позволяет Quicksy доступ в Интернет в фоновом режиме. Для получения уведомлений вы должны разрешить Quicksy неограниченный доступ в Интернет в режиме экономии трафика.\nQuicksy будет использовать настолько мало трафика, насколько это возможно. + Ваше устройство не позволяет отключить режим экономии трафика для Quicksy. + Чтобы продолжать получать уведомления, даже если экран выключен, вам необходимо добавить Quicksy в список защищенных приложений. + Quicksy не удалось отправить зашифрованные сообщения для %1$s. Причиной этому может быть использование получателем устаревшего сервера или приложения, которые не поддерживают OMEMO. + Quicksy требуется доступ к микрофону + Эта категория уведомлений используется для отображения постоянного уведомления о том что Quicksy работает. + Аватар для Quicksy + Quicksy не доступно в вашем регионе + Не удалось подтвердить сервер. + Неизвестная ошибка безопасности. + Время ожидания подключения к серверу вышло. + From e7e04837b608b0fcf38814a14d45440e5a3ad349 Mon Sep 17 00:00:00 2001 From: Marcin Mielniczuk Date: Sun, 12 Jul 2020 07:18:40 +0200 Subject: [PATCH 12/18] Support sending messages with ctrl+enter Currently Conversations lacks any keyboard shortcut to send a message if enter_is_send is disabled. KeyboardListener has been extended to include the original KeyEvent as an argument. fixes #3829 --- .../java/eu/siacs/conversations/ui/ConversationFragment.java | 5 +++-- .../java/eu/siacs/conversations/ui/widget/EditMessage.java | 4 ++-- src/main/res/values/strings.xml | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 90a005a69..05e02c53f 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -32,6 +32,7 @@ import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Gravity; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -2734,10 +2735,10 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } @Override - public boolean onEnterPressed() { + public boolean onEnterPressed(KeyEvent event) { SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(getActivity()); final boolean enterIsSend = p.getBoolean("enter_is_send", getResources().getBoolean(R.bool.enter_is_send)); - if (enterIsSend) { + if (enterIsSend || event.isCtrlPressed()) { sendMessage(); return true; } else { diff --git a/src/main/java/eu/siacs/conversations/ui/widget/EditMessage.java b/src/main/java/eu/siacs/conversations/ui/widget/EditMessage.java index 342867576..0687b57b9 100644 --- a/src/main/java/eu/siacs/conversations/ui/widget/EditMessage.java +++ b/src/main/java/eu/siacs/conversations/ui/widget/EditMessage.java @@ -57,7 +57,7 @@ public class EditMessage extends EmojiWrapperEditText { public boolean onKeyDown(int keyCode, KeyEvent e) { if (keyCode == KeyEvent.KEYCODE_ENTER && !e.isShiftPressed()) { lastInputWasTab = false; - if (keyboardListener != null && keyboardListener.onEnterPressed()) { + if (keyboardListener != null && keyboardListener.onEnterPressed(e)) { return true; } } else if (keyCode == KeyEvent.KEYCODE_TAB && !e.isAltPressed() && !e.isCtrlPressed()) { @@ -191,7 +191,7 @@ public class EditMessage extends EmojiWrapperEditText { } public interface KeyboardListener { - boolean onEnterPressed(); + boolean onEnterPressed(KeyEvent event); void onTypingStarted(); diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 734a015c3..e3b668dfb 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -401,7 +401,7 @@ Mark as read Input Enter is send - Use enter key to send message + Use enter key to send message. You can always use ctrl+enter to send message, even if this option is disabled. Show enter key Change the emoticons key to an enter key audio From c9e6653e33676c3df8502eb7a18d5dc24b7e7750 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 12 Jul 2020 08:28:09 +0200 Subject: [PATCH 13/18] fixups and code clean up for 'Ctrl+Enter' --- .../conversations/ui/ConversationFragment.java | 14 ++++++++------ .../siacs/conversations/ui/widget/EditMessage.java | 9 +++++---- src/main/res/values/strings.xml | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 05e02c53f..5fa034b20 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -2735,15 +2735,17 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } @Override - public boolean onEnterPressed(KeyEvent event) { - SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(getActivity()); - final boolean enterIsSend = p.getBoolean("enter_is_send", getResources().getBoolean(R.bool.enter_is_send)); - if (enterIsSend || event.isCtrlPressed()) { + public boolean onEnterPressed(final boolean isCtrlPressed) { + if (isCtrlPressed || enterIsSend()) { sendMessage(); return true; - } else { - return false; } + return false; + } + + private boolean enterIsSend() { + final SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(getActivity()); + return p.getBoolean("enter_is_send", getResources().getBoolean(R.bool.enter_is_send)); } @Override diff --git a/src/main/java/eu/siacs/conversations/ui/widget/EditMessage.java b/src/main/java/eu/siacs/conversations/ui/widget/EditMessage.java index 0687b57b9..1a1327ec4 100644 --- a/src/main/java/eu/siacs/conversations/ui/widget/EditMessage.java +++ b/src/main/java/eu/siacs/conversations/ui/widget/EditMessage.java @@ -54,13 +54,14 @@ public class EditMessage extends EmojiWrapperEditText { } @Override - public boolean onKeyDown(int keyCode, KeyEvent e) { + public boolean onKeyDown(final int keyCode, final KeyEvent e) { + final boolean isCtrlPressed = e.isCtrlPressed(); if (keyCode == KeyEvent.KEYCODE_ENTER && !e.isShiftPressed()) { lastInputWasTab = false; - if (keyboardListener != null && keyboardListener.onEnterPressed(e)) { + if (keyboardListener != null && keyboardListener.onEnterPressed(isCtrlPressed)) { return true; } - } else if (keyCode == KeyEvent.KEYCODE_TAB && !e.isAltPressed() && !e.isCtrlPressed()) { + } else if (keyCode == KeyEvent.KEYCODE_TAB && !e.isAltPressed() && !isCtrlPressed) { if (keyboardListener != null && keyboardListener.onTabPressed(this.lastInputWasTab)) { lastInputWasTab = true; return true; @@ -191,7 +192,7 @@ public class EditMessage extends EmojiWrapperEditText { } public interface KeyboardListener { - boolean onEnterPressed(KeyEvent event); + boolean onEnterPressed(boolean isCtrlPressed); void onTypingStarted(); diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index e3b668dfb..1e46347c6 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -401,7 +401,7 @@ Mark as read Input Enter is send - Use enter key to send message. You can always use ctrl+enter to send message, even if this option is disabled. + Use Enter key to send message. You can always use Ctrl+Enter to send message, even if this option is disabled. Show enter key Change the emoticons key to an enter key audio From 590deef8e936d8e3d200ff16e4f6165830ec6c5b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 12 Jul 2020 09:45:27 +0200 Subject: [PATCH 14/18] use ctrl+arrow up to correct last message. fixes #3806 --- .../conversations/entities/Conversation.java | 15 +++++++++++++++ .../eu/siacs/conversations/entities/Message.java | 7 +++---- .../conversations/ui/ConversationFragment.java | 9 +++++++++ .../conversations/ui/ConversationsActivity.java | 16 ++++++++++++++-- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index d96260957..97deda2af 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -186,6 +186,21 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl return null; } + public Message getLastEditableMessage() { + synchronized (this.messages) { + for(final Message message : Lists.reverse(this.messages)) { + if (message.isEditable()) { + if (message.isGeoUri() || message.getType() != Message.TYPE_TEXT) { + return null; + } + return message; + } + } + } + return null; + } + + public Message findUnsentMessageWithUuid(String uuid) { synchronized (this.messages) { for (final Message message : this.messages) { diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 44f7588f8..90b2bdc61 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -15,7 +15,6 @@ import java.lang.ref.WeakReference; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; -import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -613,15 +612,15 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable public boolean isLastCorrectableMessage() { Message next = next(); while (next != null) { - if (next.isCorrectable()) { + if (next.isEditable()) { return false; } next = next.next(); } - return isCorrectable(); + return isEditable(); } - private boolean isCorrectable() { + public boolean isEditable() { return getStatus() != STATUS_RECEIVED && !isCarbon(); } diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 5fa034b20..ce4cc008e 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -2748,6 +2748,15 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke return p.getBoolean("enter_is_send", getResources().getBoolean(R.bool.enter_is_send)); } + public boolean onArrowUpCtrlPressed() { + final Message lastEditableMessage = conversation == null ? null : conversation.getLastEditableMessage(); + if (lastEditableMessage != null) { + correctMessage(lastEditableMessage); + return true; + } + return false; + } + @Override public void onTypingStarted() { final XmppConnectionService service = activity == null ? null : activity.xmppConnectionService; diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java index 24e167e85..261907d5b 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java @@ -49,6 +49,7 @@ import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; import android.support.v7.widget.Toolbar; import android.util.Log; +import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; @@ -493,8 +494,19 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio } @Override - public void onSaveInstanceState(Bundle savedInstanceState) { - Intent pendingIntent = pendingViewIntent.peek(); + public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) { + if (keyCode == KeyEvent.KEYCODE_DPAD_UP && keyEvent.isCtrlPressed()) { + final ConversationFragment conversationFragment = ConversationFragment.get(this); + if (conversationFragment != null && conversationFragment.onArrowUpCtrlPressed()) { + return true; + } + } + return super.onKeyDown(keyCode, keyEvent); + } + + @Override + public void onSaveInstanceState(final Bundle savedInstanceState) { + final Intent pendingIntent = pendingViewIntent.peek(); savedInstanceState.putParcelable("intent", pendingIntent != null ? pendingIntent : getIntent()); super.onSaveInstanceState(savedInstanceState); } From 7aeb2b2740f22799807da22435dd3013946dc4eb Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 12 Jul 2020 10:15:51 +0200 Subject: [PATCH 15/18] pulled translations from transifex. re-enabled some linter warnings --- build.gradle | 2 +- src/conversations/res/values-es/strings.xml | 3 ++- .../res/values-ro-rRO/strings.xml | 3 ++- src/conversations/res/values-uk/strings.xml | 3 ++- .../conversations/entities/Conversation.java | 6 ++--- src/main/res/values-ar/strings.xml | 1 - src/main/res/values-bg/strings.xml | 1 - src/main/res/values-ca/strings.xml | 1 - src/main/res/values-cs/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 | 2 +- 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-id/strings.xml | 1 - src/main/res/values-it/strings.xml | 1 - src/main/res/values-iw/strings.xml | 1 - src/main/res/values-ja/strings.xml | 1 - src/main/res/values-ko/strings.xml | 1 - src/main/res/values-nb-rNO/strings.xml | 1 - src/main/res/values-nl/strings.xml | 1 - src/main/res/values-pl/strings.xml | 1 - src/main/res/values-pt-rBR/strings.xml | 1 - src/main/res/values-pt/strings.xml | 1 - src/main/res/values-ro-rRO/strings.xml | 2 +- src/main/res/values-ru/strings.xml | 2 +- src/main/res/values-sk/strings.xml | 1 - src/main/res/values-sr/strings.xml | 1 - src/main/res/values-sv/strings.xml | 1 - src/main/res/values-tr-rTR/strings.xml | 1 - src/main/res/values-uk/strings.xml | 2 +- src/main/res/values-vi/strings.xml | 1 - src/main/res/values-zh-rCN/strings.xml | 1 - src/main/res/values-zh-rTW/strings.xml | 1 - src/quicksy/res/values-uk/strings.xml | 26 +++++++++---------- 37 files changed, 27 insertions(+), 51 deletions(-) diff --git a/build.gradle b/build.gradle index 42c1246be..33bc7776b 100644 --- a/build.gradle +++ b/build.gradle @@ -243,7 +243,7 @@ android { } lintOptions { - disable 'ExtraTranslation', 'MissingTranslation', 'InvalidPackage', 'MissingQuantity', 'AppCompatResource' + disable 'MissingTranslation', 'InvalidPackage','AppCompatResource' } subprojects { diff --git a/src/conversations/res/values-es/strings.xml b/src/conversations/res/values-es/strings.xml index 8d952a7a2..6878b558c 100644 --- a/src/conversations/res/values-es/strings.xml +++ b/src/conversations/res/values-es/strings.xml @@ -8,4 +8,5 @@ Has sido invitado a %1$s. Te guiaremos durante el proceso de creación de la cuenta.\nCuando selecciones %1$s como proveedor podrás comunicarte con usuarios de otros servidores proporcionándoles tu dirección XMPP completa. Has sido invitado a %1$s. Un nombre de usuario ya ha sido escogido para ti. Te guiaremos durante el proceso de creación de la cuenta.\nPodrás comunicarte con otros usuarios de otros servidores proporcionándoles tu dirección XMPP completa. Tu invitación al servidor - \ No newline at end of file + Código de abastecimiento formateado incorrectamente + \ No newline at end of file diff --git a/src/conversations/res/values-ro-rRO/strings.xml b/src/conversations/res/values-ro-rRO/strings.xml index 7764e1b7a..97ca14b65 100644 --- a/src/conversations/res/values-ro-rRO/strings.xml +++ b/src/conversations/res/values-ro-rRO/strings.xml @@ -8,4 +8,5 @@ Ați fost invitați la %1$s. Vă vom ghida prin procesul de creare al unui cont.\nCând alegeți %1$s ca furnizor veți putea comunica cu utilizatorii altor furnizori oferindu-le adresa dumneavoastră completă XMPP. Ați fost invitați la %1$s. Un nume de utilizator a fost deja ales pentru dumneavoastră. Vă vom ghida prin procesul de creare al unui cont.\nVeți putea comunica cu utilizatorii altor furnizori oferindu-le adresa dumneavoastră completă XMPP. Invitația serverului dumneavoastră - \ No newline at end of file + Cod de acces formatat necorespunzător + \ No newline at end of file diff --git a/src/conversations/res/values-uk/strings.xml b/src/conversations/res/values-uk/strings.xml index 9d95077bd..787a1c94f 100644 --- a/src/conversations/res/values-uk/strings.xml +++ b/src/conversations/res/values-uk/strings.xml @@ -8,4 +8,5 @@ Вас запросили до %1$s. Ми проведемо вас крок за кроком, щоб створити обліковий запис.\nОбираючи %1$s в якості свого постачальника, ви зможете спілкуватися з користувачами інших постачальників, для цього повідомте їм свою повну адресу XMPP. Вас запросили до %1$s. Для вас створено ім\'я користувача. Ми проведемо вас крок за кроком, щоб створити обліковий запис.\nВи зможете спілкуватися з користувачами інших постачальників, для цього повідомите їм свою повну адресу XMPP. Ваше запрошення до сервера - \ No newline at end of file + Неправильно відформатований код забезпечення + \ No newline at end of file diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 97deda2af..68ad4d316 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -173,7 +173,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl public String findMostRecentRemoteDisplayableId() { final boolean multi = mode == Conversation.MODE_MULTI; synchronized (this.messages) { - for(final Message message : Lists.reverse(this.messages)) { + for (final Message message : Lists.reverse(this.messages)) { if (message.getStatus() == Message.STATUS_RECEIVED) { final String serverMsgId = message.getServerMsgId(); if (serverMsgId != null && multi) { @@ -188,7 +188,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl public Message getLastEditableMessage() { synchronized (this.messages) { - for(final Message message : Lists.reverse(this.messages)) { + for (final Message message : Lists.reverse(this.messages)) { if (message.isEditable()) { if (message.isGeoUri() || message.getType() != Message.TYPE_TEXT) { return null; @@ -514,7 +514,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl @Override public int compareTo(@NonNull Conversation another) { return ComparisonChain.start() - .compareFalseFirst(another.getBooleanAttribute(ATTRIBUTE_PINNED_ON_TOP, false), getBooleanAttribute(ATTRIBUTE_PINNED_ON_TOP,false)) + .compareFalseFirst(another.getBooleanAttribute(ATTRIBUTE_PINNED_ON_TOP, false), getBooleanAttribute(ATTRIBUTE_PINNED_ON_TOP, false)) .compare(another.getSortableTime(), getSortableTime()) .result(); } diff --git a/src/main/res/values-ar/strings.xml b/src/main/res/values-ar/strings.xml index a2ef79598..d1395e762 100644 --- a/src/main/res/values-ar/strings.xml +++ b/src/main/res/values-ar/strings.xml @@ -316,7 +316,6 @@ الرد إعتباره كمقروء أدخل للإرسال - استخدام مفتاح الدخول لإرسال رسالة عرض مفتاح الادخال تغيير مفتاح الرموز إلى مفتاح الدخول صوت diff --git a/src/main/res/values-bg/strings.xml b/src/main/res/values-bg/strings.xml index ebc28ba57..6349bd0d8 100644 --- a/src/main/res/values-bg/strings.xml +++ b/src/main/res/values-bg/strings.xml @@ -316,7 +316,6 @@ Отбелязване като прочетено Въвеждане Enter изпраща - Натискането на клавиша Enter изпраща съобщението Показване на клавиша Enter Смяна на клавиша за емотикони с клавиша Enter аудио diff --git a/src/main/res/values-ca/strings.xml b/src/main/res/values-ca/strings.xml index d2b85f8a6..b65925ff2 100644 --- a/src/main/res/values-ca/strings.xml +++ b/src/main/res/values-ca/strings.xml @@ -314,7 +314,6 @@ Marcar com llegit Entrada Entra per enviar - Utilitza el botó enter per enviar el missatge Mostra el botó enter Canviar la clau dels emoticones per un botó d\'entrada audio diff --git a/src/main/res/values-cs/strings.xml b/src/main/res/values-cs/strings.xml index 545c29215..c231f9bee 100644 --- a/src/main/res/values-cs/strings.xml +++ b/src/main/res/values-cs/strings.xml @@ -264,7 +264,6 @@ Než opět změním Vstup Enter odesílá - Použít klávesu enter pro odesílání zpráv Zobrazit klávesu enter Změnit klávesu emotikon na klávesu enter audio diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index cc06fd1be..c4d222ba8 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -401,7 +401,6 @@ Als gelesen markieren Eingabe Eingabe-Taste (Enter) sendet Nachricht - Eingabe-Taste (Enter) zum Versenden einer Nachricht verwenden Zeige Eingabe-Taste (Enter) Emoji-Taste durch Eingabe-Taste ersetzen Audio diff --git a/src/main/res/values-el/strings.xml b/src/main/res/values-el/strings.xml index 77a2279c4..c0be73378 100644 --- a/src/main/res/values-el/strings.xml +++ b/src/main/res/values-el/strings.xml @@ -347,7 +347,6 @@ Σημείωμα ως αναγνωσμένο Είσοδος Αποστολή με το πλήκτρο Enter - Χρήση του πλήκτρου Enter για την αποστολή μηνύματος Εμφάνιση του πλήκτρου Enter Αλλαγή του πλήκτρου emoticons σε πλήκτρο Enter ήχος diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 7bada1588..74cfe92a3 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -401,7 +401,6 @@ Marcar como leído Entrada Intro para enviar - Usar la tecla intro para enviar el mensaje Mostrar tecla Intro Cambiar la tecla de emoticonos por la tecla Intro audio @@ -916,6 +915,7 @@ Audio llamada Video llamada Ayuda + Cambiar a conversación Tu micrófono no está disponible Solo puedes hacer una llamada a la vez Volver a la llamada en curso diff --git a/src/main/res/values-eu/strings.xml b/src/main/res/values-eu/strings.xml index c4e8b3d96..687db96db 100644 --- a/src/main/res/values-eu/strings.xml +++ b/src/main/res/values-eu/strings.xml @@ -344,7 +344,6 @@ Irakurrita bezala markatu Sarrera Sartu teklak bidaltzen du - Sartu tekla erabili mezua bidaltzeko Sartu tekla erakutsi Aurpegieren tekla sartu teklarekin aldatu audioa diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml index 58f1ac344..0ef628729 100644 --- a/src/main/res/values-fr/strings.xml +++ b/src/main/res/values-fr/strings.xml @@ -401,7 +401,6 @@ Marquer comme lu Saisie Touche Entrée pour envoyer - Utiliser la touche Entrée pour envoyer un message. Afficher la touche Entrée Remplacer la touche Émoticônes par une touche Entrée. audio diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index 50b85e6bb..d3780645a 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -401,7 +401,6 @@ Marcar como lido Entrada Enter envía - Utilizar a tecla Enter para enviar mensaxe Mostrar a tecla Enter Cambiar a chave de emoticonas pola tecla Enter son diff --git a/src/main/res/values-hu/strings.xml b/src/main/res/values-hu/strings.xml index dd1f62576..055499efe 100644 --- a/src/main/res/values-hu/strings.xml +++ b/src/main/res/values-hu/strings.xml @@ -384,7 +384,6 @@ Megjelölés olvasottként Bevitel Küldés enterrel - Az enter billentyű használata az üzenet küldéséhez Enter billentyű megjelenítése Hangulatjelek billentyű megváltoztatása az enter billentyűre hang diff --git a/src/main/res/values-id/strings.xml b/src/main/res/values-id/strings.xml index 7700f2359..78fa9411f 100644 --- a/src/main/res/values-id/strings.xml +++ b/src/main/res/values-id/strings.xml @@ -226,7 +226,6 @@ Sampai pemberitahuan selanjutnya Masukan Enter untuk mengirim - Gunakan enter untuk mengrim pesan Tampilkan masukan kunci Mengubah kunci emoji untuk memasukan kunci audio diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml index c2d1d7d88..7ea9504ca 100644 --- a/src/main/res/values-it/strings.xml +++ b/src/main/res/values-it/strings.xml @@ -401,7 +401,6 @@ Segna come già letto Input Invio spedisce - Il tasto invio spedisce il messaggio Mostra il tasto invio Cambia il tasto delle faccine nel tasto di invio audio diff --git a/src/main/res/values-iw/strings.xml b/src/main/res/values-iw/strings.xml index 532d5c187..2427c5098 100644 --- a/src/main/res/values-iw/strings.xml +++ b/src/main/res/values-iw/strings.xml @@ -220,7 +220,6 @@ לעולם לא עד אחרית הימים לחצן Enter שולח את ההודעה - השתמש בלחצן ה-Enter כלחצן השליחה הראה את לחצן ה Enter שנה את לחצן האימוג\'י ללחצן Enter קול diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml index 6936041e7..36f223084 100644 --- a/src/main/res/values-ja/strings.xml +++ b/src/main/res/values-ja/strings.xml @@ -316,7 +316,6 @@ 既読にする 入力 Enter は送信 - Enter キーをメッセージの送信に使用します Enter キーを表示 絵文字キーを Enter キーに変更 オーディオ diff --git a/src/main/res/values-ko/strings.xml b/src/main/res/values-ko/strings.xml index 83c5053bb..f37f07a33 100644 --- a/src/main/res/values-ko/strings.xml +++ b/src/main/res/values-ko/strings.xml @@ -257,7 +257,6 @@ 나중에 알릴때까지 입력 엔터 키로 전송 - 엔터 키로 메세지를 보냅니다 엔터 키 표시 이모티콘 키를 엔터 키로 바꿉니다 오디오 diff --git a/src/main/res/values-nb-rNO/strings.xml b/src/main/res/values-nb-rNO/strings.xml index 9e9507e6a..4ecdbcbc5 100644 --- a/src/main/res/values-nb-rNO/strings.xml +++ b/src/main/res/values-nb-rNO/strings.xml @@ -285,7 +285,6 @@ Merk som lest Inndata Enter-forsendelsesknapp - Bruk enter for å sende en melding Vis enter-tast Endre smilefjas-tast til en enter-tast lyd diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml index b4ddb26d9..02f5d2e06 100644 --- a/src/main/res/values-nl/strings.xml +++ b/src/main/res/values-nl/strings.xml @@ -356,7 +356,6 @@ Markeren als gelezen Invoer Enter is versturen - Gebruik de enter-toets om berichten te versturen Toon enter-toets Verander de emoticon-toets in een enter-toets audio diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml index 6ade662c9..7180d5256 100644 --- a/src/main/res/values-pl/strings.xml +++ b/src/main/res/values-pl/strings.xml @@ -401,7 +401,6 @@ Oznacz jako przeczytane Ustawienia wprowadzania Enter wysyła - Używaj klawisza Enter do wysyłania wiadomości Pokaż klawisz Enter Zamień klawisz emotikon na klawisz Enter plik audio diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml index 547d21db1..ddddc0310 100644 --- a/src/main/res/values-pt-rBR/strings.xml +++ b/src/main/res/values-pt-rBR/strings.xml @@ -401,7 +401,6 @@ Marcar como lida Entrada Enter envia - Usa o botão Enter para enviar a mensagem. Exibir o botão Enter Altera o botão de emoticons para um botão Enter. áudio diff --git a/src/main/res/values-pt/strings.xml b/src/main/res/values-pt/strings.xml index 0e1415941..1a49ef2d9 100644 --- a/src/main/res/values-pt/strings.xml +++ b/src/main/res/values-pt/strings.xml @@ -279,7 +279,6 @@ Marcar como lida Introdução O enter envia - Use o enter para enviar a mensagem Exibir tecla enter Alterar a tecla dos emoticons para uma tecla enter áudio diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index b25555ea3..ea92aaa79 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -401,7 +401,6 @@ Marchează ca citit Opțiuni introducere text ENTER trimite - Apasă tasta ENTER pentru a trimite mesajul Arată tasta ENTER Preschimbă tasta emoticon în ENTER audio @@ -924,6 +923,7 @@ Apel audio Apel video Ajutor + Comutare la discuție Microfonul nu este disponibil Puteți avea un singur apel simultan. Reveniți la apelul în curs diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml index 3c73ece40..890d2d519 100644 --- a/src/main/res/values-ru/strings.xml +++ b/src/main/res/values-ru/strings.xml @@ -399,7 +399,6 @@ Прочитано Ввод Отправить на \"Enter\" - Клавиша \"Enter\" отправляет сообщение Показывать клавишу ввода Поменять кнопку смайликов на кнопку ввода аудио @@ -930,6 +929,7 @@ Аудиозвонок Видеозвонок Помощь + Переключиться на беседу Микрофон недоступен Нельзя одновременно совершать больше одного звонка. Вернуться к текущему звонку diff --git a/src/main/res/values-sk/strings.xml b/src/main/res/values-sk/strings.xml index 2b1bc7a5f..cd8643ff1 100644 --- a/src/main/res/values-sk/strings.xml +++ b/src/main/res/values-sk/strings.xml @@ -216,7 +216,6 @@ Nikdy Až do odvolania Enter odosiela - Použiť klávesu enter na odoslanie správy Zobraziť klávesu enter Zmeniť klávesu s emotikonmi na klávesu enter audio diff --git a/src/main/res/values-sr/strings.xml b/src/main/res/values-sr/strings.xml index 31f2d50aa..69102e87b 100644 --- a/src/main/res/values-sr/strings.xml +++ b/src/main/res/values-sr/strings.xml @@ -296,7 +296,6 @@ Означи прочитаним Унос Ентер шаље - Користи Ентер тастер за слање порука Прикажи Ентер тастер Промени тастер за емотиконе у ентер тастер звук diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml index affc4780d..2929dba55 100644 --- a/src/main/res/values-sv/strings.xml +++ b/src/main/res/values-sv/strings.xml @@ -319,7 +319,6 @@ Läsmarkera Input Skicka med enter - Använd enter-knappen för att skicka meddelande Visa enter-knappen Byt ut emoticons-tangenten mot en enter-tangent ljud diff --git a/src/main/res/values-tr-rTR/strings.xml b/src/main/res/values-tr-rTR/strings.xml index 6953e774a..de11cb3eb 100644 --- a/src/main/res/values-tr-rTR/strings.xml +++ b/src/main/res/values-tr-rTR/strings.xml @@ -271,7 +271,6 @@ İkinci bildirime kadar Girdi Enter=gönder - İleti göndermek için \"enter\" tuşunu kullan \"Enter\" tuşunu göster İfade simgesi tuşunu \"enter\" tuşu olarak değiştir ses diff --git a/src/main/res/values-uk/strings.xml b/src/main/res/values-uk/strings.xml index 0d3da3030..2f41c4e8c 100644 --- a/src/main/res/values-uk/strings.xml +++ b/src/main/res/values-uk/strings.xml @@ -401,7 +401,6 @@ Позначити як прочитане Введення Enter для надсилання - Використовувати Enter для надсилання повідомлення Показувати кнопку Enter Змінити клавішу емоційок на кнопку Enter аудіо @@ -932,6 +931,7 @@ Голосовий виклик Відеовиклик Допомога + Перейти до розмови Недоступний мікрофон Водночас можливо здійснювати лише один виклик. Назад до активного виклику diff --git a/src/main/res/values-vi/strings.xml b/src/main/res/values-vi/strings.xml index bc329d8cf..ff68350b9 100644 --- a/src/main/res/values-vi/strings.xml +++ b/src/main/res/values-vi/strings.xml @@ -246,7 +246,6 @@ Chưa từng Cho đến thông báo tiếp theo Bấm Enter để gửi - Bấm nút Enter để gửi tin nhắn Hiện nút Enter Đổi nút biểu tượng cảm xúc thành nút Enter âm thanh diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml index b94f7a156..27e8cd01c 100644 --- a/src/main/res/values-zh-rCN/strings.xml +++ b/src/main/res/values-zh-rCN/strings.xml @@ -401,7 +401,6 @@ 标记为已读 输入 点击回车发送 - 回车键发送消息 显示回车键 将表情键改为回车键 音频 diff --git a/src/main/res/values-zh-rTW/strings.xml b/src/main/res/values-zh-rTW/strings.xml index 9cbae7602..c78987f5a 100644 --- a/src/main/res/values-zh-rTW/strings.xml +++ b/src/main/res/values-zh-rTW/strings.xml @@ -260,7 +260,6 @@ 直到新的通知 輸入 回車是發送 - 用 Enter 鍵來發送訊息 顯示回車鍵 改變表情鍵為回車鍵 音訊 diff --git a/src/quicksy/res/values-uk/strings.xml b/src/quicksy/res/values-uk/strings.xml index d9069b63c..da4251850 100644 --- a/src/quicksy/res/values-uk/strings.xml +++ b/src/quicksy/res/values-uk/strings.xml @@ -1,26 +1,26 @@ - Програма дала збій - Надсилаючи траси стеків виклику Ви допомагаєте розробці цієї програми\nУвага: Це використовуватиме ваш обліковий запис XMPP, щоб надсилати траси стеків виклику розробнику. - Ця програма використовує сторонній додаток, який називається OpenKeychain, для шифрування повідомлень і впорядкування ваших публічних ключів.\n\nOpenKeychain поширюється на умова ліцензії GPLv3 й доступна в F-Droid та Google Play.\n\n(Будь ласка, перезапустіть цю програму після цього.) - Ця програма не змогла зашифрувати повідомлення, оскільки публічний ключ адресата не опубліковано.\n\nБудь ласка, попросіть адресата налаштувати OpenPGP. - Ця програма не змогла зашифрувати повідомлення, оскільки публічні ключі адресатів не опубліковано.\n\nБудь ласка, попросіть їх налаштувати OpenPGP. - Час, протягом якого ця програма дотримується тиші після активності на іншому пристрої. - Надсилаючи траси стеків виклику, ви допомагаєте розробці цієї програми. - Ця програма потребує доступу до зовнішнього сховища - Ця програма потребує доступу до камери + Відмова застосунку + Надсилаючи траси стеків виклику, ви допомагаєте у розробці цього застосунку.\nУвага: Це використовуватиме ваш обліковий запис XMPP, щоб надсилати траси стеків виклику розробнику. + Цей застосунок використовує сторонній застосунок, який називається OpenKeychain, для шифрування повідомлень і впорядкування ваших публічних ключів.\n\nOpenKeychain поширюється на умова ліцензії GPLv3 й доступна в F-Droid та Google Play.\n\n(Будь ласка, перезапустіть цю програму після цього.) + Застосунок не зміг зашифрувати повідомлення, оскільки публічний ключ адресата не опубліковано.\n\nБудь ласка, попросіть адресата налаштувати OpenPGP. + Застосунок не зміг зашифрувати повідомлення, оскільки публічні ключі адресатів не опубліковано.\n\nБудь ласка, попросіть їх налаштувати OpenPGP. + Час, протягом якого застосунок дотримується тиші після активності на іншому пристрої. + Надсилаючи траси стеків виклику, ви допомагаєте розробці цього застосунку. + Цей застосунок потребує доступу до зовнішнього сховища + Цей застосунок потребує доступу до камери Ваш пристрій використовує посилену оптимізацію батареї для Quicksy, що може призвести до затримок у отриманні сповіщень або навіть втраті повідомлень.\nlt Рекомендується вимкнути цю функцію. Ваш пристрій використовує посилену оптимізацію батареї для Quicksy, що може призвести до затримок у отриманні сповіщень або навіть втраті повідомлень.\n\n Ми вас попросимо вимкнути цю функцію. Дозволити всім вашим контактам знати, коли ви використовуєте цю програму. Операційна система обмежує цю програму в доступі до Інтернету, коли вона не на екрані. Щоб отримувати сповіщення про нові повідомлення, слід дозволити цій програмі доступ, коли ввімкнено заощадження трафіку.\nЦя програма все одно намагатиметься заощадити трафік, коли можливо. Цей пристрій не надає можливості зробити виняток щодо заощадження трафіку для цієї програми. Щоб продовжувати отримувати сповіщення, навіть коли екран вимкнуто, потрібно додати цю програму до списку захищених. - Програма не може надіслати зашифроване повідомлення до %1$s. Можливо, це обумовлено тим, що адресат користується застарілим сервером або програмою, яка не підтримує OMEMO. - Програма потребує доступу до мікрофона + Застосунок не може надіслати зашифроване повідомлення до %1$s. Можливо, це обумовлено тим, що адресат користується застарілим сервером або програмою, яка не підтримує OMEMO. + Цей застосунок потребує доступу до мікрофона Цей вид сповіщень показує постійне сповіщення про те, що ця програма працює. Зображення профілю для Quicksy - Ця програма не доступна у Вашій країні. - Автентичність сервера не підтверджено + Цей застосунок не доступний у вашій країні. + Автентичність сервера не підтверджено. Невідома помилка безпеки. Вичерпано час для встановлення з\'єднання із сервером. From 9e6f7237af368fe09b011822256e3bf0bcfc7686 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sun, 12 Jul 2020 12:31:13 +0200 Subject: [PATCH 16/18] use smaller image previews on narrow screens --- .../conversations/ui/adapter/MessageAdapter.java | 4 ++-- src/main/res/values-w384dp/dimens.xml | 15 ++++++++------- src/main/res/values/dimens.xml | 1 + 3 files changed, 11 insertions(+), 9 deletions(-) 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 662f03c93..02e925f7d 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -555,7 +555,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie viewHolder.audioPlayer.setVisibility(View.GONE); viewHolder.image.setVisibility(View.VISIBLE); final FileParams params = message.getFileParams(); - final double target = metrics.density * 288; + final float target = activity.getResources().getDimension(R.dimen.image_preview_width); final int scaledW; final int scaledH; if (Math.max(params.height, params.width) * metrics.density <= target) { @@ -571,7 +571,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie scaledW = (int) target; scaledH = (int) (params.height / ((double) params.width / target)); } - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(scaledW, scaledH); + final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(scaledW, scaledH); layoutParams.setMargins(0, (int) (metrics.density * 4), 0, (int) (metrics.density * 4)); viewHolder.image.setLayoutParams(layoutParams); activity.loadBitmap(message, viewHolder.image); diff --git a/src/main/res/values-w384dp/dimens.xml b/src/main/res/values-w384dp/dimens.xml index 4a29d6f40..4f3550ab5 100644 --- a/src/main/res/values-w384dp/dimens.xml +++ b/src/main/res/values-w384dp/dimens.xml @@ -1,9 +1,10 @@ - - - 12sp - 288dp - 72dp - 64dp - 288dp + + + 12sp + 288dp + 288dp + 72dp + 64dp + 288dp diff --git a/src/main/res/values/dimens.xml b/src/main/res/values/dimens.xml index 215f11a14..069c19edc 100644 --- a/src/main/res/values/dimens.xml +++ b/src/main/res/values/dimens.xml @@ -10,6 +10,7 @@ 11sp 224dp + 224dp 16dp 80dp From fd68bfb8ca391d712fcc996f075ff536ff91831a Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 13 Jul 2020 17:34:49 +0200 Subject: [PATCH 17/18] pulled translations from transifex --- src/conversations/res/values-fr/strings.xml | 3 ++- src/main/res/values-de/strings.xml | 7 ++++--- src/main/res/values-es/strings.xml | 1 + src/main/res/values-gl/strings.xml | 2 ++ src/main/res/values-ro-rRO/strings.xml | 1 + 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/conversations/res/values-fr/strings.xml b/src/conversations/res/values-fr/strings.xml index 7e616d601..1ce216954 100644 --- a/src/conversations/res/values-fr/strings.xml +++ b/src/conversations/res/values-fr/strings.xml @@ -8,4 +8,5 @@ Vous avez été invité à %1$s. Nous allons vous guider à travers le processus de création d’un compte.\nEn choisissant %1$s comme fournisseur, vous pourrez communiquer avec les utilisateurs des autres fournisseurs en leur donnant votre adresse XMPP complète. Vous avez été invité à %1$s. Un nom d’utilisateur a déjà été choisi pour vous. Nous allons vous guider à travers le processus de création d’un compte.\nVous pourrez communiquer avec les utilisateurs des autres fournisseurs en leur donnant votre adresse XMPP complète. Votre invitation au serveur - \ No newline at end of file + Code de provisionnement mal formaté + \ No newline at end of file diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml index c4d222ba8..d301dabaa 100644 --- a/src/main/res/values-de/strings.xml +++ b/src/main/res/values-de/strings.xml @@ -400,9 +400,10 @@ Antworten Als gelesen markieren Eingabe - Eingabe-Taste (Enter) sendet Nachricht - Zeige Eingabe-Taste (Enter) - Emoji-Taste durch Eingabe-Taste ersetzen + Eingabetaste sendet Nachricht + Nutze die Eingabetaste zum Versenden einer Nachricht. Strg+Eingabetaste sendet die Nachricht unabhängig von dieser Einstellung. + Zeige Eingabetaste + Emoji-Taste durch Eingabetaste ersetzen Audio Video Bild diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml index 74cfe92a3..fa8f782cc 100644 --- a/src/main/res/values-es/strings.xml +++ b/src/main/res/values-es/strings.xml @@ -401,6 +401,7 @@ Marcar como leído Entrada Intro para enviar + Utilizar la tecla Enter para enviar un mensaje. Siempre puedes usar Ctrl+Enter para enviar un mensaje, incluso si esta opción está deshabilitada. Mostrar tecla Intro Cambiar la tecla de emoticonos por la tecla Intro audio diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index d3780645a..db1eceb20 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -401,6 +401,7 @@ Marcar como lido Entrada Enter envía + Usa a tecla Enter para enviar a mensaxe. Igualmente poderás usar Ctrl+Enter para enviar, incluso se esta opción está desactivada. Mostrar a tecla Enter Cambiar a chave de emoticonas pola tecla Enter son @@ -915,6 +916,7 @@ Chamada de audio Chamada de vídeo Axuda + Ir á conversa O micrófono non está dispoñible Só podes manter unha chamada en cada momento. Voltar á chamada activa diff --git a/src/main/res/values-ro-rRO/strings.xml b/src/main/res/values-ro-rRO/strings.xml index ea92aaa79..610cc7d60 100644 --- a/src/main/res/values-ro-rRO/strings.xml +++ b/src/main/res/values-ro-rRO/strings.xml @@ -401,6 +401,7 @@ Marchează ca citit Opțiuni introducere text ENTER trimite + Apasă tasta Enter pentru a trimite mesajul. Puteți mereu apăsa Ctrl-Enter pentru a trimite mesajul, chiar dacă această opțiune nu este activată. Arată tasta ENTER Preschimbă tasta emoticon în ENTER audio From cb9623703d9b2c30230bcd751977099228f7e4b4 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Mon, 13 Jul 2020 17:35:06 +0200 Subject: [PATCH 18/18] version bump to 2.8.9 + changelog --- CHANGELOG.md | 7 +++++++ build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/395.txt | 3 +++ 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/395.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index feb9f314e..a24790fa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # Changelog +### Version 2.8.9 + +* add 'Return to chat' to audio call screen +* Improve keyboard shortcuts +* bug fixes + ### Version 2.8.8 + * Fixed notifications not showing up under certain conditions * Fixed compatibility issues and crashes related to A/V calls diff --git a/build.gradle b/build.gradle index 33bc7776b..636184d05 100644 --- a/build.gradle +++ b/build.gradle @@ -95,8 +95,8 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 28 - versionCode 394 - versionName "2.8.8" + versionCode 395 + versionName "2.8.9" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" resValue "string", "applicationId", applicationId diff --git a/fastlane/metadata/android/en-US/changelogs/395.txt b/fastlane/metadata/android/en-US/changelogs/395.txt new file mode 100644 index 000000000..76a654338 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/395.txt @@ -0,0 +1,3 @@ +* add 'Return to chat' to audio call screen +* Improve keyboard shortcuts +* bug fixes