~singpolyma/cheogram-android

470213a36e7fcd8681790c1fc4fdcb057b2d0e9e — Stephen Paul Weber 1 year, 2 months ago e9e177d + 0beb1e9
Merge remote-tracking branch 'upstream/master'

* upstream/master:
  every device is 21+ now
  bump targetSdk to 32
  use signal protocol android
  version bump to 2.10.7
  do not show toast when activity is gone. fixes #4335
  fix orbot detection
  pulled translations from transifex
  Here too
  Show battery dialogue always
  fix array out of bounds. fixes #4334
  add local only flag to foreground service
  pulled translations from transifex
  bump dependencies
  A Quicky user can be a stranger
  pulled translations from transifex
  minor code clean up
  use item id 'current' for nick as fallback as per XEP-0060 §12.20
  bump various libraries
  pulled translations from transifex
  support sasl/temporary-auth-failure
39 files changed, 1899 insertions(+), 347 deletions(-)

M CHANGELOG.md
M build.gradle
M src/cheogram/AndroidManifest.xml
M src/conversations/AndroidManifest.xml
M src/conversations/res/values-nl/strings.xml
A src/conversations/res/values-szl/strings.xml
M src/main/AndroidManifest.xml
M src/main/java/eu/siacs/conversations/entities/Account.java
M src/main/java/eu/siacs/conversations/entities/Conversation.java
M src/main/java/eu/siacs/conversations/generator/IqGenerator.java
M src/main/java/eu/siacs/conversations/persistance/FileBackend.java
M src/main/java/eu/siacs/conversations/services/NotificationService.java
M src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
M src/main/java/eu/siacs/conversations/ui/ConversationFragment.java
M src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java
M src/main/java/eu/siacs/conversations/ui/util/Attachment.java
M src/main/java/eu/siacs/conversations/ui/util/EditMessageActionModeCallback.java
M src/main/java/eu/siacs/conversations/utils/Compatibility.java
M src/main/java/eu/siacs/conversations/utils/TorServiceUtils.java
M src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java
M src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java
M src/main/res/values-da-rDK/strings.xml
M src/main/res/values-de/strings.xml
M src/main/res/values-el/strings.xml
M src/main/res/values-es/strings.xml
M src/main/res/values-fr/strings.xml
M src/main/res/values-gl/strings.xml
M src/main/res/values-it/strings.xml
M src/main/res/values-ja/strings.xml
M src/main/res/values-nl/strings.xml
M src/main/res/values-pl/strings.xml
M src/main/res/values-pt-rBR/strings.xml
M src/main/res/values-pt/strings.xml
M src/main/res/values-ro-rRO/strings.xml
A src/main/res/values-szl/strings.xml
M src/main/res/values-tr-rTR/strings.xml
M src/main/res/values-zh-rCN/strings.xml
M src/main/res/values/strings.xml
A src/quicksy/res/values-szl/strings.xml
M CHANGELOG.md => CHANGELOG.md +6 -0
@@ 1,5 1,11 @@
# Changelog

### Version 2.10.7

* always ask for battery optimizations opt-out
* set local only flag on 'x connected accounts' notifications
* Minor bug fixes

### Version 2.10.6

* Minor bug fixes

M build.gradle => build.gradle +8 -8
@@ 6,7 6,7 @@ buildscript {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:7.2.0'
        classpath 'com.android.tools.build:gradle:7.2.1'
    }
}



@@ 58,7 58,7 @@ dependencies {

    implementation 'androidx.viewpager:viewpager:1.0.0'

    playstoreImplementation('com.google.firebase:firebase-messaging:23.0.3') {
    playstoreImplementation('com.google.firebase:firebase-messaging:23.0.6') {
        exclude group: 'com.google.firebase', module: 'firebase-core'
        exclude group: 'com.google.firebase', module: 'firebase-analytics'
        exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'


@@ 68,7 68,7 @@ dependencies {
    quicksyPlaystoreImplementation 'com.google.android.gms:play-services-auth-api-phone:18.0.1'
    implementation 'org.sufficientlysecure:openpgp-api:10.0'
    implementation 'com.theartofdev.edmodo:android-image-cropper:2.8.0'
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'androidx.appcompat:appcompat:1.4.2'
    implementation 'androidx.exifinterface:exifinterface:1.3.3'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'


@@ 83,7 83,7 @@ dependencies {
    implementation 'com.google.zxing:core:3.3.3'
    implementation 'de.measite.minidns:minidns-hla:0.2.4'
    implementation 'me.leolin:ShortcutBadger:1.1.22@aar'
    implementation 'org.whispersystems:signal-protocol-java:2.6.2'
    implementation 'org.whispersystems:signal-protocol-android:2.6.2'
    implementation 'com.makeramen:roundedimageview:2.3.0'
    implementation "com.wefika:flowlayout:0.4.1"
    implementation 'com.otaliastudios:transcoder:0.10.4'


@@ 97,10 97,10 @@ dependencies {

    implementation "com.squareup.retrofit2:retrofit:2.9.0"
    implementation "com.squareup.retrofit2:converter-gson:2.9.0"
    implementation "com.squareup.okhttp3:okhttp:4.9.3"
    implementation "com.squareup.okhttp3:okhttp:4.10.0"

    implementation 'com.google.guava:guava:30.1.1-android'
    implementation 'io.michaelrocks:libphonenumber-android:8.12.36'
    implementation 'io.michaelrocks:libphonenumber-android:8.12.49'
    implementation 'io.github.nishkarsh:android-permissions:2.1.6'
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
    implementation urlFile('https://cloudflare-ipfs.com/ipfs/QmeqMiLxHi8AAjXobxr3QTfa1bSSLyAu86YviAqQnjxCjM/libwebrtc.aar', 'libwebrtc.aar')


@@ 115,11 115,11 @@ ext {

android {
    namespace 'eu.siacs.conversations'
    compileSdkVersion 31
    compileSdkVersion 32

    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 30
        targetSdkVersion 32
        versionCode 42024 + grgit.tag.list().findAll { it.dateTime != null }.size()
        versionName grgit.describe(always: true)
        applicationId "eu.siacs.conversations"

M src/cheogram/AndroidManifest.xml => src/cheogram/AndroidManifest.xml +4 -2
@@ 9,7 9,8 @@

        <service android:name="com.cheogram.android.ConnectionService"
            android:label="Cheogram"
            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
            android:exported="true">
            <intent-filter>
                <action android:name="android.telecom.ConnectionService" />
            </intent-filter>


@@ 38,7 39,8 @@
        <activity
            android:name=".ui.ImportBackupActivity"
            android:label="@string/restore_backup"
            android:launchMode="singleTask">
            android:launchMode="singleTask"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />

M src/conversations/AndroidManifest.xml => src/conversations/AndroidManifest.xml +2 -1
@@ 26,7 26,8 @@
        <activity
            android:name=".ui.ImportBackupActivity"
            android:label="@string/restore_backup"
            android:launchMode="singleTask">
            android:launchMode="singleTask"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />

M src/conversations/res/values-nl/strings.xml => src/conversations/res/values-nl/strings.xml +4 -1
@@ 8,4 8,7 @@
    <string name="magic_create_text_on_x">Je ontving een uitnodiging voor %1$s. We zullen je helpen een account aan te maken.\nWanneer je %1$s als je provider kiest kan je met gebruikers van andere providers communiceren door hen je volledige XMPP-adres te geven.</string>
    <string name="magic_create_text_fixed">Je ontving een uitnodiging voor %1$s. Er werd reeds een gebruikersnaam voor jou gekozen. We zullen je helpen een account aan te maken.\nJe zal met gebruikers van andere providers communiceren door hen je volledige XMPP-adres te geven.</string>
    <string name="your_server_invitation">Je server uitnodiging</string>
    </resources>
\ No newline at end of file
    <string name="tap_share_button_send_invite">Tik op de delen knop om een uitnodiging te versturen naar %1$s</string>
    <string name="if_contact_is_nearby_use_qr">Als je contactpersoon in de buurt is, kan deze ook onderstaande code scannen om de uitnodiging te aanvaarden.</string>
    <string name="share_invite_with">Deel de uitnodiging met ...</string>
</resources>
\ No newline at end of file

A src/conversations/res/values-szl/strings.xml => src/conversations/res/values-szl/strings.xml +16 -0
@@ 0,0 1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="pick_a_server">Wybier liferanta XMPP</string>
    <string name="use_conversations.im">Użyj conversations.im</string>
    <string name="create_new_account">Stwōrz nowe kōnto</string>
    <string name="do_you_have_an_account">Mosz już kōnto XMPP? Tak może być, jeźli już używosz inkszego klijynta XMPP aboś używoł abo używała wcześnij  Conversations. Jak niy, to możesz stworzić teroz nowe kōnto XMPP.\nDorada: Niykerzi liferańcio emaili dowajōm tyż kōnta XMPP.</string>
    <string name="server_select_text">XMPP to je nec wartkich wiadōmości niyzależny ôd liferanta. Możesz używać tego klijynta ze serwerym XMPP, jaki sie wybieresz.\nAle dlo twojij wygody ułacniyli my tworzynie kōnt na conversations.im; liferańcie ekstra dopasowanym do używanio ze Conversations.</string>
    <string name="magic_create_text_on_x">Mosz zaproszynie na %1$s. Pokludzymy cie bez proces tworzynio kōnta.\nPo wybraniu %1$s za liferanta, poradzisz kōmunikować sie ze używoczami ôd inkszych liferantōw bez danie im swojij połnyj adresy XMPP.</string>
    <string name="magic_create_text_fixed">Mosz zaproszynie na %1$s. Miano ôd używocza już je do ciebie wybrane. Pokludzymy cie bez proces tworzynio kōnta.\nBydzie szło kōmunikować sie ze używoczami ôd inkszych liferantōw bez danie im swojij połnyj adresy XMPP.</string>
    <string name="your_server_invitation">Twoje zaproszynie na serwer</string>
    <string name="improperly_formatted_provisioning">Niynoleżnie sformatowany kod lifrowanio</string>
    <string name="tap_share_button_send_invite">Tyknij knefla dzielynio sie, żeby posłać kōntaktowi zaproszynie na %1$s.</string>
    <string name="if_contact_is_nearby_use_qr">Jeźli kōntakt je blisko, to może tyż zeskanować kod niżyj, żeby zaakceptować twoje zaproszynie.</string>
    <string name="easy_invite_share_text">Pōdź na %1$s i pogodej zy mnōm: %2$s</string>
    <string name="share_invite_with">Poślij zaproszynie do…</string>
</resources>
\ No newline at end of file

M src/main/AndroidManifest.xml => src/main/AndroidManifest.xml +18 -10
@@ 50,27 50,29 @@
        android:required="false" />

    <queries>
        <package android:name="org.sufficientlysecure.keychain"/>
        <package android:name="org.sufficientlysecure.keychain" />
        <package android:name="org.torproject.android" />

        <intent>
            <action android:name="eu.siacs.conversations.location.request"/>
            <action android:name="eu.siacs.conversations.location.request" />
        </intent>
        <intent>
            <action android:name="eu.siacs.conversations.location.show"/>
            <action android:name="eu.siacs.conversations.location.show" />
        </intent>
    </queries>


    <application
        android:allowBackup="true"
        android:fullBackupContent="@xml/backup_content"
        android:appCategory="social"
        android:fullBackupContent="@xml/backup_content"
        android:hardwareAccelerated="true"
        android:icon="@mipmap/new_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:networkSecurityConfig="@xml/network_security_configuration"
        android:requestLegacyExternalStorage="true"
        android:preserveLegacyExternalStorage="true"
        android:requestLegacyExternalStorage="true"
        android:theme="@style/ConversationsTheme"
        tools:replace="android:label"
        tools:targetApi="q">


@@ 81,7 83,9 @@

        <service android:name=".services.XmppConnectionService" android:foregroundServiceType="microphone" />

        <receiver android:name=".services.EventReceiver">
        <receiver
            android:name=".services.EventReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />


@@ 105,6 109,7 @@
            android:label="@string/title_activity_show_location" />
        <activity
            android:name=".ui.ConversationActivity"
            android:exported="true"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />


@@ 125,6 130,7 @@
            android:windowSoftInputMode="stateAlwaysHidden" />
        <activity
            android:name=".ui.UriHandlerActivity"
            android:exported="true"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />


@@ 164,6 170,7 @@
        </activity>
        <activity
            android:name=".ui.StartConversationActivity"
            android:exported="true"
            android:label="@string/title_activity_start_conversation"
            android:launchMode="singleTop">
            <intent-filter>


@@ 172,6 179,7 @@
        </activity>
        <activity
            android:name=".ui.SettingsActivity"
            android:exported="true"
            android:label="@string/title_activity_settings">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />


@@ 190,6 198,7 @@
        <activity
            android:name=".ui.ChooseAccountForProfilePictureActivity"
            android:enabled="false"
            android:exported="true"
            android:label="@string/choose_account">
            <intent-filter android:label="@string/set_profile_picture">
                <action android:name="android.intent.action.ATTACH_DATA" />


@@ 223,6 232,7 @@
            android:label="@string/group_chat_avatar" />
        <activity
            android:name=".ui.ShareWithActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:launchMode="singleTop">



@@ 259,10 269,6 @@
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="eu.siacs.conversations.ui.SettingsActivity" />
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.PREFERENCE" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.theartofdev.edmodo.cropper.CropImageActivity"


@@ 277,6 283,7 @@
        <service android:name=".services.ImportBackupService" />
        <service
            android:name=".services.ContactChooserTargetService"
            android:exported="true"
            android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE">
            <intent-filter>
                <action android:name="android.service.chooser.ChooserTargetService" />


@@ 300,6 307,7 @@

        <activity
            android:name=".ui.ShortcutActivity"
            android:exported="true"
            android:label="@string/contact">
            <intent-filter>
                <action android:name="android.intent.action.CREATE_SHORTCUT" />

M src/main/java/eu/siacs/conversations/entities/Account.java => src/main/java/eu/siacs/conversations/entities/Account.java +3 -0
@@ 627,6 627,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable 
        ONLINE(false),
        NO_INTERNET(false),
        UNAUTHORIZED,
        TEMPORARY_AUTH_FAILURE,
        SERVER_NOT_FOUND,
        REGISTRATION_SUCCESSFUL(false),
        REGISTRATION_FAILED(true, false),


@@ 732,6 733,8 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable 
                    return R.string.payment_required;
                case MISSING_INTERNET_PERMISSION:
                    return R.string.missing_internet_permission;
                case TEMPORARY_AUTH_FAILURE:
                    return R.string.account_status_temporary_auth_failure;
                default:
                    return R.string.account_status_unknown;
            }

M src/main/java/eu/siacs/conversations/entities/Conversation.java => src/main/java/eu/siacs/conversations/entities/Conversation.java +1 -1
@@ 1076,7 1076,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
                && !contact.isOwnServer()
                && !contact.showInContactList()
                && !contact.isSelf()
                && !JidHelper.isQuicksyDomain(contact.getJid())
                && !(contact.getJid().isDomainJid() && JidHelper.isQuicksyDomain(contact.getJid()))
                && sentMessagesCount() == 0;
    }


M src/main/java/eu/siacs/conversations/generator/IqGenerator.java => src/main/java/eu/siacs/conversations/generator/IqGenerator.java +1 -0
@@ 131,6 131,7 @@ public class IqGenerator extends AbstractGenerator {

    public IqPacket publishNick(String nick) {
        final Element item = new Element("item");
        item.setAttribute("id", "current");
        item.addChild("nick", Namespace.NICK).setContent(nick);
        return publish(Namespace.NICK, item);
    }

M src/main/java/eu/siacs/conversations/persistance/FileBackend.java => src/main/java/eu/siacs/conversations/persistance/FileBackend.java +4 -4
@@ 442,7 442,7 @@ public class FileBackend {
            return bitmap;
        }
        final String mime = attachment.getMime();
        if ("application/pdf".equals(mime) && Compatibility.runsTwentyOne()) {
        if ("application/pdf".equals(mime)) {
            bitmap = cropCenterSquarePdf(attachment.getUri(), size);
            drawOverlay(
                    bitmap,


@@ 966,7 966,7 @@ public class FileBackend {
                }
                DownloadableFile file = getFile(message);
                final String mime = file.getMimeType();
                if ("application/pdf".equals(mime) && Compatibility.runsTwentyOne()) {
                if ("application/pdf".equals(mime)) {
                    thumbnail = new BitmapDrawable(res, getPdfDocumentPreview(file, size));
                } else if (mime.startsWith("video/")) {
                    thumbnail = new BitmapDrawable(res, getVideoPreview(file, size));


@@ 1548,12 1548,12 @@ public class FileBackend {
            fileParams.url = url;
        }
        fileParams.size = file.getSize();
        if (image || video || (pdf && Compatibility.runsTwentyOne())) {
        if (image || video || pdf) {
            try {
                final Dimensions dimensions;
                if (video) {
                    dimensions = getVideoDimensions(file);
                } else if (pdf && Compatibility.runsTwentyOne()) {
                } else if (pdf) {
                    dimensions = getPdfDocumentDimensions(file);
                } else {
                    dimensions = getImageDimensions(file);

M src/main/java/eu/siacs/conversations/services/NotificationService.java => src/main/java/eu/siacs/conversations/services/NotificationService.java +583 -249
@@ 1,6 1,8 @@
package eu.siacs.conversations.services;

import android.Manifest;
import static eu.siacs.conversations.utils.Compatibility.s;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;


@@ 85,7 87,8 @@ import eu.siacs.conversations.xmpp.jingle.Media;

public class NotificationService {

    private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = Executors.newSingleThreadScheduledExecutor();
    private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE =
            Executors.newSingleThreadScheduledExecutor();

    public static final Object CATCHUP_LOCK = new Object();



@@ 146,7 149,8 @@ public class NotificationService {
    @RequiresApi(api = Build.VERSION_CODES.O)
    void initializeChannels() {
        final Context c = mXmppConnectionService;
        final NotificationManager notificationManager = c.getSystemService(NotificationManager.class);
        final NotificationManager notificationManager =
                c.getSystemService(NotificationManager.class);
        if (notificationManager == null) {
            return;
        }


@@ 154,41 158,60 @@ public class NotificationService {
        notificationManager.deleteNotificationChannel("export");
        notificationManager.deleteNotificationChannel("incoming_calls");

        notificationManager.createNotificationChannelGroup(new NotificationChannelGroup("status", c.getString(R.string.notification_group_status_information)));
        notificationManager.createNotificationChannelGroup(new NotificationChannelGroup("chats", c.getString(R.string.notification_group_messages)));
        notificationManager.createNotificationChannelGroup(new NotificationChannelGroup("calls", c.getString(R.string.notification_group_calls)));
        final NotificationChannel foregroundServiceChannel = new NotificationChannel("foreground",
                c.getString(R.string.foreground_service_channel_name),
                NotificationManager.IMPORTANCE_MIN);
        foregroundServiceChannel.setDescription(c.getString(R.string.foreground_service_channel_description, c.getString(R.string.app_name)));
        notificationManager.createNotificationChannelGroup(
                new NotificationChannelGroup(
                        "status", c.getString(R.string.notification_group_status_information)));
        notificationManager.createNotificationChannelGroup(
                new NotificationChannelGroup(
                        "chats", c.getString(R.string.notification_group_messages)));
        notificationManager.createNotificationChannelGroup(
                new NotificationChannelGroup(
                        "calls", c.getString(R.string.notification_group_calls)));
        final NotificationChannel foregroundServiceChannel =
                new NotificationChannel(
                        "foreground",
                        c.getString(R.string.foreground_service_channel_name),
                        NotificationManager.IMPORTANCE_MIN);
        foregroundServiceChannel.setDescription(
                c.getString(
                        R.string.foreground_service_channel_description,
                        c.getString(R.string.app_name)));
        foregroundServiceChannel.setShowBadge(false);
        foregroundServiceChannel.setGroup("status");
        notificationManager.createNotificationChannel(foregroundServiceChannel);
        final NotificationChannel errorChannel = new NotificationChannel("error",
                c.getString(R.string.error_channel_name),
                NotificationManager.IMPORTANCE_LOW);
        final NotificationChannel errorChannel =
                new NotificationChannel(
                        "error",
                        c.getString(R.string.error_channel_name),
                        NotificationManager.IMPORTANCE_LOW);
        errorChannel.setDescription(c.getString(R.string.error_channel_description));
        errorChannel.setShowBadge(false);
        errorChannel.setGroup("status");
        notificationManager.createNotificationChannel(errorChannel);

        final NotificationChannel videoCompressionChannel = new NotificationChannel("compression",
                c.getString(R.string.video_compression_channel_name),
                NotificationManager.IMPORTANCE_LOW);
        final NotificationChannel videoCompressionChannel =
                new NotificationChannel(
                        "compression",
                        c.getString(R.string.video_compression_channel_name),
                        NotificationManager.IMPORTANCE_LOW);
        videoCompressionChannel.setShowBadge(false);
        videoCompressionChannel.setGroup("status");
        notificationManager.createNotificationChannel(videoCompressionChannel);

        final NotificationChannel exportChannel = new NotificationChannel("backup",
                c.getString(R.string.backup_channel_name),
                NotificationManager.IMPORTANCE_LOW);
        final NotificationChannel exportChannel =
                new NotificationChannel(
                        "backup",
                        c.getString(R.string.backup_channel_name),
                        NotificationManager.IMPORTANCE_LOW);
        exportChannel.setShowBadge(false);
        exportChannel.setGroup("status");
        notificationManager.createNotificationChannel(exportChannel);

        final NotificationChannel incomingCallsChannel = new NotificationChannel(INCOMING_CALLS_NOTIFICATION_CHANNEL,
                c.getString(R.string.incoming_calls_channel_name),
                NotificationManager.IMPORTANCE_HIGH);
        final NotificationChannel incomingCallsChannel =
                new NotificationChannel(
                        INCOMING_CALLS_NOTIFICATION_CHANNEL,
                        c.getString(R.string.incoming_calls_channel_name),
                        NotificationManager.IMPORTANCE_HIGH);
        incomingCallsChannel.setSound(null, null);
        incomingCallsChannel.setShowBadge(false);
        incomingCallsChannel.setLightColor(LED_COLOR);


@@ 198,9 221,11 @@ public class NotificationService {
        incomingCallsChannel.enableVibration(false);
        notificationManager.createNotificationChannel(incomingCallsChannel);

        final NotificationChannel ongoingCallsChannel = new NotificationChannel("ongoing_calls",
                c.getString(R.string.ongoing_calls_channel_name),
                NotificationManager.IMPORTANCE_LOW);
        final NotificationChannel ongoingCallsChannel =
                new NotificationChannel(
                        "ongoing_calls",
                        c.getString(R.string.ongoing_calls_channel_name),
                        NotificationManager.IMPORTANCE_LOW);
        ongoingCallsChannel.setShowBadge(false);
        ongoingCallsChannel.setGroup("calls");
        notificationManager.createNotificationChannel(ongoingCallsChannel);


@@ 215,14 240,18 @@ public class NotificationService {
        missedCallsChannel.setGroup("calls");
        notificationManager.createNotificationChannel(missedCallsChannel);

        final NotificationChannel messagesChannel = new NotificationChannel("messages",
                c.getString(R.string.messages_channel_name),
                NotificationManager.IMPORTANCE_HIGH);
        final NotificationChannel messagesChannel =
                new NotificationChannel(
                        "messages",
                        c.getString(R.string.messages_channel_name),
                        NotificationManager.IMPORTANCE_HIGH);
        messagesChannel.setShowBadge(true);
        messagesChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), new AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT)
                .build());
        messagesChannel.setSound(
                RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
                new AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                        .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT)
                        .build());
        messagesChannel.setLightColor(LED_COLOR);
        final int dat = 70;
        final long[] pattern = {0, 3 * dat, dat, dat};


@@ 231,19 260,24 @@ public class NotificationService {
        messagesChannel.enableLights(true);
        messagesChannel.setGroup("chats");
        notificationManager.createNotificationChannel(messagesChannel);
        final NotificationChannel silentMessagesChannel = new NotificationChannel("silent_messages",
                c.getString(R.string.silent_messages_channel_name),
                NotificationManager.IMPORTANCE_LOW);
        silentMessagesChannel.setDescription(c.getString(R.string.silent_messages_channel_description));
        final NotificationChannel silentMessagesChannel =
                new NotificationChannel(
                        "silent_messages",
                        c.getString(R.string.silent_messages_channel_name),
                        NotificationManager.IMPORTANCE_LOW);
        silentMessagesChannel.setDescription(
                c.getString(R.string.silent_messages_channel_description));
        silentMessagesChannel.setShowBadge(true);
        silentMessagesChannel.setLightColor(LED_COLOR);
        silentMessagesChannel.enableLights(true);
        silentMessagesChannel.setGroup("chats");
        notificationManager.createNotificationChannel(silentMessagesChannel);

        final NotificationChannel quietHoursChannel = new NotificationChannel("quiet_hours",
                c.getString(R.string.title_pref_quiet_hours),
                NotificationManager.IMPORTANCE_LOW);
        final NotificationChannel quietHoursChannel =
                new NotificationChannel(
                        "quiet_hours",
                        c.getString(R.string.title_pref_quiet_hours),
                        NotificationManager.IMPORTANCE_LOW);
        quietHoursChannel.setShowBadge(true);
        quietHoursChannel.setLightColor(LED_COLOR);
        quietHoursChannel.enableLights(true);


@@ 253,14 287,18 @@ public class NotificationService {

        notificationManager.createNotificationChannel(quietHoursChannel);

        final NotificationChannel deliveryFailedChannel = new NotificationChannel("delivery_failed",
                c.getString(R.string.delivery_failed_channel_name),
                NotificationManager.IMPORTANCE_DEFAULT);
        final NotificationChannel deliveryFailedChannel =
                new NotificationChannel(
                        "delivery_failed",
                        c.getString(R.string.delivery_failed_channel_name),
                        NotificationManager.IMPORTANCE_DEFAULT);
        deliveryFailedChannel.setShowBadge(false);
        deliveryFailedChannel.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION), new AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT)
                .build());
        deliveryFailedChannel.setSound(
                RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
                new AudioAttributes.Builder()
                        .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                        .setUsage(AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT)
                        .build());
        deliveryFailedChannel.setGroup("chats");
        notificationManager.createNotificationChannel(deliveryFailedChannel);
    }


@@ 280,16 318,23 @@ public class NotificationService {
    }

    public boolean notificationsFromStrangers() {
        return mXmppConnectionService.getBooleanPreference("notifications_from_strangers", R.bool.notifications_from_strangers);
        return mXmppConnectionService.getBooleanPreference(
                "notifications_from_strangers", R.bool.notifications_from_strangers);
    }

    private boolean isQuietHours() {
        if (!mXmppConnectionService.getBooleanPreference("enable_quiet_hours", R.bool.enable_quiet_hours)) {
        if (!mXmppConnectionService.getBooleanPreference(
                "enable_quiet_hours", R.bool.enable_quiet_hours)) {
            return false;
        }
        final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService);
        final long startTime = TimePreference.minutesToTimestamp(preferences.getLong("quiet_hours_start", TimePreference.DEFAULT_VALUE));
        final long endTime = TimePreference.minutesToTimestamp(preferences.getLong("quiet_hours_end", TimePreference.DEFAULT_VALUE));
        final SharedPreferences preferences =
                PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService);
        final long startTime =
                TimePreference.minutesToTimestamp(
                        preferences.getLong("quiet_hours_start", TimePreference.DEFAULT_VALUE));
        final long endTime =
                TimePreference.minutesToTimestamp(
                        preferences.getLong("quiet_hours_end", TimePreference.DEFAULT_VALUE));
        final long nowTime = Calendar.getInstance().getTimeInMillis();

        if (endTime < startTime) {


@@ 302,7 347,8 @@ public class NotificationService {
    public void pushFromBacklog(final Message message) {
        if (notifyMessage(message)) {
            synchronized (notifications) {
                getBacklogMessageCounter((Conversation) message.getConversation()).incrementAndGet();
                getBacklogMessageCounter((Conversation) message.getConversation())
                        .incrementAndGet();
                pushToStack(message);
            }
        } else if (notifyMissedCall(message)) {


@@ 360,7 406,9 @@ public class NotificationService {

    private int getBacklogMessageCount(Account account) {
        int count = 0;
        for (Iterator<Map.Entry<Conversation, AtomicInteger>> it = mBacklogMessageCounter.entrySet().iterator(); it.hasNext(); ) {
        for (Iterator<Map.Entry<Conversation, AtomicInteger>> it =
                        mBacklogMessageCounter.entrySet().iterator();
                it.hasNext(); ) {
            Map.Entry<Conversation, AtomicInteger> entry = it.next();
            if (entry.getKey().getAccount() == account) {
                count += entry.getValue().get();


@@ 388,7 436,8 @@ public class NotificationService {

    public void push(final Message message) {
        synchronized (CATCHUP_LOCK) {
            final XmppConnection connection = message.getConversation().getAccount().getXmppConnection();
            final XmppConnection connection =
                    message.getConversation().getAccount().getXmppConnection();
            if (connection != null && connection.isWaitingForSmCatchup()) {
                connection.incrementSmCatchupMessageCounter();
                pushFromBacklog(message);


@@ 401,25 450,43 @@ public class NotificationService {
    public void pushFailedDelivery(final Message message) {
        final Conversation conversation = (Conversation) message.getConversation();
        final boolean isScreenLocked = !mXmppConnectionService.isScreenLocked();
        if (this.mIsInForeground && isScreenLocked && this.mOpenConversation == message.getConversation()) {
            Log.d(Config.LOGTAG, message.getConversation().getAccount().getJid().asBareJid() + ": suppressing failed delivery notification because conversation is open");
        if (this.mIsInForeground
                && isScreenLocked
                && this.mOpenConversation == message.getConversation()) {
            Log.d(
                    Config.LOGTAG,
                    message.getConversation().getAccount().getJid().asBareJid()
                            + ": suppressing failed delivery notification because conversation is open");
            return;
        }
        final PendingIntent pendingIntent = createContentIntent(conversation);
        final int notificationId = generateRequestCode(conversation, 0) + DELIVERY_FAILED_NOTIFICATION_ID;
        final int notificationId =
                generateRequestCode(conversation, 0) + DELIVERY_FAILED_NOTIFICATION_ID;
        final int failedDeliveries = conversation.countFailedDeliveries();
        final Notification notification =
                new Builder(mXmppConnectionService, "delivery_failed")
                        .setContentTitle(conversation.getName())
                        .setAutoCancel(true)
                        .setSmallIcon(R.drawable.ic_error_white_24dp)
                        .setContentText(mXmppConnectionService.getResources().getQuantityText(R.plurals.some_messages_could_not_be_delivered, failedDeliveries))
                        .setContentText(
                                mXmppConnectionService
                                        .getResources()
                                        .getQuantityText(
                                                R.plurals.some_messages_could_not_be_delivered,
                                                failedDeliveries))
                        .setGroup("delivery_failed")
                        .setContentIntent(pendingIntent).build();
                        .setContentIntent(pendingIntent)
                        .build();
        final Notification summaryNotification =
                new Builder(mXmppConnectionService, "delivery_failed")
                        .setContentTitle(mXmppConnectionService.getString(R.string.failed_deliveries))
                        .setContentText(mXmppConnectionService.getResources().getQuantityText(R.plurals.some_messages_could_not_be_delivered, 1024))
                        .setContentTitle(
                                mXmppConnectionService.getString(R.string.failed_deliveries))
                        .setContentText(
                                mXmppConnectionService
                                        .getResources()
                                        .getQuantityText(
                                                R.plurals.some_messages_could_not_be_delivered,
                                                1024))
                        .setSmallIcon(R.drawable.ic_error_white_24dp)
                        .setGroup("delivery_failed")
                        .setGroupSummary(true)


@@ 489,30 556,35 @@ public class NotificationService {
        }

        showIncomingCallNotification(id, media);
        final NotificationManager notificationManager = (NotificationManager) mXmppConnectionService.getSystemService(Context.NOTIFICATION_SERVICE);
        final NotificationManager notificationManager =
                (NotificationManager)
                        mXmppConnectionService.getSystemService(Context.NOTIFICATION_SERVICE);
        final int currentInterruptionFilter;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && notificationManager != null) {
            currentInterruptionFilter = notificationManager.getCurrentInterruptionFilter();
        } else {
            currentInterruptionFilter = 1; //INTERRUPTION_FILTER_ALL
            currentInterruptionFilter = 1; // INTERRUPTION_FILTER_ALL
        }
        if (currentInterruptionFilter != 1) {
            Log.d(Config.LOGTAG, "do not ring or vibrate because interruption filter has been set to " + currentInterruptionFilter);
            Log.d(
                    Config.LOGTAG,
                    "do not ring or vibrate because interruption filter has been set to "
                            + currentInterruptionFilter);
            return;
        }
        final ScheduledFuture<?> currentVibrationFuture = this.vibrationFuture;
        this.vibrationFuture = SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate(
                new VibrationRunnable(),
                0,
                3,
                TimeUnit.SECONDS
        );
        this.vibrationFuture =
                SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate(
                        new VibrationRunnable(), 0, 3, TimeUnit.SECONDS);
        if (currentVibrationFuture != null) {
            currentVibrationFuture.cancel(true);
        }
        final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService);
        final SharedPreferences preferences =
                PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService);
        final Resources resources = mXmppConnectionService.getResources();
        final String ringtonePreference = preferences.getString("call_ringtone", resources.getString(R.string.incoming_call_ringtone));
        final String ringtonePreference =
                preferences.getString(
                        "call_ringtone", resources.getString(R.string.incoming_call_ringtone));
        if (Strings.isNullOrEmpty(ringtonePreference)) {
            Log.d(Config.LOGTAG, "ringtone has been set to none");
            return;


@@ 529,26 601,34 @@ public class NotificationService {
        this.currentlyPlayingRingtone.play();
    }

    private void showIncomingCallNotification(final AbstractJingleConnection.Id id, final Set<Media> media) {
        final Intent fullScreenIntent = new Intent(mXmppConnectionService, RtpSessionActivity.class);
        fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, id.account.getJid().asBareJid().toEscapedString());
    private void showIncomingCallNotification(
            final AbstractJingleConnection.Id id, final Set<Media> media) {
        final Intent fullScreenIntent =
                new Intent(mXmppConnectionService, RtpSessionActivity.class);
        fullScreenIntent.putExtra(
                RtpSessionActivity.EXTRA_ACCOUNT,
                id.account.getJid().asBareJid().toEscapedString());
        fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_WITH, id.with.toEscapedString());
        fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, id.sessionId);
        fullScreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        fullScreenIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        final NotificationCompat.Builder builder = new NotificationCompat.Builder(mXmppConnectionService, INCOMING_CALLS_NOTIFICATION_CHANNEL);
        final NotificationCompat.Builder builder =
                new NotificationCompat.Builder(
                        mXmppConnectionService, INCOMING_CALLS_NOTIFICATION_CHANNEL);
        if (media.contains(Media.VIDEO)) {
            builder.setSmallIcon(R.drawable.ic_videocam_white_24dp);
            builder.setContentTitle(mXmppConnectionService.getString(R.string.rtp_state_incoming_video_call));
            builder.setContentTitle(
                    mXmppConnectionService.getString(R.string.rtp_state_incoming_video_call));
        } else {
            builder.setSmallIcon(R.drawable.ic_call_white_24dp);
            builder.setContentTitle(mXmppConnectionService.getString(R.string.rtp_state_incoming_call));
            builder.setContentTitle(
                    mXmppConnectionService.getString(R.string.rtp_state_incoming_call));
        }
        final Contact contact = id.getContact();
        builder.setLargeIcon(mXmppConnectionService.getAvatarService().get(
                contact,
                AvatarService.getSystemUiAvatarSize(mXmppConnectionService))
        );
        builder.setLargeIcon(
                mXmppConnectionService
                        .getAvatarService()
                        .get(contact, AvatarService.getSystemUiAvatarSize(mXmppConnectionService)));
        final Uri systemAccount = contact.getSystemAccount();
        if (systemAccount != null) {
            builder.addPerson(systemAccount.toString());


@@ 559,38 639,49 @@ public class NotificationService {
        builder.setCategory(NotificationCompat.CATEGORY_CALL);
        PendingIntent pendingIntent = createPendingRtpSession(id, Intent.ACTION_VIEW, 101);
        builder.setFullScreenIntent(pendingIntent, true);
        builder.setContentIntent(pendingIntent); //old androids need this?
        builder.setContentIntent(pendingIntent); // old androids need this?
        builder.setOngoing(true);
        builder.addAction(new NotificationCompat.Action.Builder(
                R.drawable.ic_call_end_white_48dp,
                mXmppConnectionService.getString(R.string.dismiss_call),
                createCallAction(id.sessionId, XmppConnectionService.ACTION_DISMISS_CALL, 102))
                .build());
        builder.addAction(new NotificationCompat.Action.Builder(
                R.drawable.ic_call_white_24dp,
                mXmppConnectionService.getString(R.string.answer_call),
                createPendingRtpSession(id, RtpSessionActivity.ACTION_ACCEPT_CALL, 103))
                .build());
        builder.addAction(
                new NotificationCompat.Action.Builder(
                                R.drawable.ic_call_end_white_48dp,
                                mXmppConnectionService.getString(R.string.dismiss_call),
                                createCallAction(
                                        id.sessionId,
                                        XmppConnectionService.ACTION_DISMISS_CALL,
                                        102))
                        .build());
        builder.addAction(
                new NotificationCompat.Action.Builder(
                                R.drawable.ic_call_white_24dp,
                                mXmppConnectionService.getString(R.string.answer_call),
                                createPendingRtpSession(
                                        id, RtpSessionActivity.ACTION_ACCEPT_CALL, 103))
                        .build());
        modifyIncomingCall(builder);
        final Notification notification = builder.build();
        notification.flags = notification.flags | Notification.FLAG_INSISTENT;
        notify(INCOMING_CALL_NOTIFICATION_ID, notification);
    }

    public Notification getOngoingCallNotification(final XmppConnectionService.OngoingCall ongoingCall) {
    public Notification getOngoingCallNotification(
            final XmppConnectionService.OngoingCall ongoingCall) {
        final AbstractJingleConnection.Id id = ongoingCall.id;
        final NotificationCompat.Builder builder = new NotificationCompat.Builder(mXmppConnectionService, "ongoing_calls");
        final NotificationCompat.Builder builder =
                new NotificationCompat.Builder(mXmppConnectionService, "ongoing_calls");
        if (ongoingCall.media.contains(Media.VIDEO)) {
            builder.setSmallIcon(R.drawable.ic_videocam_white_24dp);
            if (ongoingCall.reconnecting) {
                builder.setContentTitle(mXmppConnectionService.getString(R.string.reconnecting_video_call));
                builder.setContentTitle(
                        mXmppConnectionService.getString(R.string.reconnecting_video_call));
            } else {
                builder.setContentTitle(mXmppConnectionService.getString(R.string.ongoing_video_call));
                builder.setContentTitle(
                        mXmppConnectionService.getString(R.string.ongoing_video_call));
            }
        } else {
            builder.setSmallIcon(R.drawable.ic_call_white_24dp);
            if (ongoingCall.reconnecting) {
                builder.setContentTitle(mXmppConnectionService.getString(R.string.reconnecting_call));
                builder.setContentTitle(
                        mXmppConnectionService.getString(R.string.reconnecting_call));
            } else {
                builder.setContentTitle(mXmppConnectionService.getString(R.string.ongoing_call));
            }


@@ 601,21 692,33 @@ public class NotificationService {
        builder.setCategory(NotificationCompat.CATEGORY_CALL);
        builder.setContentIntent(createPendingRtpSession(id, Intent.ACTION_VIEW, 101));
        builder.setOngoing(true);
        builder.addAction(new NotificationCompat.Action.Builder(
                R.drawable.ic_call_end_white_48dp,
                mXmppConnectionService.getString(R.string.hang_up),
                createCallAction(id.sessionId, XmppConnectionService.ACTION_END_CALL, 104))
                .build());
        builder.addAction(
                new NotificationCompat.Action.Builder(
                                R.drawable.ic_call_end_white_48dp,
                                mXmppConnectionService.getString(R.string.hang_up),
                                createCallAction(
                                        id.sessionId, XmppConnectionService.ACTION_END_CALL, 104))
                        .build());
        return builder.build();
    }

    private PendingIntent createPendingRtpSession(final AbstractJingleConnection.Id id, final String action, final int requestCode) {
        final Intent fullScreenIntent = new Intent(mXmppConnectionService, RtpSessionActivity.class);
    private PendingIntent createPendingRtpSession(
            final AbstractJingleConnection.Id id, final String action, final int requestCode) {
        final Intent fullScreenIntent =
                new Intent(mXmppConnectionService, RtpSessionActivity.class);
        fullScreenIntent.setAction(action);
        fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_ACCOUNT, id.account.getJid().asBareJid().toEscapedString());
        fullScreenIntent.putExtra(
                RtpSessionActivity.EXTRA_ACCOUNT,
                id.account.getJid().asBareJid().toEscapedString());
        fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_WITH, id.with.toEscapedString());
        fullScreenIntent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, id.sessionId);
        return PendingIntent.getActivity(mXmppConnectionService, requestCode, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        return PendingIntent.getActivity(
                mXmppConnectionService,
                requestCode,
                fullScreenIntent,
                s()
                        ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                        : PendingIntent.FLAG_UPDATE_CURRENT);
    }

    public void cancelIncomingCallNotification() {


@@ 641,7 744,8 @@ public class NotificationService {
    }

    public static void cancelIncomingCallNotification(final Context context) {
        final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
        final NotificationManagerCompat notificationManager =
                NotificationManagerCompat.from(context);
        try {
            notificationManager.cancel(INCOMING_CALL_NOTIFICATION_ID);
        } catch (RuntimeException e) {


@@ 652,21 756,30 @@ public class NotificationService {
    private void pushNow(final Message message) {
        mXmppConnectionService.updateUnreadCountBadge();
        if (!notifyMessage(message)) {
            Log.d(Config.LOGTAG, message.getConversation().getAccount().getJid().asBareJid() + ": suppressing notification because turned off");
            Log.d(
                    Config.LOGTAG,
                    message.getConversation().getAccount().getJid().asBareJid()
                            + ": suppressing notification because turned off");
            return;
        }
        final boolean isScreenLocked = mXmppConnectionService.isScreenLocked();
        if (this.mIsInForeground && !isScreenLocked && this.mOpenConversation == message.getConversation()) {
            Log.d(Config.LOGTAG, message.getConversation().getAccount().getJid().asBareJid() + ": suppressing notification because conversation is open");
        if (this.mIsInForeground
                && !isScreenLocked
                && this.mOpenConversation == message.getConversation()) {
            Log.d(
                    Config.LOGTAG,
                    message.getConversation().getAccount().getJid().asBareJid()
                            + ": suppressing notification because conversation is open");
            return;
        }
        synchronized (notifications) {
            pushToStack(message);
            final Conversational conversation = message.getConversation();
            final Account account = conversation.getAccount();
            final boolean doNotify = (!(this.mIsInForeground && this.mOpenConversation == null) || isScreenLocked)
                    && !account.inGracePeriod()
                    && !this.inMiniGracePeriod(account);
            final boolean doNotify =
                    (!(this.mIsInForeground && this.mOpenConversation == null) || isScreenLocked)
                            && !account.inGracePeriod()
                            && !this.inMiniGracePeriod(account);
            updateNotification(doNotify, Collections.singletonList(conversation.getUuid()));
        }
    }


@@ 770,13 883,19 @@ public class NotificationService {
        updateNotification(notify, conversations, false);
    }

    private void updateNotification(final boolean notify, final List<String> conversations, final boolean summaryOnly) {
        final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService);
    private void updateNotification(
            final boolean notify, final List<String> conversations, final boolean summaryOnly) {
        final SharedPreferences preferences =
                PreferenceManager.getDefaultSharedPreferences(mXmppConnectionService);

        final boolean quiteHours = isQuietHours();

        final boolean notifyOnlyOneChild = notify && conversations != null && conversations.size() == 1; //if this check is changed to > 0 catchup messages will create one notification per conversation

        final boolean notifyOnlyOneChild =
                notify
                        && conversations != null
                        && conversations.size()
                                == 1; // if this check is changed to > 0 catchup messages will
        // create one notification per conversation

        if (notifications.size() == 0) {
            cancel(NOTIFICATION_ID);


@@ 786,7 905,9 @@ public class NotificationService {
            }
            final Builder mBuilder;
            if (notifications.size() == 1 && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
                mBuilder = buildSingleConversations(notifications.values().iterator().next(), notify, quiteHours);
                mBuilder =
                        buildSingleConversations(
                                notifications.values().iterator().next(), notify, quiteHours);
                modifyForSoundVibrationAndLight(mBuilder, notify, quiteHours, preferences);
                notify(NOTIFICATION_ID, mBuilder.build());
            } else {


@@ 798,10 919,13 @@ public class NotificationService {
                if (!summaryOnly) {
                    for (Map.Entry<String, ArrayList<Message>> entry : notifications.entrySet()) {
                        String uuid = entry.getKey();
                        final boolean notifyThis = notifyOnlyOneChild ? conversations.contains(uuid) : notify;
                        Builder singleBuilder = buildSingleConversations(entry.getValue(), notifyThis, quiteHours);
                        final boolean notifyThis =
                                notifyOnlyOneChild ? conversations.contains(uuid) : notify;
                        Builder singleBuilder =
                                buildSingleConversations(entry.getValue(), notifyThis, quiteHours);
                        if (!notifyOnlyOneChild) {
                            singleBuilder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY);
                            singleBuilder.setGroupAlertBehavior(
                                    NotificationCompat.GROUP_ALERT_SUMMARY);
                        }
                        modifyForSoundVibrationAndLight(singleBuilder, notifyThis, quiteHours, preferences);
                        singleBuilder.setGroup(MESSAGES_GROUP);


@@ 839,19 963,28 @@ public class NotificationService {
        }
    }

    private void modifyForSoundVibrationAndLight(Builder mBuilder, boolean notify, boolean quietHours, SharedPreferences preferences) {
    private void modifyForSoundVibrationAndLight(
            Builder mBuilder, boolean notify, boolean quietHours, SharedPreferences preferences) {
        final Resources resources = mXmppConnectionService.getResources();
        final String ringtone = preferences.getString("notification_ringtone", resources.getString(R.string.notification_ringtone));
        final boolean vibrate = preferences.getBoolean("vibrate_on_notification", resources.getBoolean(R.bool.vibrate_on_notification));
        final String ringtone =
                preferences.getString(
                        "notification_ringtone",
                        resources.getString(R.string.notification_ringtone));
        final boolean vibrate =
                preferences.getBoolean(
                        "vibrate_on_notification",
                        resources.getBoolean(R.bool.vibrate_on_notification));
        final boolean led = preferences.getBoolean("led", resources.getBoolean(R.bool.led));
        final boolean headsup = preferences.getBoolean("notification_headsup", resources.getBoolean(R.bool.headsup_notifications));
        final boolean headsup =
                preferences.getBoolean(
                        "notification_headsup", resources.getBoolean(R.bool.headsup_notifications));
        if (notify && !quietHours) {
            if (vibrate) {
                final int dat = 70;
                final long[] pattern = {0, 3 * dat, dat, dat};
                mBuilder.setVibrate(pattern);
            } else {
                mBuilder.setVibrate(new long[]{0});
                mBuilder.setVibrate(new long[] {0});
            }
            Uri uri = Uri.parse(ringtone);
            try {


@@ 862,10 995,13 @@ public class NotificationService {
        } else {
            mBuilder.setLocalOnly(true);
        }
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mBuilder.setCategory(Notification.CATEGORY_MESSAGE);
        }
        mBuilder.setPriority(notify ? (headsup ? NotificationCompat.PRIORITY_HIGH : NotificationCompat.PRIORITY_DEFAULT) : NotificationCompat.PRIORITY_LOW);
        mBuilder.setCategory(Notification.CATEGORY_MESSAGE);
        mBuilder.setPriority(
                notify
                        ? (headsup
                                ? NotificationCompat.PRIORITY_HIGH
                                : NotificationCompat.PRIORITY_DEFAULT)
                        : NotificationCompat.PRIORITY_LOW);
        setNotificationColor(mBuilder);
        mBuilder.setDefaults(0);
        if (led) {


@@ 983,9 1119,18 @@ public class NotificationService {
    }

    private Builder buildMultipleConversation(final boolean notify, final boolean quietHours) {
        final Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService, quietHours ? "quiet_hours" : (notify ? "messages" : "silent_messages"));
        final Builder mBuilder =
                new NotificationCompat.Builder(
                        mXmppConnectionService,
                        quietHours ? "quiet_hours" : (notify ? "messages" : "silent_messages"));
        final NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle();
        style.setBigContentTitle(mXmppConnectionService.getResources().getQuantityString(R.plurals.x_unread_conversations, notifications.size(), notifications.size()));
        style.setBigContentTitle(
                mXmppConnectionService
                        .getResources()
                        .getQuantityString(
                                R.plurals.x_unread_conversations,
                                notifications.size(),
                                notifications.size()));
        final StringBuilder names = new StringBuilder();
        Conversation conversation = null;
        for (final ArrayList<Message> messages : notifications.values()) {


@@ 995,11 1140,24 @@ public class NotificationService {
                SpannableString styledString;
                if (Config.HIDE_MESSAGE_TEXT_IN_NOTIFICATION) {
                    int count = messages.size();
                    styledString = new SpannableString(name + ": " + mXmppConnectionService.getResources().getQuantityString(R.plurals.x_messages, count, count));
                    styledString =
                            new SpannableString(
                                    name
                                            + ": "
                                            + mXmppConnectionService
                                                    .getResources()
                                                    .getQuantityString(
                                                            R.plurals.x_messages, count, count));
                    styledString.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), 0);
                    style.addLine(styledString);
                } else {
                    styledString = new SpannableString(name + ": " + UIHelper.getMessagePreview(mXmppConnectionService, messages.get(0)).first);
                    styledString =
                            new SpannableString(
                                    name
                                            + ": "
                                            + UIHelper.getMessagePreview(
                                                            mXmppConnectionService, messages.get(0))
                                                    .first);
                    styledString.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), 0);
                    style.addLine(styledString);
                }


@@ 1010,7 1168,13 @@ public class NotificationService {
        if (names.length() >= 2) {
            names.delete(names.length() - 2, names.length());
        }
        final String contentTitle = mXmppConnectionService.getResources().getQuantityString(R.plurals.x_unread_conversations, notifications.size(), notifications.size());
        final String contentTitle =
                mXmppConnectionService
                        .getResources()
                        .getQuantityString(
                                R.plurals.x_unread_conversations,
                                notifications.size(),
                                notifications.size());
        mBuilder.setContentTitle(contentTitle);
        mBuilder.setTicker(contentTitle);
        mBuilder.setContentText(names.toString());


@@ 1025,46 1189,72 @@ public class NotificationService {
        return mBuilder;
    }

    private Builder buildSingleConversations(final ArrayList<Message> messages, final boolean notify, final boolean quietHours) {
        final Builder mBuilder = new NotificationCompat.Builder(mXmppConnectionService, quietHours ? "quiet_hours" : (notify ? "messages" : "silent_messages"));
    private Builder buildSingleConversations(
            final ArrayList<Message> messages, final boolean notify, final boolean quietHours) {
        final Builder mBuilder =
                new NotificationCompat.Builder(
                        mXmppConnectionService,
                        quietHours ? "quiet_hours" : (notify ? "messages" : "silent_messages"));
        if (messages.size() >= 1) {
            final Conversation conversation = (Conversation) messages.get(0).getConversation();
            mBuilder.setLargeIcon(mXmppConnectionService.getAvatarService()
                    .get(conversation, AvatarService.getSystemUiAvatarSize(mXmppConnectionService)));
            mBuilder.setLargeIcon(
                    mXmppConnectionService
                            .getAvatarService()
                            .get(
                                    conversation,
                                    AvatarService.getSystemUiAvatarSize(mXmppConnectionService)));
            mBuilder.setContentTitle(conversation.getName());
            if (Config.HIDE_MESSAGE_TEXT_IN_NOTIFICATION) {
                int count = messages.size();
                mBuilder.setContentText(mXmppConnectionService.getResources().getQuantityString(R.plurals.x_messages, count, count));
                mBuilder.setContentText(
                        mXmppConnectionService
                                .getResources()
                                .getQuantityString(R.plurals.x_messages, count, count));
            } else {
                Message message;
                //TODO starting with Android 9 we might want to put images in MessageStyle
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P && (message = getImage(messages)) != null) {
                // TODO starting with Android 9 we might want to put images in MessageStyle
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P
                        && (message = getImage(messages)) != null) {
                    modifyForImage(mBuilder, message, messages);
                } else {
                    modifyForTextOnly(mBuilder, messages);
                }
                RemoteInput remoteInput = new RemoteInput.Builder("text_reply").setLabel(UIHelper.getMessageHint(mXmppConnectionService, conversation)).build();
                RemoteInput remoteInput =
                        new RemoteInput.Builder("text_reply")
                                .setLabel(
                                        UIHelper.getMessageHint(
                                                mXmppConnectionService, conversation))
                                .build();
                PendingIntent markAsReadPendingIntent = createReadPendingIntent(conversation);
                NotificationCompat.Action markReadAction = new NotificationCompat.Action.Builder(
                        R.drawable.ic_drafts_white_24dp,
                        mXmppConnectionService.getString(R.string.mark_as_read),
                        markAsReadPendingIntent)
                        .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ)
                        .setShowsUserInterface(false)
                        .build();
                NotificationCompat.Action markReadAction =
                        new NotificationCompat.Action.Builder(
                                        R.drawable.ic_drafts_white_24dp,
                                        mXmppConnectionService.getString(R.string.mark_as_read),
                                        markAsReadPendingIntent)
                                .setSemanticAction(
                                        NotificationCompat.Action.SEMANTIC_ACTION_MARK_AS_READ)
                                .setShowsUserInterface(false)
                                .build();
                final String replyLabel = mXmppConnectionService.getString(R.string.reply);
                final String lastMessageUuid = Iterables.getLast(messages).getUuid();
                final NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder(
                        R.drawable.ic_send_text_offline,
                        replyLabel,
                        createReplyIntent(conversation, lastMessageUuid, false))
                        .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY)
                        .setShowsUserInterface(false)
                        .addRemoteInput(remoteInput).build();
                final NotificationCompat.Action wearReplyAction = new NotificationCompat.Action.Builder(R.drawable.ic_wear_reply,
                        replyLabel,
                        createReplyIntent(conversation, lastMessageUuid, true)).addRemoteInput(remoteInput).build();
                mBuilder.extend(new NotificationCompat.WearableExtender().addAction(wearReplyAction));
                final NotificationCompat.Action replyAction =
                        new NotificationCompat.Action.Builder(
                                        R.drawable.ic_send_text_offline,
                                        replyLabel,
                                        createReplyIntent(conversation, lastMessageUuid, false))
                                .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_REPLY)
                                .setShowsUserInterface(false)
                                .addRemoteInput(remoteInput)
                                .build();
                final NotificationCompat.Action wearReplyAction =
                        new NotificationCompat.Action.Builder(
                                        R.drawable.ic_wear_reply,
                                        replyLabel,
                                        createReplyIntent(conversation, lastMessageUuid, true))
                                .addRemoteInput(remoteInput)
                                .build();
                mBuilder.extend(
                        new NotificationCompat.WearableExtender().addAction(wearReplyAction));
                int addedActionsCount = 1;
                mBuilder.addAction(markReadAction);
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {


@@ 1075,23 1265,31 @@ public class NotificationService {
                if (displaySnoozeAction(messages)) {
                    String label = mXmppConnectionService.getString(R.string.snooze);
                    PendingIntent pendingSnoozeIntent = createSnoozeIntent(conversation);
                    NotificationCompat.Action snoozeAction = new NotificationCompat.Action.Builder(
                            R.drawable.ic_notifications_paused_white_24dp,
                            label,
                            pendingSnoozeIntent).build();
                    NotificationCompat.Action snoozeAction =
                            new NotificationCompat.Action.Builder(
                                            R.drawable.ic_notifications_paused_white_24dp,
                                            label,
                                            pendingSnoozeIntent)
                                    .build();
                    mBuilder.addAction(snoozeAction);
                    ++addedActionsCount;
                }
                if (addedActionsCount < 3) {
                    final Message firstLocationMessage = getFirstLocationMessage(messages);
                    if (firstLocationMessage != null) {
                        final PendingIntent pendingShowLocationIntent = createShowLocationIntent(firstLocationMessage);
                        final PendingIntent pendingShowLocationIntent =
                                createShowLocationIntent(firstLocationMessage);
                        if (pendingShowLocationIntent != null) {
                            final String label = mXmppConnectionService.getResources().getString(R.string.show_location);
                            NotificationCompat.Action locationAction = new NotificationCompat.Action.Builder(
                                    R.drawable.ic_room_white_24dp,
                                    label,
                                    pendingShowLocationIntent).build();
                            final String label =
                                    mXmppConnectionService
                                            .getResources()
                                            .getString(R.string.show_location);
                            NotificationCompat.Action locationAction =
                                    new NotificationCompat.Action.Builder(
                                                    R.drawable.ic_room_white_24dp,
                                                    label,
                                                    pendingShowLocationIntent)
                                            .build();
                            mBuilder.addAction(locationAction);
                            ++addedActionsCount;
                        }


@@ 1100,12 1298,22 @@ public class NotificationService {
                if (addedActionsCount < 3) {
                    Message firstDownloadableMessage = getFirstDownloadableMessage(messages);
                    if (firstDownloadableMessage != null) {
                        String label = mXmppConnectionService.getResources().getString(R.string.download_x_file, UIHelper.getFileDescriptionString(mXmppConnectionService, firstDownloadableMessage));
                        PendingIntent pendingDownloadIntent = createDownloadIntent(firstDownloadableMessage);
                        NotificationCompat.Action downloadAction = new NotificationCompat.Action.Builder(
                                R.drawable.ic_file_download_white_24dp,
                                label,
                                pendingDownloadIntent).build();
                        String label =
                                mXmppConnectionService
                                        .getResources()
                                        .getString(
                                                R.string.download_x_file,
                                                UIHelper.getFileDescriptionString(
                                                        mXmppConnectionService,
                                                        firstDownloadableMessage));
                        PendingIntent pendingDownloadIntent =
                                createDownloadIntent(firstDownloadableMessage);
                        NotificationCompat.Action downloadAction =
                                new NotificationCompat.Action.Builder(
                                                R.drawable.ic_file_download_white_24dp,
                                                label,
                                                pendingDownloadIntent)
                                        .build();
                        mBuilder.addAction(downloadAction);
                        ++addedActionsCount;
                    }


@@ 1126,13 1334,13 @@ public class NotificationService {
        return mBuilder;
    }

    private void modifyForImage(final Builder builder, final Message message, final ArrayList<Message> messages) {
    private void modifyForImage(
            final Builder builder, final Message message, final ArrayList<Message> messages) {
        try {
            final Bitmap bitmap = mXmppConnectionService.getFileBackend().getThumbnailBitmap(message, mXmppConnectionService.getResources(), getPixel(288));
            final ArrayList<Message> tmp = new ArrayList<>();
            for (final Message msg : messages) {
                if (msg.getType() == Message.TYPE_TEXT
                        && msg.getTransferable() == null) {
                if (msg.getType() == Message.TYPE_TEXT && msg.getTransferable() == null) {
                    tmp.add(msg);
                }
            }


@@ 1144,7 1352,8 @@ public class NotificationService {
                builder.setContentText(text);
                builder.setTicker(text);
            } else {
                final String description = UIHelper.getFileDescriptionString(mXmppConnectionService, message);
                final String description =
                        UIHelper.getFileDescriptionString(mXmppConnectionService, message);
                builder.setContentText(description);
                builder.setTicker(description);
            }


@@ 1167,7 1376,15 @@ public class NotificationService {
            builder.setName(UIHelper.getMessageDisplayName(message));
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            builder.setIcon(IconCompat.createWithBitmap(mXmppConnectionService.getAvatarService().get(message, AvatarService.getSystemUiAvatarSize(mXmppConnectionService), false)));
            builder.setIcon(
                    IconCompat.createWithBitmap(
                            mXmppConnectionService
                                    .getAvatarService()
                                    .get(
                                            message,
                                            AvatarService.getSystemUiAvatarSize(
                                                    mXmppConnectionService),
                                            false)));
        }
        return builder.build();
    }


@@ 1175,35 1392,60 @@ public class NotificationService {
    private void modifyForTextOnly(final Builder builder, final ArrayList<Message> messages) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            final Conversation conversation = (Conversation) messages.get(0).getConversation();
            final Person.Builder meBuilder = new Person.Builder().setName(mXmppConnectionService.getString(R.string.me));
            final Person.Builder meBuilder =
                    new Person.Builder().setName(mXmppConnectionService.getString(R.string.me));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                meBuilder.setIcon(IconCompat.createWithBitmap(mXmppConnectionService.getAvatarService().get(conversation.getAccount(), AvatarService.getSystemUiAvatarSize(mXmppConnectionService))));
                meBuilder.setIcon(
                        IconCompat.createWithBitmap(
                                mXmppConnectionService
                                        .getAvatarService()
                                        .get(
                                                conversation.getAccount(),
                                                AvatarService.getSystemUiAvatarSize(
                                                        mXmppConnectionService))));
            }
            final Person me = meBuilder.build();
            NotificationCompat.MessagingStyle messagingStyle = new NotificationCompat.MessagingStyle(me);
            NotificationCompat.MessagingStyle messagingStyle =
                    new NotificationCompat.MessagingStyle(me);
            final boolean multiple = conversation.getMode() == Conversation.MODE_MULTI;
            if (multiple) {
                messagingStyle.setConversationTitle(conversation.getName());
            }
            for (Message message : messages) {
                final Person sender = message.getStatus() == Message.STATUS_RECEIVED ? getPerson(message) : null;
                final Person sender =
                        message.getStatus() == Message.STATUS_RECEIVED ? getPerson(message) : null;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && isImageMessage(message)) {
                    final Uri dataUri = FileBackend.getMediaUri(mXmppConnectionService, mXmppConnectionService.getFileBackend().getFile(message));
                    NotificationCompat.MessagingStyle.Message imageMessage = new NotificationCompat.MessagingStyle.Message(UIHelper.getMessagePreview(mXmppConnectionService, message).first, message.getTimeSent(), sender);
                    final Uri dataUri =
                            FileBackend.getMediaUri(
                                    mXmppConnectionService,
                                    mXmppConnectionService.getFileBackend().getFile(message));
                    NotificationCompat.MessagingStyle.Message imageMessage =
                            new NotificationCompat.MessagingStyle.Message(
                                    UIHelper.getMessagePreview(mXmppConnectionService, message)
                                            .first,
                                    message.getTimeSent(),
                                    sender);
                    if (dataUri != null) {
                        imageMessage.setData(message.getMimeType(), dataUri);
                    }
                    messagingStyle.addMessage(imageMessage);
                } else {
                    messagingStyle.addMessage(UIHelper.getMessagePreview(mXmppConnectionService, message).first, message.getTimeSent(), sender);
                    messagingStyle.addMessage(
                            UIHelper.getMessagePreview(mXmppConnectionService, message).first,
                            message.getTimeSent(),
                            sender);
                }
            }
            messagingStyle.setGroupConversation(multiple);
            builder.setStyle(messagingStyle);
        } else {
            if (messages.get(0).getConversation().getMode() == Conversation.MODE_SINGLE) {
                builder.setStyle(new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages)));
                final CharSequence preview = UIHelper.getMessagePreview(mXmppConnectionService, messages.get(messages.size() - 1)).first;
                builder.setStyle(
                        new NotificationCompat.BigTextStyle().bigText(getMergedBodies(messages)));
                final CharSequence preview =
                        UIHelper.getMessagePreview(
                                        mXmppConnectionService, messages.get(messages.size() - 1))
                                .first;
                builder.setContentText(preview);
                builder.setTicker(preview);
                builder.setNumber(messages.size());


@@ 1225,7 1467,10 @@ public class NotificationService {
                    builder.setContentText(styledString);
                    builder.setTicker(styledString);
                } else {
                    final String text = mXmppConnectionService.getResources().getQuantityString(R.plurals.x_messages, count, count);
                    final String text =
                            mXmppConnectionService
                                    .getResources()
                                    .getQuantityString(R.plurals.x_messages, count, count);
                    builder.setContentText(text);
                    builder.setTicker(text);
                }


@@ 1248,7 1493,8 @@ public class NotificationService {

    private Message getFirstDownloadableMessage(final Iterable<Message> messages) {
        for (final Message message : messages) {
            if (message.getTransferable() != null || (message.getType() == Message.TYPE_TEXT && message.treatAsDownloadable())) {
            if (message.getTransferable() != null
                    || (message.getType() == Message.TYPE_TEXT && message.treatAsDownloadable())) {
                return message;
            }
        }


@@ 1276,35 1522,52 @@ public class NotificationService {
    }

    private PendingIntent createShowLocationIntent(final Message message) {
        Iterable<Intent> intents = GeoHelper.createGeoIntentsFromMessage(mXmppConnectionService, message);
        for (Intent intent : intents) {
        Iterable<Intent> intents =
                GeoHelper.createGeoIntentsFromMessage(mXmppConnectionService, message);
        for (final Intent intent : intents) {
            if (intent.resolveActivity(mXmppConnectionService.getPackageManager()) != null) {
                return PendingIntent.getActivity(mXmppConnectionService, generateRequestCode(message.getConversation(), 18), intent, PendingIntent.FLAG_UPDATE_CURRENT);
                return PendingIntent.getActivity(
                        mXmppConnectionService,
                        generateRequestCode(message.getConversation(), 18),
                        intent,
                        s()
                                ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                                : PendingIntent.FLAG_UPDATE_CURRENT);
            }
        }
        return null;
    }

    private PendingIntent createContentIntent(final String conversationUuid, final String downloadMessageUuid) {
        final Intent viewConversationIntent = new Intent(mXmppConnectionService, ConversationsActivity.class);
    private PendingIntent createContentIntent(
            final String conversationUuid, final String downloadMessageUuid) {
        final Intent viewConversationIntent =
                new Intent(mXmppConnectionService, ConversationsActivity.class);
        viewConversationIntent.setAction(ConversationsActivity.ACTION_VIEW_CONVERSATION);
        viewConversationIntent.putExtra(ConversationsActivity.EXTRA_CONVERSATION, conversationUuid);
        if (downloadMessageUuid != null) {
            viewConversationIntent.putExtra(ConversationsActivity.EXTRA_DOWNLOAD_UUID, downloadMessageUuid);
            return PendingIntent.getActivity(mXmppConnectionService,
            viewConversationIntent.putExtra(
                    ConversationsActivity.EXTRA_DOWNLOAD_UUID, downloadMessageUuid);
            return PendingIntent.getActivity(
                    mXmppConnectionService,
                    generateRequestCode(conversationUuid, 8),
                    viewConversationIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
                    s()
                            ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                            : PendingIntent.FLAG_UPDATE_CURRENT);
        } else {
            return PendingIntent.getActivity(mXmppConnectionService,
            return PendingIntent.getActivity(
                    mXmppConnectionService,
                    generateRequestCode(conversationUuid, 10),
                    viewConversationIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);
                    s()
                            ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                            : PendingIntent.FLAG_UPDATE_CURRENT);
        }
    }

    private int generateRequestCode(String uuid, int actionId) {
        return (actionId * NOTIFICATION_ID_MULTIPLIER) + (uuid.hashCode() % NOTIFICATION_ID_MULTIPLIER);
        return (actionId * NOTIFICATION_ID_MULTIPLIER)
                + (uuid.hashCode() % NOTIFICATION_ID_MULTIPLIER);
    }

    private int generateRequestCode(Conversational conversation, int actionId) {


@@ 1324,9 1587,21 @@ public class NotificationService {
        intent.setAction(XmppConnectionService.ACTION_CLEAR_MESSAGE_NOTIFICATION);
        if (conversation != null) {
            intent.putExtra("uuid", conversation.getUuid());
            return PendingIntent.getService(mXmppConnectionService, generateRequestCode(conversation, 20), intent, 0);
        }
        return PendingIntent.getService(mXmppConnectionService, 0, intent, 0);
            return PendingIntent.getService(
                    mXmppConnectionService,
                    generateRequestCode(conversation, 20),
                    intent,
                    s()
                            ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                            : PendingIntent.FLAG_UPDATE_CURRENT);
        }
        return PendingIntent.getService(
                mXmppConnectionService,
                0,
                intent,
                s()
                        ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                        : PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private PendingIntent createMissedCallsDeleteIntent(final Conversational conversation) {


@@ 1339,14 1614,23 @@ public class NotificationService {
        return PendingIntent.getService(mXmppConnectionService, 1, intent, 0);
    }

    private PendingIntent createReplyIntent(final Conversation conversation, final String lastMessageUuid, final boolean dismissAfterReply) {
    private PendingIntent createReplyIntent(
            final Conversation conversation,
            final String lastMessageUuid,
            final boolean dismissAfterReply) {
        final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
        intent.setAction(XmppConnectionService.ACTION_REPLY_TO_CONVERSATION);
        intent.putExtra("uuid", conversation.getUuid());
        intent.putExtra("dismiss_notification", dismissAfterReply);
        intent.putExtra("last_message_uuid", lastMessageUuid);
        final int id = generateRequestCode(conversation, dismissAfterReply ? 12 : 14);
        return PendingIntent.getService(mXmppConnectionService, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        return PendingIntent.getService(
                mXmppConnectionService,
                id,
                intent,
                s()
                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                        : PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private PendingIntent createReadPendingIntent(Conversation conversation) {


@@ 1354,7 1638,13 @@ public class NotificationService {
        intent.setAction(XmppConnectionService.ACTION_MARK_AS_READ);
        intent.putExtra("uuid", conversation.getUuid());
        intent.setPackage(mXmppConnectionService.getPackageName());
        return PendingIntent.getService(mXmppConnectionService, generateRequestCode(conversation, 16), intent, PendingIntent.FLAG_UPDATE_CURRENT);
        return PendingIntent.getService(
                mXmppConnectionService,
                generateRequestCode(conversation, 16),
                intent,
                s()
                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                        : PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private PendingIntent createCallAction(String sessionId, final String action, int requestCode) {


@@ 1362,7 1652,13 @@ public class NotificationService {
        intent.setAction(action);
        intent.setPackage(mXmppConnectionService.getPackageName());
        intent.putExtra(RtpSessionActivity.EXTRA_SESSION_ID, sessionId);
        return PendingIntent.getService(mXmppConnectionService, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        return PendingIntent.getService(
                mXmppConnectionService,
                requestCode,
                intent,
                s()
                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                        : PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private PendingIntent createSnoozeIntent(Conversation conversation) {


@@ 1370,19 1666,37 @@ public class NotificationService {
        intent.setAction(XmppConnectionService.ACTION_SNOOZE);
        intent.putExtra("uuid", conversation.getUuid());
        intent.setPackage(mXmppConnectionService.getPackageName());
        return PendingIntent.getService(mXmppConnectionService, generateRequestCode(conversation, 22), intent, PendingIntent.FLAG_UPDATE_CURRENT);
        return PendingIntent.getService(
                mXmppConnectionService,
                generateRequestCode(conversation, 22),
                intent,
                s()
                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                        : PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private PendingIntent createTryAgainIntent() {
        final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
        intent.setAction(XmppConnectionService.ACTION_TRY_AGAIN);
        return PendingIntent.getService(mXmppConnectionService, 45, intent, 0);
        return PendingIntent.getService(
                mXmppConnectionService,
                45,
                intent,
                s()
                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                        : PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private PendingIntent createDismissErrorIntent() {
        final Intent intent = new Intent(mXmppConnectionService, XmppConnectionService.class);
        intent.setAction(XmppConnectionService.ACTION_DISMISS_ERROR_NOTIFICATIONS);
        return PendingIntent.getService(mXmppConnectionService, 69, intent, 0);
        return PendingIntent.getService(
                mXmppConnectionService,
                69,
                intent,
                s()
                        ? PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                        : PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private boolean wasHighlightedOrPrivate(final Message message) {


@@ 1409,8 1723,7 @@ public class NotificationService {
    }

    private int getPixel(final int dp) {
        final DisplayMetrics metrics = mXmppConnectionService.getResources()
                .getDisplayMetrics();
        final DisplayMetrics metrics = mXmppConnectionService.getResources().getDisplayMetrics();
        return ((int) (dp * metrics.density));
    }



@@ 1419,8 1732,10 @@ public class NotificationService {
    }

    private boolean inMiniGracePeriod(final Account account) {
        final int miniGrace = account.getStatus() == Account.State.ONLINE ? Config.MINI_GRACE_PERIOD
                : Config.MINI_GRACE_PERIOD * 2;
        final int miniGrace =
                account.getStatus() == Account.State.ONLINE
                        ? Config.MINI_GRACE_PERIOD
                        : Config.MINI_GRACE_PERIOD * 2;
        return SystemClock.elapsedRealtime() < (this.mLastNotification + miniGrace);
    }



@@ 1440,26 1755,34 @@ public class NotificationService {
                }
            }
        }
        mBuilder.setContentText(mXmppConnectionService.getString(R.string.connected_accounts, connected, enabled));
        mBuilder.setContentText(
                mXmppConnectionService.getString(R.string.connected_accounts, connected, enabled));
        final PendingIntent openIntent = createOpenConversationsIntent();
        if (openIntent != null) {
            mBuilder.setContentIntent(openIntent);
        }
        mBuilder.setWhen(0);
        mBuilder.setPriority(Notification.PRIORITY_MIN);
        mBuilder.setSmallIcon(connected > 0 ? R.drawable.ic_link_white_24dp : R.drawable.ic_link_off_white_24dp);
        mBuilder.setWhen(0)
                .setPriority(Notification.PRIORITY_MIN)
                .setSmallIcon(
                        connected > 0
                                ? R.drawable.ic_link_white_24dp
                                : R.drawable.ic_link_off_white_24dp)
                .setLocalOnly(true);

        if (Compatibility.runsTwentySix()) {
            mBuilder.setChannelId("foreground");
        }


        return mBuilder.build();
    }

    private PendingIntent createOpenConversationsIntent() {
        try {
            return PendingIntent.getActivity(mXmppConnectionService, 0, new Intent(mXmppConnectionService, ConversationsActivity.class), 0);
            return PendingIntent.getActivity(
                    mXmppConnectionService,
                    0,
                    new Intent(mXmppConnectionService, ConversationsActivity.class),
                    0);
        } catch (RuntimeException e) {
            return null;
        }


@@ 1474,7 1797,10 @@ public class NotificationService {
        final List<Account> errors = new ArrayList<>();
        boolean torNotAvailable = false;
        for (final Account account : mXmppConnectionService.getAccounts()) {
            if (account.hasErrorStatus() && account.showErrorNotification() && (showAllErrors || account.getLastErrorStatus() == Account.State.UNAUTHORIZED)) {
            if (account.hasErrorStatus()
                    && account.showErrorNotification()
                    && (showAllErrors
                            || account.getLastErrorStatus() == Account.State.UNAUTHORIZED)) {
                errors.add(account);
                torNotAvailable |= account.getStatus() == Account.State.TOR_NOT_AVAILABLE;
            }


@@ 1487,41 1813,37 @@ public class NotificationService {
            cancel(ERROR_NOTIFICATION_ID);
            return;
        } else if (errors.size() == 1) {
            mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.problem_connecting_to_account));
            mBuilder.setContentTitle(
                    mXmppConnectionService.getString(R.string.problem_connecting_to_account));
            mBuilder.setContentText(errors.get(0).getJid().asBareJid().toEscapedString());
        } else {
            mBuilder.setContentTitle(mXmppConnectionService.getString(R.string.problem_connecting_to_accounts));
            mBuilder.setContentTitle(
                    mXmppConnectionService.getString(R.string.problem_connecting_to_accounts));
            mBuilder.setContentText(mXmppConnectionService.getString(R.string.touch_to_fix));
        }
        mBuilder.addAction(R.drawable.ic_autorenew_white_24dp,
        mBuilder.addAction(
                R.drawable.ic_autorenew_white_24dp,
                mXmppConnectionService.getString(R.string.try_again),
                createTryAgainIntent()
        );
                createTryAgainIntent());
        if (torNotAvailable) {
            if (TorServiceUtils.isOrbotInstalled(mXmppConnectionService)) {
                mBuilder.addAction(
                        R.drawable.ic_play_circle_filled_white_48dp,
                        mXmppConnectionService.getString(R.string.start_orbot),
                        PendingIntent.getActivity(mXmppConnectionService, 147, TorServiceUtils.LAUNCH_INTENT, 0)
                );
                        PendingIntent.getActivity(
                                mXmppConnectionService, 147, TorServiceUtils.LAUNCH_INTENT, 0));
            } else {
                mBuilder.addAction(
                        R.drawable.ic_file_download_white_24dp,
                        mXmppConnectionService.getString(R.string.install_orbot),
                        PendingIntent.getActivity(mXmppConnectionService, 146, TorServiceUtils.INSTALL_INTENT, 0)
                );
                        PendingIntent.getActivity(
                                mXmppConnectionService, 146, TorServiceUtils.INSTALL_INTENT, 0));
            }
        }
        mBuilder.setDeleteIntent(createDismissErrorIntent());
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE);
            mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp);
        } else {
            mBuilder.setSmallIcon(R.drawable.ic_stat_alert_warning);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
            mBuilder.setLocalOnly(true);
        }
        mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE);
        mBuilder.setSmallIcon(R.drawable.ic_warning_white_24dp);
        mBuilder.setLocalOnly(true);
        mBuilder.setPriority(Notification.PRIORITY_LOW);
        final Intent intent;
        if (AccountUtils.MANAGE_ACCOUNT_ACTIVITY != null) {


@@ 1531,7 1853,14 @@ public class NotificationService {
            intent.putExtra("jid", errors.get(0).getJid().asBareJid().toEscapedString());
            intent.putExtra(EditAccountActivity.EXTRA_OPENED_FROM_NOTIFICATION, true);
        }
        mBuilder.setContentIntent(PendingIntent.getActivity(mXmppConnectionService, 145, intent, PendingIntent.FLAG_UPDATE_CURRENT));
        mBuilder.setContentIntent(
                PendingIntent.getActivity(
                        mXmppConnectionService,
                        145,
                        intent,
                        s()
                                ? PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT
                                : PendingIntent.FLAG_UPDATE_CURRENT));
        if (Compatibility.runsTwentySix()) {
            mBuilder.setChannelId("error");
        }


@@ 1553,7 1882,8 @@ public class NotificationService {
    }

    private void notify(String tag, int id, Notification notification) {
        final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mXmppConnectionService);
        final NotificationManagerCompat notificationManager =
                NotificationManagerCompat.from(mXmppConnectionService);
        try {
            notificationManager.notify(tag, id, notification);
        } catch (RuntimeException e) {


@@ 1562,7 1892,8 @@ public class NotificationService {
    }

    public void notify(int id, Notification notification) {
        final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mXmppConnectionService);
        final NotificationManagerCompat notificationManager =
                NotificationManagerCompat.from(mXmppConnectionService);
        try {
            notificationManager.notify(id, notification);
        } catch (RuntimeException e) {


@@ 1571,7 1902,8 @@ public class NotificationService {
    }

    public void cancel(int id) {
        final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mXmppConnectionService);
        final NotificationManagerCompat notificationManager =
                NotificationManagerCompat.from(mXmppConnectionService);
        try {
            notificationManager.cancel(id);
        } catch (RuntimeException e) {


@@ 1580,7 1912,8 @@ public class NotificationService {
    }

    private void cancel(String tag, int id) {
        final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mXmppConnectionService);
        final NotificationManagerCompat notificationManager =
                NotificationManagerCompat.from(mXmppConnectionService);
        try {
            notificationManager.cancel(tag, id);
        } catch (RuntimeException e) {


@@ 1592,7 1925,8 @@ public class NotificationService {

        @Override
        public void run() {
            final Vibrator vibrator = (Vibrator) mXmppConnectionService.getSystemService(Context.VIBRATOR_SERVICE);
            final Vibrator vibrator =
                    (Vibrator) mXmppConnectionService.getSystemService(Context.VIBRATOR_SERVICE);
            vibrator.vibrate(CALL_PATTERN, -1);
			}
		}

M src/main/java/eu/siacs/conversations/services/XmppConnectionService.java => src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +14 -3
@@ 38,6 38,7 @@ import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.security.KeyChain;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;


@@ 1242,9 1243,10 @@ public class XmppConnectionService extends Service {

    private void setupPhoneStateListener() {
        final TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        if (telephonyManager != null) {
            telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        if (telephonyManager == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            return;
        }
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    public boolean isPhoneInCall() {


@@ 1441,7 1443,16 @@ public class XmppConnectionService extends Service {
        final Intent intent = new Intent(this, EventReceiver.class);
        intent.setAction("ping");
        try {
            PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, 0);
            final PendingIntent pendingIntent;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                pendingIntent =
                        PendingIntent.getBroadcast(
                                this, requestCode, intent, PendingIntent.FLAG_IMMUTABLE);
            } else {
                pendingIntent =
                        PendingIntent.getBroadcast(
                                this, requestCode, intent, 0);
            }
            alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToWake, pendingIntent);
        } catch (RuntimeException e) {
            Log.e(Config.LOGTAG, "unable to schedule alarm for ping", e);

M src/main/java/eu/siacs/conversations/ui/ConversationFragment.java => src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +5 -1
@@ 710,8 710,12 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
                    }

                    @Override
                    public void error(final int error, Message message) {
                    public void error(final int error, final Message message) {
                        hidePrepareFileToast(prepareFileToast);
                        final ConversationsActivity activity = ConversationFragment.this.activity;
                        if (activity == null) {
                            return;
                        }
                        activity.runOnUiThread(() -> activity.replaceToast(getString(error)));
                    }
                });

M src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java => src/main/java/eu/siacs/conversations/ui/ConversationsActivity.java +2 -2
@@ 145,7 145,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
            return;
        }
        xmppConnectionService.getNotificationService().setIsInForeground(true);
        Intent intent = pendingViewIntent.pop();
        final Intent intent = pendingViewIntent.pop();
        if (intent != null) {
            if (processViewIntent(intent)) {
                if (binding.secondaryFragment != null) {


@@ 159,7 159,7 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
            notifyFragmentOfBackendConnected(id);
        }

        ActivityResult activityResult = postponedActivityResult.pop();
        final ActivityResult activityResult = postponedActivityResult.pop();
        if (activityResult != null) {
            handleActivityResult(activityResult);
        }

M src/main/java/eu/siacs/conversations/ui/util/Attachment.java => src/main/java/eu/siacs/conversations/ui/util/Attachment.java +1 -1
@@ 179,7 179,7 @@ public class Attachment implements Parcelable {
    private static boolean renderFileThumbnail(final String mime) {
        return mime.startsWith("video/")
                || isImage(mime)
                || (Compatibility.runsTwentyOne() && "application/pdf".equals(mime));
                || "application/pdf".equals(mime);
    }

    public Uri getUri() {

M src/main/java/eu/siacs/conversations/ui/util/EditMessageActionModeCallback.java => src/main/java/eu/siacs/conversations/ui/util/EditMessageActionModeCallback.java +18 -9
@@ 48,17 48,28 @@ public class EditMessageActionModeCallback implements ActionMode.Callback {

    public EditMessageActionModeCallback(EditMessage editMessage) {
        this.editMessage = editMessage;
        this.clipboardManager = (ClipboardManager) editMessage.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
        this.clipboardManager =
                (ClipboardManager)
                        editMessage.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
    public boolean onCreateActionMode(final ActionMode mode, final Menu menu) {
        final MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.edit_message_actions, menu);
        final MenuItem pasteAsQuote = menu.findItem(R.id.paste_as_quote);
        final ClipData primaryClip = clipboardManager.getPrimaryClip();
        if (primaryClip != null && primaryClip.getItemCount() >= 0) {
            pasteAsQuote.setVisible(primaryClip.getDescription().getMimeType(0).startsWith("text/") && !TextUtils.isEmpty(primaryClip.getItemAt(0).getText()));
        if (primaryClip != null && primaryClip.getItemCount() > 0) {
            final String mimeType;
            try {
                mimeType = primaryClip.getDescription().getMimeType(0);
            } catch (final Exception e) {
                pasteAsQuote.setVisible(false);
                return true;
            }
            pasteAsQuote.setVisible(
                    mimeType.startsWith("text/")
                            && !TextUtils.isEmpty(primaryClip.getItemAt(0).getText()));
        } else {
            pasteAsQuote.setVisible(false);
        }


@@ 71,10 82,10 @@ public class EditMessageActionModeCallback implements ActionMode.Callback {
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
    public boolean onActionItemClicked(final ActionMode mode, final MenuItem item) {
        if (item.getItemId() == R.id.paste_as_quote) {
            final ClipData primaryClip = clipboardManager.getPrimaryClip();
            if (primaryClip != null && primaryClip.getItemCount() >= 1) {
            if (primaryClip != null && primaryClip.getItemCount() > 0) {
                editMessage.insertAsQuote(primaryClip.getItemAt(0).getText().toString());
                return true;
            }


@@ 83,7 94,5 @@ public class EditMessageActionModeCallback implements ActionMode.Callback {
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {

    }
    public void onDestroyActionMode(ActionMode mode) {}
}

M src/main/java/eu/siacs/conversations/utils/Compatibility.java => src/main/java/eu/siacs/conversations/utils/Compatibility.java +2 -2
@@ 43,8 43,8 @@ public class Compatibility {
        return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
    }

    public static boolean runsTwentyOne() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
    public static boolean s() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
    }

    private static boolean runsTwentyFour() {

M src/main/java/eu/siacs/conversations/utils/TorServiceUtils.java => src/main/java/eu/siacs/conversations/utils/TorServiceUtils.java +17 -11
@@ 6,41 6,47 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.widget.Toast;

import eu.siacs.conversations.R;
import me.drakeet.support.toast.ToastCompat;

public class TorServiceUtils {

    private final static String URI_ORBOT = "org.torproject.android";
    private static final String URI_ORBOT = "org.torproject.android";
    private static final Uri ORBOT_PLAYSTORE_URI = Uri.parse("market://details?id=" + URI_ORBOT);
    private final static String ACTION_START_TOR = "org.torproject.android.START_TOR";
    private static final String ACTION_START_TOR = "org.torproject.android.START_TOR";

    public static final Intent INSTALL_INTENT = new Intent(Intent.ACTION_VIEW, ORBOT_PLAYSTORE_URI);
    public static final Intent LAUNCH_INTENT = new Intent(ACTION_START_TOR);

    public final static String ACTION_STATUS = "org.torproject.android.intent.action.STATUS";
    public final static String EXTRA_STATUS = "org.torproject.android.intent.extra.STATUS";
    public static final String ACTION_STATUS = "org.torproject.android.intent.action.STATUS";
    public static final String EXTRA_STATUS = "org.torproject.android.intent.extra.STATUS";

    public static boolean isOrbotInstalled(Context context) {
    public static boolean isOrbotInstalled(final Context context) {
        try {
            context.getPackageManager().getPackageInfo(URI_ORBOT, PackageManager.GET_ACTIVITIES);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
        } catch (final PackageManager.NameNotFoundException e) {
            return false;
        }
    }


    public static void downloadOrbot(Activity activity, int requestCode) {
        try {
            activity.startActivityForResult(INSTALL_INTENT, requestCode);
        } catch (ActivityNotFoundException e) {
            ToastCompat.makeText(activity, R.string.no_market_app_installed, ToastCompat.LENGTH_SHORT).show();
        } catch (final ActivityNotFoundException e) {
            ToastCompat.makeText(
                            activity, R.string.no_market_app_installed, ToastCompat.LENGTH_SHORT)
                    .show();
        }
    }

    public static void startOrbot(Activity activity, int requestCode) {
        activity.startActivityForResult(LAUNCH_INTENT, requestCode);
    public static void startOrbot(final Activity activity, final int requestCode) {
        try {
            activity.startActivityForResult(LAUNCH_INTENT, requestCode);
        } catch (final ActivityNotFoundException e) {
            Toast.makeText(activity, R.string.install_orbot, Toast.LENGTH_LONG).show();
        }
    }
}

M src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java => src/main/java/eu/siacs/conversations/xmpp/XmppConnection.java +15 -8
@@ 12,6 12,8 @@ import android.util.SparseArray;

import androidx.annotation.NonNull;

import com.google.common.base.Strings;

import org.xmlpull.v1.XmlPullParserException;

import java.io.ByteArrayInputStream;


@@ 489,20 491,25 @@ public class XmppConnection implements Runnable {
            } else if (nextTag.isStart("failure")) {
                final Element failure = tagReader.readElement(nextTag);
                if (Namespace.SASL.equals(failure.getNamespace())) {
                    final String text = failure.findChildContent("text");
                    if (failure.hasChild("account-disabled") && text != null) {
                        Matcher matcher = Patterns.AUTOLINK_WEB_URL.matcher(text);
                    if (failure.hasChild("temporary-auth-failure")) {
                        throw new StateChangingException(Account.State.TEMPORARY_AUTH_FAILURE);
                    } else if (failure.hasChild("account-disabled")) {
                        final String text = failure.findChildContent("text");
                        if ( Strings.isNullOrEmpty(text)) {
                            throw new StateChangingException(Account.State.UNAUTHORIZED);
                        }
                        final Matcher matcher = Patterns.AUTOLINK_WEB_URL.matcher(text);
                        if (matcher.find()) {
                            final HttpUrl url;
                            try {
                                url = HttpUrl.get(text.substring(matcher.start(), matcher.end()));
                                if (url.isHttps()) {
                                    this.redirectionUrl = url;
                                    throw new StateChangingException(Account.State.PAYMENT_REQUIRED);
                                }
                            } catch (IllegalArgumentException e) {
                            } catch (final IllegalArgumentException e) {
                                throw new StateChangingException(Account.State.UNAUTHORIZED);
                            }
                            if (url.isHttps()) {
                                this.redirectionUrl = url;
                                throw new StateChangingException(Account.State.PAYMENT_REQUIRED);
                            }
                        }
                    }
                    throw new StateChangingException(Account.State.UNAUTHORIZED);

M src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java => src/main/java/eu/siacs/conversations/xmpp/jingle/JingleConnectionManager.java +2 -2
@@ 566,9 566,9 @@ public class JingleConnectionManager extends AbstractConnectionManager {
            }
        }
        synchronized (this.rtpSessionProposals) {
            for (Map.Entry<RtpSessionProposal, DeviceDiscoveryState> entry :
            for (final Map.Entry<RtpSessionProposal, DeviceDiscoveryState> entry :
                    this.rtpSessionProposals.entrySet()) {
                RtpSessionProposal proposal = entry.getKey();
                final RtpSessionProposal proposal = entry.getKey();
                if (proposal.account == contact.getAccount()
                        && contact.getJid().asBareJid().equals(proposal.with)) {
                    final DeviceDiscoveryState preexistingState = entry.getValue();

M src/main/res/values-da-rDK/strings.xml => src/main/res/values-da-rDK/strings.xml +8 -0
@@ 465,6 465,7 @@
    <string name="download_failed_file_not_found">Download mislykkes: Fil ikke fundet</string>
    <string name="download_failed_could_not_connect">Download mislykkes: Kunne ikke forbinde til vært</string>
    <string name="download_failed_could_not_write_file">Download mislykkes: Kunne ikke skrive til fil</string>
    <string name="download_failed_invalid_file">Download mislykkes: Ugyldig fil</string>
    <string name="account_status_tor_unavailable">TOR netværk er utilgængelig</string>
    <string name="account_status_bind_failure">Bind fejl</string>
    <string name="account_status_host_unknown">Serveren er ikke ansvarlig for dette domæne</string>


@@ 622,6 623,8 @@
    <string name="pref_clean_private_storage_summary">Tøm privat lagerplads, hvor filer opbevares (De kan downloades igen fra serveren)</string>
    <string name="i_followed_this_link_from_a_trusted_source">Jeg fulgte dette link fra en pålidelig kilde</string>
    <string name="verifying_omemo_keys_trusted_source">Du er ved bekræfte OMEMO-nøgler af %1$s efter du har klikket på et link.  Dette er kun sikkert, hvis du fulgte linket fra troværdig kilde hvor kun %2$s kunne have offentliggjort dette link.</string>
    <string name="verifying_omemo_keys_trusted_source_account">Du er ved at bekræfte dine OMEMO-nøgler til din konto. Det er kun sikkert, hvis du fulgte linket fra en troværdig kilde, hvor kun du kan have offentliggjort dette link.</string>
    <string name="continue_btn">Fortsæt</string>
    <string name="verify_omemo_keys">Beskræft OMEMO-nøgler</string>
    <string name="show_inactive_devices">Vis inaktive</string>
    <string name="hide_inactive_devices">Skjul inaktive</string>


@@ 904,6 907,7 @@
    <string name="rtp_state_incoming_video_call">Indkommende videoopkald</string>
    <string name="rtp_state_connecting">Forbinder</string>
    <string name="rtp_state_connected">Forbundet</string>
    <string name="rtp_state_reconnecting">Forbinder igen</string>
    <string name="rtp_state_accepting_call">Accepter opkald</string>
    <string name="rtp_state_ending_call">Afslut opkald</string>
    <string name="answer_call">Svar</string>


@@ 919,6 923,8 @@
    <string name="hang_up">Læg på</string>
    <string name="ongoing_call">Udgående opkald</string>
    <string name="ongoing_video_call">Igangværende videoopkald</string>
    <string name="reconnecting_call">Forbinder igen opkald</string>
    <string name="reconnecting_video_call">Forbinder igen videoopkald</string>
    <string name="disable_tor_to_make_call">Deaktiver TOR for at lave opkald</string>
    <string name="incoming_call">Indkommende opkald</string>
    <string name="incoming_call_duration">Indkommende opkald · %s</string>


@@ 968,4 974,6 @@
    <string name="backup_started_message">Sikkerhedskopieringen er startet. Du får en notifikation, når den er afsluttet.</string>
    <string name="unable_to_enable_video">Kunne ikke aktivere video.</string>
    <string name="plain_text_document">Ren tekstdokument</string>
    <string name="account_registrations_are_not_supported">Kontoregistrering er ikke understøttet</string>
    <string name="no_xmpp_adddress_found">Ingen XMPP-adresse fundet</string>
    </resources>

M src/main/res/values-de/strings.xml => src/main/res/values-de/strings.xml +22 -21
@@ 178,7 178,7 @@
    <string name="encryption_choice_omemo">OMEMO</string>
    <string name="mgmt_account_delete">Konto löschen</string>
    <string name="mgmt_account_disable">Vorübergehend abschalten</string>
    <string name="mgmt_account_publish_avatar">Avatar veröffentlichen</string>
    <string name="mgmt_account_publish_avatar">Profilbild veröffentlichen</string>
    <string name="mgmt_account_publish_pgp">Öffentlichen OpenPGP-Schlüssel veröffentlichen</string>
    <string name="unpublish_pgp">Öffentlichen OpenPGP-Schlüssel verwerfen</string>
    <string name="unpublish_pgp_message">Bist du sicher, dass du deinen öffentlichen OpenPGP-Schlüssel aus deiner Anwesenheitsmitteilung entfernen möchtest?\nDeine Kontakte können dir dann keine OpenPGP-verschlüsselten Nachrichten senden.</string>


@@ 250,7 250,7 @@
    <string name="could_not_destroy_channel">Channel konnte nicht gelöscht werden</string>
    <string name="action_edit_subject">Gruppenchatthema bearbeiten</string>
    <string name="topic">Thema</string>
    <string name="joining_conference">Gruppenchat wird beigetreten…</string>
    <string name="joining_conference">Gruppenchat beigetreten…</string>
    <string name="leave">Verlassen</string>
    <string name="contact_added_you">Kontakt hat dich zur Kontaktliste hinzugefügt</string>
    <string name="add_back">Auch hinzufügen</string>


@@ 259,13 259,13 @@
    <string name="contacts_and_n_more_have_read_up_to_this_point">%1$s +%2$d andere haben bis zu diesem Punkt gelesen</string>
    <string name="everyone_has_read_up_to_this_point">Alle haben bis zu diesem Punkt gelesen</string>
    <string name="publish">Veröffentlichen</string>
    <string name="touch_to_choose_picture">Avatar antippen, um ein Bild aus der Galerie auszuwählen</string>
    <string name="touch_to_choose_picture">Profilbild antippen, um ein Bild aus der Galerie auszuwählen</string>
    <string name="publishing">Veröffentliche…</string>
    <string name="error_publish_avatar_server_reject">Der Server hat die Veröffentlichung des Avatars abgelehnt.</string>
    <string name="error_publish_avatar_converting">Bild konnte nicht konvertiert werden</string>
    <string name="error_saving_avatar">Avatar kann nicht gespeichert werden</string>
    <string name="error_saving_avatar">Profilbild kann nicht gespeichert werden</string>
    <string name="or_long_press_for_default">(Oder klicke lange, um den Standard wiederherzustellen)</string>
    <string name="error_publish_avatar_no_server_support">Dein Server unterstützt die Veröffentlichung von Avataren nicht</string>
    <string name="error_publish_avatar_no_server_support">Dein Server unterstützt die Veröffentlichung von Profilbildern nicht</string>
    <string name="private_message">private Nachricht:</string>
    <string name="private_message_to">an %s</string>
    <string name="send_private_message_to">Private Nachricht an %s senden</string>


@@ 356,7 356,7 @@
    <string name="enable_notifications">Benachrichtigungen aktivieren</string>
    <string name="no_conference_server_found">Keinen Gruppenchatserver gefunden</string>
    <string name="conference_creation_failed">Gruppenchat konnte nicht erstellt werden</string>
    <string name="account_image_description">Konto-Avatar</string>
    <string name="account_image_description">Konto-Profilbild</string>
    <string name="copy_omemo_clipboard_description">OMEMO-Fingerabdruck in Zwischenablage kopieren</string>
    <string name="regenerate_omemo_key">OMEMO-Schlüssel erneuern</string>
    <string name="clear_other_devices">Geräte entfernen</string>


@@ 401,8 401,8 @@
    <string name="non_anonymous">XMPP-Adressen für alle sichtbar machen</string>
    <string name="moderated">Channel wird moderiert</string>
    <string name="you_are_not_participating">Du bist kein Mitglied</string>
    <string name="modified_conference_options">Gruppenchatoptionen wurden modifiziert!</string>
    <string name="could_not_modify_conference_options">Gruppenchatoptionen konnten nicht modifiziert werden</string>
    <string name="modified_conference_options">Gruppenchatoptionen wurden geändert!</string>
    <string name="could_not_modify_conference_options">Gruppenchatoptionen konnten nicht geändert werden</string>
    <string name="never">Niemals</string>
    <string name="until_further_notice">Bis auf Weiteres</string>
    <string name="snooze">Schlummern</string>


@@ 420,7 420,7 @@
    <string name="pdf_document">PDF-Dokument</string>
    <string name="apk">Android App</string>
    <string name="vcard">Kontakt</string>
    <string name="avatar_has_been_published">Avatar wurde veröffentlicht!</string>
    <string name="avatar_has_been_published">Profilbild wurde veröffentlicht!</string>
    <string name="sending_x_file">%s wird gesendet</string>
    <string name="offering_x_file">%s wird angeboten</string>
    <string name="hide_offline">Offline verstecken</string>


@@ 440,7 440,7 @@
    <string name="pref_dont_trust_system_cas_title">Zertifizierungsstellen nicht vertrauen</string>
    <string name="pref_dont_trust_system_cas_summary">Alle Zertifikate müssen manuell bestätigt werden</string>
    <string name="pref_remove_trusted_certificates_title">Zertifikate löschen</string>
    <string name="pref_remove_trusted_certificates_summary">Als vertrauenswürdig bestätigte Zertifikate löschen</string>
    <string name="pref_remove_trusted_certificates_summary">Manuell bestätigte Zertifikate löschen</string>
    <string name="toast_no_trusted_certs">Keine manuell bestätigten Zertifikate</string>
    <string name="dialog_manage_certs_title">Zertifikate löschen</string>
    <string name="dialog_manage_certs_positivebutton">Auswahl löschen</string>


@@ 477,17 477,17 @@
    <string name="pref_dnd_on_silent_mode_summary">Als Beschäftigt anzeigen, wenn sich das Gerät im lautlosen Modus befindet</string>
    <string name="pref_treat_vibrate_as_silent">Vibration als Lautlos behandeln</string>
    <string name="pref_treat_vibrate_as_dnd_summary">Als Beschäftigt anzeigen, wenn das Gerät auf Vibration eingestellt ist</string>
    <string name="pref_show_connection_options">Erweiterte Verbindungsoptionen</string>
    <string name="pref_show_connection_options">Erweiterte Verbindungseinstellungen</string>
    <string name="pref_show_connection_options_summary">Hostname- und Port-Optionen bei Kontoeinrichtung anzeigen</string>
    <string name="hostname_example">xmpp.domain.de</string>
    <string name="action_add_account_with_certificate">Mit Zertifikat anmelden</string>
    <string name="unable_to_parse_certificate">Zertifikat konnte nicht ausgewertet werden</string>
    <string name="unable_to_parse_certificate">Zertifikat konnte nicht verarbeitet werden</string>
    <string name="mam_prefs">Archivierungseinstellungen</string>
    <string name="server_side_mam_prefs">Archivierungseinstellungen des Servers</string>
    <string name="fetching_mam_prefs">Archivierungseinstellungen werden abgerufen. Bitte warten…</string>
    <string name="unable_to_fetch_mam_prefs">Archivierungseinstellungen konnten nicht abgerufen werden</string>
    <string name="captcha_required">CAPTCHA erforderlich</string>
    <string name="captcha_hint">Gib den Text von obigem Bild ein</string>
    <string name="captcha_hint">Gib den Text aus dem Bild oben ein</string>
    <string name="certificate_chain_is_not_trusted">Nicht vertrauenswürdige Zertifikatskette</string>
    <string name="jid_does_not_match_certificate">XMPP-Adresse stimmt nicht dem Zertifikat überein</string>
    <string name="action_renew_certificate">Zertifikat erneuern</string>


@@ 515,7 515,7 @@
    <string name="no_storage_permission"> %1$s den Zugriff auf den externen Speicher gewähren</string>
    <string name="no_camera_permission">%1$s den Zugriff auf die Kamera gewähren</string>
    <string name="sync_with_contacts">Mit Kontakten synchronisieren</string>
    <string name="sync_with_contacts_long">%1$s möchte die Erlaubnis, auf deine Kontakte zuzugreifen, um sie mit deiner XMPP-Kontaktliste abzugleichen.\nDadurch werden die vollständigen Namen und Avatare deiner Kontakte angezeigt.\n\n%1$s liest nur dein Adressbuch und gleicht es lokal ab, ohne dass etwas auf deinen Server hochgeladen wird.</string>
    <string name="sync_with_contacts_long">%1$s möchte die Erlaubnis, auf deine Kontakte zuzugreifen, um sie mit deiner XMPP-Kontaktliste abzugleichen.\nDadurch werden die vollständigen Namen und Profilbilder deiner Kontakte angezeigt.\n\n%1$s liest nur dein Adressbuch und gleicht es lokal ab, ohne dass etwas auf deinen Server hochgeladen wird.</string>
    <string name="sync_with_contacts_quicksy"><![CDATA[Quicksy benötigt Zugriff auf die Telefonnummern deiner Kontakte, um Vorschläge für mögliche Kontakte zu machen, die bereits bei Quicksy sind.<br><br>Wir werden keine Kopie dieser Telefonnummern speichern.\n\nFür weitere Informationen lies unsere <a href="https://quicksy.im/#privacy">Datenschutzerklärung</a>.<br><br>Du wirst nun gefragt, ob du den Zugriff auf deine Kontakte erlauben möchtest.]]></string>
    <string name="notify_on_all_messages">Bei allen Nachrichten benachrichtigen</string>
    <string name="notify_only_when_highlighted">Nur benachrichtigen, wenn ich erwähnt werde</string>


@@ 595,7 595,7 @@
    <string name="pref_delete_omemo_identities">OMEMO-Identitäten zurücksetzen</string>
    <string name="pref_delete_omemo_identities_summary">Erzeuge neue OMEMO-Schlüssel. Alle deine Kontakte müssen sie erneut verifizieren. Verwende dies nur als letztes Mittel.</string>
    <string name="delete_selected_keys">Ausgewählte Schlüssel löschen</string>
    <string name="error_publish_avatar_offline">Du musst verbunden sein, um deinen Avatar zu veröffentlichen.</string>
    <string name="error_publish_avatar_offline">Du musst verbunden sein, um deinen Profilbild zu veröffentlichen.</string>
    <string name="show_error_message">Zeige Fehlermeldung</string>
    <string name="error_message">Fehlermeldung</string>
    <string name="data_saver_enabled">Datensparmodus aktiv</string>


@@ 745,9 745,9 @@
    <string name="p1_s3_filetransfer">HTTP-Dateifreigabe für S3</string>
    <string name="pref_start_search">Direkte Suche </string>
    <string name="pref_start_search_summary">Beim Dialog \'Unterhaltung beginnen\' Tastatur öffnen und den Cursor im Suchfeld platzieren</string>
    <string name="group_chat_avatar">Gruppenchat-Avatar</string>
    <string name="host_does_not_support_group_chat_avatars">Host unterstützt keine Gruppenchat-Avatare</string>
    <string name="only_the_owner_can_change_group_chat_avatar">Nur der Eigentümer kann den Gruppenchat-Avatar ändern</string>
    <string name="group_chat_avatar">Gruppenchat-Profilbild</string>
    <string name="host_does_not_support_group_chat_avatars">Host unterstützt keine Gruppenchat-Profilbilder</string>
    <string name="only_the_owner_can_change_group_chat_avatar">Nur der Eigentümer kann das Gruppenchat-Profilbild ändern</string>
    <string name="contact_name">Kontaktname</string>
    <string name="nickname">Nickname</string>
    <string name="group_chat_name">Name</string>


@@ 946,8 946,8 @@
    <string name="could_not_correct_message">Nachricht konnte nicht korrigiert werden</string>
    <string name="search_all_conversations">Alle Unterhaltungen</string>
    <string name="search_this_conversation">Diese Unterhaltung</string>
    <string name="your_avatar">Dein Avatar</string>
    <string name="avatar_for_x">Avatar für %s</string>
    <string name="your_avatar">Dein Profilbild</string>
    <string name="avatar_for_x">Profilbild für %s</string>
    <string name="encrypted_with_omemo">Verschlüsselt mit OMEMO</string>
    <string name="encrypted_with_openpgp">Verschlüsselt mit OpenPGP</string>
    <string name="not_encrypted">Nicht verschlüsselt</string>


@@ 968,7 968,7 @@
    <string name="more_options">Weitere Optionen</string>
    <string name="no_application_found">Keine Anwendung gefunden</string>
    <string name="invite_to_app">Einladung zu Conversations</string>
    <string name="unable_to_parse_invite">Einladung kann nicht gelesen werden</string>
    <string name="unable_to_parse_invite">Einladung kann nicht verarbeitet werden</string>
    <string name="server_does_not_support_easy_onboarding_invites">Server unterstützt keine Generierung von Einladungen</string>
    <string name="no_active_accounts_support_this">Keine aktiven Konten unterstützen diese Funktion</string>
    <string name="backup_started_message">Die Sicherung wurde gestartet. Du bekommst eine Benachrichtigung, sobald sie fertig ist.</string>


@@ 976,5 976,6 @@
    <string name="plain_text_document">Textdokument</string>
    <string name="account_registrations_are_not_supported">Kontoregistrierungen werden nicht unterstützt</string>
    <string name="no_xmpp_adddress_found">Keine XMPP-Adresse gefunden</string>
    <string name="account_status_temporary_auth_failure">Temporärer Authentifizierungsfehler</string>

</resources>

M src/main/res/values-el/strings.xml => src/main/res/values-el/strings.xml +1 -2
@@ 975,5 975,4 @@
    <string name="plain_text_document">Έγγραφο απλού κειμένου</string>
    <string name="account_registrations_are_not_supported">Δεν υποστηρίζονται εγγραφές λογαριασμών</string>
    <string name="no_xmpp_adddress_found">Δεν βρέθηκε διεύθυνση XMPP</string>

</resources>
    </resources>

M src/main/res/values-es/strings.xml => src/main/res/values-es/strings.xml +24 -1
@@ 33,6 33,9 @@
        <item quantity="one">%d conversación sin leer</item>

    
        <item quantity="many">%dconversaciones sin leer</item>

    
        <item quantity="other">%dconversaciones sin leer</item>

    </plurals>


@@ 447,6 450,7 @@
    <string name="dialog_manage_certs_negativebutton">Cancelar</string>
    <plurals name="toast_delete_certificates">
        <item quantity="one">%d certificado eliminado</item>
        <item quantity="many">%d certificados eliminados</item>
        <item quantity="other">%d certificados eliminados</item>
    </plurals>
    <string name="pref_quick_action_summary">Cambiar el botón de “Enviar” por el botón de acción rápida</string>


@@ 465,6 469,7 @@
    <string name="download_failed_file_not_found">Error al descargar: Archivo no encontrado</string>
    <string name="download_failed_could_not_connect">Error al descargar: No se ha podido conectar con el servidor</string>
    <string name="download_failed_could_not_write_file">Falló la descarga: No se puede escribir el fichero</string>
    <string name="download_failed_invalid_file">Error al descargar: Archivo no válido</string>
    <string name="account_status_tor_unavailable">Red Tor no disponible.</string>
    <string name="account_status_bind_failure">Fallo de enlace</string>
    <string name="account_status_host_unknown">El servidor no es responsable de este dominio</string>


@@ 504,6 509,7 @@
    <string name="connected_accounts">%1$d de %2$d cuentas conectadas</string>
    <plurals name="x_messages">
        <item quantity="one">%d mensaje</item>
        <item quantity="many">%d mensajes</item>
        <item quantity="other">%d mensajes</item>
    </plurals>
    <string name="load_more_messages">Cargar más mensajes</string>


@@ 622,6 628,8 @@
    <string name="pref_clean_private_storage_summary">Limpiar datos privados de ficheros descargados (Pueden volver a descargarse desde el servidor)</string>
    <string name="i_followed_this_link_from_a_trusted_source">Enlace desde una fuente de confianza</string>
    <string name="verifying_omemo_keys_trusted_source">Vas a verificar las claves OMEMO de %1$s después de hacer click en el enlace. Esto solo es seguro si conseguiste este enlace desde una fuente de confianza donde solo %2$s pudo haber publicado el enlace</string>
    <string name="verifying_omemo_keys_trusted_source_account">Está a punto de verificar las claves OMEMO de su propia cuenta. Esto solamente es seguro si ha seguido este enlace desde una fuente segura, donde solo usted lo haya publicado.</string>
    <string name="continue_btn">Continuar</string>
    <string name="verify_omemo_keys">Verificar claves OMEMO</string>
    <string name="show_inactive_devices">Mostrar inactivos</string>
    <string name="hide_inactive_devices">Ocultar inactivos</string>


@@ 629,26 637,32 @@
    <string name="distrust_omemo_key_text">¿Estás seguro de que quieres eliminar la verificación de este dispositivo?\nEste dispositivo y los mensajes que lleguen desde allí serán marcados como \"No confiables\". </string>
    <plurals name="seconds">
        <item quantity="one">%d segundo</item>
        <item quantity="many">%d segundos</item>
        <item quantity="other">%d segundos</item>
    </plurals>
    <plurals name="minutes">
        <item quantity="one">%d minuto</item>
        <item quantity="many">%d minutos</item>
        <item quantity="other">%d minutos</item>
    </plurals>
    <plurals name="hours">
        <item quantity="one">%d hora</item>
        <item quantity="many">%d horas</item>
        <item quantity="other">%d horas</item>
    </plurals>
    <plurals name="days">
        <item quantity="one">%d día</item>
        <item quantity="many">%d días</item>
        <item quantity="other">%d días</item>
    </plurals>
    <plurals name="weeks">
        <item quantity="one">%d semana</item>
        <item quantity="many">%d semanas</item>
        <item quantity="other">%d semanas</item>
    </plurals>
    <plurals name="months">
        <item quantity="one">%d mes</item>
        <item quantity="many">%d meses</item>
        <item quantity="other">%d meses</item>
    </plurals>
    <string name="pref_automatically_delete_messages">Borrado automático de mensajes</string>


@@ 904,6 918,7 @@
    <string name="rtp_state_incoming_video_call">Videollamada entrante</string>
    <string name="rtp_state_connecting">Conectando</string>
    <string name="rtp_state_connected">Conectado</string>
    <string name="rtp_state_reconnecting">Reconectando</string>
    <string name="rtp_state_accepting_call">Aceptar llamada</string>
    <string name="rtp_state_ending_call">Terminar llamada</string>
    <string name="answer_call">Contestar</string>


@@ 919,6 934,8 @@
    <string name="hang_up">Colgar</string>
    <string name="ongoing_call">Llamada saliente</string>
    <string name="ongoing_video_call">Video llamada saliente</string>
    <string name="reconnecting_call">Reconectando llamada</string>
    <string name="reconnecting_video_call">Reconectando video llamada</string>
    <string name="disable_tor_to_make_call">Deshabilitar Tor para hacer llamadas</string>
    <string name="incoming_call">Llamada entrante</string>
    <string name="incoming_call_duration">Llamada entrante · %s</string>


@@ 952,10 969,12 @@
    <string name="add_contact_or_create_or_join_group_chat">Añadir contacto, crear o unirse a un grupo de chat, o descubrir canales</string>
    <plurals name="view_users">
        <item quantity="one">Ver %1$d Participante</item>
        <item quantity="many">Ver %1$d Participantes</item>
        <item quantity="other">Ver %1$d Participantes</item>
    </plurals>
    <plurals name="some_messages_could_not_be_delivered">
        <item quantity="one">Un mensaje no se ha podido entregar</item>
        <item quantity="many">Algunos mensajes no se han podido entregar</item>
        <item quantity="other">Algunos mensajes no se han podido entregar</item>
    </plurals>
    <string name="failed_deliveries">Envíos fallidos</string>


@@ 968,4 987,8 @@
    <string name="backup_started_message">La copia de seguridad ha empezado. Recibirás una notificación cuando se haya completado.</string>
    <string name="unable_to_enable_video">No se ha podido habilitar el vídeo.</string>
    <string name="plain_text_document">Documento de texto plano</string>
    </resources>
    <string name="account_registrations_are_not_supported">Los registros de cuenta no están soportados</string>
    <string name="no_xmpp_adddress_found">Dirección XMPP no encontrada</string>
    <string name="account_status_temporary_auth_failure">Fallo temporal de autenticación</string>

</resources>

M src/main/res/values-fr/strings.xml => src/main/res/values-fr/strings.xml +22 -2
@@ 33,6 33,9 @@
        <item quantity="one">%d conversation non lue</item>

    
        <item quantity="many">%d conversations non lues</item>

    
        <item quantity="other">%d conversations non lues</item>

    </plurals>


@@ 444,6 447,7 @@
    <string name="dialog_manage_certs_negativebutton">Annuler</string>
    <plurals name="toast_delete_certificates">
        <item quantity="one">%d certificat supprimé</item>
        <item quantity="many">%d certificats supprimés</item>
        <item quantity="other">%d certificats supprimés</item>
    </plurals>
    <string name="pref_quick_action_summary">Remplacer le bouton « Envoyer » par une action rapide</string>


@@ 462,12 466,14 @@
    <string name="download_failed_file_not_found">Échec du téléchargement : impossible de trouver le fichier</string>
    <string name="download_failed_could_not_connect">Échec du téléchargement : impossible de se connecter à l\'hôte</string>
    <string name="download_failed_could_not_write_file">Échec du téléchargement : Écriture impossible</string>
    <string name="download_failed_invalid_file">Échec du téléchargement : Fichier non valide</string>
    <string name="account_status_tor_unavailable">Réseau Tor inaccessible</string>
    <string name="account_status_bind_failure">La liaison a échoué</string>
    <string name="account_status_host_unknown">Le serveur n\'est pas responsable pour ce domaine</string>
    <string name="server_info_broken">Détraqué</string>
    <string name="pref_presence_settings">Disponibilité</string>
    <string name="pref_away_when_screen_off">Absent quand l\'appareil est verrouillé</string>
    <string name="pref_away_when_screen_off_summary">Afficher comme étant absent lorsque l\'appareil est verrouillé</string>
    <string name="pref_dnd_on_silent_mode">Occupé en mode silence</string>
    <string name="pref_dnd_on_silent_mode_summary">Occupé lorsque l\'appareil est en mode silencieux</string>
    <string name="pref_treat_vibrate_as_silent">Indisponible en mode vibreur</string>


@@ 500,6 506,7 @@
    <string name="connected_accounts">%1$d compte(s) sur %2$d connecté(s)</string>
    <plurals name="x_messages">
        <item quantity="one">%d message</item>
        <item quantity="many">%d messages</item>
        <item quantity="other">%d messages</item>
    </plurals>
    <string name="load_more_messages">Charger plus de messages</string>


@@ 624,26 631,32 @@
    <string name="distrust_omemo_key_text">Êtes-vous sûr de vouloir retirer la vérification pour cet appareil ?\nCet appareil et les messages qui en proviennent seront marqués comme « indignes de confiance ».</string>
    <plurals name="seconds">
        <item quantity="one">%d seconde</item>
        <item quantity="many">%d secondes</item>
        <item quantity="other">%d secondes</item>
    </plurals>
    <plurals name="minutes">
        <item quantity="one">%d minute</item>
        <item quantity="many">%d minutes</item>
        <item quantity="other">%d minutes</item>
    </plurals>
    <plurals name="hours">
        <item quantity="one">%d heure</item>
        <item quantity="many">%d heures</item>
        <item quantity="other">%d heures</item>
    </plurals>
    <plurals name="days">
        <item quantity="one">%d jour</item>
        <item quantity="many">%d jours</item>
        <item quantity="other">%d jours</item>
    </plurals>
    <plurals name="weeks">
        <item quantity="one">%d semaine</item>
        <item quantity="many">%d semaines</item>
        <item quantity="other">%d semaines</item>
    </plurals>
    <plurals name="months">
        <item quantity="one">%d mois</item>
        <item quantity="many">%d mois</item>
        <item quantity="other">%d mois</item>
    </plurals>
    <string name="pref_automatically_delete_messages">Suppression messages auto</string>


@@ 899,6 912,7 @@
    <string name="rtp_state_incoming_video_call">Appel vidéo entrant</string>
    <string name="rtp_state_connecting">Connexion en cours</string>
    <string name="rtp_state_connected">Connecté</string>
    <string name="rtp_state_reconnecting">Reconnexion en cours</string>
    <string name="rtp_state_accepting_call">Accepter les appels</string>
    <string name="rtp_state_ending_call">Fin d\'appel</string>
    <string name="answer_call">Décrocher</string>


@@ 910,9 924,12 @@
    <string name="rtp_state_connectivity_lost_error">Connexion perdue</string>
    <string name="rtp_state_retracted">Appel annulé</string>
    <string name="rtp_state_application_failure">Échec de l\'application</string>
    <string name="rtp_state_security_error">Vérification du problème</string>
    <string name="hang_up">Raccrocher</string>
    <string name="ongoing_call">Appel en cours</string>
    <string name="ongoing_video_call">Appel vidéo en cours</string>
    <string name="reconnecting_call">En cours de reconnexion de l\'appel</string>
    <string name="reconnecting_video_call">En cours de reconnexion de l\'appel vidéo</string>
    <string name="disable_tor_to_make_call">Désactivez Tor afin de passer des appels</string>
    <string name="incoming_call">Appel entrant</string>
    <string name="incoming_call_duration">Appel entrant · %s</string>


@@ 946,10 963,12 @@
    <string name="add_contact_or_create_or_join_group_chat">Ajouter un contact, créer ou joindre un groupe de discussion, ou découvrir les salons</string>
    <plurals name="view_users">
        <item quantity="one">Voir %1$d participant</item>
        <item quantity="many">Voir %1$d participants</item>
        <item quantity="other">Voir %1$d participants</item>
    </plurals>
    <plurals name="some_messages_could_not_be_delivered">
        <item quantity="one">Certains messages n\'ont pas pu être distribués</item>
        <item quantity="many">Certains messages n\'ont pu être distribués</item>
        <item quantity="other">Certains messages n\'ont pu être distribués</item>
    </plurals>
    <string name="failed_deliveries">Échec lors de la livraison</string>


@@ 957,8 976,9 @@
    <string name="no_application_found">Aucune application trouvée</string>
    <string name="invite_to_app">Inviter à Conversations</string>
    <string name="unable_to_parse_invite">Impossible de lire l\'invitation</string>
    <string name="server_does_not_support_easy_onboarding_invites">Le serveur ne prend pas en charge la génération d\'invitations</string>
    <string name="no_active_accounts_support_this">Aucun compte actif ne prend en charge cette fonctionalité</string>
    <string name="unable_to_enable_video">Impossible d’activer la vidéo.</string>
    <string name="account_registrations_are_not_supported">La création de nouveaux comptes n’est pas prise en charge</string>
    <string name="no_xmpp_adddress_found">Aucune adresse XMPP trouvée</string>

</resources>
    </resources>

M src/main/res/values-gl/strings.xml => src/main/res/values-gl/strings.xml +1 -0
@@ 976,5 976,6 @@
    <string name="plain_text_document">Documento de texto plano</string>
    <string name="account_registrations_are_not_supported">Non está permitido o rexistro de novas contas</string>
    <string name="no_xmpp_adddress_found">Non se atopa un enderezo XMPP</string>
    <string name="account_status_temporary_auth_failure">Fallo temporal da autenticación</string>

</resources>

M src/main/res/values-it/strings.xml => src/main/res/values-it/strings.xml +14 -0
@@ 33,6 33,9 @@
        <item quantity="one">%d conversazione non letta</item>

    
        <item quantity="many">%d conversazioni non lette</item>

    
        <item quantity="other">%d conversazioni non lette</item>

    </plurals>


@@ 447,6 450,7 @@
    <string name="dialog_manage_certs_negativebutton">Annulla</string>
    <plurals name="toast_delete_certificates">
        <item quantity="one">Cancellato il %d certificato</item>
        <item quantity="many">Cancellati %d certificati</item>
        <item quantity="other">Cancellati %d certificati</item>
    </plurals>
    <string name="pref_quick_action_summary">Sostituisci il tasto \"Invio\" con un\'azione rapida</string>


@@ 505,6 509,7 @@
    <string name="connected_accounts">%1$d su %2$d profili connessi</string>
    <plurals name="x_messages">
        <item quantity="one">%d messaggio</item>
        <item quantity="many">%d messaggi</item>
        <item quantity="other">%d messaggi</item>
    </plurals>
    <string name="load_more_messages">Carica altri messaggi</string>


@@ 632,26 637,32 @@
    <string name="distrust_omemo_key_text">Sei sicuro di volere rimuovere la verifica di questo dispositivo?\nIl dispositivo e i messaggi provenienti da esso verranno segnati come \"Non fidato\".</string>
    <plurals name="seconds">
        <item quantity="one">%d secondo</item>
        <item quantity="many">%d secondi</item>
        <item quantity="other">%d secondi</item>
    </plurals>
    <plurals name="minutes">
        <item quantity="one">%d minuto</item>
        <item quantity="many">%d minuti</item>
        <item quantity="other">%d minuti</item>
    </plurals>
    <plurals name="hours">
        <item quantity="one">%d ora</item>
        <item quantity="many">%d ore</item>
        <item quantity="other">%d ore</item>
    </plurals>
    <plurals name="days">
        <item quantity="one">%d giorno</item>
        <item quantity="many">%d giorni</item>
        <item quantity="other">%d giorni</item>
    </plurals>
    <plurals name="weeks">
        <item quantity="one">%d settimana</item>
        <item quantity="many">%d settimane</item>
        <item quantity="other">%d settimane</item>
    </plurals>
    <plurals name="months">
        <item quantity="one">%d mese</item>
        <item quantity="many">%d mesi</item>
        <item quantity="other">%d mesi</item>
    </plurals>
    <string name="pref_automatically_delete_messages">Eliminazione automatica dei messaggi</string>


@@ 958,10 969,12 @@
    <string name="add_contact_or_create_or_join_group_chat">Aggiungi un contatto, crea o visita una chat di gruppo, o scopri canali</string>
    <plurals name="view_users">
        <item quantity="one">Vedi %1$d partecipante</item>
        <item quantity="many">Vedi %1$d partecipanti</item>
        <item quantity="other">Vedi %1$d partecipanti</item>
    </plurals>
    <plurals name="some_messages_could_not_be_delivered">
        <item quantity="one">Un messaggio non è stato recapitato</item>
        <item quantity="many">Alcuni messaggi non sono stati recapitati</item>
        <item quantity="other">Alcuni messaggi non sono stati recapitati</item>
    </plurals>
    <string name="failed_deliveries">Recapiti falliti</string>


@@ 976,5 989,6 @@
    <string name="plain_text_document">Documento di testo</string>
    <string name="account_registrations_are_not_supported">Le registrazioni di profili non sono supportate</string>
    <string name="no_xmpp_adddress_found">Nessun indirizzo XMPP trovato</string>
    <string name="account_status_temporary_auth_failure">Errore di autenticazione temporaneo</string>

</resources>

M src/main/res/values-ja/strings.xml => src/main/res/values-ja/strings.xml +4 -2
@@ 217,6 217,8 @@
    <string name="openpgp_key_id">OpenPGP 鍵 ID</string>
    <string name="omemo_fingerprint">OMEMO フィンガープリント</string>
    <string name="omemo_fingerprint_x509">v\\OMEMO フィンガープリント</string>
    <string name="omemo_fingerprint_selected_message">OMEMO フィンガープリント (メッセージ起源)</string>
    <string name="omemo_fingerprint_x509_selected_message">v\\OMEMO フィンガープリント (メッセージ起源)</string>
    <string name="other_devices">他のデバイス</string>
    <string name="trust_omemo_fingerprints">OMEMO フィンガープリントを信頼</string>
    <string name="fetching_keys">鍵の取得中…</string>


@@ 459,6 461,7 @@
    <string name="download_failed_file_not_found">ダウンロードに失敗しました: ファイルが見つかりません</string>
    <string name="download_failed_could_not_connect">ダウンロードに失敗しました: ホストに接続できませんでした</string>
    <string name="download_failed_could_not_write_file">ダウンロードに失敗しました: ファイルに書き込みできません</string>
    <string name="download_failed_invalid_file">ダウンロード失敗: 無効なファイル</string>
    <string name="account_status_tor_unavailable">Tor ネットワークが利用できません</string>
    <string name="account_status_bind_failure">バインド失敗</string>
    <string name="account_status_host_unknown">そのサーバーはこのドメインに責任を持ちません</string>


@@ 954,5 957,4 @@
    <string name="plain_text_document">プレーンテキスト文書</string>
    <string name="account_registrations_are_not_supported">アカウント登録はサポートされていません</string>
    <string name="no_xmpp_adddress_found">XMPPアドレスがみつかりません</string>

</resources>
    </resources>

M src/main/res/values-nl/strings.xml => src/main/res/values-nl/strings.xml +19 -0
@@ 4,6 4,7 @@
    <string name="action_add">Nieuw gesprek</string>
    <string name="action_accounts">Accounts beheren</string>
    <string name="action_account">Account beheren</string>
    <string name="action_end_conversation">Gesprek sluiten</string>
    <string name="action_contact_details">Contactgegevens</string>
    <string name="action_muc_details">Gespreksgegevens</string>
    <string name="channel_details">Kanaalinformatie</string>


@@ 28,6 29,13 @@
    <string name="just_now">zojuist</string>
    <string name="minute_ago">1 min. geleden</string>
    <string name="minutes_ago">%d min. geleden</string>
    <plurals name="x_unread_conversations">
        <item quantity="one">%d ongelezen gesprek</item>

    
        <item quantity="other">%d ongelezen gesprekken</item>

    </plurals>
    <string name="sending">versturen…</string>
    <string name="message_decrypting">Bericht aan het ontsleutelen. Even geduld…</string>
    <string name="pgp_message">OpenPGP-versleuteld bericht</string>


@@ 63,6 71,8 @@
    <string name="unblock">Deblokkeren</string>
    <string name="save">Opslaan</string>
    <string name="ok">Oké</string>
    <string name="crash_report_title">%1$s is gecrasht</string>
    <string name="crash_report_message">Door crashrapportages via uw XMPP account te sturen help je de ontwikkeling van %1$s.</string>
    <string name="send_now">Nu versturen</string>
    <string name="send_never">Niet opnieuw vragen</string>
    <string name="problem_connecting_to_account">Verbinding maken met account mislukt</string>


@@ 155,6 165,7 @@
    <string name="mgmt_account_publish_pgp">OpenPGP-publieke sleutel publiceren</string>
    <string name="unpublish_pgp">OpenPGP-publieke sleutel verwijderen</string>
    <string name="unpublish_pgp_message">Weet je zeker dat je je OpenPGP-publieke sleutel uit je aanwezigheidsaankondiging wil verwijderen?\nJe contacten zullen je geen OpenPGP-versleutelde berichten meer kunnen sturen.</string>
    <string name="openpgp_has_been_published">OpenPGP-publieke sleutel gepubliceerd.</string>
    <string name="mgmt_account_enable">Account inschakelen</string>
    <string name="mgmt_account_are_you_sure">Weet je het zeker?</string>
    <string name="attach_record_voice">Stem opnemen</string>


@@ 178,8 189,11 @@
    <string name="server_info_unavailable">niet beschikbaar</string>
    <string name="missing_public_keys">Ontbrekende publieke sleutel-aankondigingen</string>
    <string name="last_seen_now">zojuist voor het laatst gezien</string>
    <string name="last_seen_min">een minuut geleden voor het laatst gezien</string>
    <string name="last_seen_mins">%d minuten geleden voor het laatst gezien</string>
    <string name="last_seen_hour">een uur geleden voor het laatst gezien</string>
    <string name="last_seen_hours">%d uur geleden voor het laatst gezien</string>
    <string name="last_seen_day">een dag geleden voor het laatst gezien</string>
    <string name="last_seen_days">%d dagen geleden voor het laatst gezien</string>
    <string name="openpgp_key_id">OpenPGP-sleutel-ID</string>
    <string name="omemo_fingerprint">OMEMO-vingerafdruk</string>


@@ 220,6 234,7 @@
    <string name="contacts_have_read_up_to_this_point">%s hebben tot hier gelezen</string>
    <string name="everyone_has_read_up_to_this_point">Iedereen heeft tot hier gelezen</string>
    <string name="publish">Publiceer</string>
    <string name="touch_to_choose_picture">Tik op avatar om een foto uit de galerij te kiezen</string>
    <string name="publishing">Publiceren…</string>
    <string name="error_publish_avatar_server_reject">De server weigerde de publicatie van je afbeelding</string>
    <string name="error_saving_avatar">Fout bij opslaan van avatar</string>


@@ 230,6 245,7 @@
    <string name="connect">Verbind</string>
    <string name="account_already_exists">Deze account bestaat al</string>
    <string name="next">Volgende</string>
    <string name="server_info_session_established">Sessie is tot stand gekomen</string>
    <string name="skip">Overslaan</string>
    <string name="disable_notifications">Meldingen uitschakelen</string>
    <string name="enable">Inschakelen</string>


@@ 297,6 313,7 @@
    <string name="x_file_offered_for_download">%s aangeboden om te downloaden</string>
    <string name="cancel_transmission">Bestandsoverdracht annuleren</string>
    <string name="file_transmission_cancelled">bestandsoverdracht geannuleerd</string>
    <string name="no_application_found_to_open_file">Geen app om bestand te openen</string>
    <string name="pref_show_dynamic_tags">Dynamische tags</string>
    <string name="pref_show_dynamic_tags_summary">Toon enkel-lezen tags onder contacten</string>
    <string name="enable_notifications">Meldingen inschakelen</string>


@@ 314,6 331,7 @@
    <string name="change_password">Wachtwoord wijzigen</string>
    <string name="current_password">Huidig wachtwoord</string>
    <string name="new_password">Nieuw wachtwoord</string>
    <string name="password_should_not_be_empty">Wachtwoord mag niet leeg zijn</string>
    <string name="enable_all_accounts">Alle accounts inschakelen</string>
    <string name="disable_all_accounts">Alle accounts uitschakelen</string>
    <string name="perform_action_with">Actie uitvoeren met</string>


@@ 370,6 388,7 @@
    <string name="pref_chat_states_summary">Laat je contacten weten wanneer je ze een nieuw bericht schrijft</string>
    <string name="send_location">Locatie versturen</string>
    <string name="show_location">Locatie weergeven</string>
    <string name="no_application_found_to_display_location">Geen app om locatie weer te geven</string>
    <string name="location">Locatie</string>
    <string name="title_undo_swipe_out_conversation">Gesprek gesloten</string>
    <string name="title_undo_swipe_out_group_chat">Privégroep verlaten</string>

M src/main/res/values-pl/strings.xml => src/main/res/values-pl/strings.xml +1 -2
@@ 1003,5 1003,4 @@ Administrator twojego serwera będzie mógł czytać twoje wiadomości, ale moż
    <string name="plain_text_document">Dokument zwykłego tekstu</string>
    <string name="account_registrations_are_not_supported">Rejestracja kont nie jest wspierana</string>
    <string name="no_xmpp_adddress_found">Nie znaleziono adresu XMPP</string>

</resources>
    </resources>

M src/main/res/values-pt-rBR/strings.xml => src/main/res/values-pt-rBR/strings.xml +14 -0
@@ 33,6 33,9 @@
        <item quantity="one">%d conversa não lida</item>

    
        <item quantity="many">%d conversas não lidas</item>

    
        <item quantity="other">%d conversas não lidas</item>

    </plurals>


@@ 447,6 450,7 @@
    <string name="dialog_manage_certs_negativebutton">Cancelar</string>
    <plurals name="toast_delete_certificates">
        <item quantity="one">%d certificado cancelado</item>
        <item quantity="many">%d certificados cancelados</item>
        <item quantity="other">%d certificados cancelados</item>
    </plurals>
    <string name="pref_quick_action_summary">Troca o botão \"Enviar\" pelo de ação rápida</string>


@@ 505,6 509,7 @@
    <string name="connected_accounts">%1$d de %2$d contas conectadas</string>
    <plurals name="x_messages">
        <item quantity="one">%d mensagem</item>
        <item quantity="many">%d mensagens</item>
        <item quantity="other">%d mensagens</item>
    </plurals>
    <string name="load_more_messages">Carregar mais mensagens</string>


@@ 632,26 637,32 @@
    <string name="distrust_omemo_key_text">Tem certeza que deseja remover a verificação para este dispositivo?\nEste dispositivo e as mensagens oriundas dele serão marcadas como \"não confiáveis\".</string>
    <plurals name="seconds">
        <item quantity="one">%d segundo</item>
        <item quantity="many">%d segundos</item>
        <item quantity="other">%d segundos</item>
    </plurals>
    <plurals name="minutes">
        <item quantity="one">%d minuto</item>
        <item quantity="many">%d minutos</item>
        <item quantity="other">%d minutos</item>
    </plurals>
    <plurals name="hours">
        <item quantity="one">%d hora</item>
        <item quantity="many">%d horas</item>
        <item quantity="other">%d horas</item>
    </plurals>
    <plurals name="days">
        <item quantity="one">%d dia</item>
        <item quantity="many">%d dias</item>
        <item quantity="other">%d dias</item>
    </plurals>
    <plurals name="weeks">
        <item quantity="one">%d semana</item>
        <item quantity="many">%d semanas</item>
        <item quantity="other">%d semanas</item>
    </plurals>
    <plurals name="months">
        <item quantity="one">%d mês</item>
        <item quantity="many">%d meses</item>
        <item quantity="other">%d meses</item>
    </plurals>
    <string name="pref_automatically_delete_messages">Exclusão automática de mensagens</string>


@@ 958,10 969,12 @@
    <string name="add_contact_or_create_or_join_group_chat">Adicionar contato, criar ou associar-se a uma conversa em grupo ou descobrir canais</string>
    <plurals name="view_users">
        <item quantity="one">Ver %1$d participante</item>
        <item quantity="many">Ver %1$d participantes</item>
        <item quantity="other">Ver %1$d participantes</item>
    </plurals>
    <plurals name="some_messages_could_not_be_delivered">
        <item quantity="one">Não foi possível enviar a mensagem</item>
        <item quantity="many">Não foi possível enviar algumas mensagens</item>
        <item quantity="other">Não foi possível enviar algumas mensagens</item>
    </plurals>
    <string name="failed_deliveries">Entregas não efetuadas</string>


@@ 976,5 989,6 @@
    <string name="plain_text_document">Documento em texto puro</string>
    <string name="account_registrations_are_not_supported">O registro de contas não está ativo</string>
    <string name="no_xmpp_adddress_found">Não foi encontrado nenhum endereço XMPP</string>
    <string name="account_status_temporary_auth_failure">Falha temporária na autenticação</string>

</resources>

M src/main/res/values-pt/strings.xml => src/main/res/values-pt/strings.xml +2 -0
@@ 308,6 308,7 @@
    <string name="dialog_manage_certs_negativebutton">Cancelar</string>
    <plurals name="toast_delete_certificates">
        <item quantity="one">%d certificado apagado</item>
        <item quantity="many">%d certificados apagados</item>
        <item quantity="other">%d certificados apagados</item>
    </plurals>
    <string name="pref_quick_action">Ação rápida</string>


@@ 348,6 349,7 @@
    <string name="connected_accounts">%1$d de %2$d contas conectadas</string>
    <plurals name="x_messages">
        <item quantity="one">%d mensagem</item>
        <item quantity="many">%d mensagens</item>
        <item quantity="other">%d mensagens</item>
    </plurals>
    <string name="load_more_messages">Carregar mais mensagens</string>

M src/main/res/values-ro-rRO/strings.xml => src/main/res/values-ro-rRO/strings.xml +1 -0
@@ 989,5 989,6 @@
    <string name="plain_text_document">Document text</string>
    <string name="account_registrations_are_not_supported">Nu este posibilă înregistrarea unui cont</string>
    <string name="no_xmpp_adddress_found">Nu a fost găsită o adresă XMPP</string>
    <string name="account_status_temporary_auth_failure">Eroare temporară de autentificare</string>

</resources>

A src/main/res/values-szl/strings.xml => src/main/res/values-szl/strings.xml +1025 -0
@@ 0,0 1,1025 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="action_settings">Sztelōnki</string>
    <string name="action_add">Nowo godka</string>
    <string name="action_accounts">Sztelōnki kōnt</string>
    <string name="action_account">Sztelōnki kōnta</string>
    <string name="action_end_conversation">Zawrzij godka</string>
    <string name="action_contact_details">Informacyje kōntaktu</string>
    <string name="action_muc_details">Informacyje kōnferyncyje</string>
    <string name="channel_details">Informacyje kanału</string>
    <string name="action_add_account">Przidej kōnto</string>
    <string name="action_edit_contact">Edytuj miano</string>
    <string name="action_add_phone_book">Przidej do kōntaktōw</string>
    <string name="action_delete_contact">Skasuj z rostera</string>
    <string name="action_block_contact">Zablokuj kōntakt</string>
    <string name="action_unblock_contact">Ôdblokuj kōntakt</string>
    <string name="action_block_domain">Ôdblokuj dōmyna</string>
    <string name="action_unblock_domain">Ôdblokuj dōmyna</string>
    <string name="action_block_participant">Zablokuj kōntakt</string>
    <string name="action_unblock_participant">Ôdblokuj kōntakt</string>
    <string name="title_activity_manage_accounts">Sztelōnki kōnt</string>
    <string name="title_activity_settings">Sztelōnki</string>
    <string name="title_activity_sharewith">Udostympnij we godce</string>
    <string name="title_activity_start_conversation">Zacznij godka</string>
    <string name="title_activity_choose_contact">Ôbier kōntakt</string>
    <string name="title_activity_choose_contacts">Ôbier kōntakty</string>
    <string name="title_activity_share_via_account">Udostympnij bez</string>
    <string name="title_activity_block_list">Czorno lista</string>
    <string name="just_now">przed chwilōm</string>
    <string name="minute_ago">minuta tymu</string>
    <string name="minutes_ago">%d minut tymu</string>
    <plurals name="x_unread_conversations">
        <item quantity="one">%d niyprzeczytano kōnwersacyjo</item>

    
        <item quantity="few">%d niyprzeczytane kōnwersacyje</item>

    
        <item quantity="other">%d niyprzeczytanych kōnwersacyji</item>

    </plurals>
    <string name="sending">wysyłanie…</string>
    <string name="message_decrypting">Ôdszyfrowowanie wiadōmości. To weźnie ino chwila…</string>
    <string name="pgp_message">Wiadōmość zaszyfrowano OpenPGP</string>
    <string name="nick_in_use">Miano je już zajynte</string>
    <string name="invalid_muc_nick">Niynoleżny pseudōnim</string>
    <string name="admin">Admin</string>
    <string name="owner">Posiedziciel</string>
    <string name="moderator">Moderatōr</string>
    <string name="participant">Uczestnik</string>
    <string name="visitor">Gość</string>
    <string name="remove_contact_text">Chcesz wymazać kōntakt %s ze listy\? Godki ze tym kōntaktym niy bydōm wymazane.</string>
    <string name="block_contact_text">Na zicher chcesz zablokować wiadōmości ôd kōntaktu %s\?</string>
    <string name="unblock_contact_text">Na zicher chcesz ôdblokować wiadōmości ôd kōntaktu %s\?</string>
    <string name="block_domain_text">Zablokować wszyjske kōntakty ze %s\?</string>
    <string name="unblock_domain_text">Ôdblokować wszyjske kōntakty ze %s\?</string>
    <string name="contact_blocked">Kōntakt zablokowany</string>
    <string name="blocked">Zablokowane</string>
    <string name="remove_bookmark_text">Chcesz wymazać zokłodka %s\? Godki z niōm niy bydōm wymazane.</string>
    <string name="register_account">Zaregistruj nowe kōnto na serwerze</string>
    <string name="change_password_on_server">Umiyń hasło na serwerze</string>
    <string name="share_with">Udostympnij…</string>
    <string name="start_conversation">Zacznij godka</string>
    <string name="invite_contact">Zaproś kōntakt</string>
    <string name="invite">Zaproś</string>
    <string name="contacts">Kōntakty</string>
    <string name="contact">Kōntakt</string>
    <string name="cancel">Pociep</string>
    <string name="set">Nasztaluj</string>
    <string name="add">Przidej</string>
    <string name="edit">Edytuj</string>
    <string name="delete">Wymaż</string>
    <string name="block">Zablokuj</string>
    <string name="unblock">Ôdblokuj</string>
    <string name="save">Spamiyntej</string>
    <string name="ok">OK</string>
    <string name="crash_report_title">We %1$s doszło do awaryje</string>
    <string name="crash_report_message">Jak używosz swojigo kōnta XMPP do wysyłanio sztrekōw sztapla, to pōmogosz przi budowaniu %1$s.</string>
    <string name="send_now">Wyślij teroz</string>
    <string name="send_never">Niy pytej zaś</string>
    <string name="problem_connecting_to_account">Niy idzie połōnczyć z kōntym</string>
    <string name="problem_connecting_to_accounts">Niy idzie połōnczyć z mockōm kōnt</string>
    <string name="touch_to_fix">Tyknij, coby sztelować swoje kōnta</string>
    <string name="attach_file">Przidej zbiōr</string>
    <string name="not_in_roster">Przidać tyn kōntakt do twojij listy kōntaktōw\?</string>
    <string name="add_contact">Przidej kōntakt</string>
    <string name="send_failed">wysyłanie sie niy podarziło</string>
    <string name="preparing_image">Rychtowanie do wysłanio ôbrozka</string>
    <string name="preparing_images">Rychtowanie do wysłanio ôbrozkōw</string>
    <string name="sharing_files_please_wait">Udostympnianie zbiorōw. Czekej…</string>
    <string name="action_clear_history">Wymaż historyjo</string>
    <string name="clear_conversation_history">Wymaż historyjo kōnwersacyje</string>
    <string name="clear_histor_msg">Chcesz wymazać wszyjske wiadōmości we tyj godce\?
\n
\n<b>Pozōr:</b> To niy wpływo na wiadōmości trzimane na inkszych maszinach abo serwerach.</string>
    <string name="delete_file_dialog">Wymaż zbiōr</string>
    <string name="delete_file_dialog_msg">Na zicher wymazać tyn zbiōr\?
\n
\n<b>Pozōr:</b> To niy wpływo na kopije zbioru trzimane na inkszych maszinach abo serwerach. </string>
    <string name="also_end_conversation">Zawrzij potym tyż kōnwersacyjo</string>
    <string name="choose_presence">Ôbier maszina</string>
    <string name="send_unencrypted_message">Wyślij wiadōmość bez szyfrowanio</string>
    <string name="send_message">Wyślij wiadōmość</string>
    <string name="send_message_to_x">Wyślij wiadōmość do kōntaktu %s</string>
    <string name="send_omemo_message">Wyślij wiadōmość zaszyfrowano OMEMO</string>
    <string name="send_omemo_x509_message">Wyślij wiadōmość zaszyfrowano v\\OMEMO</string>
    <string name="send_pgp_message">Wyślij zaszyfrowano wiadōmość (OpenPGP)</string>
    <string name="your_nick_has_been_changed">Przemianek je umiyniōny</string>
    <string name="send_unencrypted">Wyślij bez szyfrowanio</string>
    <string name="decryption_failed">Niy idzie ôdszyfrować. Możno niy mosz noleznego prywatnego klucza.</string>
    <string name="openkeychain_required">OpenKeychain</string>
    <string name="openkeychain_required_long">%1$s używo &lt;b&gt;OpenKeychain&lt;/b&gt;, żeby szyfrować i ôdszyfrowować wiadōmości i zarzōndzać twojimi publicznymi kluczami.&lt;br&gt;&lt;br&gt;OpenKeychain je na licyncyji GPLv3+ i je dostympny we F-Droid abo Google Play.&lt;br&gt;&lt;br&gt;&lt;small&gt;(Puść %1$s na nowo po zainstalowaniu.)&lt;/small&gt;</string>
    <string name="restart">Zresztartuj</string>
    <string name="install">Zainstaluj</string>
    <string name="openkeychain_not_installed">Zainstaluj OpenKeychain</string>
    <string name="offering">ôferowanie…</string>
    <string name="waiting">czekanie…</string>
    <string name="no_pgp_key">Niy szło znojś klucza OpenPGP</string>
    <string name="contact_has_no_pgp_key">Niy idzie zaszyfrować twojij wiadōmości, bo tyn kōntakt niy ôgłoszo swojigo publicznego klucza.
\n
\n<small>Poproś kōntakt, żeby nasztalowoł OpenPGP.</small></string>
    <string name="no_pgp_keys">Niy szło znojś kluczy OpenPGP</string>
    <string name="contacts_have_no_pgp_keys">Niy idzie zaszyfrować twojij wiadōmości bo twoje kōntakty niy ôgłoszajōm swojich kluczy publicznych.
\n
\n<small>Poproś, żeby nasztalowały OpenPGP.</small></string>
    <string name="pref_general">Bazowe</string>
    <string name="pref_accept_files">Akceptuj zbiory</string>
    <string name="pref_accept_files_summary">Autōmatycznie akceptuj zbiory myńsze niż…</string>
    <string name="pref_attachments">Przidowki</string>
    <string name="pref_notification_settings">Powiadōmiynie</string>
    <string name="pref_vibrate">Wibracyje</string>
    <string name="pref_vibrate_summary">Wibruj, jak przidzie wiadōmość</string>
    <string name="pref_led">Powiadōmiynie diodōm LED</string>
    <string name="pref_led_summary">Migej diodōm, jak przidzie wiadōmość</string>
    <string name="pref_ringtone">Zwōnek</string>
    <string name="pref_notification_sound">Klang powiadōmiyń</string>
    <string name="pref_notification_sound_summary">Klang powiadōmiyń ô nowych wiadōmościach</string>
    <string name="pref_call_ringtone_summary">Zwōnek przi przichodzōncych połōnczyniach</string>
    <string name="pref_notification_grace_period">Czas bez powiadōmiyń</string>
    <string name="pref_notification_grace_period_summary">Dugość czasu, kej powiadōmiynia sōm wyciszōne po wykryciu aktywności na jednyj z twojich inkszych maszin.</string>
    <string name="pref_advanced_options">Rozszyrzōne</string>
    <string name="pref_never_send_crash">Niy wysyłej reportōw awaryje</string>
    <string name="pref_never_send_crash_summary">Jak wysyłosz sztreki sztapla, to pōmogosz przi budowaniu</string>
    <string name="pref_confirm_messages">Potwierdzynia wiadōmości</string>
    <string name="pref_confirm_messages_summary">Przizwōl na wysyłanie do ôsōb ze listy kōntaktōw informacyje ô twojim dostaniu i przeczytaniu wiadōmości ôd nich</string>
    <string name="pref_prevent_screenshots">Blokuj zopisy ekranu</string>
    <string name="pref_prevent_screenshots_summary">Skryj zawartość aplikacyje we szaltrze aplikacyji i zablokuj zopisy ekranu</string>
    <string name="pref_ui_options">UI</string>
    <string name="openpgp_error">OpenKeychain zgłosiyło błōnd.</string>
    <string name="bad_key_for_encryption">Zły klucz szyfrowanio.</string>
    <string name="accept">Akceptować</string>
    <string name="error">Doszło do błyndu</string>
    <string name="recording_error">Błōnd</string>
    <string name="your_account">Twoje kōnto</string>
    <string name="send_presence_updates">Wysyłej powiadōmiynia ôbecności</string>
    <string name="receive_presence_updates">Dostowej powiadōmiynia ôbecności</string>
    <string name="ask_for_presence_updates">Poproś ô powiadōmiynia ôbecności</string>
    <string name="attach_choose_picture">Ôbier ôbroz</string>
    <string name="attach_take_picture">Zrōb fotografijo</string>
    <string name="preemptively_grant">Autōmatyczno zwolo na subskrypcyjo</string>
    <string name="error_not_an_image_file">Ôbrany zbiōr to niy ôbroz</string>
    <string name="error_compressing_image">Błōnd kōnwersyje ôbrazu</string>
    <string name="error_file_not_found">Niy szło znojś zbioru</string>
    <string name="error_io_exception">Ôgōlny feler wchodu/wychodu. Możno skōńczōł sie plac na dane\?</string>
    <string name="error_security_exception_during_image_copy">Aplikacyjo użyto do ôbioru ôbrazu niy przizwolyła na ôdczyt zbioru.
\n
\n<small>Ôbier ôbroz przi użyciu inkszego mynedżera zbiorōw</small>.</string>
    <string name="error_security_exception">Aplikacyjo użyto do udostympniynio tego zbioru niy dała stykajōncych uprawniyń.</string>
    <string name="account_status_unknown">Niyznōmy</string>
    <string name="account_status_disabled">Tymczasowo zastawiōne</string>
    <string name="account_status_online">Połōnczōne</string>
    <string name="account_status_connecting">Łōnczynie…</string>
    <string name="account_status_offline">Rozłōnczōne</string>
    <string name="account_status_unauthorized">Błōnd autoryzacyje</string>
    <string name="account_status_not_found">Niy szło znojś serwera</string>
    <string name="account_status_no_internet">Brak połōnczynio</string>
    <string name="account_status_regis_fail">Błōnd registracyje</string>
    <string name="account_status_regis_conflict">Miano zajynte</string>
    <string name="account_status_regis_success">Zaregistrowano sprownie</string>
    <string name="account_status_regis_not_sup">Tyn serwer niy spiyro registracyje</string>
    <string name="account_status_regis_invalid_token">Niynoleżny tokyn registracyje</string>
    <string name="account_status_tls_error">Niy podarziła sie negocjacyjo TLS</string>
    <string name="account_status_tls_error_domain">Dōmyna niyweryfikowalno</string>
    <string name="account_status_policy_violation">Naruszynie prawideł</string>
    <string name="account_status_incompatible_server">Serwer niykōmpatybilny</string>
    <string name="account_status_stream_error">Błōnd potoku</string>
    <string name="account_status_stream_opening_error">Błōnd ôtwiyranio potoku</string>
    <string name="encryption_choice_unencrypted">Bez szyfrowanio</string>
    <string name="encryption_choice_otr">OTR</string>
    <string name="encryption_choice_pgp">OpenPGP</string>
    <string name="encryption_choice_omemo">OMEMO</string>
    <string name="mgmt_account_delete">Wymaż kōnto</string>
    <string name="mgmt_account_disable">Zastow tymczasowo</string>
    <string name="mgmt_account_publish_avatar">Publikuj awatar</string>
    <string name="mgmt_account_publish_pgp">Udostympnij klucz publiczny OpenPGP</string>
    <string name="unpublish_pgp">Wymaż klucz publiczny OpenPGP</string>
    <string name="unpublish_pgp_message">Na zicher chcesz wymazać klucz publiczny OpenPGP ze swojij propagacyje ôbecności\?
\nTwoje kōntakty niy bydōm już mogły wysyłać ci wiadōmości zaszyfrowanych OpenPGP.</string>
    <string name="openpgp_has_been_published">Klucz publiczny OpenPGP ôstoł ôpublikowany.</string>
    <string name="mgmt_account_enable">Włōncz kōnto</string>
    <string name="mgmt_account_are_you_sure">Na zicher\?</string>
    <string name="mgmt_account_delete_confirm_text">Wymazanie kōnta wymazuje cołko historyjo godek</string>
    <string name="attach_record_voice">Nagrej głos</string>
    <string name="account_settings_jabber_id">Adresa XMPP</string>
    <string name="block_jabber_id">Zablokuj adresa XMPP</string>
    <string name="account_settings_example_jabber_id">username@example.com</string>
    <string name="password">Hasło</string>
    <string name="invalid_jid">To niyma noleżno adresa XMPP</string>
    <string name="error_out_of_memory">Brak pamiyńci. Ôbroz je za srogi</string>
    <string name="add_phone_book_text">Chcesz przidać %s do listy kōntaktōw\?</string>
    <string name="server_info_show_more">Informacyje ô serwerze</string>
    <string name="server_info_mam">XEP-0313: MAM</string>
    <string name="server_info_carbon_messages">XEP-0280: Kopije wiadōmości</string>
    <string name="server_info_csi">XEP-0352: Skaźnik Sztandu Klijynta</string>
    <string name="server_info_blocking">XEP-0191: Rozkoz blokowanio</string>
    <string name="server_info_roster_version">XEP-0237: Wersyjowanie listy</string>
    <string name="server_info_stream_management">XEP-0198: Sztelōnki potoku</string>
    <string name="server_info_external_service_discovery">XEP-0215: Wykrywanie Zewnyntrznych Usug</string>
    <string name="server_info_pep">XEP-0163: PEP (Awatary / OMEMO)</string>
    <string name="server_info_http_upload">XEP-0363: Przesyłanie zbiorōw bez HTTP</string>
    <string name="server_info_push">XEP-0357: Push</string>
    <string name="server_info_available">dostympny</string>
    <string name="server_info_unavailable">niydostympny</string>
    <string name="missing_public_keys">Brak informacyje ô kluczu publicznym</string>
    <string name="last_seen_now">prawie widziany</string>
    <string name="last_seen_min">widziany przed minutōm</string>
    <string name="last_seen_mins">widziany prze %d minutami</string>
    <string name="last_seen_hour">widziany przed godzinōm</string>
    <string name="last_seen_hours">widziany przed %d godzinami</string>
    <string name="last_seen_day">widziany wczorej</string>
    <string name="last_seen_days">widziany przed %d dniami</string>
    <string name="install_openkeychain">Wiadōmość zaszyfrowano. Zainstaluj OpenKeychain, coby ôdszyfrować.</string>
    <string name="openpgp_messages_found">Znojdziōne nowe wiadōmości zaszyfrowane we OpenPGP</string>
    <string name="openpgp_key_id">ID klucza OpenPGP</string>
    <string name="omemo_fingerprint">Ôdcisk OMEMO</string>
    <string name="omemo_fingerprint_x509">Ôdcisk v\\OMEMO</string>
    <string name="omemo_fingerprint_selected_message">Ôdcisk OMEMO tyj wiadōmości</string>
    <string name="omemo_fingerprint_x509_selected_message">Ôdcisk v\\OMEMO tyj wiadōmości</string>
    <string name="other_devices">Insze masziny</string>
    <string name="trust_omemo_fingerprints">Zadufane ôdciski OMEMO</string>
    <string name="fetching_keys">Pobiyranie kluczy…</string>
    <string name="done">Skōńczōno</string>
    <string name="decrypt">Ôdszyfruj</string>
    <string name="bookmarks">Zokłodki</string>
    <string name="search">Szukej</string>
    <string name="enter_contact">Wpisz kōntakt</string>
    <string name="delete_contact">Wymaż kōntakt</string>
    <string name="view_contact_details">Informacyje ô kōntakcie</string>
    <string name="block_contact">Zablokuj kōntakt</string>
    <string name="unblock_contact">Ôdblokuj kōntakt</string>
    <string name="create">Stwōrz</string>
    <string name="select">Ôbier</string>
    <string name="contact_already_exists">Kōntakt już istniyje</string>
    <string name="join">Prziwstōń</string>
    <string name="channel_full_jid_example">kanal@konferyncyje.prziklod.com/przemianek</string>
    <string name="channel_bare_jid_example">kanal@konferyncyje.prziklod.com</string>
    <string name="save_as_bookmark">Przidej za zokłodka</string>
    <string name="delete_bookmark">Wymaż zokłodka</string>
    <string name="destroy_room">Wymaż kōnferyncyjo</string>
    <string name="destroy_channel">Wymaż kanał</string>
    <string name="destroy_room_dialog">Je żeś zicher, iże chcesz wymazać ta kōnferyncyjo\?
\n
\n<b>Pozōr:</b> Ta kōnferyncyjo bydzie doimyntnie wymazano na serwerze.</string>
    <string name="destroy_channel_dialog">Na zicher chcesz wymazać tyn kanał publiczny\?
\n
\n<b>Pozōr:</b> Tyn kanał bydzie doimyntnie wymazany ze serwera.</string>
    <string name="could_not_destroy_room">Niy szło wymazać kōnferyncyje</string>
    <string name="could_not_destroy_channel">Niy szło wymazać kanału</string>
    <string name="action_edit_subject">Edytuj tytuł kōnferyncyje</string>
    <string name="topic">Tymat</string>
    <string name="joining_conference">Przistympowanie do kōnferyncyje…</string>
    <string name="leave">Ôpuść izba</string>
    <string name="contact_added_you">Kōntakt przidoł cie do listy kōntaktōw</string>
    <string name="add_back">Tyż przidej</string>
    <string name="contact_has_read_up_to_this_point">Kōntakt %s przeczytoł dotōnd</string>
    <string name="contacts_have_read_up_to_this_point">Kōntakty %s przeczytały dotōnd</string>
    <string name="contacts_and_n_more_have_read_up_to_this_point">Kōntakty %1$s i %2$d inszych przeczytało dotōnd</string>
    <string name="everyone_has_read_up_to_this_point">Wszyjscy przeczytali dotōnd</string>
    <string name="publish">Publikuj</string>
    <string name="touch_to_choose_picture">Tyknij awatar, coby ôbrać ôbroz z galeryje</string>
    <string name="publishing">Publikowanie…</string>
    <string name="error_publish_avatar_server_reject">Serwer ôdkozoł publikacyje</string>
    <string name="error_publish_avatar_converting">Niy szło skōnwertować ôbrazu</string>
    <string name="error_saving_avatar">Niy szło spamiyntać ôbrazu we pamiyńci masziny</string>
    <string name="or_long_press_for_default">(abo dugo przitrzim, coby nasztalować wychodny)</string>
    <string name="error_publish_avatar_no_server_support">Twōj serwer niy umożliwo publikacyje awatarōw</string>
    <string name="private_message">szepce</string>
    <string name="private_message_to">do %s</string>
    <string name="send_private_message_to">Wyślij prywatno wiadōmość do %s</string>
    <string name="connect">Połōncz</string>
    <string name="account_already_exists">Kōnto już istniyje</string>
    <string name="next">Dalij</string>
    <string name="server_info_session_established">Połōnczōno ze serwerym</string>
    <string name="skip">Przeskocz</string>
    <string name="disable_notifications">Zastow powiadōmiynia</string>
    <string name="enable">Włōncz</string>
    <string name="conference_requires_password">Kōnferyncyjo wymogo hasła</string>
    <string name="enter_password">Wkludź hasło</string>
    <string name="request_presence_updates">Poproś kōntakt ô udostympniynie powiadōmiyń ô ôbecności.
\n
\n<small>To bydzie używane do skazowanio, jakigo programu używo twōj kōntakt</small>.</string>
    <string name="request_now">Poproś teroz</string>
    <string name="ignore">Ignoruj</string>
    <string name="without_mutual_presence_updates"><b>Pozōr:</b> Wysyłanie bez powiadōmiyń ô ôbecności ze ôbōch strōn może prziniyś niyôczekowane problymy.
\n
\n<small>Idź do „Informacyji ô kōntakcie” i wejzdrzij do subskrypcyji ôbecności.</small></string>
    <string name="pref_security_settings">Bezpieczyństwo</string>
    <string name="pref_allow_message_correction">Przizwōl na poprowianie wiadōmości</string>
    <string name="pref_allow_message_correction_summary">Przizwōl swojim kōntaktōm poprowiać wiadōmości</string>
    <string name="pref_expert_options">Sztelōnki eksperta</string>
    <string name="pref_expert_options_summary">Modyfikuj je pozornie</string>
    <string name="title_activity_about_x">Ô %s</string>
    <string name="title_pref_quiet_hours">Godziny cisze</string>
    <string name="title_pref_quiet_hours_start_time">Poczōntek</string>
    <string name="title_pref_quiet_hours_end_time">Kōniec</string>
    <string name="title_pref_enable_quiet_hours">Włōncz godziny cisze</string>
    <string name="pref_quiet_hours_summary">Powiadōmiynia bydōm wyciszōne we ôbranych godzinach</string>
    <string name="pref_expert_options_other">Inksze</string>
    <string name="pref_autojoin">Synchrōnizuj ze zokłodkami</string>
    <string name="pref_autojoin_summary">Przistympuj do godek grupowych autōmatycznie, jeźli tak pado zokłodka</string>
    <string name="toast_message_omemo_fingerprint">Ôdcisk klucza OMEMO bōł skopiowany do skrytki</string>
    <string name="conference_banned">Ôd tyj grupy mosz wykluczynie</string>
    <string name="conference_members_only">Kōnferyncyjo ino dlo czōnkōw</string>
    <string name="conference_resource_constraint">Ukrōcynie zasobu</string>
    <string name="conference_kicked">Ze tyj kōnferyncyje cie wyciepli</string>
    <string name="conference_shutdown">Kōnferyncyjo ôstała zawarto</string>
    <string name="conference_unknown_error">Już żeś niy je we tyj kōnferyncyji</string>
    <string name="using_account">ze użyciym kōnta %s</string>
    <string name="hosted_on">trzimane na %s</string>
    <string name="checking_x">Wybadowanie %s na hoście HTTP</string>
    <string name="not_connected_try_again">Brak połōnczynio. Sprōbuj zaś niyskorzij</string>
    <string name="check_x_filesize">Wybadej srogość %s</string>
    <string name="check_x_filesize_on_host">Wybadej srogość %1$s na %2$s</string>
    <string name="message_options">Ôpcyje wiadōmości</string>
    <string name="quote">Cytata</string>
    <string name="paste_as_quote">Wraź za cytata</string>
    <string name="copy_original_url">Skopiyruj ôryginalny URL</string>
    <string name="send_again">Wyślij zaś</string>
    <string name="file_url">URL zbioru</string>
    <string name="url_copied_to_clipboard">Skopiowano URL do skrytki</string>
    <string name="jabber_id_copied_to_clipboard">Skopiowano adresa XMPP do skrytki</string>
    <string name="error_message_copied_to_clipboard">Skopiowano kōmunikat błyndu do skrytki</string>
    <string name="web_address">adresa necowo</string>
    <string name="scan_qr_code">Zeskanuj kod</string>
    <string name="show_qr_code">Pokoż kod QR</string>
    <string name="show_block_list">Pokoż wykoz wykluczyń</string>
    <string name="account_details">Informacyje kōnta</string>
    <string name="confirm">Potwiyrdź</string>
    <string name="try_again">Sprōbuj zaś</string>
    <string name="pref_keep_foreground_service">Usuga na piyrszym planie</string>
    <string name="pref_keep_foreground_service_summary">Niy zwolo systymowi na przerwanie połōnczynio</string>
    <string name="pref_create_backup">Stwōrz kopijo ibryczno</string>
    <string name="pref_create_backup_summary">Kopijo ibryczno bydzie spamiyntano we %s</string>
    <string name="notification_create_backup_title">Tworzynie kopije ibrycznyj</string>
    <string name="notification_backup_created_title">Kopijo ibryczno stworzōno</string>
    <string name="notification_backup_created_subtitle">Kopijo ibryczno spamiyntano we %s</string>
    <string name="restoring_backup">Prziwrocanie ze kopije ibrycznyj</string>
    <string name="notification_restored_backup_title">Prziwrocanie ze kopije ibrycznyj gotowe</string>
    <string name="notification_restored_backup_subtitle">Niy zapōmnij ô aktywacyji tego kōnta.</string>
    <string name="choose_file">Ôbier zbiōr</string>
    <string name="receiving_x_file">Ôdbiyranie %1$s (skōńczōne %2$d%%)</string>
    <string name="download_x_file">Pobier %s</string>
    <string name="delete_x_file">Wymaż %s</string>
    <string name="file">zbiōr</string>
    <string name="open_x_file">Ôtwōrz %s</string>
    <string name="sending_file">Wysyłanie (skōńczōne %1$d%%)</string>
    <string name="preparing_file">Rychtowanie do udostympniynio ôbrozka</string>
    <string name="x_file_offered_for_download">Zapropōnowano pobranie zbioru %s</string>
    <string name="cancel_transmission">Pociep przesyłanie</string>
    <string name="file_transmission_failed">niy szło udostympnić zbioru</string>
    <string name="file_transmission_cancelled">transmisyjo zbioru pociepniynto</string>
    <string name="file_deleted">Zbiōr wymazany</string>
    <string name="no_application_found_to_open_file">Niy szło znojś aplikacyje do ôtwarcia zbioru</string>
    <string name="no_application_found_to_open_link">Niy szło znojś aplikacyje do ôtwarcia linka</string>
    <string name="no_application_found_to_view_contact">Niy szło znojś aplikacyje do pokozanio kōntaktu</string>
    <string name="pref_show_dynamic_tags">Dynamiczne tagi</string>
    <string name="pref_show_dynamic_tags_summary">Pokazuj etykety pod kōntaktami</string>
    <string name="enable_notifications">Włōncz powiadōmiynia</string>
    <string name="no_conference_server_found">Niy szło znojś serwera kōnferyncyje</string>
    <string name="conference_creation_failed">Niy szło stworzić kōnferyncyje</string>
    <string name="account_image_description">Awatar kōnta</string>
    <string name="copy_omemo_clipboard_description">Skopiuj ôdcisk klucza OMEMO do skrytki</string>
    <string name="regenerate_omemo_key">Wygyneruj zaś klucz OMEMO</string>
    <string name="clear_other_devices">Wymaż masziny</string>
    <string name="clear_other_devices_desc">Na zicher chcesz wymazać wszyjske inksze masziny z ôgłoszynio OMEMO\? Jak twoje masziny sie zaś połōnczōm, to sie zaś ôgłoszōm, ale mogōm niy dostać wiadōmości wysłanych bez tyn czas.</string>
    <string name="error_no_keys_to_trust_server_error">Niy ma dostympnych kluczy dlo tego kōntaktu.
\nNiy szło pobrać nowych kluczy ze serwera. Możno je coś niy tak ze serwerym ôd twojigo kōntaktu\?</string>
    <string name="error_no_keys_to_trust_presence">Brak dostympnych kluczy dlo tego kōntaktu.
\nDej pozōr, czy wzajymnie powiadōmiocie sie ô ôbecności.</string>
    <string name="error_trustkeys_title">Coś poszło źle</string>
    <string name="fetching_history_from_server">Pobiyranie historyje z serwera</string>
    <string name="no_more_history_on_server">Kōniec historyje na serwerze</string>
    <string name="updating">Aktualizowanie…</string>
    <string name="password_changed">Hasło było zmiyniōne!</string>
    <string name="could_not_change_password">Niy szło zmiynić hasła</string>
    <string name="change_password">Zmiyń hasło</string>
    <string name="current_password">Teroźne hasło</string>
    <string name="new_password">Nowe hasło</string>
    <string name="password_should_not_be_empty">Hasło niy może być prōzne</string>
    <string name="enable_all_accounts">Aktywuj wszyjske kōnta</string>
    <string name="disable_all_accounts">Zastow wszyjske kōnta</string>
    <string name="perform_action_with">Użyj</string>
    <string name="no_affiliation">Brak stanowiska</string>
    <string name="no_role">Offline</string>
    <string name="outcast">Wykluczōny</string>
    <string name="member">Czōnek</string>
    <string name="advanced_mode">Tryb rozszyrżōny</string>
    <string name="grant_membership">Prziznej uprawniynia czōnkostwa</string>
    <string name="remove_membership">Wymaż uprawniynia czōnkostwa</string>
    <string name="grant_admin_privileges">Prziznej uprawniynia administratora</string>
    <string name="remove_admin_privileges">Odbierz uprawniynia administratora</string>
    <string name="grant_owner_privileges">Prziznej uprawniynia posiedziciela</string>
    <string name="remove_owner_privileges">Wymaż uprawniynia posiedziciela</string>
    <string name="remove_from_room">Wyciep z kōnferyncyje</string>
    <string name="remove_from_channel">Wyciep z kanału</string>
    <string name="could_not_change_affiliation">Niy szło umiynić stanowiska ôd %s</string>
    <string name="ban_from_conference">Wyklucz</string>
    <string name="ban_from_channel">Wyklucz na kanale</string>
    <string name="removing_from_public_conference">Chcesz wyciepnōńć %s z publicznego kanału. Jedyny spusōb na to, to je wykluczyć ta ôsoba na dycki.</string>
    <string name="ban_now">Wyklucz teroz</string>
    <string name="could_not_change_role">Niy szło zmiynić funkcyje %s</string>
    <string name="conference_options">Kōnfiguracyjo prywatnyj kōnferyncyje</string>
    <string name="channel_options">Kōnfiguracyjo publicznego kanału</string>
    <string name="members_only">Prywatne, ino dlo czōnkōw</string>
    <string name="non_anonymous">Niych adresa XMPP bydzie widzialno dlo wszyjskich</string>
    <string name="moderated">Niych kanał bydzie moderowany</string>
    <string name="you_are_not_participating">Niy bieresz udziału</string>
    <string name="modified_conference_options">Sztalōnki kōnferyncyje były zmiyniōne!</string>
    <string name="could_not_modify_conference_options">Niy idzie zmiynić sztelōnkōw kōnferyncyje</string>
    <string name="never">Nigdy</string>
    <string name="until_further_notice">Ryncznie</string>
    <string name="snooze">Ôdłōż</string>
    <string name="reply">Ôdpowiydz</string>
    <string name="mark_as_read">Ôznocz za przeczytane</string>
    <string name="pref_input_options">Sztelōnki wkludzanio</string>
    <string name="pref_enter_is_send">Enter wysyło</string>
    <string name="pref_enter_is_send_summary">Używej knefla Enter do wysyłanio wiadōmości. Dycki możesz używać Ctrl+Enter, żeby wysłać wiadōmość, nawet jak ta ôpcyjo je zastawiōno.</string>
    <string name="pref_display_enter_key">Pokoż knefel Enter</string>
    <string name="pref_display_enter_key_summary">Umiyń knefel emotikōnōw na Enter</string>
    <string name="audio">zbiōr audio</string>
    <string name="video">zbiōr wideo</string>
    <string name="image">ôbroz</string>
    <string name="vector_graphic">wektorowo grafika</string>
    <string name="pdf_document">Dokumynt PDF</string>
    <string name="apk">Aplikacyjo Androida</string>
    <string name="vcard">Kōntakt</string>
    <string name="avatar_has_been_published">Avatar bōł sprownie ôpublikowany!</string>
    <string name="sending_x_file">Wysyłanie %s</string>
    <string name="offering_x_file">Propōnowanie %s</string>
    <string name="hide_offline">Skryj niydostympnych</string>
    <string name="contact_is_typing">%s pisze…</string>
    <string name="contact_has_stopped_typing">%s niy pisze</string>
    <string name="contacts_are_typing">%s piszōm…</string>
    <string name="contacts_have_stopped_typing">%s niy piszōm</string>
    <string name="pref_chat_states">Powiadōmiynia pisanio</string>
    <string name="pref_chat_states_summary">Dowej znać kōntaktōm, jak dō nich piszesz</string>
    <string name="send_location">Wyślij lokalizacyjo</string>
    <string name="show_location">Pokoż lokalizacyjo</string>
    <string name="no_application_found_to_display_location">Niy szło znojś aplikacyje do pokazowanio lokalizacyje</string>
    <string name="location">Lokalizacyjo</string>
    <string name="title_undo_swipe_out_conversation">Kōnwersacyjo zawarto</string>
    <string name="title_undo_swipe_out_group_chat">Ôpuś prywatno kōnferyncyjo</string>
    <string name="title_undo_swipe_out_channel">Ôpuś publiczny kanał</string>
    <string name="pref_dont_trust_system_cas_title">Niy dufej certyfikatōm systymowym</string>
    <string name="pref_dont_trust_system_cas_summary">Wymogej ryncznego potwiyrdzanio certyfikatōw</string>
    <string name="pref_remove_trusted_certificates_title">Wymaż certyfikaty</string>
    <string name="pref_remove_trusted_certificates_summary">Ôbier zadufane certyfikaty do wymazanio</string>
    <string name="toast_no_trusted_certs">Brak ryncznie zadufanych certyfikatōw</string>
    <string name="dialog_manage_certs_title">Wymaż certyfikaty</string>
    <string name="dialog_manage_certs_positivebutton">Wymaż zaznaczōne</string>
    <string name="dialog_manage_certs_negativebutton">Pociep</string>
    <plurals name="toast_delete_certificates">
        <item quantity="one">Wymazany %d certyfikat</item>
        <item quantity="few">Wymazane %d certyfikaty</item>
        <item quantity="other">Wymazane %d certyfikatōw</item>
    </plurals>
    <string name="pref_quick_action_summary">Zastōmp knefel wysyłanio gibkōm akcyjōm</string>
    <string name="pref_quick_action">Gibko akcyjo</string>
    <string name="none">Brak</string>
    <string name="recently_used">Ôstatnio używano</string>
    <string name="choose_quick_action">Ôbier gibko akcyjo</string>
    <string name="search_contacts">Przeszukej kōntakty</string>
    <string name="search_bookmarks">Przeszukej zokłodki</string>
    <string name="send_private_message">Wyślij wiadōmość prywatno</string>
    <string name="user_has_left_conference">%1$s już niy je we kōnferyncyji</string>
    <string name="username">Miano ôd używocza</string>
    <string name="username_hint">Miano ôd używocza</string>
    <string name="invalid_username">Niynolezne miano ôd używocza</string>
    <string name="download_failed_server_not_found">Pobiyranie niyudane: Niy szło znojś serwera</string>
    <string name="download_failed_file_not_found">Pobiyranie niyudane: Niy szło znojś zbioru</string>
    <string name="download_failed_could_not_connect">Pobiyranie niyudane: Niy szło połōnczyć z hostym</string>
    <string name="download_failed_could_not_write_file">Pobiyranie niyudane: Niy szło spamiyntać zbioru</string>
    <string name="download_failed_invalid_file">Pobiyranie niypodarzōne: Niynoleżny zbiōr</string>
    <string name="account_status_tor_unavailable">Nec TOR je niydostympny</string>
    <string name="account_status_bind_failure">Błōnd połōnczynio</string>
    <string name="account_status_host_unknown">Serwer niy ôdpado dōmynie</string>
    <string name="server_info_broken">Zepsute</string>
    <string name="pref_presence_settings">Dostympność</string>
    <string name="pref_away_when_screen_off">Status „W ôddali”, kej ekran je zastawiōny</string>
    <string name="pref_away_when_screen_off_summary">Ôznaczo twōj zasōb za „W ôddali”, kej ekran je zastawiōny</string>
    <string name="pref_dnd_on_silent_mode">„Niy szterować” we trybie cichym</string>
    <string name="pref_dnd_on_silent_mode_summary">Ôznaczo twōj zasōb za „Niy szterować”, kej maszina je w trybie cichym</string>
    <string name="pref_treat_vibrate_as_silent">Traktuj tryb wibracyje jak tryb cichy</string>
    <string name="pref_treat_vibrate_as_dnd_summary">Ôznaczo twōj zasōb za „Niy szterować”, kej maszina je w trybie wibracyje</string>
    <string name="pref_show_connection_options">Rozszyrzōne sztelōnki połōnczynio</string>
    <string name="pref_show_connection_options_summary">Pokoż miano ôd hosta i sztelōnki portu przi przidowaniu kōnta</string>
    <string name="hostname_example">xmpp.prziklod.com</string>
    <string name="action_add_account_with_certificate">Wloguj certyfikatym</string>
    <string name="unable_to_parse_certificate">Niy szło ôdczytać certyfikatu</string>
    <string name="mam_prefs">Preferyncyje archiwizacyje</string>
    <string name="server_side_mam_prefs">Preferyncyje archiwizacyje po strōnie serwera</string>
    <string name="fetching_mam_prefs">Pobiyranie preferyncyji archiwizacyje. Czekej…</string>
    <string name="unable_to_fetch_mam_prefs">Niy idzie pobrać preferyncyji archiwizacyje</string>
    <string name="captcha_required">Wymogano CAPTCHA</string>
    <string name="captcha_hint">Wkludź tekst z ôbrozka wyżyj</string>
    <string name="certificate_chain_is_not_trusted">Lyńcuch certyfikatōw niyma zadufany</string>
    <string name="jid_does_not_match_certificate">Adresa XMPP niy pasuje do certyfikatu</string>
    <string name="action_renew_certificate">Ôdnōw certyfikat</string>
    <string name="error_fetching_omemo_key">Błōnd pobiyranio klucza OMEMO!</string>
    <string name="verified_omemo_key_with_certificate">Klucz OMEMO zweryfikowany certyfikatym!</string>
    <string name="device_does_not_support_certificates">Twoja maszina niy spiyro ôbiyranio certyfikatōw klijynckich!</string>
    <string name="pref_connection_options">Połōnczynie</string>
    <string name="pref_use_tor">Połōncz bez nec TOR</string>
    <string name="pref_use_tor_summary">Tuneluj wszyjske połōnczynia bez nec TOR. Wymogo aplikacyje Orbot</string>
    <string name="account_settings_hostname">Miano hosta</string>
    <string name="account_settings_port">Port</string>
    <string name="hostname_or_onion">Adresa serwera abo .onion</string>
    <string name="not_a_valid_port">To niyma noleżny numer portu</string>
    <string name="not_valid_hostname">To niyma noleżne miano hosta</string>
    <string name="connected_accounts">%1$d z %2$d kōnt połōnczōnych</string>
    <plurals name="x_messages">
        <item quantity="one">%d wiadōmość</item>
        <item quantity="few">%d wiadōmości</item>
        <item quantity="other">%d wiadōmości</item>
    </plurals>
    <string name="load_more_messages">Zaladuj wiyncyj wiadōmości</string>
    <string name="shared_file_with_x">Zbiōr dzielōny ze %s</string>
    <string name="shared_image_with_x">Ôbroz dzielōny ze %s</string>
    <string name="shared_images_with_x">Ôbrazy dzielōne ze %s</string>
    <string name="shared_text_with_x">Tekst dzielōny ze %s</string>
    <string name="no_storage_permission">Przizwōl %1$s na dostymp do zewnyntrznego składu</string>
    <string name="no_camera_permission">Przizwōl %1$s na dostymp do aparatu</string>
    <string name="sync_with_contacts">Synchrōnizuj z kōntaktami</string>
    <string name="sync_with_contacts_long">%1$s potrzebuje twojij zwōle na dopasowanie twojich kōntaktōw XMPP z wykazym kōntaktōw w telefōnie.
\nTo pokoże jejich połne miana i awatary.
\n
\n%1$s ino przeczyto twoje kōntakty i dopasuje je lokalnie, bez wysyłanio na twōj serwer.</string>
    <string name="sync_with_contacts_quicksy">Quicksy potrzebuje dostympu do numerōw telefōnōw twojich kōntaktōw, coby zasugerować ci kōntakty, co już używajōm Quicksy. &lt;br&gt;&lt;br&gt;Niy trzimiymy kopiji tych numerōw.
\n
\nAby dostać wiyncyj informacyje przeczytej naszo polityka prywatności&lt;/a&gt;. &lt;br&gt;&lt;br&gt;Teroz pojawi sie prośba ô zwōlo na dostymp do twojich kōntaktōw.</string>
    <string name="notify_on_all_messages">Powiadōm ô wszyskich wiadōmościach</string>
    <string name="notify_only_when_highlighted">Powiadōmiej ino w przipodku spōmniynio ô mie</string>
    <string name="notify_never">Powiadōmiynia zastawiōne</string>
    <string name="notify_paused">Powiadōmiynia strzimane</string>
    <string name="pref_picture_compression">Kōmpresyjo ôbrazōw</string>
    <string name="pref_picture_compression_summary">Podpowiydź: Użyj “Wybier zbiōr” zamiast “Wybier ôbroz”, coby wysłać pojedyncze ôbrozki bez kōmpresyje bez zglyndu na tyn sztalōnek.</string>
    <string name="always">Dycki</string>
    <string name="large_images_only">Ino sroge ôbrozki</string>
    <string name="battery_optimizations_enabled">Ôptymalizacyje używanio bateryje włōnczōne</string>
    <string name="battery_optimizations_enabled_explained">Twoja maszina mo włōnczōne agresywne szporowanie bateryje, bez co %1$s może ôdbiyrać wiadōmości z ôpōźniyniym.
\nZastawiynie tych ôptymalizacyji je rekōmyndowane.</string>
    <string name="battery_optimizations_enabled_dialog">Twoja maszina mo włōnczōne agresywne szporowanie bateryje, bez co %1$s może ôdbiyrać wiadōmości z ôpōźniyniym.
\n
\nTeroz pojawi sie prośba ô jejich zastawiynie.</string>
    <string name="disable">Zastow</string>
    <string name="selection_too_large">Zaznaczōne przestrzyństwo je za sroge</string>
    <string name="no_accounts">(Brak aktywynych kōnt)</string>
    <string name="this_field_is_required">To pole je wymogane</string>
    <string name="correct_message">Poprow wiadōmość</string>
    <string name="send_corrected_message">Wyślij poprawiōno wiadōmość</string>
    <string name="no_keys_just_confirm">Tyn kōntakt już bōł ôd ciebie zweryfikowany. Bez wybranie “Gotowe” ino potwiyrdzosz, że %s noleży do tyj grupowyj godki.</string>
    <string name="this_account_is_disabled">To kōnto było ôd ciebie zastawiōne</string>
    <string name="security_error_invalid_file_access">Feler bezpieczyństwa: niynoleżny dostymp do zbioru!</string>
    <string name="no_application_to_share_uri">Niy szło znojś aplikacyje do udostympniynio URI</string>
    <string name="share_uri_with">Udostympnij URI ze pōmocōm…</string>
    <string name="welcome_text_quicksy">Quicksy to modyfikacyjo popularnego klijynta XMPP Conversations, z autōmatycznym wykrywaniym kōntaktōw.&lt;br&gt;&lt;br&gt;Zapisujesz sie przi użyciu numeru telefōnu i Quicksy autōmatycznie — podle numerōw telefōnōw we adresowyj ksiōnżce — zasugeruje potyncjalne kōntakty dlo ciebie.&lt;br&gt;&lt;br&gt;Bez zapisanie sie zgodzosz sie na naszo &lt;a href=https://quicksy.im/#privacy&gt;polityka prywatności&lt;/a&gt;.</string>
    <string name="agree_and_continue">Zgodzōm sie, kōntynuuj</string>
    <string name="magic_create_text">Pokludzymy cie bez proces tworzynio kōnta na conversations.im.¹
\nKej ôbieresz conversations.im za liferanta, to poradzisz kōmunikować sie ze używoczami inkszych liferantōw, jeźli podosz im swoja połno adresa XMPP.</string>
    <string name="your_full_jid_will_be">Twoja połno adresa XMPP to: %s</string>
    <string name="create_account">Stwōrz kōnto</string>
    <string name="use_own_provider">Użyj inkszego serwera</string>
    <string name="pick_your_username">Ôbier miano ôd używocza</string>
    <string name="pref_manually_change_presence">Regyruj dostympnościōm ryncznie</string>
    <string name="pref_manually_change_presence_summary">Sztaluj dostympność we ôknie edytowanio wiadōmości statusu.</string>
    <string name="status_message">Status</string>
    <string name="presence_chat">Pogodo</string>
    <string name="presence_online">Je</string>
    <string name="presence_away">Fōrt</string>
    <string name="presence_xa">Niy ma</string>
    <string name="presence_dnd">Zajynte</string>
    <string name="secure_password_generated">Bezpieczne hasło je wygynerowane</string>
    <string name="device_does_not_support_battery_op">Twoja maszina niy przizwolo na zastawiynie ôptymalizacyje bateryje</string>
    <string name="registration_please_wait">Registracyjo niy podarziła sie: sprōbuj niyskorzij</string>
    <string name="registration_password_too_weak">Registracyjo niy podarziła sie: hasło za słabe</string>
    <string name="choose_participants">Ôbier czōnkōw</string>
    <string name="creating_conference">Tworzynie kōnferyncyje…</string>
    <string name="invite_again">Zaproś zaś</string>
    <string name="gp_disable">Zastow</string>
    <string name="gp_short">Krōtki</string>
    <string name="gp_medium">Postrzedni</string>
    <string name="gp_long">Dugi</string>
    <string name="pref_broadcast_last_activity">Roznajmuj użycie</string>
    <string name="pref_broadcast_last_activity_summary">Informuje twoje kōntakty ô tym, kedy używosz Conversations</string>
    <string name="pref_privacy">Prywatność</string>
    <string name="pref_theme_options">Tymat</string>
    <string name="pref_theme_options_summary">Wybier paleta farbōw</string>
    <string name="pref_theme_automatic">Autōmatycznie</string>
    <string name="pref_theme_light">Jasny</string>
    <string name="pref_theme_dark">Ciymny</string>
    <string name="pref_use_green_background">Zielōny zadek</string>
    <string name="pref_use_green_background_summary">Używej zielōnego zadku dlo dostanych wiadōmości</string>
    <string name="unable_to_connect_t