Ver Fonte

Version 5.5.1

Threema há 1 ano atrás
pai
commit
44ef4b8155
76 ficheiros alterados com 686 adições e 391 exclusões
  1. 1 5
      .editorconfig
  2. 2 2
      app/build.gradle
  3. BIN
      app/libs/agcp-1.9.1.303.jar
  4. 1 1
      app/src/hms_services_based/java/ch/threema/app/push/HmsTokenUtil.kt
  5. 1 0
      app/src/libre/play/listings/de/full-description.txt
  6. 1 0
      app/src/libre/play/listings/en-US/full-description.txt
  7. 3 1
      app/src/libre/play/release-notes/de/default.txt
  8. 3 1
      app/src/libre/play/release-notes/en-US/default.txt
  9. 190 190
      app/src/main/java/ch/threema/app/activities/BiometricLockActivity.java
  10. 6 2
      app/src/main/java/ch/threema/app/activities/HomeActivity.java
  11. 2 2
      app/src/main/java/ch/threema/app/activities/wizard/WizardBackupRestoreActivity.java
  12. 1 1
      app/src/main/java/ch/threema/app/activities/wizard/WizardBaseActivity.java
  13. 0 14
      app/src/main/java/ch/threema/app/activities/wizard/WizardIntroActivity.java
  14. 1 1
      app/src/main/java/ch/threema/app/activities/wizard/WizardSafeRestoreActivity.java
  15. 1 1
      app/src/main/java/ch/threema/app/dialogs/ContactEditDialog.java
  16. 4 2
      app/src/main/java/ch/threema/app/fragments/ComposeMessageFragment.java
  17. 6 1
      app/src/main/java/ch/threema/app/services/ConversationServiceImpl.java
  18. 11 8
      app/src/main/java/ch/threema/app/services/MessageServiceImpl.java
  19. 12 0
      app/src/main/java/ch/threema/app/services/PreferenceService.java
  20. 16 5
      app/src/main/java/ch/threema/app/services/PreferenceServiceImpl.java
  21. 6 2
      app/src/main/java/ch/threema/app/stores/PreferenceStore.java
  22. 8 1
      app/src/main/java/ch/threema/app/stores/PreferenceStoreInterface.java
  23. 2 2
      app/src/main/java/ch/threema/app/stores/PreferenceStoreInterfaceDevNullImpl.java
  24. 8 0
      app/src/main/java/ch/threema/app/tasks/DeleteMessageUtils.kt
  25. 7 1
      app/src/main/java/ch/threema/app/tasks/EditMessageUtils.kt
  26. 9 6
      app/src/main/java/ch/threema/app/ui/AckjiPopup.java
  27. 9 1
      app/src/main/java/ch/threema/app/utils/ConfigUtils.java
  28. 50 1
      app/src/main/java/ch/threema/app/utils/MessageUtil.java
  29. 16 3
      app/src/main/res/layout/conversation_list_item_deleted_recv.xml
  30. 15 2
      app/src/main/res/layout/conversation_list_item_deleted_send.xml
  31. 5 2
      app/src/main/res/layout/fragment_ballot_wizard1.xml
  32. 9 0
      app/src/main/res/values-be-rBY/colorpicker_strings.xml
  33. 21 7
      app/src/main/res/values-be-rBY/strings.xml
  34. 1 1
      app/src/main/res/values-be-rBY/webclient_strings.xml
  35. 9 0
      app/src/main/res/values-cs/colorpicker_strings.xml
  36. 7 7
      app/src/main/res/values-cs/strings.xml
  37. 1 1
      app/src/main/res/values-de/strings.xml
  38. 8 6
      app/src/main/res/values-es/colorpicker_strings.xml
  39. 2 2
      app/src/main/res/values-es/strings.xml
  40. 8 21
      app/src/main/res/values-fr/colorpicker_strings.xml
  41. 2 2
      app/src/main/res/values-fr/strings.xml
  42. 9 0
      app/src/main/res/values-gsw/colorpicker_strings.xml
  43. 10 1
      app/src/main/res/values-gsw/strings.xml
  44. 6 4
      app/src/main/res/values-hu/colorpicker_strings.xml
  45. 1 1
      app/src/main/res/values-hu/poi_strings.xml
  46. 0 1
      app/src/main/res/values-hu/strings.xml
  47. 8 6
      app/src/main/res/values-it/colorpicker_strings.xml
  48. 19 2
      app/src/main/res/values-it/strings.xml
  49. 1 1
      app/src/main/res/values-ja/strings.xml
  50. 8 5
      app/src/main/res/values-nl-rNL/colorpicker_strings.xml
  51. 2 2
      app/src/main/res/values-nl-rNL/strings.xml
  52. 8 7
      app/src/main/res/values-pl/colorpicker_strings.xml
  53. 2 2
      app/src/main/res/values-pl/strings.xml
  54. 8 6
      app/src/main/res/values-pt-rBR/colorpicker_strings.xml
  55. 1 1
      app/src/main/res/values-pt-rBR/strings.xml
  56. 18 0
      app/src/main/res/values-rm/strings.xml
  57. 1 1
      app/src/main/res/values-rm/voip_strings.xml
  58. 8 6
      app/src/main/res/values-ru/colorpicker_strings.xml
  59. 1 1
      app/src/main/res/values-ru/poi_strings.xml
  60. 3 3
      app/src/main/res/values-ru/strings.xml
  61. 11 11
      app/src/main/res/values-ru/webclient_strings.xml
  62. 9 0
      app/src/main/res/values-sk/colorpicker_strings.xml
  63. 9 0
      app/src/main/res/values-tr/colorpicker_strings.xml
  64. 12 3
      app/src/main/res/values-tr/strings.xml
  65. 9 0
      app/src/main/res/values-uk/colorpicker_strings.xml
  66. 9 9
      app/src/main/res/values-uk/strings.xml
  67. 9 0
      app/src/main/res/values-zh-rCN/colorpicker_strings.xml
  68. 13 5
      app/src/main/res/values-zh-rCN/strings.xml
  69. 9 0
      app/src/main/res/values-zh-rTW/colorpicker_strings.xml
  70. 12 4
      app/src/main/res/values-zh-rTW/strings.xml
  71. 0 0
      app/src/main/res/values/colorpicker_strings.xml
  72. 1 1
      app/src/main/res/values/dimens.xml
  73. 1 0
      app/src/main/res/values/preferences_strings.xml
  74. 1 1
      app/src/main/res/values/strings.xml
  75. 1 1
      build.gradle
  76. 1 1
      domain/src/main/java/ch/threema/domain/protocol/connection/layer/MonitoringLayer.kt

+ 1 - 5
.editorconfig

@@ -2,13 +2,9 @@
 root = true
 
 [*]
-charset = utf-8
 end_of_line = lf
 insert_final_newline = true
 trim_trailing_whitespace = true
+charset = utf-8
 indent_style = space
 indent_size = 4
-
-[*.{java,php}]
-indent_style = tab
-indent_size = 4

+ 2 - 2
app/build.gradle

@@ -18,14 +18,14 @@ if (getGradle().getStartParameter().getTaskRequests().toString().contains("Hms")
 // version codes
 
 // Only use the scheme "<major>.<minor>.<patch>" for the app_version
-def app_version = "5.5"
+def app_version = "5.5.1"
 
 // beta_suffix with leading dash (e.g. `-beta1`)
 // should be one of (alpha|beta|rc) and an increasing number or empty for a regular release.
 // Note: in nightly builds this will be overwritten with a nightly version "-n12345"
 def beta_suffix = ""
 
-def defaultVersionCode = 996
+def defaultVersionCode = 998
 
 /**
  * Return the git hash, if git is installed.

BIN
app/libs/agcp-1.9.1.301.jar → app/libs/agcp-1.9.1.303.jar


+ 1 - 1
app/src/hms_services_based/java/ch/threema/app/push/HmsTokenUtil.kt

@@ -34,7 +34,7 @@ object HmsTokenUtil {
     private const val APP_ID_CONFIG_FIELD = "client/app_id"
 
     /**
-     * Obtain the app ID from the agconnect-service.json file.
+     * Obtain the app ID from the agconnect-services.json file.
      *
      * @return The app id or null if it could not be obtained
      */

+ 1 - 0
app/src/libre/play/listings/de/full-description.txt

@@ -17,6 +17,7 @@ Jegliche Kommunikation, auch Sprach- und Videoanrufe, Gruppen-Chats, Medien, Dat
 Threema schützt Ihre Privatsphäre und bietet zahlreiche und einzigartige Funktionen.
 
 · Senden Sie Text- und Sprachnachrichten
+· Bearbeiten und löschen Sie bereits gesendete Nachrichten für Chatpartner
 · Tätigen Sie Sprach-, Video- und Gruppenanrufe
 · Teilen Sie Videos Bilder und Standorte
 · Senden Sie Dateien beliebigen Formats (pdf animierte gif, mp3, doc, zip usw.)

+ 1 - 0
app/src/libre/play/listings/en-US/full-description.txt

@@ -17,6 +17,7 @@ Threema end-to-end encrypts all your communication, including messages, voice an
 Threema is not only an encrypted and private messenger but also versatile and feature-rich.
 
 · Write text and send voice messages
+· Edit and delete sent messages on the recipient’s end
 · Make voice, video and group calls
 · Share videos pictures and locations
 · Send any type of file (pdf animated gif, mp3, doc, zip, etc.)

+ 3 - 1
app/src/libre/play/release-notes/de/default.txt

@@ -1 +1,3 @@
-* Bereits gesendete Nachrichten können neu bearbeitet und für alle gelöscht werden
+* Verbesserte Darstellung von Umfragen mit grossen Schriftarten
+* Behebung eines Fehlers bei der Chatreihenfolge im Web-Client
+* Verbesserungen und Behebung verschiedener Fehler

+ 3 - 1
app/src/libre/play/release-notes/en-US/default.txt

@@ -1 +1,3 @@
-* Sent messages can now be edited or deleted on the recipient’s end
+* Improved support for large font sizes in polls
+* Fixed a bug in relation to the chat order in the web client
+* Various improvements and bug fixes

+ 190 - 190
app/src/main/java/ch/threema/app/activities/BiometricLockActivity.java

@@ -32,12 +32,11 @@ import android.view.View;
 import android.view.WindowManager;
 import android.widget.Toast;
 
+import org.slf4j.Logger;
+
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.biometric.BiometricPrompt;
-
-import org.slf4j.Logger;
-
 import ch.threema.app.R;
 import ch.threema.app.ThreemaApplication;
 import ch.threema.app.managers.ServiceManager;
@@ -50,191 +49,192 @@ import ch.threema.app.utils.RuntimeUtil;
 import ch.threema.base.utils.LoggingUtil;
 
 public class BiometricLockActivity extends ThreemaAppCompatActivity {
-	private static final Logger logger = LoggingUtil.getThreemaLogger("BiometricLockActivity");
-
-	private static final int REQUEST_CODE_SYSTEM_SCREENLOCK_CHECK = 551;
-	public static final String INTENT_DATA_AUTHENTICATION_TYPE = "auth_type";
-
-	private LockAppService lockAppService;
-	private PreferenceService preferenceService;
-	private SystemScreenLockService systemScreenLockService;
-	private boolean isCheckOnly = false;
-	private String authenticationType = null;
-
-	@Override
-	public void onCreate(Bundle savedInstanceState) {
-		logger.debug("onCreate");
-
-		super.onCreate(savedInstanceState);
-
-		ServiceManager serviceManager = ThreemaApplication.getServiceManager();
-		if (serviceManager == null) {
-			finish();
-			return;
-		}
-
-		preferenceService = serviceManager.getPreferenceService();
-		lockAppService = serviceManager.getLockAppService();
-		systemScreenLockService = serviceManager.getScreenLockService();
-
-		setContentView(R.layout.activity_biometric_lock);
-
-		getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
-
-		isCheckOnly = getIntent().getBooleanExtra(ThreemaApplication.INTENT_DATA_CHECK_ONLY, false);
-		if (getIntent().hasExtra(INTENT_DATA_AUTHENTICATION_TYPE)) {
-			authenticationType = getIntent().getStringExtra(INTENT_DATA_AUTHENTICATION_TYPE);
-		}
-
-		if (authenticationType == null) {
-			authenticationType = preferenceService.getLockMechanism();
-		}
-
-		if (!lockAppService.isLocked() && !isCheckOnly) {
-			finish();
-		}
-
-		switch (authenticationType) {
-			case PreferenceService.LockingMech_SYSTEM:
-				showSystemScreenLock();
-				break;
-			case PreferenceService.LockingMech_BIOMETRIC:
-				if (BiometricUtil.isBiometricsSupported(this)) {
-					showBiometricPrompt();
-				} else {
-					// no enrolled fingerprints - try system screen lock
-					showSystemScreenLock();
-				}
-				break;
-			default:
-				break;
-		}
-	}
-
-	@Override
-	public void finish() {
-		logger.debug("finish");
-		try {
-			super.finish();
-			overridePendingTransition(0, 0);
-		} catch (Exception ignored) {}
-	}
-
-	private void showBiometricPrompt() {
-		KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
-
-		BiometricPrompt.PromptInfo.Builder promptInfoBuilder = new BiometricPrompt.PromptInfo.Builder()
-			.setTitle(getString(R.string.prefs_title_access_protection))
-			.setSubtitle(getString(R.string.biometric_enter_authentication))
-			.setConfirmationRequired(false);
-
-		if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P && keyguardManager != null && keyguardManager.isDeviceSecure()) {
-			// allow fallback to device credentials such as PIN, passphrase or pattern
-			promptInfoBuilder.setDeviceCredentialAllowed(true);
-		} else {
-			promptInfoBuilder.setNegativeButtonText(getString(R.string.cancel));
-		}
-
-		BiometricPrompt.PromptInfo promptInfo = promptInfoBuilder.build();
-		BiometricPrompt biometricPrompt = new BiometricPrompt(this, new RuntimeUtil.MainThreadExecutor(), new BiometricPrompt.AuthenticationCallback() {
-			@Override
-			public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
-				super.onAuthenticationError(errorCode, errString);
-				if (errorCode != BiometricPrompt.ERROR_USER_CANCELED && errorCode != BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
-					Toast.makeText(BiometricLockActivity.this, errString + " (" + errorCode + ")", Toast.LENGTH_LONG).show();
-				}
-				BiometricLockActivity.this.onAuthenticationError(errorCode);
-			}
-
-			@Override
-			public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
-				super.onAuthenticationSucceeded(result);
-				BiometricLockActivity.this.onAuthenticationSuccess();
-			}
-
-			@Override
-			public void onAuthenticationFailed() {
-				super.onAuthenticationFailed();
-				BiometricLockActivity.this.onAuthenticationFailed();
-			}
-		});
-		biometricPrompt.authenticate(promptInfo);
-	}
-
-	private void showSystemScreenLock() {
-		logger.debug("showSystemScreenLock");
-		if (isCheckOnly) {
-			if (systemScreenLockService.tryEncrypt(this, REQUEST_CODE_SYSTEM_SCREENLOCK_CHECK)) {
-				onAuthenticationSuccess();
-			}
-		} else {
-			if (systemScreenLockService.systemUnlock(this)) {
-				onAuthenticationSuccess();
-			}
-		}
-	}
-
-	@Override
-	public void onWindowFocusChanged(boolean hasFocus) {
-		super.onWindowFocusChanged(hasFocus);
-		if (hasFocus) {
-			getWindow().getDecorView().setSystemUiVisibility(
-				// Set the content to appear under the system bars so that the
-				// content doesn't resize when the system bars hide and show.
-				View.SYSTEM_UI_FLAG_LAYOUT_STABLE
-				| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
-				| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
-				| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
-				| View.SYSTEM_UI_FLAG_FULLSCREEN
-			);
-		}
-	}
-
-	@Override
-	protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
-		logger.debug("onActivityResult requestCode: " + requestCode + " result: " + resultCode);
-
-		super.onActivityResult(requestCode, resultCode, data);
-
-		if (requestCode == ThreemaActivity.ACTIVITY_ID_CONFIRM_DEVICE_CREDENTIALS || requestCode == REQUEST_CODE_SYSTEM_SCREENLOCK_CHECK) {
-			// Challenge completed, proceed with using cipher
-			if (resultCode != Activity.RESULT_CANCELED) {
-				onAuthenticationSuccess();
-			} else {
-				// The user canceled or didn’t complete the lock screen
-				onAuthenticationFailed();
-			}
-		}
-	}
-
-	private void onAuthenticationSuccess() {
-		logger.debug("Authentication successful");
-		if (!isCheckOnly) {
-			lockAppService.unlock(null);
-		}
-		this.setResult(RESULT_OK);
-		this.finish();
-	}
-
-	private void onAuthenticationFailed() {
-		logger.debug("Authentication failed");
-		if (!isCheckOnly) {
-			NavigationUtil.navigateToLauncher(this);
-		}
-		this.setResult(RESULT_CANCELED);
-		this.finish();
-	}
-
-	private void onAuthenticationError(int errorCode) {
-		logger.debug("Authentication error");
-		if (!isCheckOnly) {
-			NavigationUtil.navigateToLauncher(this);
-			if (errorCode == BiometricPrompt.ERROR_USER_CANCELED && Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
-				// ugly hack for leaking content in app switcher
-				SystemClock.sleep(2000);
-			}
-		}
-		this.setResult(RESULT_CANCELED);
-		this.finish();
-	}
+    private static final Logger logger = LoggingUtil.getThreemaLogger("BiometricLockActivity");
+
+    private static final int REQUEST_CODE_SYSTEM_SCREENLOCK_CHECK = 551;
+    public static final String INTENT_DATA_AUTHENTICATION_TYPE = "auth_type";
+
+    private LockAppService lockAppService;
+    private SystemScreenLockService systemScreenLockService;
+    private boolean isCheckOnly = false;
+    private String authenticationType = null;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        logger.debug("onCreate");
+
+        super.onCreate(savedInstanceState);
+
+        ServiceManager serviceManager = ThreemaApplication.getServiceManager();
+        if (serviceManager == null) {
+            finish();
+            return;
+        }
+
+        lockAppService = serviceManager.getLockAppService();
+        systemScreenLockService = serviceManager.getScreenLockService();
+
+        setContentView(R.layout.activity_biometric_lock);
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
+
+        isCheckOnly = getIntent().getBooleanExtra(ThreemaApplication.INTENT_DATA_CHECK_ONLY, false);
+        if (getIntent().hasExtra(INTENT_DATA_AUTHENTICATION_TYPE)) {
+            authenticationType = getIntent().getStringExtra(INTENT_DATA_AUTHENTICATION_TYPE);
+        }
+
+        PreferenceService preferenceService = serviceManager.getPreferenceService();
+        if (authenticationType == null) {
+            authenticationType = preferenceService.getLockMechanism();
+        }
+
+        if (!lockAppService.isLocked() && !isCheckOnly) {
+            finish();
+        }
+
+        switch (authenticationType) {
+            case PreferenceService.LockingMech_SYSTEM:
+                showSystemScreenLock();
+                break;
+            case PreferenceService.LockingMech_BIOMETRIC:
+                if (BiometricUtil.isBiometricsSupported(this)) {
+                    showBiometricPrompt();
+                } else {
+                    // no enrolled fingerprints - try system screen lock
+                    showSystemScreenLock();
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+    @Override
+    public void finish() {
+        logger.debug("finish");
+        try {
+            super.finish();
+            overridePendingTransition(0, 0);
+        } catch (Exception ignored) {}
+    }
+
+    private void showBiometricPrompt() {
+        KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
+
+        BiometricPrompt.PromptInfo.Builder promptInfoBuilder = new BiometricPrompt.PromptInfo.Builder()
+            .setTitle(getString(R.string.prefs_title_access_protection))
+            .setSubtitle(getString(R.string.biometric_enter_authentication))
+            .setConfirmationRequired(false);
+
+        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P && keyguardManager != null && keyguardManager.isDeviceSecure()) {
+            // allow fallback to device credentials such as PIN, passphrase or pattern
+            promptInfoBuilder.setDeviceCredentialAllowed(true);
+        } else {
+            promptInfoBuilder.setNegativeButtonText(getString(R.string.cancel));
+        }
+
+        BiometricPrompt.PromptInfo promptInfo = promptInfoBuilder.build();
+        BiometricPrompt biometricPrompt = new BiometricPrompt(this, new RuntimeUtil.MainThreadExecutor(), new BiometricPrompt.AuthenticationCallback() {
+            @Override
+            public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
+                super.onAuthenticationError(errorCode, errString);
+                logger.error("Authentication error: (errorCode={}, errString={})", errorCode, errString);
+                if (errorCode != BiometricPrompt.ERROR_USER_CANCELED && errorCode != BiometricPrompt.ERROR_NEGATIVE_BUTTON) {
+                    Toast.makeText(BiometricLockActivity.this, errString + " (" + errorCode + ")", Toast.LENGTH_LONG).show();
+                }
+                BiometricLockActivity.this.onAuthenticationError(errorCode);
+            }
+
+            @Override
+            public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
+                super.onAuthenticationSucceeded(result);
+                logger.info("Authentication succeeded");
+                BiometricLockActivity.this.onAuthenticationSuccess();
+            }
+
+            @Override
+            public void onAuthenticationFailed() {
+                super.onAuthenticationFailed();
+                BiometricLockActivity.this.onAuthenticationFailed();
+            }
+        });
+        biometricPrompt.authenticate(promptInfo);
+    }
+
+    private void showSystemScreenLock() {
+        logger.debug("showSystemScreenLock");
+        if (isCheckOnly) {
+            if (systemScreenLockService.tryEncrypt(this, REQUEST_CODE_SYSTEM_SCREENLOCK_CHECK)) {
+                onAuthenticationSuccess();
+            }
+        } else {
+            if (systemScreenLockService.systemUnlock(this)) {
+                onAuthenticationSuccess();
+            }
+        }
+    }
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        super.onWindowFocusChanged(hasFocus);
+        if (hasFocus) {
+            getWindow().getDecorView().setSystemUiVisibility(
+                // Set the content to appear under the system bars so that the
+                // content doesn't resize when the system bars hide and show.
+                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+                    | View.SYSTEM_UI_FLAG_FULLSCREEN
+            );
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+        logger.info("onActivityResult (requestCode={}, resultCode={})", requestCode, resultCode);
+
+        super.onActivityResult(requestCode, resultCode, data);
+
+        if (requestCode == ThreemaActivity.ACTIVITY_ID_CONFIRM_DEVICE_CREDENTIALS || requestCode == REQUEST_CODE_SYSTEM_SCREENLOCK_CHECK) {
+            // Challenge completed, proceed with using cipher
+            if (resultCode != Activity.RESULT_CANCELED) {
+                onAuthenticationSuccess();
+            } else {
+                // The user canceled or didn’t complete the lock screen
+                onAuthenticationFailed();
+            }
+        }
+    }
+
+    private void onAuthenticationSuccess() {
+        logger.debug("Authentication successful");
+        if (!isCheckOnly) {
+            lockAppService.unlock(null);
+        }
+        this.setResult(RESULT_OK);
+        this.finish();
+    }
+
+    private void onAuthenticationFailed() {
+        logger.debug("Authentication failed");
+        if (!isCheckOnly) {
+            NavigationUtil.navigateToLauncher(this);
+        }
+        this.setResult(RESULT_CANCELED);
+        this.finish();
+    }
+
+    private void onAuthenticationError(int errorCode) {
+        logger.debug("Authentication error");
+        if (!isCheckOnly) {
+            NavigationUtil.navigateToLauncher(this);
+            if (errorCode == BiometricPrompt.ERROR_USER_CANCELED && Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                // ugly hack for leaking content in app switcher
+                SystemClock.sleep(2000);
+            }
+        }
+        this.setResult(RESULT_CANCELED);
+        this.finish();
+    }
 }

+ 6 - 2
app/src/main/java/ch/threema/app/activities/HomeActivity.java

@@ -765,7 +765,7 @@ public class HomeActivity extends ThreemaAppCompatActivity implements
 			ConfigUtils.isBackgroundRestricted(ThreemaApplication.getAppContext()) ||
 			ConfigUtils.isBackgroundDataRestricted(ThreemaApplication.getAppContext(), false) ||
 			ConfigUtils.isNotificationsDisabled(ThreemaApplication.getAppContext()) ||
-			ConfigUtils.isFullScreenNotificationsDisabled(ThreemaApplication.getAppContext()) ||
+			(preferenceService.isCallsEnabled() && ConfigUtils.isFullScreenNotificationsDisabled(ThreemaApplication.getAppContext())) ||
 			((preferenceService.useThreemaPush() || BuildFlavor.forceThreemaPush()) && !PowermanagerUtil.isIgnoringBatteryOptimizations(ThreemaApplication.getAppContext()));
 	}
 
@@ -775,7 +775,7 @@ public class HomeActivity extends ThreemaAppCompatActivity implements
 		if (preferenceService != null) {
 			if (!preferenceService.isLatestVersion(this)) {
 				// so the app has just been updated
-				ConfigUtils.requestNotificationPermission(this, notificationPermissionLauncher);
+				ConfigUtils.requestNotificationPermission(this, notificationPermissionLauncher, preferenceService);
 
 				if (preferenceService.getPrivacyPolicyAccepted() == null) {
 					preferenceService.setPrivacyPolicyAccepted(new Date(), PreferenceService.PRIVACY_POLICY_ACCEPT_UPDATE);
@@ -1319,6 +1319,10 @@ public class HomeActivity extends ThreemaAppCompatActivity implements
 		showWhatsNew();
 
 		notificationService.cancelRestoreNotification();
+
+		if (preferenceService.getLastNotificationPermissionRequestTimestamp() == 0) {
+			ConfigUtils.requestNotificationPermission(this, notificationPermissionLauncher, preferenceService);
+		}
 	}
 
 	private void initOngoingCallNotice() {

+ 2 - 2
app/src/main/java/ch/threema/app/activities/wizard/WizardBackupRestoreActivity.java

@@ -310,8 +310,8 @@ public class WizardBackupRestoreActivity extends ThreemaAppCompatActivity implem
 		this.backupFile = (File) data;
 		this.backupPassword = text;
 
-		// If the permission is already granted, then start the restore directly
-		if (ConfigUtils.requestNotificationPermission(this, permissionLauncher)) {
+		// If the notification permission is already granted, then start the restore directly
+		if (ConfigUtils.requestNotificationPermission(this, permissionLauncher, preferenceService)) {
 			startRestore();
 		}
 	}

+ 1 - 1
app/src/main/java/ch/threema/app/activities/wizard/WizardBaseActivity.java

@@ -693,9 +693,9 @@ public class WizardBaseActivity extends ThreemaAppCompatActivity implements
 				this.nickname = this.userService.getIdentity();
 				break;
 			case DIALOG_TAG_INVALID_ENTRY:
+			case DIALOG_TAG_PASSWORD_BAD:
 				prevPage();
 				break;
-			case DIALOG_TAG_PASSWORD_BAD:
 			case DIALOG_TAG_THREEMA_SAFE:
 			case DIALOG_TAG_PASSWORD_PRESET_CONFIRM:
 				break;

+ 0 - 14
app/src/main/java/ch/threema/app/activities/wizard/WizardIntroActivity.java

@@ -43,12 +43,9 @@ import android.widget.TextView;
 import androidx.activity.result.ActivityResultCallback;
 import androidx.activity.result.ActivityResultLauncher;
 import androidx.activity.result.contract.ActivityResultContract;
-import androidx.activity.result.contract.ActivityResultContracts;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import org.slf4j.Logger;
-
 import ch.threema.app.R;
 import ch.threema.app.ThreemaApplication;
 import ch.threema.app.activities.PrivacyPolicyActivity;
@@ -60,20 +57,11 @@ import ch.threema.app.utils.AppRestrictionUtil;
 import ch.threema.app.utils.ConfigUtils;
 import ch.threema.app.utils.SynchronizeContactsUtil;
 import ch.threema.app.utils.TestUtil;
-import ch.threema.base.utils.LoggingUtil;
 
 public class WizardIntroActivity extends WizardBackgroundActivity {
 	private static final int ACTIVITY_RESULT_PRIVACY_POLICY = 9442;
-	private static final Logger logger = LoggingUtil.getThreemaLogger("WizardIntroActivity");
 	private AnimationDrawable frameAnimation;
 
-	private final ActivityResultLauncher<String> notificationPermissionLauncher =
-		registerForActivityResult(new ActivityResultContracts.RequestPermission(), isGranted -> {
-			if (!Boolean.TRUE.equals(isGranted)) {
-				logger.warn("User refused notification permission");
-			}
-		});
-
 	private final ActivityResultLauncher<Void> backupResult = registerForActivityResult(new ActivityResultContract<>() {
 		@NonNull
 		@Override
@@ -163,8 +151,6 @@ public class WizardIntroActivity extends WizardBackgroundActivity {
 		findViewById(R.id.setup_threema).setOnClickListener(this::setupThreema);
 
 		isContactSyncSettingConflict();
-
-		ConfigUtils.requestNotificationPermission(this, notificationPermissionLauncher);
 	}
 
 	@Override

+ 1 - 1
app/src/main/java/ch/threema/app/activities/wizard/WizardSafeRestoreActivity.java

@@ -145,7 +145,7 @@ public class WizardSafeRestoreActivity extends WizardBackgroundActivity implemen
 		findViewById(R.id.safe_restore_button).setOnClickListener(v -> {
 			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
 				// Ask for notification permission
-				if (!ConfigUtils.requestNotificationPermission(WizardSafeRestoreActivity.this, notificationPermissionLauncher)) {
+				if (!ConfigUtils.requestNotificationPermission(WizardSafeRestoreActivity.this, notificationPermissionLauncher, preferenceService)) {
 					return;
 				}
 			}

+ 1 - 1
app/src/main/java/ch/threema/app/dialogs/ContactEditDialog.java

@@ -296,7 +296,7 @@ public class ContactEditDialog extends ThreemaDialogFragment implements AvatarEd
 
 		builder.setPositiveButton(getString(R.string.ok), (dialog, whichButton) -> {
 			if (callbackRef.get() != null) {
-				callbackRef.get().onYes(tag, editText1.getText().toString(), editText2.getText().toString(), null);
+				callbackRef.get().onYes(tag, editText1.getText().toString(), editText2.getText().toString(), croppedAvatarFile);
 			}
 		}
 		);

+ 4 - 2
app/src/main/java/ch/threema/app/fragments/ComposeMessageFragment.java

@@ -2535,7 +2535,7 @@ public class ComposeMessageFragment extends Fragment implements
 		if (messageReceiver instanceof ContactMessageReceiver) {
 			ContactMessageReceiver receiver = (ContactMessageReceiver) messageReceiver;
 			deleteContactMessageForAll(receiver, message);
-		} else if (messageReceiver instanceof GroupMessageReceiver && groupModel != null) {
+		} else if (messageReceiver instanceof GroupMessageReceiver && groupModel != null && groupService.isGroupMember(groupModel)) {
 			deleteGroupMessageForAll(message, groupModel);
 		} else {
 			logger.warn("Cannot delete message for receiver of type {}", messageReceiver.getClass().getName());
@@ -4677,7 +4677,9 @@ public class ComposeMessageFragment extends Fragment implements
 			// check receiver support
 			if (messageReceiver instanceof GroupMessageReceiver) {
 				GroupModel group = ((GroupMessageReceiver) messageReceiver).getGroup();
-				if (groupService.isNotesGroup(group)) {
+				if (!groupService.isGroupMember(group)) {
+					return false;
+				} else if (groupService.isNotesGroup(group)) {
 					// delete for all is pointless in notes group
 					return false;
 				} else {

+ 6 - 1
app/src/main/java/ch/threema/app/services/ConversationServiceImpl.java

@@ -540,7 +540,9 @@ public class ConversationServiceImpl implements ConversationService {
 	@Override
 	public synchronized int empty(final ConversationModel conversation, boolean silentMessageUpdate) {
 		// Remove all messages
-		final List<AbstractMessageModel> messages = this.messageService.getMessagesForReceiver(conversation.getReceiver());
+		MessageReceiver<?> receiver = conversation.getReceiver();
+		final List<AbstractMessageModel> messages = this.messageService.getMessagesForReceiver(receiver);
+		logger.info("Empty conversation with {} messages for receiver {} (type={})", messages.size(), receiver.getUniqueIdString(), receiver.getType());
 		for (AbstractMessageModel m : messages) {
 			this.messageService.remove(m, silentMessageUpdate);
 		}
@@ -572,6 +574,7 @@ public class ConversationServiceImpl implements ConversationService {
 		if (conversationModel != null) {
 			return this.empty(conversationModel, true);
 		}
+		logger.warn("Contact conversation model is null, cannot empty");
 		return 0;
 	}
 
@@ -581,6 +584,7 @@ public class ConversationServiceImpl implements ConversationService {
 		if (conversationModel != null) {
 			return this.empty(conversationModel, true);
 		}
+		logger.warn("Group conversation model is null, cannot empty");
 		return 0;
 	}
 
@@ -590,6 +594,7 @@ public class ConversationServiceImpl implements ConversationService {
 		if (conversationModel != null) {
 			return this.empty(conversationModel, true);
 		}
+		logger.warn("DistributionList conversation model is null, cannot empty");
 		return 0;
 	}
 

+ 11 - 8
app/src/main/java/ch/threema/app/services/MessageServiceImpl.java

@@ -1387,10 +1387,17 @@ public class MessageServiceImpl implements MessageService {
 			return false;
 		}
 
-		// Bump "lastUpdate" if necessary, depending on the message type
-		if (message.bumpLastUpdate()) {
-			contactService.bumpLastUpdate(senderIdentity);
-		}
+        // As soon as we get a direct message, unhide and unarchive the contact
+        contactService.setIsHidden(senderIdentity, false);
+        contactService.setIsArchived(senderIdentity, false);
+
+        // Bump "lastUpdate" if necessary, depending on the message type. Note that due to the
+        // listeners, we should bump the last update before saving the box message. Saving the box
+        // message will trigger the listeners that, among other things, update the webclient. For
+        // this purpose it is important that the last update flag has already been bumped.
+        if (message.bumpLastUpdate()) {
+            contactService.bumpLastUpdate(senderIdentity);
+        }
 
 		// Handle message depending on subtype
 		final Class<? extends AbstractMessage> messageClass = message.getClass();
@@ -1430,10 +1437,6 @@ public class MessageServiceImpl implements MessageService {
 			return false;
 		}
 
-		// As soon as we get a direct message, unhide and unarchive the contact
-		contactService.setIsHidden(senderIdentity, false);
-		contactService.setIsArchived(senderIdentity, false);
-
 		logger.info("processIncomingContactMessage: {} SUCCESS - Message ID = {}", message.getMessageId(), messageModel.getId());
 		return true;
 	}

+ 12 - 0
app/src/main/java/ch/threema/app/services/PreferenceService.java

@@ -545,6 +545,7 @@ public interface PreferenceService {
 	void setPipPosition(int pipPosition);
 	int getPipPosition();
 
+	boolean isCallsEnabled();
 	boolean isVideoCallsEnabled();
 
 	boolean isGroupCallsEnabled();
@@ -610,4 +611,15 @@ public interface PreferenceService {
 	boolean isMdUnlocked();
 
 	boolean showConversationLastUpdate();
+
+	/**
+	 * Set the last timestamp when the notification permission has been requested.
+	 */
+	void setLastNotificationPermissionRequestTimestamp(long timestamp);
+
+	/**
+	 * Get the last timestamp when the notification permission has been requested. If the
+	 * notification permission has not yet been requested, 0 is returned.
+	 */
+	long getLastNotificationPermissionRequestTimestamp();
 }

+ 16 - 5
app/src/main/java/ch/threema/app/services/PreferenceServiceImpl.java

@@ -554,11 +554,7 @@ public class PreferenceServiceImpl implements PreferenceService {
 
 	@Override
 	public long getLastFeatureMaskTransmission() {
-		Long lastTransmission = this.preferenceStore.getLong(this.getKeyName(R.string.preferences__last_feature_mask_transmission));
-		if (lastTransmission == null) {
-			return 0;
-		}
-		return lastTransmission;
+		return this.preferenceStore.getLong(this.getKeyName(R.string.preferences__last_feature_mask_transmission));
 	}
 
 	@Override
@@ -1553,6 +1549,11 @@ public class PreferenceServiceImpl implements PreferenceService {
 		return this.preferenceStore.getInt(this.getKeyName(R.string.preferences__pip_position));
 	}
 
+	@Override
+	public boolean isCallsEnabled() {
+		return this.preferenceStore.getBoolean(this.getKeyName(R.string.preferences__voip_enable));
+	}
+
 	@Override
 	public boolean isVideoCallsEnabled() {
 		return this.preferenceStore.getBoolean(this.getKeyName(R.string.preferences__voip_video_enable));
@@ -1775,4 +1776,14 @@ public class PreferenceServiceImpl implements PreferenceService {
 	public boolean showConversationLastUpdate() {
 		return this.preferenceStore.getBoolean(this.getKeyName(R.string.preferences__show_last_update_prefix), false);
 	}
+
+	@Override
+	public void setLastNotificationPermissionRequestTimestamp(long timestamp) {
+		this.preferenceStore.save(this.getKeyName(R.string.preferences__last_notification_request_timestamp), timestamp);
+	}
+
+	@Override
+	public long getLastNotificationPermissionRequestTimestamp() {
+		return this.preferenceStore.getLong(this.getKeyName(R.string.preferences__last_notification_request_timestamp));
+	}
 }

+ 6 - 2
app/src/main/java/ch/threema/app/stores/PreferenceStore.java

@@ -536,8 +536,12 @@ public class PreferenceStore implements PreferenceStoreInterface {
 	}
 
 	@Override
-	public Long getLong(String key) {
-		return this.getLong(key, false);
+	public long getLong(String key) {
+		Long value = this.getLong(key, false);
+		if (value == null) {
+			return 0;
+		}
+		return value;
 	}
 
 	@Override

+ 8 - 1
app/src/main/java/ch/threema/app/stores/PreferenceStoreInterface.java

@@ -99,7 +99,14 @@ public interface PreferenceStoreInterface {
 
 	String getHexString(String key, boolean crypt);
 
-	Long getLong(String key);
+	/**
+	 * Get the value as long. Note that 0 is returned if no preference with the provided key is
+	 * stored.
+	 *
+	 * @param key the key of the value
+	 * @return the value as long or 0 if no value for the provided key exists
+	 */
+	long getLong(String key);
 
 	Long getLong(String key, boolean crypt);
 

+ 2 - 2
app/src/main/java/ch/threema/app/stores/PreferenceStoreInterfaceDevNullImpl.java

@@ -185,8 +185,8 @@ public class PreferenceStoreInterfaceDevNullImpl implements PreferenceStoreInter
 	}
 
 	@Override
-	public Long getLong(String key) {
-		return null;
+	public long getLong(String key) {
+		return 0;
 	}
 
 	@Override

+ 8 - 0
app/src/main/java/ch/threema/app/tasks/DeleteMessageUtils.kt

@@ -23,6 +23,7 @@ package ch.threema.app.tasks
 
 import ch.threema.app.messagereceiver.MessageReceiver
 import ch.threema.app.services.MessageService
+import ch.threema.app.utils.MessageUtil
 import ch.threema.base.utils.LoggingUtil
 import ch.threema.domain.models.MessageId
 import ch.threema.domain.protocol.csp.messages.AbstractMessage
@@ -72,6 +73,13 @@ private fun runCommonDeleteMessageReceiveSteps(
         return null
     }
 
+    // 3. If the `message` is not deletable because of its type, discard the message and abort these
+    //    steps.
+    if (!MessageUtil.canDeleteRemotely(message.type)) {
+        logger.warn("Incoming Delete Message: Message of type {} cannot be deleted", message.type)
+        return null
+    }
+
     // 4. Replace `message` with a message informing the user that the message of
     //    the sender has been removed at `created-at`.
     message.deletedAt = deleteMessage.date

+ 7 - 1
app/src/main/java/ch/threema/app/tasks/EditMessageUtils.kt

@@ -23,6 +23,7 @@ package ch.threema.app.tasks
 
 import ch.threema.app.messagereceiver.MessageReceiver
 import ch.threema.app.services.MessageService
+import ch.threema.app.utils.MessageUtil
 import ch.threema.base.utils.LoggingUtil
 import ch.threema.domain.models.MessageId
 import ch.threema.domain.protocol.csp.messages.AbstractMessage
@@ -63,7 +64,12 @@ private fun runCommonEditMessageReceiveSteps(
         return null
     }
     if (editMessage.fromIdentity != message.identity) {
-        logger.error("Incoming Edit Message: original message's sender ${message.identity} does not equal edited message's sender ${editMessage.fromIdentity}")
+        logger.warn("Incoming Edit Message: original message's sender ${message.identity} does not equal edited message's sender ${editMessage.fromIdentity}")
+        return null
+    }
+
+    if (!MessageUtil.canEdit(message.type)) {
+        logger.warn("Incoming Edit Message: Message of type {} cannot be edited", message.type)
         return null
     }
 

+ 9 - 6
app/src/main/java/ch/threema/app/ui/AckjiPopup.java

@@ -129,7 +129,11 @@ AckjiPopup extends PopupWindow implements View.OnClickListener {
 				GroupService groupService = ThreemaApplication.getServiceManager().getGroupService();
 				GroupModel groupModel = groupService.getById(((GroupMessageModel) messageModel).getGroupId());
 				if (groupModel != null) {
-					if (!groupService.isGroupMember(groupModel) || groupService.getOtherMemberCount(groupModel) < 1) {
+					boolean isMember = groupService.isGroupMember(groupModel);
+					if (!isMember) {
+						this.editButton.setVisibility(View.GONE);
+					}
+					if (!isMember|| groupService.getOtherMemberCount(groupModel) < 1) {
 						this.decButton.setVisibility(View.GONE);
 						this.ackButton.setVisibility(View.GONE);
 					}
@@ -147,15 +151,14 @@ AckjiPopup extends PopupWindow implements View.OnClickListener {
 		}
 
 		this.infoSeparator.setVisibility(View.GONE);
-		if (!messageModel.isDeleted() &&
-			(messageModel.getType().equals(MessageType.TEXT) ||
+		if (messageModel.getType().equals(MessageType.TEXT) ||
 			messageModel.getType().equals(MessageType.FILE) ||
 			messageModel.getType().equals(MessageType.LOCATION) ||
 			messageModel.getType().equals(MessageType.BALLOT) ||
 			messageModel.getType().equals(MessageType.CONTACT) ||
 			messageModel.getType().equals(MessageType.IMAGE) ||
 			messageModel.getType().equals(MessageType.VIDEO) ||
-			messageModel.getType().equals(MessageType.VOICEMESSAGE))
+			messageModel.getType().equals(MessageType.VOICEMESSAGE)
 		) {
 			this.infoButton.setVisibility(View.VISIBLE);
 			this.starButton.setVisibility(messageModel instanceof DistributionListMessageModel ? View.GONE : View.VISIBLE);
@@ -166,12 +169,12 @@ AckjiPopup extends PopupWindow implements View.OnClickListener {
 			if ((messageModel.getDisplayTags() & DisplayTag.DISPLAY_TAG_STARRED) == DisplayTag.DISPLAY_TAG_STARRED) {
 				this.starButton.setImageResource(R.drawable.star_outline_off_black_24dp);
 				this.starButton.setColorFilter(ConfigUtils.getColorFromAttribute(parentView.getContext(), R.attr.colorOnSurface));
+			} else if (messageModel.isDeleted()) {
+				starButton.setVisibility(View.GONE);
 			} else {
 				this.starButton.setImageResource(R.drawable.ic_star_golden_24dp);
 				this.starButton.setColorFilter(null);
 			}
-		} else {
-			this.starButton.setVisibility(View.GONE);
 		}
 
 		int[] originLocation = {0, 0};

+ 9 - 1
app/src/main/java/ch/threema/app/utils/ConfigUtils.java

@@ -1154,14 +1154,22 @@ public class ConfigUtils {
 	 *
 	 * @param context                   the context is needed to check whether the permission is already granted
 	 * @param requestPermissionLauncher the request permission launcher will be used to get the result
+	 * @param preferenceService         the preference service is used to update the last notification permission request timestamp if needed
 	 * @return {@code true} if the permission is already granted, {@code false} otherwise
 	 */
-	public static boolean requestNotificationPermission(@NonNull Context context, @NonNull ActivityResultLauncher<String> requestPermissionLauncher) {
+	public static boolean requestNotificationPermission(
+		@NonNull Context context,
+		@NonNull ActivityResultLauncher<String> requestPermissionLauncher,
+		@Nullable PreferenceService preferenceService
+	) {
 		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
 			return true;
 		}
 		String permission = Manifest.permission.POST_NOTIFICATIONS;
 		if (checkIfNeedsPermissionRequest(context, new String[]{permission})) {
+			if (preferenceService != null) {
+				preferenceService.setLastNotificationPermissionRequestTimestamp(System.currentTimeMillis());
+			}
 			requestPermissionLauncher.launch(permission);
 			return false;
 		}

+ 50 - 1
app/src/main/java/ch/threema/app/utils/MessageUtil.java

@@ -854,6 +854,28 @@ public class MessageUtil {
 		);
 	}
 
+    /**
+     * Check whether the given message type allows editing the message. Note that only the message
+     * type is considered. To check whether the user should be able to edit,
+     * {@link #canEdit(AbstractMessageModel)} should be used.
+     */
+    public static boolean canEdit(@Nullable MessageType messageType) {
+        if (messageType == null) {
+            return false;
+        }
+
+        switch (messageType) {
+            case TEXT:
+            case FILE:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Check whether the user should be able to edit the given message.
+     */
 	public static boolean canEdit(@NonNull AbstractMessageModel message) {
 		long deltaTime = new Date().getTime() - message.getCreatedAt().getTime();
 		return (message.getType() == MessageType.TEXT || message.getType() == MessageType.FILE)
@@ -866,9 +888,36 @@ public class MessageUtil {
 			&& !message.isDeleted();
 	}
 
+    /**
+     * Check whether the given message type allows remote deletion of messages. Note that only the
+     * message type is considered. To check whether the user should be able to delete a message for
+     * everyone, {@link #canDeleteRemotely(AbstractMessageModel)} should be used.
+     */
+    public static boolean canDeleteRemotely(@Nullable MessageType messageType) {
+        if (messageType == null) {
+            return false;
+        }
+
+        switch (messageType) {
+            case TEXT:
+            case IMAGE:
+            case VIDEO:
+            case VOICEMESSAGE:
+            case LOCATION:
+            case CONTACT:
+            case FILE:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Check whether the user should be able to delete the given message remotely.
+     */
 	public static boolean canDeleteRemotely(@NonNull AbstractMessageModel message) {
 		long deltaTime = new Date().getTime() - message.getCreatedAt().getTime();
-		return message.getType() != MessageType.BALLOT
+		return canDeleteRemotely(message.getType())
 			&& !message.isStatusMessage()
 			&& message.isOutbox()
 			&& ConfigUtils.isDeleteMessagesEnabled()

+ 16 - 3
app/src/main/res/layout/conversation_list_item_deleted_recv.xml

@@ -14,7 +14,7 @@
         style="@style/Threema.CardView.Bubble.Receive"
         android:id="@+id/message_block">
 
-        <LinearLayout
+        <androidx.constraintlayout.widget.ConstraintLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:orientation="vertical">
@@ -56,9 +56,22 @@
                 android:singleLine="true"
                 tools:text="17:20 PM"
                 app:layout_constraintBottom_toBottomOf="parent"
-                app:layout_constraintRight_toRightOf="parent" />
+                app:layout_constraintLeft_toLeftOf="parent" />
+
+            <ImageView
+                android:id="@+id/star_icon"
+                app:srcCompat="@drawable/ic_star_golden_24dp"
+                android:layout_width="18dp"
+                android:layout_height="18dp"
+                android:padding="3dp"
+                android:layout_gravity="center_vertical"
+                android:visibility="gone"
+                android:contentDescription="@string/starred_message"
+                tools:visibility="visible"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintLeft_toRightOf="@id/date_view" />
 
-        </LinearLayout>
+        </androidx.constraintlayout.widget.ConstraintLayout>
 
     </com.google.android.material.card.MaterialCardView>
 

+ 15 - 2
app/src/main/res/layout/conversation_list_item_deleted_send.xml

@@ -13,7 +13,7 @@
         style="@style/Threema.CardView.Bubble.Send"
         android:id="@+id/message_block">
 
-        <LinearLayout
+        <androidx.constraintlayout.widget.ConstraintLayout
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:paddingLeft="@dimen/chat_bubble_margin_end"
@@ -47,7 +47,20 @@
                 app:layout_constraintBottom_toBottomOf="parent"
                 app:layout_constraintRight_toRightOf="parent" />
 
-        </LinearLayout>
+            <ImageView
+                android:id="@+id/star_icon"
+                app:srcCompat="@drawable/ic_star_golden_24dp"
+                android:layout_width="18dp"
+                android:layout_height="18dp"
+                android:padding="3dp"
+                android:layout_gravity="center_vertical"
+                android:visibility="gone"
+                android:contentDescription="@string/starred_message"
+                tools:visibility="visible"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintRight_toLeftOf="@id/date_view"/>
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
 
     </com.google.android.material.card.MaterialCardView>
 

+ 5 - 2
app/src/main/res/layout/fragment_ballot_wizard1.xml

@@ -80,7 +80,8 @@
 			android:layout_height="@dimen/emoji_button_width"
 			android:layout_toLeftOf="@+id/add_time"
 			android:drawablePadding="0dp"
-			android:contentDescription="@string/insert_date"
+            android:layout_centerVertical="true"
+            android:contentDescription="@string/insert_date"
 			app:srcCompat="@drawable/ic_event"
 			android:background="@drawable/selector_compose_button"
 			app:tint="?attr/colorOnSurface" />
@@ -92,7 +93,8 @@
 			android:layout_height="@dimen/emoji_button_width"
 			android:layout_toLeftOf="@+id/create_choice"
 			android:drawablePadding="0dp"
-			android:contentDescription="@string/insert_datetime"
+            android:layout_centerVertical="true"
+            android:contentDescription="@string/insert_datetime"
 			app:srcCompat="@drawable/ic_schedule"
 			android:background="@drawable/selector_compose_button"
 			app:tint="?attr/colorOnSurface" />
@@ -103,6 +105,7 @@
 			android:layout_width="@dimen/emoji_button_width"
 			android:layout_height="@dimen/emoji_button_width"
 			android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
 			android:drawablePadding="0dp"
 			app:srcCompat="@drawable/ic_add_circle_black_24dp"
 			app:tint="@drawable/selector_button_tint"

+ 9 - 0
app/src/main/res/values-be-rBY/colorpicker_strings.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Абярыце колер</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Колер <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Выбраны колер <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
+</resources>

+ 21 - 7
app/src/main/res/values-be-rBY/strings.xml

@@ -37,8 +37,7 @@
     <string name="prefs_sum_sync_contacts_on">Падтрымліваць сінхранізацыю карыстальнікаў %s з адраснай кнігай вашай прылады</string>
     <string name="prefs_sum_sync_contacts_off">Не сінхранізаваць карыстальнікаў %s з адраснай кнігай вашай прылады</string>
     <string name="prefs_title_sync_contacts">Сінхраніз. кантактаў</string>
-    <string name="prefs_sum_block_unknown_off">Любы карыстальнік можа адправіць вам паведамленне.  Новыя кантакты будуць дададзены аўтаматычна
-пры атрыманні першага паведамлення.</string>
+    <string name="prefs_sum_block_unknown_off">Любы чалавек можа адправіць вам паведамленне.  Новыя кантакты будуць дададзены аўтаматычна, калі прыйдзе першае паведамленне.</string>
     <string name="prefs_sum_block_unknown_on">Адправіць вам паведамленне могуць толькі людзі з вашага спісу кантактаў.</string>
     <string name="prefs_title_block_unknown">Блакаванне незнаёмых</string>
     <string name="prefs_title_read_receipts">Апавяшчаць аб чытанні</string>
@@ -512,6 +511,7 @@
     <string name="file_placeholder">Файл</string>
     <string name="internal_storage">Унутранае сховішча</string>
     <string name="no_activity_for_mime_type">Не знайшлі праграму для адкрыцця гэтага файла.</string>
+    <string name="no_activity_for_intent">Праграма не знойдзена.</string>
     <string name="open_from">Адкрыць з</string>
     <string name="file_one_contact_not_supported">%1$s не можа прымаць файлы.</string>
     <string name="file_x_contact_not_supported">Увага: %1$d кантакты(аў) не могуць прыняць ваш файл.</string>
@@ -1017,6 +1017,7 @@
     <string name="system_default">Прадвызначаны  сістэмны</string>
     <string name="open_in_maps_app">Адк-ць у праграме \"Мапы\"</string>
     <string name="delete">Выдаліць</string>
+    <string name="delete_from_this_device">Выдаліць з гэтай прылады</string>
     <string name="delete_for_all">Выдаліць для ўсіх</string>
     <string name="message_was_deleted">Гэта паведамленне было выдалена</string>
     <string name="continue_recording">Працягнуць запіс</string>
@@ -1252,7 +1253,7 @@
     <string name="id_backup_info">Аднавіць толькі ID</string>
     <string name="restore_your_id_contacts_and_groups">Аднавіць ID, кантакты і суполкі</string>
     <string name="threema_safe_backup">Бяспечная рэз. копія Threema</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>Забылі пароль?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>Даведка</a>]]></string>
     <string name="download_failed">Не ўдалося спампаваць. Код памылкі: %d</string>
     <string name="edit_answer">Змяніць адказ</string>
     <string name="share_media">Падзяліцца з іншай праграмай…</string>
@@ -1553,9 +1554,16 @@
     <string name="edit_message_not_supported_for_all_group_members">Наступныя ўдзельнікі групы не змогуць бачыць вашыя праўкі: %1$s</string>
     <string name="edit_message_not_supported_for_any_group_members">Немагчыма адрэдагаваць паведамленне, таму што ні ў аднаго члена групы няма версіі праграмы, якая падтрымлівае гэтую функцыю.</string>
     <string name="delete_message_not_supported_for_all_group_members">Гэта паведамленне не будзе выдалена для наступных удзельнікаў групы: %1$s</string>
+    <string name="work_intro_more_link_text">Даведайцеся больш аб Threema Work</string>
+    <string name="work_intro_subtitle">Бяспечны бізнес-месенджэр\nдля кампаній.</string>
+    <string name="work_intro_login">Уваход %1$s</string>
+    <string name="consumer_notice_description">Калі вы з\'яўляецеся радавым карыстальнікам, загрузіце звычайную праграму Threema.</string>
+    <string name="consumer_notice_playstore_link_description">Threema у Play Store</string>
+    <string name="consumer_notice_appgallery_link_description">Threema у AppGallery</string>
+    <string name="consumer_notice_subtitle">Для асабістага карыстання</string>
     <plurals name="contacts_counter_label">
-        <item quantity="few">%d кантактаў</item>
-        <item quantity="many">%d кантакты</item>
+        <item quantity="few">%d кантакты</item>
+        <item quantity="many">%d кантактаў</item>
         <item quantity="one">%d кантакт</item>
         <item quantity="other">%d кантактаў</item>
     </plurals>
@@ -1628,11 +1636,17 @@
         <item quantity="one">На %d гадзіну</item>
         <item quantity="other">На працягу %d гадзін</item>
     </plurals>
+    <plurals name="really_delete_contacts_message">
+        <item quantity="few">Вы сапраўды хочаце выдаліць %1$d кантакты і ўсе звязаныя чаты?</item>
+        <item quantity="many">Вы сапраўды хочаце выдаліць %1$d кантактаў і ўсе звязаныя чаты?</item>
+        <item quantity="one">Вы сапраўды хочаце выдаліць %1$d кантакт і ўсе звязаныя чаты?</item>
+        <item quantity="other">Вы сапраўды хочаце выдаліць %1$d кантактаў і ўсе звязаныя чаты?</item>
+    </plurals>
     <plurals name="some_contacts_not_deleted">
         <item quantity="few">Немагчыма выдаліць %d кантакты, таму што яны ўсё яшчэ ўваходзяць у суполку.</item>
-        <item quantity="many">Немагчыма выдаліць %d кантакты, таму што яны ўсё яшчэ ўваходзяць у суполку.</item>
+        <item quantity="many">Немагчыма выдаліць %d кантактаў, таму што яны ўсё яшчэ ўваходзяць у суполку.</item>
         <item quantity="one">%d кантакт не можа быць выдалены, таму што ён усё яшчэ ўваходзіць у суполку.</item>
-        <item quantity="other">Немагчыма выдаліць %d кантакты, таму што яны ўсё яшчэ ўваходзяць у суполку.</item>
+        <item quantity="other">Немагчыма выдаліць %d кантактаў, таму што яны ўсё яшчэ ўваходзяць у суполку.</item>
     </plurals>
     <plurals name="message_archived">
         <item quantity="few">%d чатаў заархівавана</item>

+ 1 - 1
app/src/main/res/values-be-rBY/webclient_strings.xml

@@ -17,7 +17,7 @@
     <string name="webclient_unnamed_session">Безназоўная сесія</string>
     <string name="webclient_session_remove">Выдаліць сесію</string>
     <string name="webclient_welcome_title">Майце знос. з вашага камп-а</string>
-    <string name="webclient_welcome_explain">Праграма для ПК і вэб-кліент дазваляюць мець зносіны з вашага кампутара ці наўтбука, даючы вам поўны доступ да ўсіх кантактаў, мультымедыя і чатам.\n\n<b>Усе камунікацыі паміж тэлефонам і кампутарам абаронены скразным шыфраваннем</b> і выкарыстоўваюць прамое падлучэнне, калі тэлефон і кампутар знаходзяцца ў адной сетцы.\n\nЗвярніце ўвагу: праграма для ПК / вэб-кліент можа выклікаць дадатковы разрад батарэі, пакуль сесія актыўная. Вы можаце ўключыць або адключыць праграму у любы час.</string>
+    <string name="webclient_welcome_explain">Праграма для ПК і вэб-кліент дазваляюць мець зносіны з вашага камп’ютара ці ноўтбука, даючы вам поўны доступ да ўсіх кантактаў, мультымедыя і чатам.\n\n<b>Усе камунікацыі паміж тэлефонам і камп’ютарам абаронены скразным шыфраваннем</b> і выкарыстоўваюць прамое падлучэнне, калі тэлефон і камп’ютар знаходзяцца ў адной сетцы.\n\nЗвярніце ўвагу: праграма для ПК / вэб-кліент можа выклікаць дадатковы разрад батарэі, пакуль сесія актыўная. Вы можаце ўключыць або адключыць праграму ў любы час.</string>
     <string name="webclient_launch">Запусціць праграму для ПК / вэб-кліента</string>
     <string name="webclient_qr_scan_message">Калі ласка, адскануйце QR-код, які адлюстроўваецца на кампутары.</string>
     <string name="webclient_invalid_qr_code">Няправільны QR-код</string>

+ 9 - 0
app/src/main/res/values-cs/colorpicker_strings.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Vyberte barvu</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Barva <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Barva <xliff:g id="color_index" example="14">%1$d</xliff:g> vybrána</string>
+</resources>

+ 7 - 7
app/src/main/res/values-cs/strings.xml

@@ -1025,7 +1025,7 @@ přátelům vás automaticky najít, pokud vás mají v adresáři svého telef
     <string name="continue_recording">Pokračovat v nahrávání</string>
     <string name="whatsnew_title">Co je nového v aplikaci %1$s 5.2?</string>
     <string name="whatsnew_headline"><![CDATA[
-		<p>Ohvězdičkované zprávy: Abyste je později snadno našli, označte důležité zprávy hvězdou dlouhým klepnutím.</p>
+		<p>Zprávy s hvězdičkou: Abyste je později snadno našli, označte důležité zprávy hvězdou dlouhým klepnutím.</p>
 		<p>Automatické odstranění: Nechte své konverzace po uplynutí volitelné doby automaticky vyčistit. Funkce automatického odstranění zpráv můžete aktivovat ve správě úložiště.</p>
 		<p>Další četná vylepšení a optimalizace.</p>
 		]]></string>
@@ -1251,7 +1251,7 @@ přátelům vás automaticky najít, pokud vás mají v adresáři svého telef
     <string name="id_backup_info">Obnovit pouze vaše ID</string>
     <string name="restore_your_id_contacts_and_groups">Obnovit vaše ID, kontakty a skupiny</string>
     <string name="threema_safe_backup">Záloha Threema Safe</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>Zapomněli jste heslo?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>Pomoc</a>]]></string>
     <string name="download_failed">Stažení se nezdařilo. Kód chyby: %d</string>
     <string name="edit_answer">Upravit odpověď</string>
     <string name="share_media">Sdílet v jiné aplikaci…</string>
@@ -1481,14 +1481,14 @@ přátelům vás automaticky najít, pokud vás mají v adresáři svého telef
     <string name="permission_enable_in_settings_rationale">Udělte prosím toto oprávnění v nastavení. Vyberte možnost „Oprávnění“ a poté povolte „%s“.</string>
     <string name="group_name">Název skupiny</string>
     <string name="star_message">Ohvězdičkovat zprávu</string>
-    <string name="starred_message">Ohvězdičkovaná zpráva</string>
-    <string name="starred">Ohvězdičkované</string>
-    <string name="starred_messages">Ohvězdičkované zprávy</string>
+    <string name="starred_message">Zpráva s hvězdičkou</string>
+    <string name="starred">S hvězdičkou</string>
+    <string name="starred_messages">Zprávy s hvězdičkou</string>
     <string name="sorting">Řazení</string>
     <string name="sort_by">Řadit podle…</string>
     <string name="newest_first">od nejnovějších</string>
     <string name="oldest_first">od nejstarších</string>
-    <string name="no_starred_messages">Nebyly nalezeny žádné ohvězdičkované zprávy. Zprávu ohvězdičkujete tak, že na ni dlouze klepnete a vyberete tlačítko s hvězdou.</string>
+    <string name="no_starred_messages">Nebyly nalezeny žádné zprávy s hvězdičkou. Ke zprávě přidáte hvězdičku tak, že na ni dlouze klepnete a vyberete tlačítko s hvězdou.</string>
     <string name="remove_all_stars">Odstranit všechny hvězdy</string>
     <string name="remove_star">Odstranit hvězdu</string>
     <string name="samsung_permission_problem_explain">Aplikace %1$s nemůže přistupovat k mediálním souborům kvůli chybějícímu oprávnění v systémové aplikaci. Chcete‑li tento problém opravit, ujistěte se, že je na následující obrazovce aktivovaný přepínač vedle položky „Externí úložiště“ a restartujte aplikaci %1$s.</string>
@@ -1504,7 +1504,7 @@ přátelům vás automaticky najít, pokud vás mají v adresáři svého telef
     <string name="keep_messages">Uchovávat zprávy po dobu:</string>
     <string name="clean_up_manually">Vyčistit ručně</string>
     <string name="forever">Navždy</string>
-    <string name="autodelete_explain">Pokud bude nastaveno cokoliv kromě „navždy“, příchozí a odchozí zprávy budou nenávratně odstraněny po uplynutí specifikované doby. Do toho jsou zahrnuty i nepřečtené a neodeslané zprávy. Zprávy ve skupinách pro poznámky a ohvězdičkované zprávy nebudou odstraněny. Proces odstranění je spouštěn periodicky a ne nutně ihned po aktivaci.</string>
+    <string name="autodelete_explain">Pokud bude nastaveno cokoliv kromě „navždy“, příchozí a odchozí zprávy budou nenávratně odstraněny po uplynutí specifikované doby. Do toho jsou zahrnuty i nepřečtené a neodeslané zprávy. Zprávy ve skupinách pro poznámky a zprávy s hvězdičkou nebudou odstraněny. Proces odstranění je spouštěn periodicky a ne nutně ihned po aktivaci.</string>
     <string name="autodelete_confirm">Zprávy budou automaticky odstraněny po %s. Pokračovat?</string>
     <string name="autodelete_activated">Automatické odstranění aktivováno.</string>
     <string name="autodelete_disabled">Automatické odstranění zakázáno.</string>

+ 1 - 1
app/src/main/res/values-de/strings.xml

@@ -1356,7 +1356,7 @@ sicheren Ort gesichert oder ausgedruckt haben.</string>
 	<string name="id_backup_info">Nur Ihre ID wiederherstellen</string>
 	<string name="restore_your_id_contacts_and_groups">Ihre ID, Kontakte und Gruppen wiederherstellen</string>
 	<string name="threema_safe_backup">Threema Safe Backup</string>
-	<string name="forgot_your_password"><![CDATA[<a href=%s>Passwort vergessen?</a>]]></string>
+	<string name="forgot_your_password"><![CDATA[<a href=%s>Hilfe</a>]]></string>
 	<string name="download_failed">Download fehlgeschlagen. Fehlercode: %d</string>
 	<string name="share_media">Mit anderer App teilen…</string>
 	<string name="group_link_administered">Administriert</string>

+ 8 - 6
app/src/main/res/values-es/colorpicker_strings.xml

@@ -1,7 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="color_picker_default_title" msgid="1248663997452044787">"Selecciona un color"</string>
-    <string name="color_swatch_description" msgid="2883438431173736180">"Color <xliff:g id="COLOR_INDEX">%1$d</xliff:g>"</string>
-    <string name="color_swatch_description_selected" msgid="5020921249944943124">"Color <xliff:g id="COLOR_INDEX">%1$d</xliff:g> seleccionado"</string>
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Selecciona un color</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Color <xliff:g id="COLOR_INDEX">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Color <xliff:g id="COLOR_INDEX">%1$d</xliff:g> seleccionado</string>
 </resources>

+ 2 - 2
app/src/main/res/values-es/strings.xml

@@ -37,7 +37,7 @@
     <string name="prefs_sum_sync_contacts_on">Sincronizar %s usuarios con la libreta de direcciones de su dispositivo</string>
     <string name="prefs_sum_sync_contacts_off">No sincronizar %s usuarios con la libreta de direcciones de su dispositivo</string>
     <string name="prefs_title_sync_contacts">Sincronizar contactos</string>
-    <string name="prefs_sum_block_unknown_off">Todos pueden enviarle mensajes. Con el primer mensaje, los nuevos contactos se agregan de forma automática.</string>
+    <string name="prefs_sum_block_unknown_off">Todos pueden enviarte mensajes. Con el primer mensaje, los nuevos contactos se agregan de forma automática.</string>
     <string name="prefs_sum_block_unknown_on">Solo podrán enviarle mensajes las personas de su lista de contactos.</string>
     <string name="prefs_title_block_unknown">Bloquear desconocidos</string>
     <string name="prefs_title_read_receipts">Enviar confirmaciones de lectura</string>
@@ -1258,7 +1258,7 @@ almacenado.</string>
     <string name="id_backup_info">Restablecer solo su ID</string>
     <string name="restore_your_id_contacts_and_groups">Restablecer su ID, contactos y grupos</string>
     <string name="threema_safe_backup">Copia de seguridad de Threema</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>¿Ha olvidado su contraseña?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>Ayuda</a>]]></string>
     <string name="download_failed">Descarga fallida. Código de error: %d</string>
     <string name="edit_answer">Editar respuesta</string>
     <string name="share_media">Compartir con otra aplicación...</string>

+ 8 - 21
app/src/main/res/values-fr/colorpicker_strings.xml

@@ -1,22 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="color_picker_default_title" msgid="1248663997452044787">"Sélectionner une couleur"</string>
-    <string name="color_swatch_description" msgid="2883438431173736180">"Couleur <xliff:g id="COLOR_INDEX">%1$d</xliff:g>"</string>
-    <string name="color_swatch_description_selected" msgid="5020921249944943124">"Couleur <xliff:g id="COLOR_INDEX">%1$d</xliff:g> sélectionnée"</string>
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Sélectionner une couleur</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Couleur <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Couleur <xliff:g id="COLOR_INDEX">%1$d</xliff:g> sélectionnée</string>
 </resources>

+ 2 - 2
app/src/main/res/values-fr/strings.xml

@@ -37,7 +37,7 @@
     <string name="prefs_sum_sync_contacts_on">Garder les utilisateurs %s synchronisés avec le carnet d\'adresses de votre appareil</string>
     <string name="prefs_sum_sync_contacts_off">Ne pas synchroniser les utilisateurs %s avec le carnet d\'adresses de votre appareil</string>
     <string name="prefs_title_sync_contacts">Synchroniser les contacts</string>
-    <string name="prefs_sum_block_unknown_off">Quiconque peut vous envoyer un message. Les nouveaux contacts seront automatiquement ajouté lors de réception du premier message.</string>
+    <string name="prefs_sum_block_unknown_off">Tout le monde peut vous envoyer un message. Les nouveaux contacts seront automatiquement ajoutés lors de la réception du premier message.</string>
     <string name="prefs_sum_block_unknown_on">Seules les personnes de votre liste de contacts peuvent vous envoyer un message.</string>
     <string name="prefs_title_block_unknown">Bloquer les inconnus</string>
     <string name="prefs_title_read_receipts">Envoyer des accusés réception de lecture</string>
@@ -1250,7 +1250,7 @@ Veuillez saisir une question pour votre enquête.</string>
     <string name="id_backup_info">Ne restaurer que votre ID</string>
     <string name="restore_your_id_contacts_and_groups">Restaurer votre ID, vos contacts et vos groupes</string>
     <string name="threema_safe_backup">Sauvegarde Threema Safe</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>Mot de passe oublié ?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>Aide</a>]]></string>
     <string name="download_failed">Échec de téléchargement. Code d\'erreur : %d</string>
     <string name="edit_answer">Modifier la réponse</string>
     <string name="share_media">Partager avec une autre application…</string>

+ 9 - 0
app/src/main/res/values-gsw/colorpicker_strings.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Farb uuswähle</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Farb <xliff:g id="COLOR_INDEX">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Farb <xliff:g id="COLOR_INDEX">%1$d</xliff:g> uusgwählt</string>
+</resources>

+ 10 - 1
app/src/main/res/values-gsw/strings.xml

@@ -510,6 +510,7 @@
     <string name="file_placeholder">Datei</string>
     <string name="internal_storage">Int. Speicher</string>
     <string name="no_activity_for_mime_type">Kei passendi App für die Datei gfunde.</string>
+    <string name="no_activity_for_intent">Kei passendi App gfunde.</string>
     <string name="open_from">Ufmache vo</string>
     <string name="file_one_contact_not_supported">%1$s cha no kei Dateie empfange.</string>
     <string name="file_x_contact_not_supported">Warnig: %1$d Kontäkt chönd kei Dateie empfange.</string>
@@ -1012,6 +1013,7 @@
     <string name="system_default">Systemstandard</string>
     <string name="open_in_maps_app">Ide Maps-App ufmache</string>
     <string name="delete">Lösche</string>
+    <string name="delete_from_this_device">Vo dem Grät lösche</string>
     <string name="delete_for_all">Für all lösche</string>
     <string name="message_was_deleted">Die Nachricht isch glöscht worde</string>
     <string name="continue_recording">Wiiter ufneh</string>
@@ -1241,7 +1243,7 @@
     <string name="id_backup_info">Nur Ihri ID wiederherstelle</string>
     <string name="restore_your_id_contacts_and_groups">Ihri ID, Kontäkt und Gruppe wiederherstelle</string>
     <string name="threema_safe_backup">Threema Safe-Backup</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>Passwort vergässe?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>Hilfe</a>]]></string>
     <string name="download_failed">Download fehlgschlage. Fehlercode: %d</string>
     <string name="edit_answer">Antwort bearbeite</string>
     <string name="share_media">Mitere andere App teile…</string>
@@ -1540,6 +1542,13 @@
     <string name="edit_message_not_supported_for_all_group_members">Di folgende Gruppemitglieder werded Ihri Änderige nöd gseh: %1$s</string>
     <string name="edit_message_not_supported_for_any_group_members">D’Nachricht cha nöd bearbeitet werde, wil keis Gruppemitglied en App-Version hät, wo die Funktion understützt.</string>
     <string name="delete_message_not_supported_for_all_group_members">Die Nachricht wird bi folgende Gruppemitglieder nöd glöscht: %1$s</string>
+    <string name="work_intro_more_link_text">Meh über Threema Work erfahre</string>
+    <string name="work_intro_subtitle">De sicheri Business-Messenger\nfür Undernehme.</string>
+    <string name="work_intro_login">Aamäldig %1$s</string>
+    <string name="consumer_notice_description">Wenn Sie d’App privat nutze wänd, ladet Sie bitte di regulär Threema-App abe.</string>
+    <string name="consumer_notice_playstore_link_description">Threema im Play Store</string>
+    <string name="consumer_notice_appgallery_link_description">Threema ide AppGallery</string>
+    <string name="consumer_notice_subtitle">Für di privat Nutzig</string>
     <plurals name="contacts_counter_label">
         <item quantity="other">%d Kontäkt</item>
     </plurals>

+ 6 - 4
app/src/main/res/values-hu/colorpicker_strings.xml

@@ -1,7 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
     <string name="color_picker_default_title">Szín kiválasztása</string>
+    <!-- Content description for a color square. -->
     <string name="color_swatch_description"><xliff:g id="color_index">%1$d</xliff:g> szín</string>
-    <string name="color_swatch_description_selected"><xliff:g id="color_index">%1$d</xliff:g> szín kiválasztva</string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate"><xliff:g id="color_index">%1$d</xliff:g> szín kiválasztva</string>
 </resources>

+ 1 - 1
app/src/main/res/values-hu/poi_strings.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
     <string name="hamlet">Kisfalu</string>
     <string name="village">Falu</string>
     <string name="town">Város</string>

+ 0 - 1
app/src/main/res/values-hu/strings.xml

@@ -1011,7 +1011,6 @@
     <string name="system_default">Rendszer alapértelmezett</string>
     <string name="open_in_maps_app">Megnyitás a Térképalkalmazásban</string>
     <string name="delete">Törlés</string>
-    <string name="message_was_deleted">Üzenet törölve</string>
     <string name="continue_recording">Felvétel folytatása</string>
     <string name="tap_to_start">Kattintson ide a %s indításához.</string>
     <string name="two_years">2 év</string>

+ 8 - 6
app/src/main/res/values-it/colorpicker_strings.xml

@@ -1,7 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="color_picker_default_title" msgid="1248663997452044787">"Seleziona un colore"</string>
-    <string name="color_swatch_description" msgid="2883438431173736180">"Colore <xliff:g id="COLOR_INDEX">%1$d</xliff:g>"</string>
-    <string name="color_swatch_description_selected" msgid="5020921249944943124">"Colore selezionato: <xliff:g id="COLOR_INDEX">%1$d</xliff:g>"</string>
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Seleziona un colore</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Colore <xliff:g id="COLOR_INDEX">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Colore selezionato: <xliff:g id="COLOR_INDEX">%1$d</xliff:g></string>
 </resources>

+ 19 - 2
app/src/main/res/values-it/strings.xml

@@ -323,6 +323,8 @@ automaticamente in caso di inattività dopo un intervallo predefinito (solo cara
     <string name="state_dialog_created">Creato</string>
     <string name="state_dialog_posted">Impostato</string>
     <string name="state_dialog_modified">Modificato</string>
+    <string name="state_dialog_edited">Modificato</string>
+    <string name="state_dialog_deleted">Cancellato</string>
     <string name="state_dialog_status">Stato</string>
     <string name="title_tab_recent">Ultimo</string>
     <string name="no_recent_conversations">Nessuna chat trovata</string>
@@ -531,6 +533,7 @@ automaticamente in caso di inattività dopo un intervallo predefinito (solo cara
     <string name="file_placeholder">File</string>
     <string name="internal_storage">Memoria interna</string>
     <string name="no_activity_for_mime_type">Non è stata trovata alcuna app per aprire questo file.</string>
+    <string name="no_activity_for_intent">Non è stata trovata nessuna app adatta.</string>
     <string name="open_from">Apri da</string>
     <string name="file_one_contact_not_supported">%1$s non può ricevere file.</string>
     <string name="file_x_contact_not_supported">Attenzione: %1$d contatti non possono ricevere il tuo file.</string>
@@ -1033,7 +1036,9 @@ automaticamente in caso di inattività dopo un intervallo predefinito (solo cara
     <string name="system_default">Impostazioni predefinite di sistema</string>
     <string name="open_in_maps_app">Apri in Mappe</string>
     <string name="delete">Elimina</string>
+    <string name="delete_from_this_device">Cancella da questo dispositivo</string>
     <string name="delete_for_all">Elimina per tutti</string>
+    <string name="message_was_deleted">Il messaggio è stato cancellato</string>
     <string name="continue_recording">Continua registrazione</string>
     <string name="whatsnew_title">Nuove funzioni in %1$s 5.2</string>
     <string name="whatsnew_headline"><![CDATA[
@@ -1554,6 +1559,18 @@ Numerosi altri miglioramenti e ottimizzazioni.</p>]]></string>
     <string name="media_gallery_animated_webps">WebP animati</string>
     <string name="unsupported_image_type">Tipo di immagine non supportato: %s</string>
     <string name="application_setup_steps_failed">Per controllare lo stato dei contatti è necessaria una connessione Internet attiva. Assicurati di essere connesso a Internet e riprova.</string>
+    <string name="add_contact_failed">Impossibile aggiungere il contatto</string>
+    <string name="edit_message_not_supported_for_contact">Impossibile modificare il messaggio, poiché la versione dell\'app del destinatario non supporta questa funzione.</string>
+    <string name="edit_message_not_supported_for_all_group_members">I seguenti membri del gruppo non possono vedere le modifiche: %1$s</string>
+    <string name="edit_message_not_supported_for_any_group_members">Impossibile modificare il messaggio, poiché nessun membro del gruppo dispone di una versione dell\'app che supporta questa funzione.</string>
+    <string name="delete_message_not_supported_for_all_group_members">Dai seguenti membri del gruppo il messaggio non sarà cancellato: %1$s</string>
+    <string name="work_intro_more_link_text">Maggiori informazioni su Threema Work</string>
+    <string name="work_intro_subtitle">L\'app di messaggistica sicura per le imprese.</string>
+    <string name="work_intro_login">Accedi %1$s</string>
+    <string name="consumer_notice_description">Se vuoi usare l\'app privatamente sei pregato di scaricare l\'app Threema regolare.</string>
+    <string name="consumer_notice_playstore_link_description">Threema nel Play Store</string>
+    <string name="consumer_notice_appgallery_link_description">Threema nell\'AppGallery</string>
+    <string name="consumer_notice_subtitle">Per uso privato</string>
     <plurals name="contacts_counter_label">
         <item quantity="one">%d contatto</item>
         <item quantity="other">%d contatti</item>
@@ -1635,8 +1652,8 @@ Numerosi altri miglioramenti e ottimizzazioni.</p>]]></string>
         <item quantity="other">Dall\'ultimo messaggio %d messaggi sono andati persi.</item>
     </plurals>
     <plurals name="delete_messages">
-        <item quantity="one">Cancellare %d messaggio da questo dispositivo?</item>
-        <item quantity="other">Cancellare %d messaggi da questo dispositivo?</item>
+        <item quantity="one">Cancellare %d messaggio?</item>
+        <item quantity="other">Cancellare %d messaggi?</item>
     </plurals>
     <plurals name="number_of_group_members">
         <item quantity="one">%d membro del gruppo</item>

+ 1 - 1
app/src/main/res/values-ja/strings.xml

@@ -1623,7 +1623,7 @@ https://myid.threema.ch/revoke に入力することで ID を削除すること
         <item quantity="other">%d 件のメッセージが最後のメッセージからロストしました。</item>
     </plurals>
     <plurals name="delete_messages">
-        <item quantity="other">%d 件のメッセージをこのデバイスから削除しますか?</item>
+        <item quantity="other">%d 件のメッセージを削除しますか?</item>
     </plurals>
     <plurals name="number_of_group_members">
         <item quantity="other">%d名のグループメンバー</item>

+ 8 - 5
app/src/main/res/values-nl-rNL/colorpicker_strings.xml

@@ -1,6 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="color_picker_default_title" msgid="1248663997452044787">"Een kleur selecteren"</string>
-    <string name="color_swatch_description" msgid="2883438431173736180">"Kleur <xliff:g id="COLOR_INDEX">%1$d</xliff:g>"</string>
-    <string name="color_swatch_description_selected" msgid="5020921249944943124">"Kleur <xliff:g id="COLOR_INDEX">%1$d</xliff:g> geselecteerd"</string>
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Een kleur selecteren</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Kleur <xliff:g id="COLOR_INDEX">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Kleur <xliff:g id="COLOR_INDEX">%1$d</xliff:g> geselecteerd</string>
 </resources>

+ 2 - 2
app/src/main/res/values-nl-rNL/strings.xml

@@ -37,7 +37,7 @@
     <string name="prefs_sum_sync_contacts_on">Houd %s-gebruikers in sync met het adresboek van uw apparaat</string>
     <string name="prefs_sum_sync_contacts_off">%s-gebruikers niet synchroniseren met het adresboek van uw apparaat</string>
     <string name="prefs_title_sync_contacts">Contactpersonen synchroniseren</string>
-    <string name="prefs_sum_block_unknown_off">Iedereen kan u een bericht sturen. Nieuwe contactpersonen worden automiatisch toegevoegd wanneer het eerste bericht arriveert.</string>
+    <string name="prefs_sum_block_unknown_off">Iedereen kan u een bericht sturen. Nieuwe contactpersonen worden automatisch toegevoegd wanneer het eerste bericht binnenkomt.</string>
     <string name="prefs_sum_block_unknown_on">Alleen mensen in uw adresboek kunnen u berichten sturen.</string>
     <string name="prefs_title_block_unknown">Onbekenden blokkeren</string>
     <string name="prefs_title_read_receipts">Leesbevestiging versturen</string>
@@ -1252,7 +1252,7 @@ Weet u zeker dat u Threema anoniem wil gebruiken?</string>
     <string name="id_backup_info">Alleen je ID herstellen</string>
     <string name="restore_your_id_contacts_and_groups">Je ID, contactpersonen en groepen herstellen</string>
     <string name="threema_safe_backup">Threema Safe Back-up</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>Je wachtwoord vergeten?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>Help</a>]]></string>
     <string name="download_failed">Niet gedownload. Foutcode: %d</string>
     <string name="edit_answer">Antwoord bewerken</string>
     <string name="share_media">Delen met andere app…</string>

+ 8 - 7
app/src/main/res/values-pl/colorpicker_strings.xml

@@ -1,8 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="color_picker_default_title" msgid="1248663997452044787">"Wybierz kolor"</string>
-    <string name="color_swatch_description" msgid="2883438431173736180">"Kolor <xliff:g id="COLOR_INDEX">%1$d</xliff:g>"</string>
-    <string name="color_swatch_description_selected" msgid="5020921249944943124">"Wybrałeś kolor <xliff:g id="COLOR_INDEX">%1$d</xliff:g>"</string>
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Wybierz kolor</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Kolor <xliff:g id="COLOR_INDEX">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Wybrałeś kolor <xliff:g id="COLOR_INDEX">%1$d</xliff:g></string>
 </resources>

+ 2 - 2
app/src/main/res/values-pl/strings.xml

@@ -37,7 +37,7 @@
     <string name="prefs_sum_sync_contacts_on">Utrzymuj synchronizację użytkowników %s z książką adresową Twojego urządzenia</string>
     <string name="prefs_sum_sync_contacts_off">Nie synchronizuj użytkowników %s z książką adresową Twojego urządzenia</string>
     <string name="prefs_title_sync_contacts">Synchronizuj kontakty</string>
-    <string name="prefs_sum_block_unknown_off">Każdy może wysłać do Ciebie wiadomość. Nowe kontakty zostaną dodane automatycznie po odebraniu wiadomości.</string>
+    <string name="prefs_sum_block_unknown_off">Każdy może wysłać do Pana/Pani wiadomość. Nowe kontakty zostaną dodane automatycznie po odebraniu pierwszej wiadomości.</string>
     <string name="prefs_sum_block_unknown_on">Tylko osoby z Twojej listy kontaktów mogą wysłać do Ciebie wiadomość.</string>
     <string name="prefs_title_block_unknown">Blokuj nieznajomych</string>
     <string name="prefs_title_read_receipts">Potwierdzaj przeczytane</string>
@@ -1266,7 +1266,7 @@ anonimowo?</string>
     <string name="id_backup_info">Przywróć tylko swoje ID</string>
     <string name="restore_your_id_contacts_and_groups">Przywróć swój identyfikator, kontakty i grupy</string>
     <string name="threema_safe_backup">Threema Safe</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>Nie pamiętasz hasła?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>Pomoc</a>]]></string>
     <string name="download_failed">Pobieranie nie powiodło się. Kod błędu: %d</string>
     <string name="edit_answer">Edytuj odpowiedź</string>
     <string name="share_media">Udostępnij innej aplikacji...</string>

+ 8 - 6
app/src/main/res/values-pt-rBR/colorpicker_strings.xml

@@ -1,7 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="color_picker_default_title" msgid="1248663997452044787">"Selecione uma cor"</string>
-    <string name="color_swatch_description" msgid="2883438431173736180">"Cor <xliff:g id="COLOR_INDEX">%1$d</xliff:g>"</string>
-    <string name="color_swatch_description_selected" msgid="5020921249944943124">"Cor <xliff:g id="COLOR_INDEX">%1$d</xliff:g> selecionada"</string>
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Selecione uma cor</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Cor <xliff:g id="COLOR_INDEX">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Cor <xliff:g id="COLOR_INDEX">%1$d</xliff:g> selecionada</string>
 </resources>

+ 1 - 1
app/src/main/res/values-pt-rBR/strings.xml

@@ -1251,7 +1251,7 @@ Por favor, insira uma pergunta para a sua enquete.</string>
     <string name="id_backup_info">Apenas restaurar sua ID</string>
     <string name="restore_your_id_contacts_and_groups">Restaurar sua ID, contatos e grupos</string>
     <string name="threema_safe_backup">Backup seguro do Backup</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>Esqueceu sua senha?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>Ajuda</a>]]></string>
     <string name="download_failed">Falha no download. Código de erro: %d</string>
     <string name="edit_answer">Editar resposta</string>
     <string name="share_media">Compartilhe com outro aplicativo...</string>

+ 18 - 0
app/src/main/res/values-rm/strings.xml

@@ -307,6 +307,8 @@ Endatescha in pled-clav per tes backup da datas.</string>
     <string name="state_dialog_created">Creà</string>
     <string name="state_dialog_posted">Tramess</string>
     <string name="state_dialog_modified">Actualisà</string>
+    <string name="state_dialog_edited">Elavurà</string>
+    <string name="state_dialog_deleted">Stizzà</string>
     <string name="state_dialog_status">Status</string>
     <string name="title_tab_recent">Ultims</string>
     <string name="no_recent_conversations">Chattà nagins chats</string>
@@ -509,6 +511,7 @@ Endatescha in pled-clav per tes backup da datas.</string>
     <string name="file_placeholder">Datoteca</string>
     <string name="internal_storage">Arcun intern</string>
     <string name="no_activity_for_mime_type">Chattà nagina app adattada per questa datoteca.</string>
+    <string name="no_activity_for_intent">Chattà nagina app adattada.</string>
     <string name="open_from">Avrir da</string>
     <string name="file_one_contact_not_supported">%1$s na po anc retschaiver naginas datotecas.</string>
     <string name="file_x_contact_not_supported">Attenziun: %1$d contacts na pon retschaiver naginas datotecas.</string>
@@ -1011,8 +1014,18 @@ Endatescha in pled-clav per tes backup da datas.</string>
     <string name="system_default">Standard</string>
     <string name="open_in_maps_app">Avrir en l\'app Maps</string>
     <string name="delete">Stizzar</string>
+    <string name="delete_from_this_device">Stizzar sin quest apparat</string>
     <string name="delete_for_all">Stizzar per tuts</string>
+    <string name="message_was_deleted">Stizzà quest messadi</string>
     <string name="continue_recording">Registrar vinavant</string>
+    <string name="whatsnew_title">Novas funcziuns en %1$s 5.2</string>
+    <string name="whatsnew_headline"><![CDATA[
+<p>Marcar messadis: cun tippar ditg sin in messadi marcheschas ti el cun ina staila, uschia che ti al chattas spert pli tard.</p>
+
+<p>Stizzar automaticamain: ti pos laschar far urden automaticamain cun tes chats suenter in temp che ti defineschas. La funcziun da stizzar automaticamain messadis pos ti activar en il management da l\'arcun.</p>
+
+<p>Numerusas ulteriuras meglieraziuns ed optimaziuns.</p>
+		]]></string>
     <string name="tap_to_start">Smatga qua per aviar uss %s.</string>
     <string name="two_years">2 onns</string>
     <string name="invalid_backup_path">Percurs dal backup nunvalaivel</string>
@@ -1500,6 +1513,11 @@ Sche ti midas sin in nov apparat, deinstallescha u deactivescha p.pl. %s sin l\'
     <string name="action_dissolve_group">Annullar la gruppa</string>
     <string name="really_dissolve_group">Sche ti annulleschas sulettamain la gruppa, na po nagin pli trametter novs messadis en la gruppa ed i n\'è betg pli pussaivel d\'administrar ella. Igl è però vinavant pussaivel da clonar la gruppa.</string>
     <string name="status_orphaned_group">*Questa gruppa è orfna*\nLa persuna che ha creà la gruppa l\'ha bandunà. Ella n\'è betg pli administrabla. Ina commembra u in commember da la gruppa restant duai clonar la gruppa (via detagls da la gruppa) per daventar la nova administratura resp. il nov administratur.</string>
+    <string name="group_orphaned_notice">Questa gruppa è orfna, perquai che la persuna che ha creà la gruppa l\'ha bandunà. P.pl. clonar la  gruppar per daventar il nov administratur.</string>
+    <string name="group_not_a_member_notice">Ti n\'es betg pli commember da questa gruppa e na la pos betg pli duvrar.</string>
+    <string name="group_dissolved_notice">Questa gruppa è vegnida schliada e na po betg pli vegnir duvrada.</string>
+    <string name="directory_request_failed">Betg reussì da consultar il register. P.pl. empruvar anc ina giada.</string>
+    <string name="add_shortcut_exists">Igl exista gia ina scursanida per quest object.</string>
     <plurals name="contacts_counter_label">
         <item quantity="one">%d contact</item>
         <item quantity="other">%d contacts</item>

+ 1 - 1
app/src/main/res/values-rm/voip_strings.xml

@@ -39,7 +39,7 @@
     <string name="voip_reject">Refusar</string>
     <string name="voip_speakerphone">Telefonar a maun liber</string>
     <string name="voip_wired_headset">Uregliers</string>
-    <string name="voip_earpiece">Telefonat</string>
+    <string name="voip_earpiece">Telefon</string>
     <string name="voip_bluetooth">Bluetooth</string>
     <string name="voip_none">Betg a disposiziun</string>
     <string name="voip_call_finished">Terminà il telefonat da Threema</string>

+ 8 - 6
app/src/main/res/values-ru/colorpicker_strings.xml

@@ -1,7 +1,9 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="color_picker_default_title" msgid="1248663997452044787">"Выберите цвет"</string>
-    <string name="color_swatch_description" msgid="2883438431173736180">"Цвет: <xliff:g id="COLOR_INDEX">%1$d</xliff:g>"</string>
-    <string name="color_swatch_description_selected" msgid="5020921249944943124">"Выбран цвет <xliff:g id="COLOR_INDEX">%1$d</xliff:g>"</string>
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Выберите цвет</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Цвет: <xliff:g id="COLOR_INDEX">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Выбран цвет <xliff:g id="COLOR_INDEX">%1$d</xliff:g></string>
 </resources>

+ 1 - 1
app/src/main/res/values-ru/poi_strings.xml

@@ -10,7 +10,7 @@
     <string name="city">Мегаполис</string>
     <string name="city_block">Квартал</string>
     <string name="neighbourhood">Район</string>
-    <string name="locality">Населенный пункт</string>
+    <string name="locality">Местность</string>
     <string name="state">Штат</string>
     <string name="farm">Ферма</string>
     <string name="street">Улица</string>

+ 3 - 3
app/src/main/res/values-ru/strings.xml

@@ -161,7 +161,7 @@
     <string name="support">Поддержка</string>
     <string name="support_url">https://threema.ch/android/support/</string>
     <string name="backup_share_content">Следующие резервные копии могут быть использованы вместе с выбранным паролем для восстановления вашего Threema ID.</string>
-    <string name="backup_share_subject">Экспорт ID Threema для</string>
+    <string name="backup_share_subject">Экспорт Threema ID для</string>
     <string name="add_attachment">Новое вложение</string>
     <string name="invalid_passphrase">Неправильная кодовая фраза</string>
     <string name="master_key_locked">Главный ключ заблокирован</string>
@@ -1018,7 +1018,7 @@
     <string name="open_in_maps_app">Открыть в приложении «Карты»</string>
     <string name="delete">Удалить</string>
     <string name="delete_from_this_device">Удалить с этого устройства</string>
-    <string name="delete_for_all">Удалить для всех</string>
+    <string name="delete_for_all">Удалить у всех</string>
     <string name="message_was_deleted">Это сообщение удалено</string>
     <string name="continue_recording">Продолжить запись</string>
     <string name="whatsnew_title">Что нового в версии %1$s 5.2?</string>
@@ -1249,7 +1249,7 @@
     <string name="id_backup_info">Восстановить только ID</string>
     <string name="restore_your_id_contacts_and_groups">Восстановить ID, контакты и группы</string>
     <string name="threema_safe_backup">Безопасная рез. копия Threema</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>Забыли пароль?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>Помощь</a>]]></string>
     <string name="download_failed">Невозможно скачать. Код ошибки: %d</string>
     <string name="edit_answer">Изменить ответ</string>
     <string name="share_media">Поделиться с другим приложением…</string>

+ 11 - 11
app/src/main/res/values-ru/webclient_strings.xml

@@ -6,8 +6,8 @@
     <string name="webclient_last_usage">Последнее использование: %s</string>
     <string name="webclient_created_at">Создано: %1$s (%2$s)</string>
     <string name="webclient_active_since">Активно с: %s</string>
-    <string name="webclient_enable">Включить приложение для ПК/webклиент</string>
-    <string name="webclient_no_sessions_found">Для подключения загрузите приложение для ПК (<b>https://threema.ch/download</b>) или откройте webклиент (<b>%s</b>) на компьютере и нажмите кнопку ниже, чтобы сканировать QR-код с экрана компьютера.</string>
+    <string name="webclient_enable">Включить приложение для ПК/web-клиент</string>
+    <string name="webclient_no_sessions_found">Для подключения загрузите приложение для ПК (<b>https://threema.ch/download</b>) или откройте web-клиент (<b>%s</b>) на компьютере и нажмите кнопку ниже, чтобы сканировать QR-код с экрана компьютера.</string>
     <string name="webclient_session_rename">Переименовать сессию</string>
     <string name="webclient_session_label">Новое имя</string>
     <string name="webclient_session_start">Начать сессию</string>
@@ -17,26 +17,26 @@
     <string name="webclient_unnamed_session">Безымянная сессия</string>
     <string name="webclient_session_remove">Удалить сессию</string>
     <string name="webclient_welcome_title">Общайтесь с вашего компьютера!</string>
-    <string name="webclient_welcome_explain">Приложение для ПК и webклиент позволяют общаться с компьютера или ноутбука, давая вам полный доступ ко всем контактам, мультимедиа и чатам.\n\n<b>Все коммуникации между телефоном и компьютером защищены сквозным шифрованием</b> и используют прямое подключение, если телефон и компьютер находятся в одной сети.\n\nОбратите внимание: приложение для ПК/webклиент может вызвать дополнительный разряд батареи, пока сессия активна. Вы можете включить или отключить приложение в любое время.</string>
-    <string name="webclient_launch">Запустить приложение для ПК/webклиент</string>
+    <string name="webclient_welcome_explain">Приложение для ПК и web-клиент позволяют общаться с компьютера или ноутбука, давая вам полный доступ ко всем контактам, мультимедиа и чатам.\n\n<b>Все коммуникации между телефоном и компьютером защищены сквозным шифрованием</b> и используют прямое подключение, если телефон и компьютер находятся в одной сети.\n\nОбратите внимание: приложение для ПК/web-клиент может вызвать дополнительный разряд батареи, пока сессия активна. Вы можете включить или отключить приложение в любое время.</string>
+    <string name="webclient_launch">Запустить приложение для ПК/web-клиент</string>
     <string name="webclient_qr_scan_message">Отсканируйте QR-код с экрана компьютера.</string>
     <string name="webclient_invalid_qr_code">Неправильный QR-код</string>
-    <string name="webclient_new_connection_toast">Сессия приложения для ПК/webклиента запущена</string>
+    <string name="webclient_new_connection_toast">Сессия приложения для ПК/web-клиента запущена</string>
     <string name="webclient_protocol_error">Ошибка протокола</string>
-    <string name="webclient_protocol_version_to_old">Ваше приложение не поддерживает данную версию приложения для ПК/webклиента. Обновите Threema для Android до последней версии.</string>
-    <string name="webclient_protocol_version_too_new_selfhosted">Ваше приложение не поддерживает данную версию данную версию приложения для ПК/webклиента. Загрузите последнюю версию приложения для ПК или попросите администратора webклиента перейти на последнюю версию.</string>
+    <string name="webclient_protocol_version_to_old">Ваше приложение не поддерживает данную версию приложения для ПК/web-клиента. Обновите Threema для Android до последней версии.</string>
+    <string name="webclient_protocol_version_too_new_selfhosted">Ваше приложение не поддерживает данную версию данную версию приложения для ПК/web-клиента. Загрузите последнюю версию приложения для ПК или попросите администратора web-клиента перейти на последнюю версию.</string>
     <string name="webclient_protocol_version_too_new_threema">Ваше приложение не поддерживает данную версию приложения для ПК/web-клиента. Используйте более новую версию приложения для ПК/web-клиента.</string>
-    <string name="webclient_session_already_exists">Сессия, соответствующая сканированному вами QR-коду, уже существует. Перезапустите приложение для ПК или перезагрузите webклиент и повторите попытку.</string>
+    <string name="webclient_session_already_exists">Сессия, соответствующая сканированному вами QR-коду, уже существует. Перезапустите приложение для ПК или перезагрузите web-клиент и повторите попытку.</string>
     <string name="webclient_really_start_webclient_by_payload_body">Запустить эту сессию?</string>
     <string name="webclient_cannot_restore">Невозможно восстановить сессию</string>
-    <string name="webclient_disabled">Программа для ПК/webверсия не активирована</string>
+    <string name="webclient_disabled">Программа для ПК/web-версия не активирована</string>
     <string name="webclient_cannot_start">Невозможно запустить сессию</string>
     <string name="webclient_constrained_by_mdm">Сервер не утвержден администратором.</string>
     <string name="webclient_clear_all_sessions">Очистить все сессии</string>
     <string name="webclient_clear_all_sessions_confirm">Остановить и удалить все сессии?</string>
     <string name="webclient_prefs_debug_tool_summary">Запустите это средство для отладки неполадок с настройкой соединения с приложением для ПК или web-клиентом</string>
-    <string name="webclient_diagnostics">Диагностика приложения для ПК/webклиента</string>
+    <string name="webclient_diagnostics">Диагностика приложения для ПК/web-клиента</string>
     <string name="webclient_diagnostics_start">Пуск</string>
     <string name="webclient_diagnostics_intro">Нажмите кнопку «Пуск» для запуска теста</string>
-    <string name="webclient_diagnostics_done">Готово! Если у вас возникают неполадки с настройкой соединения с приложением для ПК или webклиентом, отправьте данные в службу поддержки Threema.</string>
+    <string name="webclient_diagnostics_done">Готово! Если у вас возникают неполадки с настройкой соединения с приложением для ПК или web-клиентом, отправьте данные в службу поддержки Threema.</string>
 </resources>

+ 9 - 0
app/src/main/res/values-sk/colorpicker_strings.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Vyberte farbu</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Farba <xliff:g id="color_index" príklad="14">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Farba <xliff:g id="color_index" príklad="14">%1$d</xliff:g> selected</string>
+</resources>

+ 9 - 0
app/src/main/res/values-tr/colorpicker_strings.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Bir Renk Seçin</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Renk <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Renk <xliff:g id="color_index" example="14">%1$d</xliff:g> seçildi</string>
+</resources>

+ 12 - 3
app/src/main/res/values-tr/strings.xml

@@ -37,7 +37,7 @@
     <string name="prefs_sum_sync_contacts_on">%s kullanıcıyı cihazın adres defteriyle eşitle</string>
     <string name="prefs_sum_sync_contacts_off">%s kullanıcıyı cihazın adres defteriyle eşitleme</string>
     <string name="prefs_title_sync_contacts">Kişileri eşitle</string>
-    <string name="prefs_sum_block_unknown_off">Herhangi biri size mesaj gönderebilir. İlk mesaj geldiğinde yeni kişilere otomatik olarak eklenecektir.</string>
+    <string name="prefs_sum_block_unknown_off">Herkes size mesaj gönderebilir. İlk mesaj geldiğinde yeni kişiler otomatik olarak eklenecektir.</string>
     <string name="prefs_sum_block_unknown_on">Yalnızca adres defterinizdeki kişiler size mesaj gönderebilir.</string>
     <string name="prefs_title_block_unknown">Bilinmeyeni engelle</string>
     <string name="prefs_title_read_receipts">Okundu bilgisini gönder</string>
@@ -511,6 +511,7 @@ tekrar denemeden önce girdiğiniz numaranın doğru olduğundan ve mobil ağa b
     <string name="file_placeholder">Dosya</string>
     <string name="internal_storage">Dahili depolama</string>
     <string name="no_activity_for_mime_type">Bu dosyayı açacak uygulama bulunamadı.</string>
+    <string name="no_activity_for_intent">Uygulama bulunamadı.</string>
     <string name="open_from">Şuradan aç</string>
     <string name="file_one_contact_not_supported">%1$s dosya alamıyor.</string>
     <string name="file_x_contact_not_supported">Uyarı: %1$d kişi dosyanızı alamıyor.</string>
@@ -1014,7 +1015,8 @@ sunucularımıza güvenli bir şekilde iletildi. Kişisel anahtar hiçbir zaman
     <string name="system_default">Sistem varsayılanı</string>
     <string name="open_in_maps_app">Haritalar uygulamasında aç</string>
     <string name="delete">Sil</string>
-    <string name="delete_for_all">Tümünü sil</string>
+    <string name="delete_from_this_device">Bu cihazdan sil</string>
+    <string name="delete_for_all">Herkesten sil</string>
     <string name="message_was_deleted">Bu mesaj silindi</string>
     <string name="continue_recording">Kayda devam et</string>
     <string name="whatsnew_title">%1$s 5.2\'deki yenilikler nelerdir?</string>
@@ -1245,7 +1247,7 @@ sunucularımıza güvenli bir şekilde iletildi. Kişisel anahtar hiçbir zaman
     <string name="id_backup_info">Yalnızca kimliğinizi geri yükleyin</string>
     <string name="restore_your_id_contacts_and_groups">Kimliğinizi, kişilerinizi ve gruplarınızı geri yükleyin</string>
     <string name="threema_safe_backup">Threema Safe yedekleme</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>Şifrenizi mi unuttunuz?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>Yardım</a>]]></string>
     <string name="download_failed">İndirme başarısız. Hata kodu: %d</string>
     <string name="edit_answer">Cevabı düzenle</string>
     <string name="share_media">Başka bir uygulamayla paylaş…</string>
@@ -1546,6 +1548,13 @@ sunucularımıza güvenli bir şekilde iletildi. Kişisel anahtar hiçbir zaman
     <string name="edit_message_not_supported_for_all_group_members">Aşağıdaki grup üyeleri düzenlemelerinizi göremeyecek: %1$s</string>
     <string name="edit_message_not_supported_for_any_group_members">Hiçbir grup üyesi bu özelliği destekleyen bir uygulama sürümüne sahip olmadığı için mesaj düzenlenemiyor.</string>
     <string name="delete_message_not_supported_for_all_group_members">Bu mesaj aşağıdaki grup üyeleri için silinmeyecektir: %1$s</string>
+    <string name="work_intro_more_link_text">Threema Work hakkında daha fazla bilgi edinin</string>
+    <string name="work_intro_subtitle">Şirketler için güvenli mesajlaşma aracı.</string>
+    <string name="work_intro_login">Giriş %1$s</string>
+    <string name="consumer_notice_description">Özel bir kullanıcıysanız lütfen normal Threema uygulamasını indirin.</string>
+    <string name="consumer_notice_playstore_link_description">Play Store\'da Threema</string>
+    <string name="consumer_notice_appgallery_link_description">AppGallery\'de Threema</string>
+    <string name="consumer_notice_subtitle">Özel kullanım için</string>
     <plurals name="contacts_counter_label">
         <item quantity="one">%d kişi</item>
         <item quantity="other">%d kişi</item>

+ 9 - 0
app/src/main/res/values-uk/colorpicker_strings.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">Виберіть колір</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">Колір <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">Вибрано колір <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
+</resources>

+ 9 - 9
app/src/main/res/values-uk/strings.xml

@@ -532,7 +532,7 @@
     <string name="file_placeholder">Файл</string>
     <string name="internal_storage">Внутрішня пам\'ять</string>
     <string name="no_activity_for_mime_type">Немає додатків, які можуть відкрити цей файл.</string>
-    <string name="no_activity_for_intent">Застосунок не знайдено.</string>
+    <string name="no_activity_for_intent">Додаток не знайдено.</string>
     <string name="open_from">Відкрити з</string>
     <string name="file_one_contact_not_supported">Контакт \"%1$s\" не може отримувати файли.</string>
     <string name="file_x_contact_not_supported">Увага! Кілька контактів (%1$d) не зможе отримати ваш файл.</string>
@@ -1061,7 +1061,7 @@
     <string name="system_default">Налаштування системи</string>
     <string name="open_in_maps_app">Відкрити в додатку для карт</string>
     <string name="delete">Видалити</string>
-    <string name="delete_from_this_device">Видалити з цього пристрою</string>
+    <string name="delete_from_this_device">Видалити із цього пристрою</string>
     <string name="delete_for_all">Видалити для всіх</string>
     <string name="message_was_deleted">Це повідомлення видалено</string>
     <string name="continue_recording">Продовжити запис</string>
@@ -1596,13 +1596,13 @@
     <string name="edit_message_not_supported_for_all_group_members">Ваші зміни не бачитимуть такі учасники групи: %1$s</string>
     <string name="edit_message_not_supported_for_any_group_members">Неможливо редагувати повідомлення, оскільки в жодного з учасників групи не встановлено версію додатка, яка підтримує цю функцію.</string>
     <string name="delete_message_not_supported_for_all_group_members">Це повідомлення не буде видалено для таких учасників групи: %1$s</string>
-    <string name="work_intro_more_link_text">Дізнатися більше про Threema Work</string>
-    <string name="work_intro_subtitle">Безпечний застосунок для спілкування \nдля компаній.</string>
-    <string name="work_intro_login">Увійти %1$s</string>
-    <string name="consumer_notice_description">Будь ласка, завантажте звичайний застосунок Threema, якщо Ви - звичайний користувач.</string>
-    <string name="consumer_notice_playstore_link_description">Threema у Play Маркеті</string>
-    <string name="consumer_notice_appgallery_link_description">Threema у AppGallery</string>
-    <string name="consumer_notice_subtitle">Для приватного користування</string>
+    <string name="work_intro_more_link_text">Докладніше про Threema Work</string>
+    <string name="work_intro_subtitle">Безпечний месенджер\nдля компаній.</string>
+    <string name="work_intro_login">Увійти в %1$s</string>
+    <string name="consumer_notice_description">Для особистого використання завантажте звичайний додаток Threema.</string>
+    <string name="consumer_notice_playstore_link_description">Threema в Google Play</string>
+    <string name="consumer_notice_appgallery_link_description">Threema в AppGallery</string>
+    <string name="consumer_notice_subtitle">Для особистого використання</string>
     <plurals name="contacts_counter_label">
         <item quantity="few">%d контакти</item>
         <item quantity="many">%d контактів</item>

+ 9 - 0
app/src/main/res/values-zh-rCN/colorpicker_strings.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">选择颜色</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">颜色 <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">颜色 <xliff:g id="color_index" example="14">%1$d</xliff:g> 已选择</string>
+</resources>

+ 13 - 5
app/src/main/res/values-zh-rCN/strings.xml

@@ -37,8 +37,7 @@
     <string name="prefs_sum_sync_contacts_on">使用设备通讯录同步 %s 用户</string>
     <string name="prefs_sum_sync_contacts_off">不要将 %s 用户与设备通讯录同步</string>
     <string name="prefs_title_sync_contacts">联系人同步</string>
-    <string name="prefs_sum_block_unknown_off">任何人都可以向您发送消息。
-当第一条消息到达时,新的联系人将被自动添加。</string>
+    <string name="prefs_sum_block_unknown_off">任何人都可以向您发送消息。当您收到第一条消息时,新的联系人将被自动添加。</string>
     <string name="prefs_sum_block_unknown_on">只有您的联系人列表中的人才能向您发送消息。</string>
     <string name="prefs_title_block_unknown">屏蔽未知联系人</string>
     <string name="prefs_title_read_receipts">发送已读回执</string>
@@ -70,7 +69,7 @@
     <string name="prefs_title_threema_push_switch">使用 Threema Push</string>
     <string name="prefs_sum_threema_push_on">使用 Threema Push 以获取新消息通知</string>
     <string name="prefs_sum_threema_push_off">使用系统推送服务检查新消息</string>
-    <string name="prefs_logging">记录</string>
+    <string name="prefs_logging">日志记录</string>
     <string name="prefs_title_message_log_switch">记录到文件</string>
     <string name="prefs_title_sum_message_log_on">事件和网络消息将记录到 debug_log.txt</string>
     <string name="prefs_title_sum_message_log_off">事件将不会被记录</string>
@@ -527,6 +526,7 @@ http://www.7-zip.org 或 https://itunes.apple.com/us/app/the-unarchiver/id425424
     <string name="file_placeholder">文件</string>
     <string name="internal_storage">内部存储</string>
     <string name="no_activity_for_mime_type">找不到打开此文件的应用。</string>
+    <string name="no_activity_for_intent">找不到应用程序。</string>
     <string name="open_from">从...打开</string>
     <string name="file_one_contact_not_supported">%1$s 无法接收文件。</string>
     <string name="file_x_contact_not_supported">警告:%1$d个联系人无法收到您的文件。</string>
@@ -1050,6 +1050,7 @@ Threema ID。您将不会出现在朋友的联系人列表中。您确定要
     <string name="system_default">系统默认</string>
     <string name="open_in_maps_app">在地图应用中打开</string>
     <string name="delete">删除</string>
+    <string name="delete_from_this_device">从此设备中删除</string>
     <string name="delete_for_all">为所有人删除</string>
     <string name="message_was_deleted">此消息已删除</string>
     <string name="continue_recording">继续录音</string>
@@ -1281,7 +1282,7 @@ Threema ID。您将不会出现在朋友的联系人列表中。您确定要
     <string name="id_backup_info">仅恢复您的ID</string>
     <string name="restore_your_id_contacts_and_groups">恢复您的ID、联系人和群组</string>
     <string name="threema_safe_backup">Threema Safe 备份</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>忘记密码?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>需要帮忙?</a>]]></string>
     <string name="download_failed">下载失败。错误代码:%d</string>
     <string name="edit_answer">编辑答案</string>
     <string name="share_media">与其他应用分享...</string>
@@ -1450,7 +1451,7 @@ Threema ID。您将不会出现在朋友的联系人列表中。您确定要
     <string name="prefs_title_read_phone_state">授予通话权限</string>
     <string name="prefs_title_hibernation">未使用的应用设置</string>
     <string name="prefs_summary_hibernation_api_32">为防止 Threema 在长时间不使用后被系统暂停,请禁用系统设置中的 “撤销权限并释放空间” 。</string>
-    <string name="prefs_summary_hibernation_api">为防止 Threema 在长时间不使用后被系统暂停,请禁用系统设置中的 “暂停未使用应用的活动” 。</string>
+    <string name="prefs_summary_hibernation_api">为防止 Threema 在长时间不使用后被系统暂停,请禁用系统设置中的 “暂停闲置应用的活动” 。</string>
     <string name="unable_to_fetch_configuration">无法从配置服务器获取数据,请稍后再试。</string>
     <string name="rogue_device_warning"><![CDATA[我们的服务器检测到有人试图从另一台设备登录现有的 Threema ID,您最近是否在其他设备上登录过您的 Threema ID?&lt;br&gt;&lt;br&gt;如果有,就可以忽略此消息。&lt;br&gt;&lt;br&gt;如果没有,您的私钥可能已经泄露。在创建新ID之前,请<a href="https://threema.ch/en/faq/another_connection">按照我们的建议</a>保护您的设备和数据。]]></string>
     <string name="fetch2_failure">与配置服务器同步失败。</string>
@@ -1582,6 +1583,13 @@ Threema ID。您将不会出现在朋友的联系人列表中。您确定要
     <string name="edit_message_not_supported_for_all_group_members">以下群组成员将无法看到您对消息的编辑:%1$s</string>
     <string name="edit_message_not_supported_for_any_group_members">由于有部分群组成员使用的应用版本不支持编辑消息功能,因此无法编辑消息。</string>
     <string name="delete_message_not_supported_for_all_group_members">此消息不会为以下群组成员删除:%1$s</string>
+    <string name="work_intro_more_link_text">进一步了解 Threema Work</string>
+    <string name="work_intro_subtitle">为公司而设的安全商业版通讯工具。</string>
+    <string name="work_intro_login">登录 %1$s</string>
+    <string name="consumer_notice_description">如果您是个人用户,请下载普通版 Threema 应用程序。</string>
+    <string name="consumer_notice_playstore_link_description">Google Play 商店上的 Threema</string>
+    <string name="consumer_notice_appgallery_link_description">华为 AppGallery 商店上的 Threema</string>
+    <string name="consumer_notice_subtitle">仅限个人用户使用</string>
     <plurals name="contacts_counter_label">
         <item quantity="other">%d个联系人</item>
     </plurals>

+ 9 - 0
app/src/main/res/values-zh-rTW/colorpicker_strings.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:tools="http://schemas.android.com/tools" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default title for color picker dialog [CHAR LIMIT=30] -->
+    <string name="color_picker_default_title">選擇顏色</string>
+    <!-- Content description for a color square. -->
+    <string name="color_swatch_description">顏色 <xliff:g id="color_index" example="14">%1$d</xliff:g></string>
+    <!-- Content description for a selected color square. -->
+    <string name="color_swatch_description_selected" tools:ignore="PluralsCandidate">顏色 <xliff:g id="color_index" example="14">%1$d</xliff:g> 已選擇</string>
+</resources>

+ 12 - 4
app/src/main/res/values-zh-rTW/strings.xml

@@ -37,8 +37,7 @@
     <string name="prefs_sum_sync_contacts_on">使用裝置通訊錄同步 %s 使用者</string>
     <string name="prefs_sum_sync_contacts_off">不要將 %s 使用者與裝置通訊錄同步</string>
     <string name="prefs_title_sync_contacts">聯絡人同步</string>
-    <string name="prefs_sum_block_unknown_off">任何人都可以向您傳送訊息。
-當您收到第一則訊息時,新的聯絡人將被自動新增。</string>
+    <string name="prefs_sum_block_unknown_off">任何人都可以向您傳送訊息。當您收到第一則訊息時,新的聯絡人將被自動新增。</string>
     <string name="prefs_sum_block_unknown_on">只有在您的聯絡人名單中的人才能向您傳送訊息。</string>
     <string name="prefs_title_block_unknown">封鎖未知聯絡人</string>
     <string name="prefs_title_read_receipts">傳送已讀標記</string>
@@ -70,7 +69,7 @@
     <string name="prefs_title_threema_push_switch">使用 Threema Push</string>
     <string name="prefs_sum_threema_push_on">使用 Threema Push 以取得新訊息通知</string>
     <string name="prefs_sum_threema_push_off">使用系統推播服務檢查新訊息</string>
-    <string name="prefs_logging">記錄</string>
+    <string name="prefs_logging">記錄</string>
     <string name="prefs_title_message_log_switch">記錄至檔案</string>
     <string name="prefs_title_sum_message_log_on">事件和網路訊息將記錄至 debug_log.txt</string>
     <string name="prefs_title_sum_message_log_off">事件將不會被記錄</string>
@@ -527,6 +526,7 @@ http://www.7-zip.org 或 https://itunes.apple.com/us/app/the-unarchiver/id425424
     <string name="file_placeholder">檔案</string>
     <string name="internal_storage">內部儲存</string>
     <string name="no_activity_for_mime_type">找不到開啟此檔案的應用程式。</string>
+    <string name="no_activity_for_intent">找不到應用程式。</string>
     <string name="open_from">從...開啟</string>
     <string name="file_one_contact_not_supported">%1$s 無法接收檔案。</string>
     <string name="file_x_contact_not_supported">警告:%1$d個聯絡人無法接收您的檔案。</string>
@@ -1044,6 +1044,7 @@ Threema 支援的所有表情符號。</string>
     <string name="system_default">系統預設</string>
     <string name="open_in_maps_app">在地圖應用程式中開啟</string>
     <string name="delete">刪除</string>
+    <string name="delete_from_this_device">從此裝置中刪除</string>
     <string name="delete_for_all">為所有人刪除</string>
     <string name="message_was_deleted">此訊息已刪除</string>
     <string name="continue_recording">繼續錄音</string>
@@ -1275,7 +1276,7 @@ Threema 支援的所有表情符號。</string>
     <string name="id_backup_info">僅限還原您的ID</string>
     <string name="restore_your_id_contacts_and_groups">還原您的ID、聯絡人和群組</string>
     <string name="threema_safe_backup">Threema Safe 備份</string>
-    <string name="forgot_your_password"><![CDATA[<a href=%s>忘記密碼?</a>]]></string>
+    <string name="forgot_your_password"><![CDATA[<a href=%s>需要協助?</a>]]></string>
     <string name="download_failed">下載失敗。錯誤代碼:%d</string>
     <string name="edit_answer">編輯答案</string>
     <string name="share_media">與其他應用程式分享...</string>
@@ -1576,6 +1577,13 @@ Threema 支援的所有表情符號。</string>
     <string name="edit_message_not_supported_for_all_group_members">以下群組成員將無法看到您對訊息的編輯:%1$s</string>
     <string name="edit_message_not_supported_for_any_group_members">由於有部分群組成員使用的應用程式版本不支援編輯訊息功能,因此無法編輯訊息。</string>
     <string name="delete_message_not_supported_for_all_group_members">此訊息不會為以下群組成員刪除:%1$s</string>
+    <string name="work_intro_more_link_text">進一步了解 Threema Work</string>
+    <string name="work_intro_subtitle">為公司而設的安全商業版即時通訊工具。</string>
+    <string name="work_intro_login">登入 %1$s</string>
+    <string name="consumer_notice_description">如果您是個人使用者,請下載普通版 Threema 應用程式。</string>
+    <string name="consumer_notice_playstore_link_description">Google Play 商店上的 Threema</string>
+    <string name="consumer_notice_appgallery_link_description">華為 AppGallery 商店上的 Threema</string>
+    <string name="consumer_notice_subtitle">僅限個人使用者使用</string>
     <plurals name="contacts_counter_label">
         <item quantity="other">%d位聯絡人</item>
     </plurals>

+ 0 - 0
app/src/main/res/values/colorpicker_string.xml → app/src/main/res/values/colorpicker_strings.xml


+ 1 - 1
app/src/main/res/values/dimens.xml

@@ -58,7 +58,7 @@
 
     <!-- ballot choice list -->
     <dimen name="ballotchoice_list_item_height">40dp</dimen>
-	<dimen name="ballotchoice_list_entry_height">44dp</dimen>
+	<dimen name="ballotchoice_list_entry_height">44sp</dimen>
 	<dimen name="ballotchoice_bottom_margin">54dp</dimen>
 
 	<!-- ballot choice list -->

+ 1 - 0
app/src/main/res/values/preferences_strings.xml

@@ -215,4 +215,5 @@
     <string name="preferences__contact_sync_time" translatable="false">pref_contact_sync_time</string>
 	<string name="preferences__md_unlocked" translatable="false">pref_md_unlocked</string>
 	<string name="preferences__show_last_update_prefix" translatable="false">pref_show_last_update_prefix</string>
+    <string name="preferences__last_notification_request_timestamp" translatable="false">pref_last_notification_request_timestamp</string>
 </resources>

+ 1 - 1
app/src/main/res/values/strings.xml

@@ -1298,7 +1298,7 @@
 	<string name="id_backup_info">Only restore your ID</string>
 	<string name="restore_your_id_contacts_and_groups">Restore your ID, contacts and groups</string>
 	<string name="threema_safe_backup">Threema Safe Backup</string>
-	<string name="forgot_your_password"><![CDATA[<a href=%s>Forgot your password?</a>]]></string>
+	<string name="forgot_your_password"><![CDATA[<a href=%s>Help</a>]]></string>
 	<string name="download_failed">Download unsuccessful. Error code: %d</string>
 	<string name="edit_answer">Edit answer</string>
 	<string name="share_media">Share with another app…</string>

+ 1 - 1
build.gradle

@@ -17,7 +17,7 @@ buildscript {
         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
 
         // Huawei agconnect plugin
-        classpath 'com.huawei.agconnect:agcp-1.9.1.301'
+        classpath 'com.huawei.agconnect:agcp-1.9.1.303'
         classpath 'com.huawei.agconnect:agconnect-crash-symbol-lib-1.9.1.301'
         classpath 'com.huawei.agconnect:agconnect-apms-plugin-1.6.2.300'
         classpath 'com.huawei.agconnect:agconnect-core-1.9.1.301@aar'

+ 1 - 1
domain/src/main/java/ch/threema/domain/protocol/connection/layer/MonitoringLayer.kt

@@ -234,7 +234,7 @@ internal class MonitoringLayer(
         controller.dispatcher.assertDispatcherContext()
 
         lastSentEchoSeq++
-        logger.debug("Sending echo request (seq: $lastSentEchoSeq)")
+        logger.info("Sending echo request (seq: $lastSentEchoSeq)")
         outbound.send(prepareEchoRequest(lastSentEchoSeq))
 
         delay(ProtocolDefines.ECHO_RESPONSE_TIMEOUT * 1000L)