diff --git a/BUILDING.md b/BUILDING.md
new file mode 100644
index 000000000..ea58e1d15
--- /dev/null
+++ b/BUILDING.md
@@ -0,0 +1,257 @@
+# Building and Testing
+
+This document describes how to set up the build environment,
+build and test the app. Before diving into developing, please
+first read [CONTRIBUTING.md](./CONTRIBUTING.md) for general
+contribution hints and conventions.
+
+Please follow all steps precisely.
+If you run into troubles,
+ask on one of the [communication channels](https://delta.chat/contribute) for help
+
+
+## Check Out Repository
+
+When checking out _deltachat-android_, make sure also to check out the
+subproject _deltachat-core-rust_:
+
+- When using Git, you can do this initially by
+ `$ git clone --recursive https://github.com/deltachat/deltachat-android`
+ or later by `git submodule update --init --recursive`. If you do this in your
+ home directory, this results in the folder `~/deltachat-android` which is just fine.
+
+## Generate JSON-RPC bindings
+
+To generate the JSON-RPC bindings (ex. `chat.delta.rpc.*` package)
+install the [dcrpcgen tool](https://github.com/chatmail/dcrpcgen)
+then generate the `schema.json` file:
+
+```
+# install deltachat-rpc-server program:
+cargo install --path ./jni/deltachat-core-rust/deltachat-rpc-server
+# check the version of core matches:
+deltachat-rpc-server --version
+# generate the schema:
+deltachat-rpc-server --openrpc > schema.json
+```
+
+then pass the schema file to the `dcrpcgen` tool to generate the
+code:
+
+```
+dcrpcgen java --schema schema.json -o ./src/main/java/
+```
+
+## Build Using Nix
+
+The repository contains [Nix](https://nixos.org/) development environment
+described in `flake.nix` file.
+If you don't have Nix installed,
+the easiest way is to follow the [Lix installation instructions](https://lix.systems/install/)
+as this results in a setup with [Flakes](https://nixos.wiki/wiki/Flakes) feature enabled out of the box
+and can be cleanly uninstalled with `/nix/nix-installer uninstall` once you don't need it anymore.
+
+Once you have Nix with Flakes feature set up start the development environment shell:
+```
+nix develop
+```
+Nix development environment contains Rust with cross-compilation toolchains and Android SDK.
+
+To [build an APK](https://developer.android.com/studio/build/building-cmdline) run the following 2 steps.
+Note that the first step may take some time to build for all architectures. You can optionally read
+[the first comment block in the `ndk-make.sh` script](https://github.com/deltachat/deltachat-android/blob/master/scripts/ndk-make.sh)
+for pointers on how to build for a specific architecture.
+```
+$ scripts/ndk-make.sh
+$ ./gradlew assembleDebug
+```
+
+Resulting APK files can be found in
+`build/outputs/apk/gplay/debug/` and
+`build/outputs/apk/fat/debug/`.
+
+## Build Using Dockerfile
+
+Another way to build APK is to use provided `Dockerfile`
+with [Docker](https://www.docker.com/) or [Podman](https://podman.io/).
+Podman is a drop-in replacement for Docker that does not require root privileges.
+
+If you don't have Docker or Podman setup yet, read [how to setup Podman](#setup-podman)
+below. If you don't want to use Docker or Podman, read [how to manually install the
+build environment](#install-build-environment).
+
+First, build the image `deltachat-android` by running
+```
+podman build --build-arg UID=$(id -u) --build-arg GID=$(id -g) . -t deltachat-android
+```
+or
+```
+docker build --build-arg UID=$(id -u) --build-arg GID=$(id -g) . -t deltachat-android
+```
+
+Then, run the image:
+```
+podman run --userns=keep-id -it --name deltachat -v $(pwd):/home/app:z -w /home/app localhost/deltachat-android
+```
+or
+```
+docker run -it --name deltachat -v $(pwd):/home/app:z -w /home/app localhost/deltachat-android
+```
+
+You can leave the container with Ctrl+D or by typing `exit` and re-enter it with
+`docker start -ia deltachat` or `podman start -ia deltachat`.
+
+Within the container, install toolchains and build the native library:
+```
+deltachat@6012dcb974fe:/home/app$ scripts/install-toolchains.sh
+deltachat@6012dcb974fe:/home/app$ scripts/ndk-make.sh
+```
+
+Then, [build an APK](https://developer.android.com/studio/build/building-cmdline):
+```
+deltachat@6012dcb974fe:/home/app$ ./gradlew assembleDebug
+```
+
+### Troubleshooting
+
+- Executing `./gradlew assembleDebug` inside the container fails with `The SDK directory '/home/user/Android/Sdk' does not exist.`:
+
+ The problem is that Android Studio (outside the container) automatically creates a file `local.properties` with a content like `sdk.dir=/home/username/Android/Sdk`,
+ so, Gradle-inside-the-container looks for the Sdk at `/home/username/Android/Sdk`, where it can't find it.
+ You could:
+ - either: remove the file or just the line starting with `sdk.dir`
+ - or: run `./gradlew assembleDebug` from outside the container (however, there may be incompatibility issues if different versions are installed inside and outside the container)
+
+- Running the image fails with `ERRO[0000] The storage 'driver' option must be set in /etc/containers/storage.conf, guarantee proper operation.`:
+
+ In /etc/containers/storage.conf, replace the line: `driver = ""` with: `driver = "overlay"`.
+ You can also set the `driver` option to something else, you just need to set it to _something_.
+ [Read about possible options here](https://github.com/containers/storage/blob/master/docs/containers-storage.conf.5.md#storage-table).
+
+## Setup Podman
+
+These instructions were only tested on a Manjaro machine so far. If anything doesn't work, please open an issue.
+
+First, [Install Podman](https://podman.io/getting-started/installation).
+
+Then, if you want to run Podman without root, run:
+```
+sudo touch /etc/subgid
+sudo touch /etc/subuid
+sudo usermod --add-subuids 165536-231072 --add-subgids 165536-231072 yourusername
+```
+(replace `yourusername` with your username).
+See https://wiki.archlinux.org/index.php/Podman#Rootless_Podman for more information.
+
+## Install Build Environment (without Docker or Podman)
+
+To setup build environment manually:
+- _Either_, in Android Studio, go to "Tools / SDK Manager / SDK Tools", enable "Show Package Details",
+ select "CMake" and the desired NDK (install the same NDK version as the [Dockerfile](https://github.com/deltachat/deltachat-android/blob/master/Dockerfile)), hit "Apply".
+- _Or_ read [Dockerfile](https://github.com/deltachat/deltachat-android/blob/master/Dockerfile) and mimic what it does.
+
+Then, in both cases, install Rust using [rustup](https://rustup.rs/)
+and Rust toolchains for cross-compilation by executing `scripts/install-toolchains.sh`.
+
+Then, configure `ANDROID_NDK_ROOT` environment variable to point to the Android NDK
+installation directory e.g. by adding this to your `.bashrc`:
+
+```bash
+export ANDROID_NDK_ROOT=${HOME}/Android/Sdk/ndk/[version] # (or wherever your NDK is) Note that there is no `/` at the end!
+export PATH=${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/:${ANDROID_NDK_ROOT}
+```
+
+After that, call `scripts/ndk-make.sh` in the root directory to build core-rust.
+Afterwards run the project in Android Studio. The project requires API 25.
+
+With chance, that's it :) - if not, read on how to set up a proper development
+environment.
+
+
+## Install Development Environment
+
+1. Some libs required by Android Studio may be missing on 64 bit Linux machines
+ [Source](https://developer.android.com/studio/install.html)], so for Ubuntu execute
+ `$ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386`
+ and for Fedora execute
+ `$ sudo yum install zlib.i686 ncurses-libs.i686 bzip2-libs.i686`.
+
+2. Download Android Studio from (android-studio-ide-...-linux.zip)
+ and unpack the archive which contains a single folder called `android-studio`;
+ move this folder e.g. to `~/android-studio`.
+
+3. To launch Android Studio for the first time, open a terminal, navigate to
+ `~/android-studio/bin`, execute `./studio.sh` and use all the standard values
+ from the wizard.
+
+4. Android Studio now asks you if you want to open an existing project;
+ choose `~/deltachat-android` as created in the "Build" chapter (Android Studio starts to
+ build the project, however, there are some steps missing before this will
+ succeed).
+
+5. If components are missing, click on the corresponding error
+ message and install eg. required SDKs and the "Build-Tools" (you should
+ also find the option at "Tools / Android / SDK Manager / SDK Platforms").
+ Now the build should succeed - but the app still misses the native part.
+
+6. Download Android NDK from
+ [NDK Archives](https://developer.android.com/ndk/downloads)
+ and extract the archive containing a single folder
+ called something like `android-ndk-r23b-linux`; move this folder e.g. to `~/android-ndk`.
+
+7. Export the folder path to your environment as `ANDROID_NDK_ROOT` and add it to `PATH`.
+ You can achieve this e.g. by adding this to your `.bashrc`
+ ```bash
+ export ANDROID_NDK_ROOT=${HOME}/android-ndk
+ export PATH=${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/:${ANDROID_NDK_ROOT}
+ ```
+
+## Run UI Tests and Benchmarks
+
+- You don't necessarily need a dedicated testing device.
+ Backup your current account first, maybe there are some bugs in switching accounts.
+
+- You can run benchmarks on either an emulated device or a real device.
+ You need at least Android 9. For better benchmark results,
+ you should run the benchmark on a real device and make sure that the core is compiled in release mode.
+
+- Disable animations on your device, otherwise the test may fail:
+ at "Developer options"
+ set all of "Window animation scale", "Transition animation scale" and "Animator duration scale" to 0x
+
+- In Android Studio: "File" / "Sync project with gradle files"
+
+- In Android Studio: "Run" / "Edit configurations" / "+" / "Android Instrumented test":
+ Either select a specific class or select "All in Module" / "OK" /
+ Select your configuration in the toolbar / Click on the green "run" button in the toolbar to run the tests
+
+### Get the benchmark results
+
+When the benchmark is done, you will get a result like
+`MEASURED RESULTS (Benchmark) - Going thorough all 10 chats: 11635,11207,11363,11352,11279,11183,11137,11145,11032,11057`.
+You can paste `11635,11207,11363,11352,11279,11183,11137,11145,11032,11057`
+into a cell in a LibreOffice spreadsheet, do "Data" / "Text to columns",
+choose `,` as a separator, hit "OK", and create a diagram.
+
+### Run online tests
+
+For some tests, you need to provide the credentials to an actual email account.
+You have 2 ways to do this:
+
+1. (Recommended): Put them into the file ~/.gradle/gradle.properties (create it if it doesn't exist):
+ ```
+ TEST_ADDR=youraccount@yourdomain.org
+ TEST_MAIL_PW=youpassword
+ ```
+
+2. Or set them via environment variables.
+
+## Decoding Symbols in Crash Reports
+
+```
+$ANDROID_NDK_ROOT/ndk-stack --sym obj/local/armeabi-v7a --dump crash.txt > decoded.txt
+```
+
+`obj/local/armeabi-v7a` is the extracted path from `deltachat-gplay-release-X.X.X.apk-symbols.zip` file from https://download.delta.chat/android/symbols/
+
+Replace `armeabi-v7a` by the correct architecture the logs come from (can be guessed by trial and error)
diff --git a/CHANGELOG-upstream.md b/CHANGELOG-upstream.md
index a1c3d4e81..05b4ea5f5 100644
--- a/CHANGELOG-upstream.md
+++ b/CHANGELOG-upstream.md
@@ -1,6 +1,7 @@
# Delta Chat Android Changelog
-## Unreleased
+## v2.22.0
+2025-10
* target Android 15
* improve readability of info messages in dark mode
@@ -16,7 +17,7 @@
* show dialog if user has permanently denied camera permission and tries to take picture for group avatar
* several small fixes and improvements
* add experimental built-in calls
-* update to core 2.20.0
+* update to core 2.22.0
## v2.11.0
2025-08
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 61f2e74d8..49414fe1b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -45,7 +45,7 @@ Some rough ideas, that may be helpful when thinking about how to enhance things:
## Contributing Code
-The [README](./README.md) explains in detail how to set up the build environment.
+The [BUILDING.md](./BUILDING.md) file explains in detail how to set up the build environment.
Please follow all steps precisely.
If you run into troubles,
ask on one of the [communication channels](https://delta.chat/contribute) for help.
diff --git a/build.gradle b/build.gradle
index 2163795b8..c70e3c808 100644
--- a/build.gradle
+++ b/build.gradle
@@ -33,8 +33,8 @@ android {
useLibrary 'org.apache.http.legacy'
defaultConfig {
- versionCode 30000729
- versionName "2.20.0"
+ versionCode 30000730
+ versionName "2.22.0"
applicationId "chat.delta.lite"
multiDexEnabled true
diff --git a/jni/deltachat-core-rust b/jni/deltachat-core-rust
index fc0fe1bd0..73db91266 160000
--- a/jni/deltachat-core-rust
+++ b/jni/deltachat-core-rust
@@ -1 +1 @@
-Subproject commit fc0fe1bd0610f3d9d460e9f47e3fc656c599d8be
+Subproject commit 73db91266ec4a377718a26caed2e54efc177e070
diff --git a/src/main/java/com/b44t/messenger/util/concurrent/ListenableFuture.java b/src/main/java/com/b44t/messenger/util/concurrent/ListenableFuture.java
deleted file mode 100644
index 9b5f252c1..000000000
--- a/src/main/java/com/b44t/messenger/util/concurrent/ListenableFuture.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.b44t.messenger.util.concurrent;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-
-public interface ListenableFuture extends Future {
- void addListener(Listener listener);
-
- public interface Listener {
- public void onSuccess(T result);
- public void onFailure(ExecutionException e);
- }
-}
diff --git a/src/main/java/com/b44t/messenger/util/concurrent/SettableFuture.java b/src/main/java/com/b44t/messenger/util/concurrent/SettableFuture.java
deleted file mode 100644
index 003f93b8a..000000000
--- a/src/main/java/com/b44t/messenger/util/concurrent/SettableFuture.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package com.b44t.messenger.util.concurrent;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-public class SettableFuture implements ListenableFuture {
-
- private final List> listeners = new LinkedList<>();
-
- private boolean completed;
- private boolean canceled;
- private volatile T result;
- private volatile Throwable exception;
-
- public SettableFuture() { }
-
- public SettableFuture(T value) {
- this.result = value;
- this.completed = true;
- }
-
- @Override
- public synchronized boolean cancel(boolean mayInterruptIfRunning) {
- if (!completed && !canceled) {
- canceled = true;
- return true;
- }
-
- return false;
- }
-
- @Override
- public synchronized boolean isCancelled() {
- return canceled;
- }
-
- @Override
- public synchronized boolean isDone() {
- return completed;
- }
-
- public boolean set(T result) {
- synchronized (this) {
- if (completed || canceled) return false;
-
- this.result = result;
- this.completed = true;
-
- notifyAll();
- }
-
- notifyAllListeners();
- return true;
- }
-
- public boolean setException(Throwable throwable) {
- synchronized (this) {
- if (completed || canceled) return false;
-
- this.exception = throwable;
- this.completed = true;
-
- notifyAll();
- }
-
- notifyAllListeners();
- return true;
- }
-
- public void deferTo(ListenableFuture other) {
- other.addListener(new Listener() {
- @Override
- public void onSuccess(T result) {
- SettableFuture.this.set(result);
- }
-
- @Override
- public void onFailure(ExecutionException e) {
- SettableFuture.this.setException(e.getCause());
- }
- });
- }
-
- @Override
- public synchronized T get() throws InterruptedException, ExecutionException {
- while (!completed) wait();
-
- if (exception != null) throw new ExecutionException(exception);
- else return result;
- }
-
- @Override
- public synchronized T get(long timeout, TimeUnit unit)
- throws InterruptedException, ExecutionException, TimeoutException
- {
- long startTime = System.currentTimeMillis();
-
- while (!completed && System.currentTimeMillis() - startTime > unit.toMillis(timeout)) {
- wait(unit.toMillis(timeout));
- }
-
- if (!completed) throw new TimeoutException();
- else return get();
- }
-
- @Override
- public void addListener(Listener listener) {
- synchronized (this) {
- listeners.add(listener);
-
- if (!completed) return;
- }
-
- notifyListener(listener);
- }
-
- private void notifyAllListeners() {
- List> localListeners;
-
- synchronized (this) {
- localListeners = new LinkedList<>(listeners);
- }
-
- for (Listener listener : localListeners) {
- notifyListener(listener);
- }
- }
-
- private void notifyListener(Listener listener) {
- if (exception != null) listener.onFailure(new ExecutionException(exception));
- else listener.onSuccess(result);
- }
-}
diff --git a/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java
index 5fcb48ad9..e5f86e0bd 100644
--- a/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java
+++ b/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java
@@ -1,7 +1,5 @@
package org.thoughtcrime.securesms;
-import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_VERIFIED_ONE_ON_ONE_CHATS;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -150,21 +148,6 @@ public class ApplicationContext extends MultiDexApplication {
Log.i("DeltaChat", "shutting down event handler");
}, "eventThread").start();
- // migrating global notifications pref. to per-account config, added 10/July/24
- final String NOTIFICATION_PREF = "pref_key_enable_notifications";
- boolean isMuted = !Prefs.getBooleanPreference(this, NOTIFICATION_PREF, true);
- if (isMuted) {
- for (int accId : dcAccounts.getAll()) {
- dcAccounts.getAccount(accId).setMuted(true);
- }
- Prefs.removePreference(this, NOTIFICATION_PREF);
- }
- // /migrating global notifications
-
- for (int accountId : allAccounts) {
- dcAccounts.getAccount(accountId).setConfig(CONFIG_VERIFIED_ONE_ON_ONE_CHATS, "1");
- }
-
// set translations before starting I/O to avoid sending untranslated MDNs (issue #2288)
DcHelper.setStockTranslations(this);
diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java
index c3cbc415d..6b09a674a 100644
--- a/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java
+++ b/src/main/java/org/thoughtcrime/securesms/ConversationActivity.java
@@ -74,8 +74,6 @@ import com.b44t.messenger.DcContact;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.DcMsg;
-import com.b44t.messenger.util.concurrent.ListenableFuture;
-import com.b44t.messenger.util.concurrent.SettableFuture;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.UriAttachment;
@@ -130,6 +128,8 @@ import java.util.concurrent.ExecutionException;
import chat.delta.rpc.Rpc;
import chat.delta.rpc.RpcException;
+import chat.delta.util.ListenableFuture;
+import chat.delta.util.SettableFuture;
/**
* Activity for displaying a message thread, as well as
diff --git a/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java b/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java
index 6c128b943..18702517f 100644
--- a/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java
+++ b/src/main/java/org/thoughtcrime/securesms/ConversationListActivity.java
@@ -204,7 +204,8 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
String archProperty = System.getProperty("os.arch");
String arch;
- if (archProperty.startsWith("armv7")) arch = "armeabi-v7a";
+ // armv8l is 32 bit mode in 64 bit CPU:
+ if (archProperty.startsWith("armv7") || archProperty.startsWith("armv8l")) arch = "armeabi-v7a";
else if (archProperty.equals("aarch64")) arch = "arm64-v8a";
else if (archProperty.equals("i686")) arch = "x86";
else if (archProperty.equals("x86_64")) arch = "x86_64";
diff --git a/src/main/java/org/thoughtcrime/securesms/RegistrationActivity.java b/src/main/java/org/thoughtcrime/securesms/RegistrationActivity.java
index df6408066..7d1012408 100644
--- a/src/main/java/org/thoughtcrime/securesms/RegistrationActivity.java
+++ b/src/main/java/org/thoughtcrime/securesms/RegistrationActivity.java
@@ -46,8 +46,6 @@ import androidx.constraintlayout.widget.Group;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEvent;
import com.b44t.messenger.DcProvider;
-import com.b44t.messenger.util.concurrent.ListenableFuture;
-import com.b44t.messenger.util.concurrent.SettableFuture;
import com.google.android.material.textfield.TextInputEditText;
import org.thoughtcrime.securesms.connect.DcEventCenter;
@@ -68,6 +66,8 @@ import chat.delta.rpc.RpcException;
import chat.delta.rpc.types.EnteredCertificateChecks;
import chat.delta.rpc.types.EnteredLoginParam;
import chat.delta.rpc.types.Socket;
+import chat.delta.util.ListenableFuture;
+import chat.delta.util.SettableFuture;
public class RegistrationActivity extends BaseActionBarActivity implements DcEventCenter.DcEventDelegate {
diff --git a/src/main/java/org/thoughtcrime/securesms/audio/AudioRecorder.java b/src/main/java/org/thoughtcrime/securesms/audio/AudioRecorder.java
index 8eb99cd60..0bfd9decf 100644
--- a/src/main/java/org/thoughtcrime/securesms/audio/AudioRecorder.java
+++ b/src/main/java/org/thoughtcrime/securesms/audio/AudioRecorder.java
@@ -8,9 +8,6 @@ import android.util.Pair;
import androidx.annotation.NonNull;
-import com.b44t.messenger.util.concurrent.ListenableFuture;
-import com.b44t.messenger.util.concurrent.SettableFuture;
-
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.ThreadUtil;
@@ -19,6 +16,9 @@ import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
+import chat.delta.util.ListenableFuture;
+import chat.delta.util.SettableFuture;
+
public class AudioRecorder {
private static final String TAG = AudioRecorder.class.getSimpleName();
diff --git a/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java b/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java
index b7726b67e..ed8bf0255 100644
--- a/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java
+++ b/src/main/java/org/thoughtcrime/securesms/components/ConversationItemThumbnail.java
@@ -16,8 +16,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
-import com.b44t.messenger.util.concurrent.ListenableFuture;
-
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
import org.thoughtcrime.securesms.mms.GlideRequests;
@@ -28,6 +26,8 @@ import org.thoughtcrime.securesms.util.Util;
import java.util.concurrent.ExecutionException;
+import chat.delta.util.ListenableFuture;
+
public class ConversationItemThumbnail extends FrameLayout {
private static final Paint LIGHT_THEME_OUTLINE_PAINT = new Paint();
diff --git a/src/main/java/org/thoughtcrime/securesms/components/GlideDrawableListeningTarget.java b/src/main/java/org/thoughtcrime/securesms/components/GlideDrawableListeningTarget.java
index c7b7f61fc..9d47e18fe 100644
--- a/src/main/java/org/thoughtcrime/securesms/components/GlideDrawableListeningTarget.java
+++ b/src/main/java/org/thoughtcrime/securesms/components/GlideDrawableListeningTarget.java
@@ -5,9 +5,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.widget.ImageView;
-import com.b44t.messenger.util.concurrent.SettableFuture;
import com.bumptech.glide.request.target.DrawableImageViewTarget;
+import chat.delta.util.SettableFuture;
+
public class GlideDrawableListeningTarget extends DrawableImageViewTarget {
private final SettableFuture loaded;
diff --git a/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java b/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java
index afa0c191f..16cfb012d 100644
--- a/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java
+++ b/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java
@@ -23,8 +23,6 @@ import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import com.b44t.messenger.DcMsg;
-import com.b44t.messenger.util.concurrent.ListenableFuture;
-import com.b44t.messenger.util.concurrent.SettableFuture;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.animation.AnimationCompleteListener;
@@ -42,6 +40,9 @@ import org.thoughtcrime.securesms.util.guava.Optional;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
+import chat.delta.util.ListenableFuture;
+import chat.delta.util.SettableFuture;
+
public class InputPanel extends ConstraintLayout
implements MicrophoneRecorderView.Listener,
KeyboardAwareLinearLayout.OnKeyboardShownListener,
diff --git a/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java b/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java
index c88fccf64..f57946ccf 100644
--- a/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java
+++ b/src/main/java/org/thoughtcrime/securesms/components/ThumbnailView.java
@@ -14,8 +14,6 @@ import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.UiThread;
-import com.b44t.messenger.util.concurrent.ListenableFuture;
-import com.b44t.messenger.util.concurrent.SettableFuture;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.thoughtcrime.securesms.R;
@@ -32,6 +30,9 @@ import java.util.Locale;
import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
+import chat.delta.util.ListenableFuture;
+import chat.delta.util.SettableFuture;
+
public class ThumbnailView extends FrameLayout {
private static final String TAG = ThumbnailView.class.getSimpleName();
diff --git a/src/main/java/org/thoughtcrime/securesms/connect/AccountManager.java b/src/main/java/org/thoughtcrime/securesms/connect/AccountManager.java
index 2a0fbf5a1..4997bdf37 100644
--- a/src/main/java/org/thoughtcrime/securesms/connect/AccountManager.java
+++ b/src/main/java/org/thoughtcrime/securesms/connect/AccountManager.java
@@ -1,7 +1,5 @@
package org.thoughtcrime.securesms.connect;
-import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_VERIFIED_ONE_ON_ONE_CHATS;
-
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -35,7 +33,6 @@ public class AccountManager {
ApplicationContext appContext = (ApplicationContext)context.getApplicationContext();
appContext.dcContext = ApplicationContext.dcAccounts.getSelectedAccount();
DcHelper.setStockTranslations(context);
- DcHelper.getContext(context).setConfig(CONFIG_VERIFIED_ONE_ON_ONE_CHATS, "1");
DirectShareUtil.resetAllShortcuts(appContext);
}
diff --git a/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java b/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java
index a796a4f50..3f16483a0 100644
--- a/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java
+++ b/src/main/java/org/thoughtcrime/securesms/connect/DcHelper.java
@@ -72,7 +72,6 @@ public class DcHelper {
public static final String CONFIG_MEDIA_QUALITY = "media_quality";
public static final String CONFIG_PROXY_ENABLED = "proxy_enabled";
public static final String CONFIG_PROXY_URL = "proxy_url";
- public static final String CONFIG_VERIFIED_ONE_ON_ONE_CHATS = "verified_one_on_one_chats";
public static final String CONFIG_WEBXDC_REALTIME_ENABLED = "webxdc_realtime_enabled";
public static final String CONFIG_PRIVATE_TAG = "private_tag";
@@ -152,7 +151,6 @@ public class DcHelper {
dcContext.setStockTranslation(11, context.getString(R.string.audio));
dcContext.setStockTranslation(12, context.getString(R.string.file));
dcContext.setStockTranslation(23, context.getString(R.string.gif));
- dcContext.setStockTranslation(29, context.getString(R.string.systemmsg_cannot_decrypt));
dcContext.setStockTranslation(35, context.getString(R.string.contact_verified));
dcContext.setStockTranslation(40, context.getString(R.string.chat_archived_label));
dcContext.setStockTranslation(60, context.getString(R.string.login_error_cannot_login));
diff --git a/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java b/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java
index 24d05b5bb..c0dde8289 100644
--- a/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java
+++ b/src/main/java/org/thoughtcrime/securesms/mms/AttachmentManager.java
@@ -40,9 +40,6 @@ import androidx.appcompat.app.AlertDialog;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcMsg;
-import com.b44t.messenger.util.concurrent.ListenableFuture;
-import com.b44t.messenger.util.concurrent.ListenableFuture.Listener;
-import com.b44t.messenger.util.concurrent.SettableFuture;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.MediaPreviewActivity;
@@ -78,6 +75,8 @@ import java.util.List;
import java.util.concurrent.ExecutionException;
import chat.delta.rpc.RpcException;
+import chat.delta.util.ListenableFuture;
+import chat.delta.util.SettableFuture;
public class AttachmentManager {
@@ -133,7 +132,7 @@ public class AttachmentManager {
if (attachmentViewStub.resolved()) {
if (animate) {
- ViewUtil.fadeOut(attachmentViewStub.get(), 200).addListener(new Listener() {
+ ViewUtil.fadeOut(attachmentViewStub.get(), 200).addListener(new ListenableFuture.Listener() {
@Override
public void onSuccess(Boolean result) {
thumbnail.clear(glideRequests);
@@ -234,9 +233,9 @@ public class AttachmentManager {
@NonNull final Uri uri,
@Nullable final DcMsg msg,
@NonNull final MediaType mediaType,
- final int width,
- final int height,
- final int chatId)
+ final int width,
+ final int height,
+ final int chatId)
{
inflateStub();
diff --git a/src/main/java/org/thoughtcrime/securesms/util/ViewUtil.java b/src/main/java/org/thoughtcrime/securesms/util/ViewUtil.java
index 7cf33747b..52776edc2 100644
--- a/src/main/java/org/thoughtcrime/securesms/util/ViewUtil.java
+++ b/src/main/java/org/thoughtcrime/securesms/util/ViewUtil.java
@@ -45,11 +45,11 @@ import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
-import com.b44t.messenger.util.concurrent.ListenableFuture;
-import com.b44t.messenger.util.concurrent.SettableFuture;
-
import org.thoughtcrime.securesms.util.views.Stub;
+import chat.delta.util.ListenableFuture;
+import chat.delta.util.SettableFuture;
+
public class ViewUtil {
private final static String TAG = ViewUtil.class.getSimpleName();
diff --git a/src/main/java/org/thoughtcrime/securesms/util/concurrent/AssertedSuccessListener.java b/src/main/java/org/thoughtcrime/securesms/util/concurrent/AssertedSuccessListener.java
index d4550883a..90a4eedb4 100644
--- a/src/main/java/org/thoughtcrime/securesms/util/concurrent/AssertedSuccessListener.java
+++ b/src/main/java/org/thoughtcrime/securesms/util/concurrent/AssertedSuccessListener.java
@@ -1,10 +1,10 @@
package org.thoughtcrime.securesms.util.concurrent;
-import com.b44t.messenger.util.concurrent.ListenableFuture.Listener;
-
import java.util.concurrent.ExecutionException;
-public abstract class AssertedSuccessListener implements Listener {
+import chat.delta.util.ListenableFuture;
+
+public abstract class AssertedSuccessListener implements ListenableFuture.Listener {
@Override
public void onFailure(ExecutionException e) {
throw new AssertionError(e);
diff --git a/src/main/res/values-et/strings.xml b/src/main/res/values-et/strings.xml
index b5fcea54a..72f83a756 100644
--- a/src/main/res/values-et/strings.xml
+++ b/src/main/res/values-et/strings.xml
@@ -118,6 +118,16 @@
Viimati nähtud: %1$s
Viimati nähtud: pole teada
+
+
+ - %d sekund
+ - %d sekundit
+
+
+
+ - %d minut
+ - %d minutit
+
- %d min
@@ -240,6 +250,7 @@
Uus grupp
Saada sõnum…
+ Tee vestlusest koopia
Kanal
@@ -366,6 +377,20 @@
Fail on salvestatud: „%1$s“.
+
+ Helista
+
+ Vasta
+
+ Keeldu
+ Väljuv kõne
+ Saabuv kõne
+ Keeldutud kõne
+ katkestatud kõne
+ Märkamata kõne
+
+ %1$s, %2$s
+
Videovestlus
@@ -404,7 +429,13 @@
- Kas kustutad %d sõnumi kõikidest oma seadmetest?
- Kas kustutad %d sõnumit kõikidest oma seadmetest?
+
+
+ - Kas soovid kustutada %d sõnumi?
+ - Kas soovid kustutada %d sõnumit?
+
Kas edastad sõnumi kasutajale %1$s?
+ Kas edastad sõnumid %1$d vestlusesse?
Kas lõpetad kontakti blokeerimise?
Kas soovid vestelda kasutajaga %1$s?
@@ -452,6 +483,8 @@
Päring
Lisa päringud nii loenduritesse kui teavitustesse
Sõnumeid pole.
+ Sõnumid sulle endale
+ Arhiveeritud vestlused saavad olema leitavad siin.
Salvesta sõnum
Salvestatud sõnumid
@@ -461,13 +494,29 @@
Proovi uuesti sõnumit saata
Selle failitüübi kuvamine pole võimalik: %s
Manuse laadimine ei õnnestunud
+
+ Jätka salvestamist
+
Postiloend
+
+
+ Alusta…
+
+ Esmalt palun nõustu vestluskutsega.
Saada sõnum…
+ Reaalajas toimivad rakendused
+ Vestlustega seotud rakendused võivad kasutada reaalajas ühendusi. Kui valik on kasutusel, siis vestluste osapooltel on võimalik peale rakenduse käivitamist tuvastada sinu IP-aadress.
+
Saada huvipunkti teave
+
+ Sellele vestluse süsteemsed teated saavad olema nähtavad siin.
%1$s vestluse kontroll-logi
+
+
+ Ära enam %1$s puhul küsi
Tuvastasin kahtlase lingi
Otsi
@@ -509,6 +558,10 @@
Ükspuha mis vestlusele lisatud dokumendid ja muud failid saavad olema nähtavad siin.
Ükspuha mis vestlusele lisatud rakendused saavad olema nähtavad siin.
Meediumi eelvaade
+
+ Proportsionaalne ruudustikuvaade
+
+ Range ruudustikuvaade
Saada sõnum
@@ -624,6 +677,8 @@
Palun sisesta korrektne pordi number (1–65535)
Palun sisesta kehtiv e-posti aadress ja salasõna
Taasta varukoopiast
+ Asukohas „%1$s“ on olemas varukoopia.\n\nKas sa soovid ta importida ning kasutada kõiki seal leiduvaid andmeid ja seadistusi?
+ Varukoopiaid ei leidu.\n\nKopeeri varukoopia siia: „%1$s“ ning proovi uuesti. Alternatiivina võid vajutada „Alusta suhtlemist“ ning jätka tavalist seadistamist.
E-posti aadressiga „%1$s“ ei õnnestu sisse logida. Palun kontrolli, kas aadress ja salasõna on õiged.
@@ -669,6 +724,7 @@
Elulugu/allkiri/moto
Sisestusklahv saadab sõnumi
Saadetava meediumi kvaliteet
+ Tasakaalustatud
Kõige kehvem kvaliteet, aga väikseim maht
Väristamine
Ekraani turvalisus
@@ -735,7 +791,10 @@
Välju saadetud sõnumite kausta
Saada koopia iseendale
Vajalik, kui kasutad seda kontot mitmes seadmes.
+ Tõsta automaatselt DeltaChati kausta
+ Laadi vaid DeltaChati kasutast
Näita klassikalisi e-kirju
+ Kõik
Katselised funktsionaalsused
Arendaja režiim
Lülitab sisse veaotsingu tarvikud ja see võib rakenduse töökindlust vähendada. Sobib arendajatele.
@@ -760,6 +819,7 @@
Kustuta profiilipilt
Näita süsteemisalve ikooni
Muuda profiili
+ Lülita IMAP IDLE välja
Saada statistikat Delta Chati kasutajatele
@@ -1085,6 +1145,8 @@
Delta Chat võib kasutada Face ID teenust sinu kohaliku profiili kaitsmiseks, varukoopia tegemiseks ja täiendavate seadmete seadistamiseks.
Kasuta ühendust taustal
+ Põhjustab püsiteavituse
+
Kui soovid, et Delta Chat saaks sõnumeid ka taustateenusena toimides, siis klõpsi siin.
diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml
index fb9d40acd..580b25de9 100644
--- a/src/main/res/values-it/strings.xml
+++ b/src/main/res/values-it/strings.xml
@@ -393,9 +393,9 @@
File salvato su \"%1$s\".
- Chiamata
+ Chiama
- Risposta
+ Rispondi
Rifiuta
Chiamata in uscita
@@ -441,7 +441,7 @@
- Eliminare %d chat su tutti i tuoi dispositivi?
- Eliminare %d chats su tutti i tuoi dispositivi?
- - Eliminare %d chats su tutti i tuoi dispositivi?
+ - Eliminare %d chat su tutti i tuoi dispositivi?
Eliminare la chat \"%1$s\" su tutti i tuoi dispositivi?
Vuoi eliminare questo messaggio da tutti i tuoi dispositivi?
@@ -545,7 +545,7 @@
Invia Messaggio a...
App in Tempo Reale
- Abilita connessioni in tempo reale per apps condivise nelle chats. Se abilitato, i partner della chat potrebbero essere in grado di scoprire il tuo indirizzo IP quando avvii un\'app.
+ Abilita connessioni in tempo reale per apps condivise nelle chat. Se abilitato, i partner della chat potrebbero essere in grado di scoprire il tuo indirizzo IP quando avvii un\'app.
Mostra le posizioni nell\'intervallo di tempo
@@ -587,7 +587,7 @@
Aggiungi Membri
Devi essere un membro del gruppo per fare questa azione.
Crittografia
- Chats in Comune
+ Chat in Comune
Chat Correlate
Membri Passati
@@ -819,7 +819,7 @@
Disattiva il supporto delle emoji integrato in Delta Chat
Leggi Rubrica di Sistema
Offri la possibilità di creare chat con i contatti della rubrica.
- Chats
+ Chat
Suoni In-Chat
Vedi Registro
Registro salvato nella cartella \"Downloads\"
@@ -1101,7 +1101,7 @@
Nuovi messaggi
Hai nuovi messaggi
- %1$d messaggi in %2$d chats
+ %1$d messaggi in %2$d chat
diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml
index 0dac63b44..65903775d 100644
--- a/src/main/res/values-ru/strings.xml
+++ b/src/main/res/values-ru/strings.xml
@@ -411,8 +411,8 @@
Отклонить
Исходящий звонок
Входящий звонок
- Отклоненный звонок
- Отмененный звонок
+ Отклонённый звонок
+ Отменённый звонок
Пропущенный звонок
%1$s, %2$s
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 9e1190960..9ef28211f 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -943,7 +943,6 @@
Prefer End-To-End Encryption
- This message cannot be decrypted.\n\n• It might already help to simply reply to this message and ask the sender to send the message again.\n\n• If you just re-installed Delta Chat then it is best if you re-setup Delta Chat now and choose "Add as second device" or import a backup.
Unknown sender for this chat. See \'info\' for more details.
Message from %1$s
Failed to send message to %1$s.