From 6785d8c69fa4a48dc7db6d9bd3b2aae635bdc546 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 8 May 2019 14:11:06 +0200 Subject: [PATCH 01/12] set volume control channel to media volume / default. fixes #3451 --- src/main/java/eu/siacs/conversations/ui/XmppActivity.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java index 87c417697..1bf41d4d2 100644 --- a/src/main/java/eu/siacs/conversations/ui/XmppActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/XmppActivity.java @@ -25,7 +25,6 @@ import android.graphics.Color; import android.graphics.Point; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -import android.media.AudioManager; import android.net.ConnectivityManager; import android.net.Uri; import android.os.AsyncTask; @@ -39,7 +38,6 @@ import android.preference.PreferenceManager; import android.support.annotation.BoolRes; import android.support.annotation.NonNull; import android.support.annotation.StringRes; -import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog.Builder; import android.support.v7.app.AppCompatDelegate; @@ -393,7 +391,6 @@ public abstract class XmppActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setVolumeControlStream(AudioManager.STREAM_NOTIFICATION); metrics = getResources().getDisplayMetrics(); ExceptionHelper.init(getApplicationContext()); new EmojiService(this).init(); From 5bedde7913ab9301a4efd8b427bba5c6175ae4b3 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 8 May 2019 14:11:28 +0200 Subject: [PATCH 02/12] run postDelayed in background thread --- .../java/eu/siacs/conversations/ui/service/AudioPlayer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/service/AudioPlayer.java b/src/main/java/eu/siacs/conversations/ui/service/AudioPlayer.java index 33f475812..5e89fca49 100644 --- a/src/main/java/eu/siacs/conversations/ui/service/AudioPlayer.java +++ b/src/main/java/eu/siacs/conversations/ui/service/AudioPlayer.java @@ -23,6 +23,8 @@ import android.widget.TextView; import java.lang.ref.WeakReference; import java.util.Locale; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; @@ -46,6 +48,8 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti private final Sensor proximitySensor; private final PendingItem> pendingOnClickView = new PendingItem<>(); + private final ExecutorService executor = Executors.newSingleThreadExecutor(); + private final Handler handler = new Handler(); public AudioPlayer(MessageAdapter adapter) { @@ -87,7 +91,7 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti audioPlayer.setTag(message); if (init(ViewHolder.get(audioPlayer), message)) { this.audioPlayerLayouts.addWeakReferenceTo(audioPlayer); - this.stopRefresher(true); + executor.execute(()-> this.stopRefresher(true)); } else { this.audioPlayerLayouts.removeWeakReferenceTo(audioPlayer); } From 708476cee864e6e3db073f4dbff9f1b3ea4861d7 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 10 May 2019 19:57:54 +0200 Subject: [PATCH 03/12] explain omemo and backups. fixes #3454 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index da8639baa..7beadbf75 100644 --- a/README.md +++ b/README.md @@ -293,6 +293,10 @@ On the one hand Conversations supports Message Archive Management to keep a serv As of version 2.4.0 an integrated Backup & Restore function will help with this, go to Settings → Expert settings → Create backup. A notification will pop-up during the creation process that will announce you when it's ready. After the files, one for each account, are created, you can move the **Conversations** folder *(if you want your old media files too)* or only the **Conversations/Backup** folder *(for OMEMO keys and history only)* to your new device (or to a storage place) where a freshly installed Conversations can restore each account. Don't forget to enable the accounts after a succesful restore. +This backup method will include your OMEMO keys. Due to forward secrecy you will not be able to recover messages sent and received between creating the backup and restoring it. If you have a server side archive (MAM) those messages will be retrieved but displayed as *unable to decrypt*. For technical reasons you might also lose the first message you either sent or receive after the restore; for each conversation you have. This message will then also show up as *unable to decrypt*, but this will automatically recover itself as long as both participants are on Conversations 2.3.11+. Note that this doesn’t happen if you just transfer to a new phone and no messages have been exchanged between backup and restore. + +In the vast, vast majority of cases you won’t have to manually delete OMEMO keys or do anything like that. Conversations only introduced the offical backup feature in 2.4.0 after making sure the *OMEMO self healing* mechanism introduced in 2.3.11 works fine. + **WARNING**: Be sure to know your accounts passwords or find ways to reset them **before** doing the backup as the files are encrypted using those passwords and the Restore process will ask for them. **WARNING**: Do not use the restore backup feature in an attempt to clone (run simultaneously) an installation. Restoring a backup is only meant for migrations or in case you’ve lost the original device. From 1db07b84f325104cd64f831d0fd831a5d67d6733 Mon Sep 17 00:00:00 2001 From: Licaon_Kter Date: Mon, 20 May 2019 10:26:17 +0300 Subject: [PATCH 04/12] Readme typo (#3462) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7beadbf75..93b382caa 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,7 @@ You can find a detailed description of how your server, the app server and FCM a #### But why do I need a permanent notification if I use Google Push? -FCM (Google Push) allows an app to wake up from *Doze* which is (as the name suggests) a hibernation feature of the Android operating system that cuts the network connection and also reduces the number of times the app is allowed to wake up (to ping the server for example). The app can ask to be excluded from doze. Non push variants of the app (from F-Droid or if the server doesn’t support it) will do this on first start up. So if you get exemption from *Doze*, or if you get regular push events sent to you, Doze should not pose a threat to Conversatons working properly. But even with *Doze* the app is still open in the background (kept in memory); it is just limited in the actions it can do. Conversations needs to stay in memory to hold certain session state (online status of concats, join status of group chats, …). However with Android 8 Google changed all of this again and now an App that wants to stay in memory needs to have a foreground service which is visible to the user via the annoying notification. But why does Conversations need to hold that state? XMPP is a stateful protocol that has a lot of per-session information; packets need to be counted, presence information needs to be held, some features like Message Carbons get activated once per session, MAM catchup happens once, service discovery happens only once; the list goes on. When Conversations was created in early 2014 none of this was a problem because apps were just allowed to stay in memory. Basically every XMPP client out there holds that information in memory because it would be a lot more complicated trying to persist it to disk. An entire rewrite of Conversations in the year 2019 would attempt to do that and would probably succeed however it would require exactly that; a complete rewrite which is not feasible right now. That’s by the way also the reason why it is difficult to write an XMPP client on iOS. Or more broadly put this is also the reason why other protocols are designed as or migrated to stateless protocols (often based on HTTP); take for example the migration of IMAP to [JMAP](https://jmap.io/). +FCM (Google Push) allows an app to wake up from *Doze* which is (as the name suggests) a hibernation feature of the Android operating system that cuts the network connection and also reduces the number of times the app is allowed to wake up (to ping the server for example). The app can ask to be excluded from doze. Non push variants of the app (from F-Droid or if the server doesn’t support it) will do this on first start up. So if you get exemption from *Doze*, or if you get regular push events sent to you, Doze should not pose a threat to Conversatons working properly. But even with *Doze* the app is still open in the background (kept in memory); it is just limited in the actions it can do. Conversations needs to stay in memory to hold certain session state (online status of contacts, join status of group chats, …). However with Android 8 Google changed all of this again and now an App that wants to stay in memory needs to have a foreground service which is visible to the user via the annoying notification. But why does Conversations need to hold that state? XMPP is a stateful protocol that has a lot of per-session information; packets need to be counted, presence information needs to be held, some features like Message Carbons get activated once per session, MAM catchup happens once, service discovery happens only once; the list goes on. When Conversations was created in early 2014 none of this was a problem because apps were just allowed to stay in memory. Basically every XMPP client out there holds that information in memory because it would be a lot more complicated trying to persist it to disk. An entire rewrite of Conversations in the year 2019 would attempt to do that and would probably succeed however it would require exactly that; a complete rewrite which is not feasible right now. That’s by the way also the reason why it is difficult to write an XMPP client on iOS. Or more broadly put this is also the reason why other protocols are designed as or migrated to stateless protocols (often based on HTTP); take for example the migration of IMAP to [JMAP](https://jmap.io/). #### Conversations doesn’t work for me. Where can I get help? From a909e1a7cfb335e0cda8a106b498389f1edc355b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 May 2019 17:29:27 +0200 Subject: [PATCH 05/12] fixed NPE in channel discovery after race to create menu --- .../eu/siacs/conversations/ui/ChannelDiscoveryActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ChannelDiscoveryActivity.java b/src/main/java/eu/siacs/conversations/ui/ChannelDiscoveryActivity.java index aabd6607f..ab5b66b10 100644 --- a/src/main/java/eu/siacs/conversations/ui/ChannelDiscoveryActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ChannelDiscoveryActivity.java @@ -94,7 +94,7 @@ public class ChannelDiscoveryActivity extends XmppActivity implements MenuItem.O mMenuSearchView.expandActionView(); mSearchEditText.append(initialSearchValue); mSearchEditText.requestFocus(); - if (optedIn) { + if (optedIn && xmppConnectionService != null) { xmppConnectionService.discoverChannels(initialSearchValue, this); } } From 132f81df23482c93ae46ac1dc3548cc348e2726e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 May 2019 17:30:04 +0200 Subject: [PATCH 06/12] double check that activity is not null in updateSend button --- .../java/eu/siacs/conversations/ui/ConversationFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 2e91b750e..da7793276 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -2254,7 +2254,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke public void updateSendButton() { boolean hasAttachments = mediaPreviewAdapter != null && mediaPreviewAdapter.hasAttachments(); - boolean useSendButtonToIndicateStatus = PreferenceManager.getDefaultSharedPreferences(getActivity()).getBoolean("send_button_status", getResources().getBoolean(R.bool.send_button_status)); + boolean useSendButtonToIndicateStatus = activity != null && PreferenceManager.getDefaultSharedPreferences(activity).getBoolean("send_button_status", getResources().getBoolean(R.bool.send_button_status)); final Conversation c = this.conversation; final Presence.Status status; final String text = this.binding.textinput == null ? "" : this.binding.textinput.getText().toString(); @@ -2265,7 +2265,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke action = SendButtonTool.getAction(getActivity(), c, text); } if (useSendButtonToIndicateStatus && c.getAccount().getStatus() == Account.State.ONLINE) { - if (activity.xmppConnectionService != null && activity.xmppConnectionService.getMessageArchiveService().isCatchingUp(c)) { + if (activity != null && activity.xmppConnectionService != null && activity.xmppConnectionService.getMessageArchiveService().isCatchingUp(c)) { status = Presence.Status.OFFLINE; } else if (c.getMode() == Conversation.MODE_SINGLE) { status = c.getContact().getShownStatus(); From c965049605c360c93a898ae0a6382e2b091dae62 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 May 2019 17:30:51 +0200 Subject: [PATCH 07/12] handle invalid canditates in jingle --- .../eu/siacs/conversations/xmpp/jingle/JingleCandidate.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java index 64db37f66..d48804691 100644 --- a/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java +++ b/src/main/java/eu/siacs/conversations/xmpp/jingle/JingleCandidate.java @@ -60,6 +60,10 @@ public class JingleCandidate { } public void setType(String type) { + if (type == null) { + this.type = TYPE_UNKNOWN; + return; + } switch (type) { case "proxy": this.type = TYPE_PROXY; From 10653df164f84db042a426738d9644391e4f980c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 May 2019 17:31:11 +0200 Subject: [PATCH 08/12] show error messages in text layout not edittext --- .../conversations/ui/EnterJidDialog.java | 19 ++++++++++++++----- src/main/res/layout/enter_jid_dialog.xml | 2 +- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java b/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java index 98cc492dc..89cd56b6f 100644 --- a/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java +++ b/src/main/java/eu/siacs/conversations/ui/EnterJidDialog.java @@ -15,6 +15,7 @@ import android.widget.ArrayAdapter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; import eu.siacs.conversations.Config; @@ -41,6 +42,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected private static final String SANITY_CHECK_JID = "sanity_check_jid"; private KnownHostsAdapter knownHostsAdapter; + private Collection whitelistedDomains = Collections.emptyList(); private EnterJidDialogBinding binding; private AlertDialog dialog; @@ -155,19 +157,19 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected try { contactJid = Jid.of(binding.jid.getText().toString()); } catch (final IllegalArgumentException e) { - binding.jid.setError(getActivity().getString(R.string.invalid_jid)); + binding.jidLayout.setError(getActivity().getString(R.string.invalid_jid)); return; } if (!issuedWarning && sanityCheckJid) { if (contactJid.isDomainJid()) { - binding.jid.setError(getActivity().getString(R.string.this_looks_like_a_domain)); + binding.jidLayout.setError(getActivity().getString(R.string.this_looks_like_a_domain)); dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add_anway); issuedWarning = true; return; } if (suspiciousSubDomain(contactJid.getDomain())) { - binding.jid.setError(getActivity().getString(R.string.this_looks_like_channel)); + binding.jidLayout.setError(getActivity().getString(R.string.this_looks_like_channel)); dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add_anway); issuedWarning = true; return; @@ -180,7 +182,9 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected dialog.dismiss(); } } catch (JidError error) { - binding.jid.setError(error.toString()); + binding.jidLayout.setError(error.toString()); + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add); + issuedWarning = false; } } } @@ -199,6 +203,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected if (activity instanceof XmppActivity) { Collection hosts = ((XmppActivity) activity).xmppConnectionService.getKnownHosts(); this.knownHostsAdapter.refresh(hosts); + this.whitelistedDomains = hosts; } } @@ -216,6 +221,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected public void afterTextChanged(Editable s) { if (issuedWarning) { dialog.getButton(AlertDialog.BUTTON_POSITIVE).setText(R.string.add); + binding.jidLayout.setError(null); issuedWarning = false; } } @@ -245,7 +251,10 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected super.onDestroyView(); } - private static boolean suspiciousSubDomain(String domain) { + private boolean suspiciousSubDomain(String domain) { + if (this.whitelistedDomains.contains(domain)) { + return false; + } final String[] parts = domain.split("\\."); return parts.length >= 3 && SUSPICIOUS_DOMAINS.contains(parts[0]); } diff --git a/src/main/res/layout/enter_jid_dialog.xml b/src/main/res/layout/enter_jid_dialog.xml index fe58ea85f..1c20ef722 100644 --- a/src/main/res/layout/enter_jid_dialog.xml +++ b/src/main/res/layout/enter_jid_dialog.xml @@ -23,7 +23,7 @@ android:layout_height="wrap_content"/> Date: Wed, 22 May 2019 17:32:14 +0200 Subject: [PATCH 09/12] pulled translations from transifex --- src/conversations/res/values-uk/strings.xml | 9 +++ src/main/res/values-gl/strings.xml | 8 +-- src/main/res/values-ja/strings.xml | 11 +++ src/main/res/values-uk/strings.xml | 77 +++++++++++++++++++++ src/quicksy/res/values-uk/strings.xml | 22 ++++++ 5 files changed, 123 insertions(+), 4 deletions(-) create mode 100644 src/conversations/res/values-uk/strings.xml create mode 100644 src/quicksy/res/values-uk/strings.xml diff --git a/src/conversations/res/values-uk/strings.xml b/src/conversations/res/values-uk/strings.xml new file mode 100644 index 000000000..d179bc54d --- /dev/null +++ b/src/conversations/res/values-uk/strings.xml @@ -0,0 +1,9 @@ + + + Виберіть постачальника послуг обміну повідомленнями XMPP + Скористатися conversations.im + Створити новий обліковий запис + Вже маєте обліковий запис XMPP? Можливо, користуєтеся іншою програмою XMPP або користувалися цією програмою раніше. Якщо ні, можете створити новий обліковий запис XMPP просто зараз.\nЗверніть увагу: Деякі постачальники електронної пошти водночас надають облікові записи XMPP. + XMPP — це мережа обміну повідомленнями, незалежна від постачальників. Можете використовувати цю програму з будь-яким XMPP сервером, який оберете.\nПроте, для зручності, ми спростили створення облікового запису на conversations.im¹ — в постачальника, який спеціально налаштований на роботу з цією програмою. + + \ No newline at end of file diff --git a/src/main/res/values-gl/strings.xml b/src/main/res/values-gl/strings.xml index b6b4acfb1..02c01564b 100644 --- a/src/main/res/values-gl/strings.xml +++ b/src/main/res/values-gl/strings.xml @@ -854,14 +854,14 @@ Buscar participantes Ficheiro demasiado grande Anexar - Descubrir canles - Buscar canles + Descubrir canales + Buscar canales Posible intrusión na intimidade! - search.jabbercat.org.

Ao utilizar esta característica transmitirá o seu enderezo IP e os termos de busca a ese servizo. Lea a súa Política de Intimidade para máis información.]]>
+ search.jabbercat.org.

Ao utilizar esta característica transmitirá o seu enderezo IP e os termos de busca a ese servizo. Lea a súa Política de Intimidade para máis información.]]>
Xa teño unha conta Engadir conta existente Rexistrar unha nova conta Esto semella un enderezo de dominio Engadir igualmente - Esto semella o enderezo de unha canle + Esto semella o enderezo de un canal diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml index 8897dfc5b..bcc03cb83 100644 --- a/src/main/res/values-ja/strings.xml +++ b/src/main/res/values-ja/strings.xml @@ -7,6 +7,7 @@ この会話を閉じる 連絡先の詳細 談話室の詳細 + チャンネルの詳細 安全に会話 アカウントを追加 名前の編集 @@ -171,8 +172,11 @@ よろしいですか? アカウントを削除すると、会話履歴すべてが失われます 音声を録音 + XMPP アドレス + XMPP アドレスをブロック username@example.com パスワード + 正しい XMPP アドレスではありません メモリ不足です。画像が大きすぎます %s をお使いのアドレス帳に追加しますか? サーバー情報 @@ -217,6 +221,8 @@ 選択 連絡先はすでに存在します 参加 + channel@conference.example.com/nick + channel@conference.example.com ブックマークとして保存 ブックマークを削除 グループチャットを破棄する @@ -642,6 +648,7 @@ メッセージを検索 GIF ウェブアドレスをコピー + XMPP アドレスをコピー はい いいえ 検証しています… @@ -649,4 +656,8 @@ 要求の処理中に、何か問題が発生しました。 要求を拒否 Conversations プロフィール写真 + XMPP アドレスを入力 + チャンネル名 + XMPP アドレス + このチャンネルは既に存在しています diff --git a/src/main/res/values-uk/strings.xml b/src/main/res/values-uk/strings.xml index 70723a12b..13e6d17cb 100644 --- a/src/main/res/values-uk/strings.xml +++ b/src/main/res/values-uk/strings.xml @@ -7,6 +7,7 @@ Закрити цю розмову Деталі контакту Деталі групи + Деталі каналу Захищена розмова Додати обліковий запис Редагувати ім\'я @@ -51,6 +52,7 @@ Поділитися з… Почати розмову Запросити контакт + Запросити Контакти Контакт Скасувати @@ -210,6 +212,7 @@ Отримую ключі… Зроблено Розшифрувати + Закладки Пошук Увести контакт Видалити контакт @@ -220,12 +223,17 @@ Вибрати Контакт уже існує Долучитися + channel@conference.example.com/nick + channel@conference.example.com Зберегти як закладку Видалити закладку Видалити груповий чат + Знищити канал Ви впевнені що бажаєте видалити цей груповий чат?\n\n 1 Увага: 1 Груповий чат буде видалений з сервера. + Упевнені, що бажаєте знищити цей публічний канал?\n\nУвага: Канал буде повністю знищено та видалено з сервера. Видалити цей груповий чат не вдалось + Не вдалося знищити канал Ця закладка вже існує Редагувати тему групи Тема @@ -298,6 +306,7 @@ Надіслати знову URL файла URL скопійовано до комірки обміну + Адресу XMPP скопійовано до комірки обміну Текст повідомлення про помилку скопійовано до комірки обміну веб адреса Розпізнати QR-код @@ -308,6 +317,14 @@ Спробуйте ще Підтримувати сервіс на першому плані Не дає операційній системі припиняти Ваш зв\'язок + Створити резервну копію + Резервні копії зберігатимуться до %s + Створення резервних копій + Резервну копію створено + Резервні копії збережено до %s + Відтворення з резервної копії + Відтворено з резервної копії + Не забудьте включити обліковий запис Вибрати файл Отримання %1$s (%2$d%% завершено) Завантажити %s @@ -357,13 +374,18 @@ Відкликати право участі Дати права адміністратора Відкликати права адміністратора + Надати права власника + Відкликати права власника Видалити з групи + Прибрати з каналу Не можу змінити пов\'язаність з %s Заборонити доступ до групи + Заборонити в каналі Щоб видалити %s з публічної групи, забороніть йому доступ назавжди. Вигнати зараз Не можу змінити роль %s Налаштування приватного чату + Налаштування публічного каналу Приватно, лише для членів Зробити XMPP адрес доступним для всіх Зробити канал модерованим @@ -401,6 +423,8 @@ Не знайдено програми, щоб показати місцезнаходження Місцезнаходження Розмову закрито + Полишити приватну групу обміну повідомленнями + Полишити публічний канал Не довіряти системним центрам сертифікації Усі сертифікати мають бути підтверджені вручну Видалити сертифікати @@ -421,6 +445,7 @@ Остання, що використана Вибрати швидку дію Шукати в контактах + Шукати закладки Відправити приватне повідомлення %1$s залишила групу! Ім\'я користувача @@ -506,7 +531,10 @@ Помилка безпеки: Недійсний доступ до файлу Не знайдено програми, щоб поділитися URI Поділитися URI з… +
Реєструєтеся за номером телефона, а Quicksy автоматично за номерами телефонів зі списку контактів на пристрої запропонує Вам можливі контакти.

Підписуючись на цю послугу Ви погоджуєтеся з нашою політикою конфіденційності.]]>
Прийняти й продовжити + Ми проведемо Вас через створення облікового запису на conversations.im.¹\nОбираючи conversations.im в якості постачальника, Ви зможете спілкуватися з користувачами інших постачальників, надаючи їм свою повну XMPP адресу. + Ваша повна адреса XMPP буде: %s Створити обліковий запис Використати мого власного провайдера Оберіть Ваше ім\'я користувача @@ -741,6 +769,8 @@ Важливість, звук, вібрація Стиснення відео Перегляд медіа + Переглянути учасників + Учасники Переглядач медіа Файл пропущено через порушення безпеки. Якість відео @@ -799,9 +829,56 @@ Встановити Orbot Запустити Orbot Не знайдено програми для пошуку й встановлення нових програм. + Цей канал опублікує вашу адресу XMPP електронна книга Оригінал (не стиснений) Відкрити за допомогою... Фото профілю чату Виберіть обліковий запис + Відновити з резервної копії + Відновити + Введіть пароль для облікового запису %s, щоб відновити з резервної копії. + Не використовуйте відновлення з резервної копії з метою клонувати інсталяцію (запускати одночасно ще один примірник). Відновлення з резервної копії призначене виключно для перенесення або на випадок втрати оригінального пристрою. + Не можу відновити з резервної копії. + Не можу розшифрувати резервну копію. Пароль правильний? + Створити або відновити резервну копію + Ввести адресу XMPP + Створити групу обміну повідомленнями + Приєднатися до публічного каналу + Створити приватну групу обміну повідомленнями + Створити публічний канал + Назва каналу + Адреса XMPP + Будь ласка, дайте назву для каналу + Будь ласка, надайте адресу XMPP + Це адреса XMPP. Будь ласка, дайте назву. + Створення публічного каналу… + Цей канал уже існує + Ви приєдналися до наявного каналу + Не можу налаштувати канал + Дозволити будь-кому редагувати тему + Дозволити будь-кому запрошувати інших + Будь-хто може редагувати тему. + Власники можуть редагувати тему. + Адміністратори можуть редагувати тему. + Власники можуть запрошувати інших. + Будь-хто може запрошувати інших. + Адміністратори бачать адреси XMPP. + Будь-хто бачить адреси XMPP. + Цей публічний канал без учасників. Запросіть Ваші контакти або скористайтеся кнопкою поширення, щоб поділитися адресою XMPP. + Ця приватна група обміну повідомленнями без учасників. + Управляти правами + Шукати учасників + Файл надто великий + Долучити + Знайти канали + Шукати канали + Можливе порушення приватності! + search.jabbercat.org.

Використання цієї функції передає Вашу IP адресу та пошукові запити цьому сервісу. Перегляньте їхню політику конфіденційності, щоб отримати більше інформації.]]>
+ Я вже маю обліковий запис + Додати наявний обліковий запис + Зареєструвати новий обліковий запис + Це схоже на ім\'я домену + Додати все одно + Це схоже на адресу каналу diff --git a/src/quicksy/res/values-uk/strings.xml b/src/quicksy/res/values-uk/strings.xml new file mode 100644 index 000000000..ea10e6f82 --- /dev/null +++ b/src/quicksy/res/values-uk/strings.xml @@ -0,0 +1,22 @@ + + + Програма дала збій + Надсилаючи траси стеків виклику Ви допомагаєте розробці цієї програми\nУвага: Це використовуватиме ваш обліковий запис XMPP, щоб надсилати траси стеків виклику розробнику. + Ця програма використовує сторонній додаток, який називається OpenKeychain, для шифрування повідомлень і впорядкування ваших публічних ключів.\n\nOpenKeychain поширюється на умова ліцензії GPLv3 й доступна в F-Droid та Google Play.\n\n(Будь ласка, перезапустіть цю програму після цього.) + Ця програма не змогла зашифрувати повідомлення, оскільки публічний ключ адресата не опубліковано.\n\nБудь ласка, попросіть адресата налаштувати OpenPGP. + Ця програма не змогла зашифрувати повідомлення, оскільки публічні ключі адресатів не опубліковано.\n\nБудь ласка, попросіть їх налаштувати OpenPGP. + Час, протягом якого ця програма дотримується тиші після активності на іншому пристрої. + Надсилаючи траси стеків виклику, ви допомагаєте розробці цієї програми. + Ця програма потребує доступу до зовнішнього сховища + Ця програма потребує доступу до камери + Пристрій застосовує до цієї програми правила оптимізації використання батареї, які можуть призвести до затримки сповіщень або навіть втрати повідомлень.\nРекомендовано їх відключити. + Пристрій застосовує до цієї програми правила оптимізації використання батареї, які можуть призвести до затримки сповіщень або навіть втрати повідомлень.\nЗараз буде запропоновано їх відключити. + Дозволити всім вашим контактам знати, коли ви використовуєте цю програму. + Операційна система обмежує цю програму в доступі до Інтернету, коли вона не на екрані. Щоб отримувати сповіщення про нові повідомлення, слід дозволити цій програмі доступ, коли ввімкнено заощадження трафіку.\nЦя програма все одно намагатиметься заощадити трафік, коли можливо. + Цей пристрій не надає можливості зробити виняток щодо заощадження трафіку для цієї програми. + Щоб продовжувати отримувати сповіщення, навіть коли екран вимкнуто, потрібно додати цю програму до списку захищених. + Програма не може надіслати зашифроване повідомлення до %1$s. Можливо, це обумовлено тим, що адресат користується застарілим сервером або програмою, яка не підтримує OMEMO. + Програма потребує доступу до мікрофона + Цей вид сповіщень показує постійне сповіщення про те, що ця програма працює. + Зображення профілю для Quicksy + From e5378df39c5254b9839ee62d17d0845b234fdbc5 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 May 2019 23:58:08 +0200 Subject: [PATCH 10/12] synchronize around attributes in toContentValues() --- .../java/eu/siacs/conversations/entities/Conversation.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 8b02d8be5..8b359713a 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -576,7 +576,9 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl values.put(CREATED, created); values.put(STATUS, status); values.put(MODE, mode); - values.put(ATTRIBUTES, attributes.toString()); + synchronized (this.attributes) { + values.put(ATTRIBUTES, attributes.toString()); + } return values; } From 9a8cc5b2e7d0aa295912e3063caf954a554c3802 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 May 2019 23:58:39 +0200 Subject: [PATCH 11/12] fixed some NPE --- .../siacs/conversations/ui/ConferenceDetailsActivity.java | 3 +++ .../eu/siacs/conversations/ui/ConversationFragment.java | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java index cc716cea4..48abb03fe 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java @@ -436,6 +436,9 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers private void updateView() { invalidateOptionsMenu(); + if (mConversation == null) { + return; + } final MucOptions mucOptions = mConversation.getMucOptions(); final User self = mucOptions.getSelf(); String account; diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index da7793276..feefbd105 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -2606,7 +2606,12 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke service.sendChatState(conversation); } if (storeNextMessage()) { - runOnUiThread(() -> activity.onConversationsListItemUpdated()); + runOnUiThread(() -> { + if (activity == null) { + return; + } + activity.onConversationsListItemUpdated(); + }); } runOnUiThread(this::updateSendButton); } From 631d9c846f6383bd78d921676f2e453f1fbf35d8 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 22 May 2019 23:59:40 +0200 Subject: [PATCH 12/12] version bump to 2.5.2 --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index a191d6e8e..65410e1b0 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.4.0' + classpath 'com.android.tools.build:gradle:3.4.1' } } @@ -81,8 +81,8 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 28 - versionCode 327 - versionName "2.5.1" + versionCode 329 + versionName "2.5.2" archivesBaseName += "-$versionName" applicationId "eu.siacs.conversations" resValue "string", "applicationId", applicationId