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 <b>OpenKeychain</b>, żeby szyfrować i ôdszyfrowować wiadōmości i zarzōndzać twojimi publicznymi kluczami.<br><br>OpenKeychain je na licyncyji GPLv3+ i je dostympny we F-Droid abo Google Play.<br><br><small>(Puść %1$s na nowo po zainstalowaniu.)</small></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. <br><br>Niy trzimiymy kopiji tych numerōw.
+\n
+\nAby dostać wiyncyj informacyje przeczytej naszo polityka prywatności</a>. <br><br>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.<br><br>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.<br><br>Bez zapisanie sie zgodzosz sie na naszo <a href=https://quicksy.im/#privacy>polityka prywatności</a>.</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