Compare commits

...

19 Commits

Author SHA1 Message Date
adbenitez ad6f232d34 undo community hack 2025-04-27 02:11:35 +02:00
adbenitez efbe43ec70 Merge remote-tracking branch 'upstream/main' 2025-04-27 02:09:10 +02:00
B. Petersen 5e38b25c43 make 'microphone' hint fitting for desktop as well
i think, it is even an improvement for Android:
the hint is now also anchored by 'System Settings'
which is more in focus by casual users than 'App Settings' (long tap icon).
also, some android derivates may have different order,
which is captured better by a broader hint.
2025-04-26 17:33:06 +02:00
B. Petersen 6f3f356997 update CHANGELOG 2025-04-26 17:29:55 +02:00
B. Petersen d6f485511c fix selfName if displayname is not set
classic onboarding allows not setting a displayname on purpose,
however, that results in broken webxdc layouts
as the name is then replaced by a 40-or-so-chars-hash-without-spaces.

one can argue, that apps should handle that gracefully,
but most do not and just look buggy.

it seems reasonable,
to use the email address in that case,
same as we do at other places if the name is unknwon.
(tbh, i thought it was like that, but i mixed sth up in OS comparison).
this was also the situation before we changed selfAddr calculation, btw.
it is anyway a cornercase, webxdc cannot send the address somewhere
nor can correlate reasonably, and if the user sets a name, things are fine
(and more often than not we nudge user to set one :)
2025-04-26 17:29:55 +02:00
adb a527b2f404 Merge pull request #3747 from deltachat/prep-1.58.2
prepare 1.58.2
2025-04-24 12:46:41 +00:00
adbenitez 7c77b946ed update version number 2025-04-24 14:45:50 +02:00
adb ca77886012 Merge pull request #3746 from deltachat/update-core-and-stuff-24/4/25
Update core to 1.159.2
2025-04-24 12:42:17 +00:00
adbenitez fa5e305dff update local help 2025-04-24 14:31:01 +02:00
adbenitez 9e70bfb5ae update changelog: fix core version 2025-04-24 14:08:57 +02:00
adbenitez f4c7a9439d update strings 2025-04-24 13:47:09 +02:00
adbenitez 5d05e99ad6 update changelog 2025-04-24 13:45:32 +02:00
adbenitez 79bd1c7cb3 update deltachat-core-rust to 'chore(release): prepare for 1.159.2' of 'v1.159.2' 2025-04-24 13:42:04 +02:00
adb 848a86c718 Merge pull request #3745 from deltachat/adb/fix-warnings-in-profile
fix some linter warnings in classes related to profile
2025-04-23 14:05:43 +00:00
adb e759efc389 Merge pull request #3744 from deltachat/adb/fix-some-linter-warnings-22/4/25
fix some linter warnings
2025-04-22 22:11:40 +00:00
adb 63ea218b98 Merge pull request #3743 from deltachat/adb/fix-lint-warnings-conversationlistitem
fix linter warnings in ConversationListItem
2025-04-22 21:49:16 +00:00
adbenitez 07f4a859f3 fix some linter warnings in classes related to profile 2025-04-22 23:22:57 +02:00
adbenitez 34eeec4a39 fix some linter warnings 2025-04-22 23:02:57 +02:00
adbenitez 7f1734b57c fix linter warnings in ConversationListItem 2025-04-22 22:53:47 +02:00
38 changed files with 180 additions and 562 deletions
+10
View File
@@ -1,5 +1,15 @@
# Delta Chat Android Changelog
## Unreleased
* fix: webxdc.selfName uses the name otherwise displayed
## v1.58.2
2025-04
* fix draft writing area disappearing for some chats
* update to core 1.159.2
## v1.58.1
2025-04
-1
View File
@@ -15,7 +15,6 @@ This app has some extended support for WebXDC apps:
- `window.webxdc.arcanechat` a string with the ArcaneChat version and can be used by app developers
to detect when they can use the ArcaneChat-specific features.
- `window.webxdc.isCommunity` true if the current account is a community account
- `sendToChat()`: extra property `subject` can be set to a text string to set message/email's subject.
- `sendToChat()`: extra property `html` can be set to a string of html markup to set the HTML part of the email/message.
- `sendToChat()`: the file object parameter also accepts a `type` field that can be one of:
+2 -2
View File
@@ -33,8 +33,8 @@ android {
useLibrary 'org.apache.http.legacy'
defaultConfig {
versionCode 30000719
versionName "1.58.1"
versionCode 30000720
versionName "1.58.2"
applicationId "chat.delta.lite"
multiDexEnabled true
-5
View File
@@ -1373,11 +1373,6 @@ JNIEXPORT jint Java_com_b44t_messenger_DcMsg_getId(JNIEnv *env, jobject obj)
return dc_msg_get_id(get_dc_msg(env, obj));
}
JNIEXPORT jint Java_com_b44t_messenger_DcMsg_getSenderColor(JNIEnv *env, jobject obj)
{
return dc_msg_get_sender_color(get_dc_msg(env, obj));
}
JNIEXPORT jstring Java_com_b44t_messenger_DcMsg_getText(JNIEnv *env, jobject obj)
{
char* temp = dc_msg_get_text(get_dc_msg(env, obj));
+47 -75
View File
@@ -10,9 +10,9 @@
<li><a href="#хто-бачить-моє-зображення-профілю">Хто бачить моє зображення профілю?</a></li>
<li><a href="#signature">Чи можу я встановити текст підпису/статусу/девізу у Delta Chat?</a></li>
<li><a href="#що-значить-закріплення-приглушення-архівування">Що значить Закріплення, Приглушення, Архівування?</a></li>
<li><a href="#save">How do “Saved Messages” work?</a></li>
<li><a href="#save">Як працюють “Збережені повідомлення”?</a></li>
<li><a href="#що-означає-зелена-точка">Що означає зелена точка?</a></li>
<li><a href="#edit">Correct typos and delete messages after sending</a></li>
<li><a href="#edit">Виправлення помилок та видалення повідомлень після надсилання</a></li>
<li><a href="#ephemeralmsgs">Як працюють повідомлення, що зникають?</a></li>
</ul>
</li>
@@ -66,7 +66,7 @@
<li><a href="#чи-можна-використовувати-delta-chat-на-декількох-пристроях-одночасно">Чи можна використовувати Delta Chat на декількох пристроях одночасно?</a></li>
<li><a href="#вирішення-проблем">Вирішення проблем</a></li>
<li><a href="#backup">Ручне перенесення</a></li>
<li><a href="#is-deletion-pinning-archiving-saving-muting-etc-synced-to-all-devices">Is Deletion, Pinning, Archiving, Saving, Muting etc. synced to all devices?</a></li>
<li><a href="#чи-синхронізовані-видалення-закріплення-архівування-збереження-вимкнення-сповіщень-тощо-з-усіма-пристроями">Чи синхронізовані видалення, закріплення, архівування, збереження, вимкнення сповіщень тощо з усіма пристроями?</a></li>
<li><a href="#чи-планується-впровадження-веб-клієнта-delta-chat">Чи планується впровадження веб-клієнта Delta Chat?</a></li>
</ul>
</li>
@@ -83,7 +83,7 @@
<li><a href="#що-таке-списки-широкомовлення-та-як-ними-користуватися">Що таке списки широкомовлення та як ними користуватися?</a></li>
<li><a href="#як-я-можу-поділитися-своїм-місцезнаходженням-зі-своїми-співрозмовниками-в-чаті">Як я можу поділитися своїм місцезнаходженням зі своїми співрозмовниками в чаті?</a></li>
<li><a href="#чому-я-можу-вибрати-лише-стеження-за-папкою-deltachat">Чому я можу вибрати лише стеження за папкою DeltaChat?</a></li>
<li><a href="#як-я-можу-змінити-мій-обліковий-запис-на-іншу-адресу-електронної-пошти">Як я можу змінити мій обліковий запис на іншу адресу електронної пошти?</a></li>
<li><a href="#як-я-можу-використовувати-іншу-адресу-електронної-пошти-у-своєму-профілі">Як я можу використовувати іншу адресу електронної пошти у своєму профілі?</a></li>
</ul>
</li>
<li><a href="#інше">Інше</a>
@@ -119,7 +119,7 @@
<p>Delta Chat - це надійний, децентралізований та безпечний додаток для обміну повідомленнями, доступний для мобільних і десктопних платформ.</p>
<p>Delta Chat схожий на Whatsapp або Telegram, але ви також можете використовувати його як додаток електронної пошти. Ви можете анонімно зареєструватися на різних <a href="https://delta.chat/chatmail">сумісних chatmail-серверах</a> які є мінімальними поштовими серверами, оптимізованими для швидкої та безпечної роботи. Або ви можете використовувати класичні поштові сервери та існуючий обліковий запис електронної пошти в цьому випадку Delta Chat буде працювати як поштовий додаток.</p>
<p>Delta Chat схожий на Whatsapp або Telegram, але ви також можете використовувати його як додаток електронної пошти. Ви можете анонімно зареєструватися на різних <a href="https://delta.chat/chatmail">сумісних chatmail-серверах</a> які є мінімальними поштовими серверами, оптимізованими для швидкої та безпечної роботи. Або ви можете використовувати класичні поштові сервери та існуючий профіль електронної пошти в цьому випадку Delta Chat буде працювати як поштовий додаток.</p>
<p><img style="float:right; width:50%; max-width:360%; margin:1em;" src="../delta-what-optim.png" /></p>
@@ -283,37 +283,32 @@
<h3 id="save">
How do “Saved Messages” work? <a href="#save" class="anchor"></a>
Як працюють “Збережені повідомлення”? <a href="#save" class="anchor"></a>
</h3>
<p><strong>Saved Messages</strong> is a chat that you can use to easily remember and find messages.</p>
<p><strong>Збережені повідомлення</strong> - це чат, за допомогою якого ви можете легко запам’ятовувати та знаходити повідомлення.</p>
<ul>
<li>
<p>In any chat, long tap or right click a message and select <strong>Save</strong></p>
<p>У будь-якому чаті натисніть і утримуйте повідомлення або клацніть правою кнопкою миші та виберіть <strong>Зберегти</strong>.</p>
</li>
<li>
<p>Saved messages are marked by the symbol
<img style="vertical-align:middle; width:1.2em; margin:1px" src="../saved-icon.png" alt="Saved icon" />
next to the timestamp</p>
<p>Збережені повідомлення позначені символом <img style="vertical-align:middle; width:1.2em; margin:1px" src="../saved-icon.png" alt="Saved icon" /> поруч з міткою часу</p>
</li>
<li>
<p>Later, open the “Saved Messages” chat - and you will see the saved messages there.
By tapping <img style="vertical-align:middle; width:1.2em; margin:1px" src="../go-to-original.png" alt="Arrow-right icon" />,
you can go back to the original message in the original chat</p>
<p>Пізніше відкрийте чат “Збережені повідомлення” - і ви побачите там збережені повідомлення. Натиснувши <img style="vertical-align:middle; width:1.2em; margin:1px" src="../go-to-original.png" alt="Arrow-right icon" />, ви можете повернутися до початкового повідомлення в оригінальному чаті</p>
</li>
<li>
<p>Finally, you can also use “Save Messages” to take <strong>personal notes</strong> - open the chat, type something, add a photo or a voice message etc.</p>
<p>Нарешті, ви також можете використовувати “Зберегти повідомлення”, щоб робити <strong>особисті нотатки</strong> - відкрити чат, набрати щось, додати фотографію або голосове повідомлення тощо.</p>
</li>
<li>
<p>As “Saved Message” are synced, they can become very handy for transferring data between devices</p>
<p>Оскільки “Збережені повідомлення” синхронізуються, вони можуть стати дуже зручними для передачі даних між пристроями</p>
</li>
</ul>
<p>Messages stay saved even if they are edited or deleted -
may it be by <a href="#edit">sender</a>, by <a href="#delold">device cleanup</a> or by <a href="#ephemeralmsgs">disappearing messages of other chats</a>.</p>
<p>Повідомлення залишаються збереженими, навіть якщо вони були відредаговані або видалені - чи то через <a href="#edit">відправника</a>, чи то через <a href="#delold">очищення пристрою</a>, чи то через <a href="#ephemeralmsgs">зникнення повідомлень інших чатів</a>.</p>
<h3 id="що-означає-зелена-точка">
@@ -323,53 +318,40 @@ may it be by <a href="#edit">sender</a>, by <a href="#delold">device cleanup</a>
</h3>
<p>You can sometimes see a <strong>green dot</strong> <img style="vertical-align:middle; width:1.2em; margin:1px" src="../green-dot.png" alt="" />
next to the avatar of a contact.
It means they were <strong>recently seen</strong> in the last 10 minutes:</p>
<p>Іноді ви можете бачити <strong>зелену крапку</strong> <img style="vertical-align:middle; width:1.2em; margin:1px" src="../green-dot.png" alt="" /> поруч з аватаркою контакту. Це означає, що його <strong>недавно бачили</strong> протягом останніх 10 хвилин:</p>
<ul>
<li>either because they messaged you directly,</li>
<li>because they wrote something to a group you are both a member of,</li>
<li>because they sent you a read receipt for a message you wrote,</li>
<li>because they edit or delete a message in a chat shared with you,</li>
<li>or because they use an <a href="#webxdc">app</a> in a chat shared with you.</li>
<li>або тому, що вони написали вам безпосередньо,</li>
<li>тому що вони написали щось у групі, в якій ви обидва є учасниками,</li>
<li>тому що вони надіслали вам квитанцію про прочитання повідомлення, яке ви написали,</li>
<li>тому що вони відредагували або видалили повідомлення у спільному з вами чаті,</li>
<li>або тому, що вони використовують <a href="#webxdc">app</a> у спільному з вами чаті.</li>
</ul>
<p>So this is not a real time online status -
and if someone doesnt answer right away even though they seem to be online,
dont worry and give them some space :)</p>
<p>Отже, це не онлайн статус в реальному часі - і якщо хтось не відповідає одразу, хоча здається, що вони онлайн, не хвилюйтеся і дайте їм трохи часу :)</p>
<p>On the other hand, others will not always “see that you are online”.
If you have turned off read receipts,
they will not see the green dot
until one of the above conditions are met.</p>
<p>З іншого боку, інші не завжди “бачать, що ви онлайн”. Якщо ви вимкнули звіти про прочитання, вони не побачать зелену крапку доки не буде виконано одну з вищезазначених умов.</p>
<h3 id="edit">
Correct typos and delete messages after sending <a href="#edit" class="anchor"></a>
Виправлення помилок та видалення повідомлень після надсилання <a href="#edit" class="anchor"></a>
</h3>
<ul>
<li>
<p>You can edit the text of your messages after sending.
For that, long tap or right click the message and select <strong>Edit</strong>
or <img style="vertical-align:middle; width:1.2em; margin:1px" src="../edit-icon.png" alt="Edit icon" />.</p>
<p>Ви можете редагувати текст ваших повідомлень після відправлення. Для цього натисніть на повідомлення довгим натисканням або правою кнопкою миші і виберіть <strong>Редагувати</strong> або <img style="vertical-align:middle; width:1.2em; margin:1px" src="../edit-icon.png" alt="Edit icon" />.</p>
</li>
<li>
<p>If you have sent a message accidentally,
from the same menu, select <strong>Delete</strong> and then <strong>Delete for Everyone</strong>.</p>
<p>Якщо ви випадково надіслали повідомлення, в тому ж меню виберіть <strong>Видалити</strong>, а потім <strong>Видалити для всіх</strong>.</p>
</li>
</ul>
<p>While edited messages will have the word “Edited” next to the timestamp,
deleted messages will be removed without a marker in the chat.
Notifications are not sent and there is no time limit.</p>
<p>Відредаговані повідомлення матимуть позначку “Відредаговано” поруч з міткою часу, видалені повідомлення будуть видалені без позначки в чаті. Сповіщення не надсилаються і відсутнє часове обмеження.</p>
<p>Note, that the original message may still be received by chat members
who could have already replied, forwarded, saved, screenshotted or otherwise copied the message.</p>
<p>Зауважте, що початкове повідомлення все ще може бути отримане учасниками чату які могли вже відповісти, переслати, зберегти, зробити знімок екрану або іншим чином скопіювати повідомлення.</p>
<h3 id="ephemeralmsgs">
@@ -482,7 +464,7 @@ who could have already replied, forwarded, saved, screenshotted or otherwise cop
<p>Щоб увімкнути його, перейдіть до <strong>Видалити старі повідомлення → Видалити повідомлення з сервера</strong> в налаштуваннях «Чати та медіа». Ви можете встановити часові рамки між «Одразу» та «Через 1 рік». Усі електронні листи, отримані Delta Chat, будуть видалені з сервера після закінчення цього терміну.</p>
</li>
<li>
<p>Зауважте, що якщо ви використовуєте Delta Chat на кількох пристроях, вам слід залишити повідомлення на сервері, доки інший пристрій не зможе завантажити їх. У цьому випадку вам слід встановити для автоматичного видалення значення «через день» або щось подібне, залежно від того, як часто ви вмикаєте інший пристрій.</p>
<p>Зверніть увагу, що якщо ви використовуєте Delta Chat на декількох пристроях, вам потрібно залишити повідомлення на сервері з достатнім проміжком часу щоб інші пристрої також могли їх завантажити.</p>
</li>
</ul>
@@ -716,11 +698,11 @@ Autocrypt використовує обмежену і <a href="#openpgp-secure"
<p><strong>Ваш контакт використовує Delta Chat на другому пристрої (телефоні або ноутбуці)</strong>.</p>
<p>Якщо у них є інший пристрій із запущеним додатком Delta Chat, вони повинні видалити обліковий запис з нового пристрою і додати його <a href="#multiclient">як другий пристрій, як описано тут</a>. Як тільки вони напишуть вам повідомлення, попередження зникне і гарантоване шифрування буде встановлено на обох пристроях вашого контакту.</p>
<p>Якщо у них є інший пристрій із запущеним додатком Delta Chat, вони повинні видалити профіль з нового пристрою і додати його <a href="#multiclient">як другий пристрій, як описано тут</a>. Як тільки вони напишуть вам повідомлення, попередження зникне і гарантоване шифрування буде встановлено на обох пристроях вашого контакту.</p>
<p><strong>Ваш контакт перевстановив Delta Chat, використовуючи свій старий логін</strong></p>
<p>Якщо у них є <a href="#backup">файл резервної копії</a>, вони повинні видалити обліковий запис з нового пристрою і, замість цього, імпортувати файл резервної копії для відновлення свого облікового запису. Як тільки вони напишуть вам повідомлення, попередження зникне і гарантоване шифрування буде відновлено для цього контакту.</p>
<p>Якщо у них є <a href="#backup">файл резервної копії</a>, вони повинні видалити профіль з нового пристрою і, замість цього, імпортувати файл резервної копії для відновлення свого профілю. Як тільки вони напишуть вам повідомлення, попередження зникне і гарантоване шифрування буде відновлено для цього контакту.</p>
<p>Якщо у них немає резервної копії файлу, найкраще виконати <a href="#howtoe2ee">QR-сканування</a> з вашим співрозмовником, щоб відновити гарантоване кінцеве шифрування.</p>
@@ -834,7 +816,7 @@ Delta Chat скоріше використовує реалізацію OpenPGP
</h3>
<p>Як для захисту від поштових серверів, що збирають метадані, так і для захисту від загрози вилучення пристрою ми рекомендуємо використовувати оптимізований для Delta Chat <a href="https://delta.chat/serverguide">екземпляр поштового сервера</a> для створення псевдонімних тимчасових акаунтів за допомогою сканування QR-коду. Зверніть увагу, що додатки Delta Chat на всіх платформах підтримують кілька облікових записів тому ви можете легко використовувати “1-тижневі” або “1-місячні” акаунти поруч з вашим “основним” акаунтом знаючи, що всі дані тимчасових акаунтів разом з усіма метаданими будуть видалені. Більше того, якщо пристрій вилучається, то контакти, які використовують тимчасові електронні скриньки, не можуть бути легко ідентифіковані, на відміну від месенджерів, які розкривають телефонні номери в групах чату, які, в свою чергу, часто пов’язані з юридичними особами.</p>
<p>Як для захисту від поштових серверів, що збирають метадані а також для захисту від загрози вилучення пристрою ми рекомендуємо використовувати <a href="https://delta.chat/chatmail">chatmail-сервер</a> для створення псевдонімних тимчасових профілів за допомогою сканування QR-коду. Зверніть увагу, що додатки Delta Chat на всіх платформах підтримують кілька профілів тому ви можете легко використовувати ситуативні профілі поруч з вашим “основним” профілем знаючи, що всі їхні дані, разом з усіма метаданими, будуть видалені. Більше того, якщо пристрій вилучено, то контакти, які використовують тимчасові профілі не можна буде легко ідентифікувати, на відміну від месенджерів, які розкривають номери телефонів у групах чату, які, в свою чергу, часто пов’язані з юридичними особами.</p>
<h3 id="як-перевірити-інформацію-про-шифрування">
@@ -925,14 +907,11 @@ Delta Chat скоріше використовує реалізацію OpenPGP
</h3>
<p>No.</p>
<p>Ні.</p>
<p>Delta Chat generates secure OpenPGP keys according to the Autocrypt specification 1.1.
You can export your private key but you can not import additional private keys.</p>
<p>Delta Chat генерує безпечні ключі OpenPGP відповідно до специфікації Autocrypt 1.1. Ви можете експортувати свій приватний ключ, але не можете імпортувати додаткові приватні ключі.</p>
<p>In general, we do not recommend or offer users to perform manual key management.
We want to ensure that security audits can focus on a few proven cryptographic algorithms
instead of the full breadth of possible algorithms allowed with OpenPGP.</p>
<p>Загалом, ми не рекомендуємо і не пропонуємо користувачам керувати ключами вручну. Ми хочемо гарантувати, що аудит безпеки може зосередитися на декількох перевірених криптографічних алгоритмах а не на всій широті можливих алгоритмів, дозволених у OpenPGP.</p>
<h3 id="security-audits">
@@ -1038,8 +1017,7 @@ instead of the full breadth of possible algorithms allowed with OpenPGP.</p>
<p><strong>Гостьові мережі</strong> можуть не дозволяти пристроям зв’язуватися один з одним. Якщо можливо, використовуйте негостьову мережу.</p>
</li>
<li>
<p>If you still have troubles using the same network,
try to open <strong>Mobile Hotspot</strong> on one device and join that Wi-Fi from the other one</p>
<p>Якщо у вас все ще виникають проблеми з використанням однієї мережі, спробуйте відкрити <strong>Мобільну точку доступу</strong> на одному пристрої та приєднатися до цього Wi-Fi з іншого</p>
</li>
<li>
<p>Переконайтеся, що на цільовому пристрої <strong>достатньо пам’яті</strong></p>
@@ -1048,7 +1026,7 @@ try to open <strong>Mobile Hotspot</strong> on one device and join that Wi-Fi fr
<p>Якщо передача почалася, переконайтеся, що пристрої <strong>залишаються активними</strong> і не засинають. Не виходьте з Delta Chat. (ми докладаємо всіх зусиль, щоб програма працювала у фоновому режимі, але <a href="https://dontkillmyapp.com">системи, як правило, вбивають програми</a>, на жаль)</p>
</li>
<li>
<p>Delta Chat <strong>уже ввійшов</strong> на цільовому пристрої? Ви можете використовувати кілька облікових записів на одному пристрої, просто <a href="#multiple-accounts">додайте інший обліковий запис</a></p>
<p>Delta Chat <strong>вже зареєстрований</strong> на цільовому пристрої? Ви можете використовувати кілька профілів на одному пристрої, просто <a href="#multiple-accounts">додайте ще один профіль</a></p>
</li>
<li>
<p>Якщо у вас усе ще виникають проблеми або якщо ви <strong>не можете відсканувати QR-код</strong> спробуйте <strong>перенесення вручну</strong>, описане нижче</p>
@@ -1066,31 +1044,25 @@ try to open <strong>Mobile Hotspot</strong> on one device and join that Wi-Fi fr
<p>Цей спосіб рекомендований, лише якщо «Додати другий пристрій», як описано вище, не працює.</p>
<ul>
<li>На старому пристрої перейдіть до “Налаштування -&gt; Чати та медіа -&gt; Експортувати резервну копію”. Введіть свій PIN-код, графічний ключ або пароль розблокування екрана. Потім ви можете натиснути на “Почати Резервне копіювання”. Це збереже файл резервної копії на вашому пристрої. Тепер вам потрібно якось перенести його на інший пристрій.</li>
<li>На новому пристрої на екрані входу замість того, щоб увійти до свого облікового запису електронної пошти, виберіть “Імпортувати резервну копію” виберіть “Імпортувати резервну копію”. Після імпорту ваші листування, ключі шифрування ключі шифрування та медіа повинні бути скопійовані на новий пристрій.
<ul>
<li>Якщо ви користуєтеся iOS:** і у вас виникли труднощі, можливо <a href="https://support.delta.chat/t/import-backup-to-ios/1628">цей посібник</a> допоможе вам.</li>
</ul>
</li>
<li>Тепер ви синхронізовані і можете використовувати обидва пристрої для надсилання та отримання наскрізно зашифрованих повідомлень зі своїми партнерами по спілкуванню.</li>
<li>На старому пристрої перейдіть до “Налаштування -&gt; Чати та медіа -&gt; Експортувати резервну копію”. Введіть свій PIN-код, графічний ключ або пароль розблокування екрана. Потім ви можете натиснути на “Почати резервне копіювання”. Це збереже файл резервної копії на вашому пристрої. Тепер вам потрібно якось перенести його на інший пристрій.</li>
<li>На новому пристрої в меню “У мене вже є профіль” виберіть “Відновити з резервної копії”. Після імпорту ваші розмови, ключі шифрування ключі шифрування та медіа повинні бути скопійовані на новий пристрій.</li>
<li>Якщо ви користуєтеся iOS:** і у вас виникли труднощі, можливо <a href="https://support.delta.chat/t/import-backup-to-ios/1628">цей посібник</a> допоможе вам.</li>
<li>Тепер ви синхронізовані і можете використовувати обидва пристрої для надсилання та отримання наскрізних зашифрованих повідомлень зі своїми партнерами по спілкуванню.</li>
</ul>
<h3 id="is-deletion-pinning-archiving-saving-muting-etc-synced-to-all-devices">
<h3 id="чи-синхронізовані-видалення-закріплення-архівування-збереження-вимкнення-сповіщень-тощо-з-усіма-пристроями">
Is Deletion, Pinning, Archiving, Saving, Muting etc. synced to all devices? <a href="#is-deletion-pinning-archiving-saving-muting-etc-synced-to-all-devices" class="anchor"></a>
Чи синхронізовані видалення, закріплення, архівування, збереження, вимкнення сповіщень тощо з усіма пристроями? <a href="#чи-синхронізовані-видалення-закріплення-архівування-збереження-вимкнення-сповіщень-тощо-з-усіма-пристроями" class="anchor"></a>
</h3>
<p>Так.</p>
<p>If you e.g. delete a chat or a message from your phone,
it will be deleted on your desktop as soon as it comes online again.</p>
<p>Якщо ви, наприклад, видалите чат або повідомлення з телефону, воно буде видалено на вашому робочому столі, щойно ви знову з’явитесь в мережі.</p>
<p>Notable exceptions are <a href="#delold">Delete old messages from Device</a>,
as different devices may have different storage capacities,
and system specific settings as notification sounds.</p>
<p>Винятком є <a href="#delold">Видалення старих повідомлень з пристрою</a>, оскільки різні пристрої можуть мати різний обсяг пам’яті, а також системні налаштування звуків сповіщень.</p>
<h3 id="чи-планується-впровадження-веб-клієнта-delta-chat">
@@ -1240,17 +1212,17 @@ and system specific settings as notification sounds.</p>
<p>У цьому випадку Delta Chat не потрібно стежити за папкою «Вхідні», а достатньо лише стежити за папкою DeltaChat.</p>
<h3 id="як-я-можу-змінити-мій-обліковий-запис-на-іншу-адресу-електронної-пошти">
<h3 id="як-я-можу-використовувати-іншу-адресу-електронної-пошти-у-своєму-профілі">
Як я можу змінити мій обліковий запис на іншу адресу електронної пошти? <a href="#як-я-можу-змінити-мій-обліковий-запис-на-іншу-адресу-електронної-пошти" class="anchor"></a>
Як я можу використовувати іншу адресу електронної пошти у своєму профілі? <a href="#як-я-можу-використовувати-іншу-адресу-електронної-пошти-у-своєму-профілі" class="anchor"></a>
</h3>
<ol>
<li>
<p>Змініть свою адресу в розділі “Налаштування → Додатково → Пароль та обліковий запис” та введіть пароль вашого нового облікового запису (і, за необхідності, налаштування сервера). Ви отримаєте інформаційне повідомлення про те, що ви переїжджаєте на нову адресу. Додаткове повідомлення також з’явиться у вашому чаті “Повідомлення пристрою”.</p>
<p>Змініть свою адресу в розділі “Налаштування → Додатково → Пароль та обліковий запис” та введіть пароль вашого нового поштового акаунта (і, за необхідності, налаштування сервера). Ви отримаєте інформаційне повідомлення про те, що ви переїжджаєте на нову адресу. Додаткове повідомлення також з’явиться у вашому чаті “Повідомлення пристрою”.</p>
</li>
<li>
<p>Якщо можливо, нехай ваш старий провайдер електронної пошти пересилає всі повідомлення на вашу нову адресу.</p>
@@ -1543,7 +1515,7 @@ and system specific settings as notification sounds.</p>
завершення прив’язок Rust/Python та запуск екосистеми чат-ботів.</p>
</li>
<li>
<p>У 2021 році ми отримали подальше фінансування ЄС для двох Інтернет-технологій наступного покоління пропозиції, а саме для <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - каталог перенесення електронної пошти</a> (~97 тис. євро) та <a href="https://nlnet.nl/project/EmailPorting/">AEAP - перенесення електронної адреси</a> (~90 тис. євро), що призвело до кращої підтримки кількох облікових записів, покращеного QR-коду контактів і налаштувань груп, а також багатьох покращень роботи мережі на всіх платформах.</p>
<p>У 2021 році ми отримали подальше фінансування від ЄС на дві пропозиції щодо Інтернету наступного покоління а саме на <a href="https://dapsi.ngi.eu/hall-of-fame/eppd/">EPPD - каталог перенесення провайдерів електронної пошти</a> (~97 тис. євро) та <a href="https://nlnet.nl/project/EmailPorting/">AEAP - перенесення адрес електронної пошти</a> (~90 тис. євро), що дозволило нам покращити багатопрофільну підтримку, вдосконалити налаштування контактів та груп за допомогою QR-коду та багато інших мережевих покращень на всіх платформах.</p>
</li>
<li>
<p>З кінця 2021 до березня 2023 року ми отримували фінансування <em>Internet Freedom</em> (500 тис. дол. США) від Бюро США з питань демократії, прав людини та праці (DRL). Це фінансування підтримало наші довгострокові цілі зробити Delta Chat більш зручним для використання і сумісним з широким спектром серверів електронної пошти по всьому світу, більш стійким і безпечним в місцях, які постраждали від інтернет-цензури та відключення інтернету.</p>
@@ -245,23 +245,6 @@ public class DcContext {
return displayname;
}
public boolean isCommunity() {
return getConfigInt("is_community") == 1;
}
public void setCommunityMode(boolean enable) {
setConfig("is_community", enable? "1" : null);
}
public String getCommunityUser() {
String name = getConfig("ui.community.selfname");
return name == null? "" : name;
}
public void setCommunityUser(String name) {
setConfig("ui.community.selfname", name);
}
public boolean isChatmail() {
return getConfigInt("is_chatmail") == 1;
}
@@ -169,7 +169,6 @@ public class DcMsg {
public native String getQuotedText ();
public native String getError ();
public native String getOverrideSenderName();
public native int getSenderColor();
public native boolean isEdited ();
public String getSenderName(DcContact dcContact) {
@@ -336,7 +336,7 @@ public class ConversationFragment extends MessageSelectorFragment
menu.findItem(R.id.menu_context_reply).setVisible(chat.canSend() && canReply);
boolean canEdit = canEditMsg(messageRecord);
menu.findItem(R.id.menu_context_edit).setVisible(chat.canSend() && canEdit);
boolean showReplyPrivately = !dcContext.isCommunity() && chat.isMultiUser() && !messageRecord.isOutgoing() && canReply;
boolean showReplyPrivately = chat.isMultiUser() && !messageRecord.isOutgoing() && canReply;
menu.findItem(R.id.menu_context_reply_privately).setVisible(showReplyPrivately);
menu.findItem(R.id.menu_add_to_home_screen).setVisible(messageRecord.getType() == DcMsg.DC_MSG_WEBXDC);
@@ -801,9 +801,6 @@ public class ConversationFragment extends MessageSelectorFragment
list.getAdapter().notifyDataSetChanged();
actionMode = ((AppCompatActivity)getActivity()).startSupportActionMode(actionModeCallback);
if (dcContext.isCommunity()) return;
addReactionView.show(messageRecord, view, () -> {
if (actionMode != null) {
actionMode.finish();
@@ -178,7 +178,7 @@ public class ConversationItem extends BaseConversationItem
{
bind(messageRecord, dcChat, batchSelected, pulseHighlight, recipients);
this.glideRequests = glideRequests;
this.showSender = dcContext.isCommunity() || ((dcChat.isMultiUser() || dcChat.isSelfTalk()) && !messageRecord.isOutgoing()) || messageRecord.getOverrideSenderName() != null;
this.showSender = ((dcChat.isMultiUser() || dcChat.isSelfTalk()) && !messageRecord.isOutgoing()) || messageRecord.getOverrideSenderName() != null;
if (showSender) {
this.dcContact = dcContext.getContact(messageRecord.getFromId());
@@ -270,11 +270,10 @@ public class ConversationItem extends BaseConversationItem
R.attr.conversation_item_incoming_bubble_color,
R.attr.conversation_item_outgoing_bubble_color,
};
final TypedArray attrs = context.obtainStyledAttributes(attributes);
incomingBubbleColor = attrs.getColor(0, Color.WHITE);
outgoingBubbleColor = attrs.getColor(1, Color.WHITE);
attrs.recycle();
try (TypedArray attrs = context.obtainStyledAttributes(attributes)) {
incomingBubbleColor = attrs.getColor(0, Color.WHITE);
outgoingBubbleColor = attrs.getColor(1, Color.WHITE);
}
}
@Override
@@ -438,10 +437,10 @@ public class ConversationItem extends BaseConversationItem
showFullButton.setVisibility(View.GONE);
msgActionButton.setVisibility(View.VISIBLE);
msgActionButton.setEnabled(true);
msgActionButton.setText(webxdcViewStub.get().isCommunity()? R.string.join: R.string.start_app);
msgActionButton.setText(R.string.start_app);
msgActionButton.setOnClickListener(view -> {
if (batchSelected.isEmpty()) {
DcHelper.openWebxdc(getContext(), messageRecord);
WebxdcActivity.openWebxdcActivity(getContext(), messageRecord);
} else {
passthroughClickListener.onClick(view);
}
@@ -675,9 +674,7 @@ public class ConversationItem extends BaseConversationItem
if (!showSender || dcContact ==null) {
contactPhoto.setVisibility(View.GONE);
} else {
int color = messageRecord.getSenderColor();
Recipient recipient = new Recipient(context, dcContact, messageRecord.getSenderName(dcContact), color);
contactPhoto.setAvatar(glideRequests, recipient, true);
contactPhoto.setAvatar(glideRequests, new Recipient(context, dcContact), true);
contactPhoto.setVisibility(View.VISIBLE);
}
}
@@ -702,7 +699,7 @@ public class ConversationItem extends BaseConversationItem
Recipient author = null;
SlideDeck slideDeck = new SlideDeck();
if (msg != null) {
author = new Recipient(context, dcContext.getContact(msg.getFromId()), msg.getSenderColor());
author = new Recipient(context, dcContext.getContact(msg.getFromId()));
if (msg.getType() != DcMsg.DC_MSG_TEXT) {
Slide slide = MediaUtil.getSlideForMsg(context, msg);
if (slide != null) {
@@ -810,8 +807,7 @@ public class ConversationItem extends BaseConversationItem
}
else if (showSender && dcContact !=null) {
this.groupSender.setText(messageRecord.getSenderName(dcContact));
int color = messageRecord.getSenderColor();
this.groupSender.setTextColor(Util.rgbToArgbColor(color!=0? color : dcContact.getColor()));
this.groupSender.setTextColor(Util.rgbToArgbColor(dcContact.getColor()));
}
}
@@ -894,7 +890,7 @@ public class ConversationItem extends BaseConversationItem
if (shouldInterceptClicks(messageRecord) || !batchSelected.isEmpty()) {
performClick();
} else if (slide.isWebxdcDocument()) {
msgActionButton.performClick();
WebxdcActivity.openWebxdcActivity(context, messageRecord);
} else if (slide.isVcard()) {
try {
String path = slide.asAttachment().getRealPath(context);
@@ -904,7 +900,7 @@ public class ConversationItem extends BaseConversationItem
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
try {
List<Integer> contactIds = rpc.importVcard(dcContext.getAccountId(), path);
if (contactIds.size() > 0) {
if (!contactIds.isEmpty()) {
int chatId = dcContext.createChatByContactId(contactIds.get(0));
if (chatId != 0) {
Intent intent = new Intent(context, ConversationActivity.class);
@@ -64,11 +64,9 @@ public class ConversationListItem extends RelativeLayout
private final static Typeface BOLD_TYPEFACE = Typeface.create("sans-serif-medium", Typeface.NORMAL);
private final static Typeface LIGHT_TYPEFACE = Typeface.create("sans-serif", Typeface.NORMAL);
private DcLot dcSummary;
private Set<Long> selectedThreads;
private long chatId;
private int msgId;
private GlideRequests glideRequests;
private TextView subjectView;
private FromTextView fromView;
private TextView dateView;
@@ -122,12 +120,10 @@ public class ConversationListItem extends RelativeLayout
boolean batchMode,
@Nullable String highlightSubstring)
{
this.dcSummary = dcSummary;
this.selectedThreads = selectedThreads;
Recipient recipient = thread.getRecipient();
this.chatId = thread.getThreadId();
this.msgId = msgId;
this.glideRequests = glideRequests;
int state = dcSummary.getState();
int unreadCount = thread.getUnreadCount();
@@ -163,7 +159,7 @@ public class ConversationListItem extends RelativeLayout
this.avatar.setAvatar(glideRequests, recipient, false);
DcContact contact = recipient.getDcContact();
avatar.setSeenRecently(contact!=null? contact.wasSeenRecently() : false);
avatar.setSeenRecently(contact != null && contact.wasSeenRecently());
boolean isProtected = thread.isProtected() || DcHelper.getContext(getContext()).getChat((int)chatId).isDeviceTalk();
@@ -180,7 +176,6 @@ public class ConversationListItem extends RelativeLayout
{
this.selectedThreads = Collections.emptySet();
Recipient recipient = new Recipient(getContext(), contact);
this.glideRequests = glideRequests;
fromView.setText(getHighlightedSpan(contact.getDisplayName(), highlightSubstring));
fromView.setCompoundDrawablesWithIntrinsicBounds(0, 0, contact.isVerified()? R.drawable.ic_verified : 0, 0);
@@ -205,7 +200,6 @@ public class ConversationListItem extends RelativeLayout
DcContact sender = dcContext.getContact(messageResult.getFromId());
this.selectedThreads = Collections.emptySet();
Recipient recipient = new Recipient(getContext(), sender);
this.glideRequests = glideRequests;
fromView.setText(recipient, true);
fromView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
@@ -312,9 +306,9 @@ public class ConversationListItem extends RelativeLayout
if (thread!=null && thread.getVisibility()==DcChat.DC_CHAT_VISIBILITY_PINNED) {
bg = R.attr.pinned_list_item_background;
}
TypedArray ta = getContext().obtainStyledAttributes(new int[] { bg });
ViewUtil.setBackground(this, ta.getDrawable(0));
ta.recycle();
try (TypedArray ta = getContext().obtainStyledAttributes(new int[]{bg})) {
ViewUtil.setBackground(this, ta.getDrawable(0));
}
}
private Spanned getHighlightedSpan(@Nullable String value,
@@ -332,7 +326,10 @@ public class ConversationListItem extends RelativeLayout
String normalizedValue = value.toLowerCase(Util.getLocale());
String normalizedTest = highlight.toLowerCase(Util.getLocale());
List<String> testTokens = Stream.of(normalizedTest.split(" ")).filter(s -> s.trim().length() > 0).toList();
List<String> testTokens;
try (Stream<String> stream = Stream.of(normalizedTest.split(" "))) {
testTokens = stream.filter(s -> !s.trim().isEmpty()).toList();
}
Spannable spanned = new SpannableString(value);
int searchStartIndex = 0;
@@ -99,10 +99,7 @@ public class ConversationTitleView extends RelativeLayout {
}
} else if( dcChat.isMultiUser() ) {
if (!profileView) {
if (dcContext.isCommunity() && chatContacts.length == 1)
subtitleStr = context.getString(R.string.super_group);
else
subtitleStr = context.getResources().getQuantityString(R.plurals.n_members, chatContacts.length, chatContacts.length);
subtitleStr = context.getResources().getQuantityString(R.plurals.n_members, chatContacts.length, chatContacts.length);
}
} else if( chatContacts.length>=1 ) {
if( dcChat.isSelfTalk() ) {
@@ -60,7 +60,6 @@ public class CreateProfileActivity extends BaseActionBarActivity {
private InputAwareLayout container;
private ImageView avatar;
private EditText name;
private EditText overridenName;
private EditText statusView;
private boolean fromWelcome;
@@ -184,27 +183,14 @@ public class CreateProfileActivity extends BaseActionBarActivity {
TextView loginSuccessText = ViewUtil.findById(this, R.id.login_success_text);
this.avatar = ViewUtil.findById(this, R.id.avatar);
this.name = ViewUtil.findById(this, R.id.name_text);
this.overridenName = ViewUtil.findById(this, R.id.overriden_name);
this.container = ViewUtil.findById(this, R.id.container);
this.statusView = ViewUtil.findById(this, R.id.status_text);
if (fromWelcome) {
if (DcHelper.getContext(this).isCommunity()) {
ViewUtil.findById(this, R.id.community_user_container).setVisibility(View.VISIBLE);
loginSuccessText.setText(R.string.community_set_name_explain);
ViewUtil.findById(this, R.id.avatar_and_name).setVisibility(View.GONE);
} else {
loginSuccessText.setText(R.string.set_name_and_avatar_explain);
}
loginSuccessText.setText(R.string.set_name_and_avatar_explain);
ViewUtil.findById(this, R.id.status_text_layout).setVisibility(View.GONE);
ViewUtil.findById(this, R.id.information_label).setVisibility(View.GONE);
} else {
if (DcHelper.getContext(this).isCommunity()) {
ViewUtil.findById(this, R.id.community_user_container).setVisibility(View.VISIBLE);
ViewUtil.findById(this, R.id.information_label).setVisibility(View.GONE);
((TextInputLayout)ViewUtil.findById(this, R.id.name)).setHint(R.string.community);
((TextInputLayout)ViewUtil.findById(this, R.id.status_text_layout)).setHint(R.string.description);
}
loginSuccessText.setVisibility(View.GONE);
}
}
@@ -215,10 +201,6 @@ public class CreateProfileActivity extends BaseActionBarActivity {
name.setText(profileName);
name.setSelection(profileName.length(), profileName.length());
}
DcContext dcContext = DcHelper.getContext(this);
if (dcContext.isCommunity()) {
overridenName.setText(dcContext.getCommunityUser());
}
}
private void initializeProfileAvatar() {
@@ -245,22 +227,16 @@ public class CreateProfileActivity extends BaseActionBarActivity {
}
private void updateProfile() {
boolean isCommunity = DcHelper.getContext(this).isCommunity();
if (TextUtils.isEmpty(this.name.getText()) && !(isCommunity && fromWelcome)) {
if (TextUtils.isEmpty(this.name.getText())) {
Toast.makeText(this, R.string.please_enter_name, Toast.LENGTH_LONG).show();
return;
}
final String name = this.name.getText().toString();
final String ovName = this.overridenName.getText().toString().trim();
new AsyncTask<Void, Void, Boolean>() {
@Override
protected Boolean doInBackground(Void... params) {
Context context = CreateProfileActivity.this;
if (isCommunity) {
DcHelper.getContext(context).setCommunityUser(ovName);
}
DcHelper.set(context, DcHelper.CONFIG_DISPLAY_NAME, name);
setStatusText();
@@ -96,23 +96,25 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
setSupportActionBar(this.toolbar);
ActionBar supportActionBar = getSupportActionBar();
if (isGlobalProfile()) {
supportActionBar.setDisplayHomeAsUpEnabled(true);
supportActionBar.setHomeActionContentDescription(getString(R.string.back));
} else {
supportActionBar.setDisplayHomeAsUpEnabled(false);
supportActionBar.setCustomView(R.layout.conversation_title_view);
supportActionBar.setDisplayShowCustomEnabled(true);
supportActionBar.setDisplayShowTitleEnabled(false);
Toolbar parent = (Toolbar) supportActionBar.getCustomView().getParent();
parent.setPadding(0,0,0,0);
parent.setContentInsetsAbsolute(0,0);
if (supportActionBar != null) {
if (isGlobalProfile()) {
supportActionBar.setDisplayHomeAsUpEnabled(true);
supportActionBar.setHomeActionContentDescription(getString(R.string.back));
} else {
supportActionBar.setDisplayHomeAsUpEnabled(false);
supportActionBar.setCustomView(R.layout.conversation_title_view);
supportActionBar.setDisplayShowCustomEnabled(true);
supportActionBar.setDisplayShowTitleEnabled(false);
Toolbar parent = (Toolbar) supportActionBar.getCustomView().getParent();
parent.setPadding(0,0,0,0);
parent.setContentInsetsAbsolute(0,0);
titleView = (ConversationTitleView) supportActionBar.getCustomView();
titleView.setOnBackClickedListener(view -> onBackPressed());
titleView.setOnClickListener(view -> onEnlargeAvatar());
if (isContactProfile() && !isSelfProfile() && !chatIsDeviceTalk) {
titleView.registerForContextMenu(this);
titleView = (ConversationTitleView) supportActionBar.getCustomView();
titleView.setOnBackClickedListener(view -> onBackPressed());
titleView.setOnClickListener(view -> onEnlargeAvatar());
if (isContactProfile() && !isSelfProfile() && !chatIsDeviceTalk) {
titleView.registerForContextMenu(this);
}
}
}
@@ -304,7 +306,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
super.setPrimaryItem(container, position, object);
if (currentFragment != null && currentFragment != object) {
ActionMode action = null;
@@ -320,6 +322,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
currentFragment = object;
}
@NonNull
@Override
public Fragment getItem(int position) {
int tabId = tabs.get(position);
@@ -417,7 +420,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
// =========================================================================
@Override
public boolean onOptionsItemSelected(MenuItem item) {
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
super.onOptionsItemSelected(item);
int itemId = item.getItemId();
@@ -447,7 +450,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
}
@Override
public boolean onContextItemSelected(MenuItem item) {
public boolean onContextItemSelected(@NonNull MenuItem item) {
super.onContextItemSelected(item);
if (item.getItemId() == R.id.copy_addr_to_clipboard) {
onCopyAddrToClipboard();
@@ -460,7 +463,7 @@ public class ProfileActivity extends PassphraseRequiredActionBarActivity
setMuted(0);
}
else {
MuteDialog.show(this, duration -> setMuted(duration));
MuteDialog.show(this, this::setMuted);
}
}
@@ -179,7 +179,7 @@ public class ProfileDocumentsFragment
}
if (dcMsg.getType() == DcMsg.DC_MSG_WEBXDC) {
DcHelper.openWebxdc(context, dcMsg);
WebxdcActivity.openWebxdcActivity(context, dcMsg);
} else {
DcHelper.openForViewOrShare(getActivity(), dcMsg.getId(), Intent.ACTION_VIEW);
}
@@ -42,7 +42,6 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter
private final @NonNull ArrayList<ItemData> itemData = new ArrayList<>();
private int itemDataMemberCount;
private DcChatlist itemDataSharedChats;
private DcContact itemDataContact;
private String itemDataStatusText;
private boolean isMailingList;
private boolean isBroadcast;
@@ -116,8 +115,9 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter
}
}
@NonNull
@Override
public ProfileSettingsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
public ProfileSettingsAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == ItemData.CATEGORY_MEMBERS) {
final ContactSelectionListItem item = (ContactSelectionListItem)layoutInflater.inflate(R.layout.contact_selection_list_item, parent, false);
item.setNoHeaderPadding();
@@ -139,7 +139,7 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
ViewHolder holder = (ViewHolder) viewHolder;
if (holder.itemView instanceof ContactSelectionListItem) {
ContactSelectionListItem contactItem = (ContactSelectionListItem) holder.itemView;
@@ -280,23 +280,24 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter
itemData.clear();
itemDataMemberCount = 0;
itemDataSharedChats = null;
itemDataContact = null;
itemDataStatusText = "";
isMailingList = false;
isBroadcast = false;
if (memberList!=null) {
itemDataMemberCount = memberList.length;
if (dcChat.isBroadcast()) {
isBroadcast = true;
}
if (dcChat != null) {
if (dcChat.isBroadcast()) {
isBroadcast = true;
}
if (dcChat.isMailingList()) {
isMailingList = true;
} else if (dcChat.canSend()) {
itemData.add(new ItemData(ItemData.CATEGORY_MEMBERS, DcContact.DC_CONTACT_ID_ADD_MEMBER, 0));
if (!isBroadcast) {
itemData.add(new ItemData(ItemData.CATEGORY_MEMBERS, DcContact.DC_CONTACT_ID_QR_INVITE, 0));
if (dcChat.isMailingList()) {
isMailingList = true;
} else if (dcChat.canSend()) {
itemData.add(new ItemData(ItemData.CATEGORY_MEMBERS, DcContact.DC_CONTACT_ID_ADD_MEMBER, 0));
if (!isBroadcast) {
itemData.add(new ItemData(ItemData.CATEGORY_MEMBERS, DcContact.DC_CONTACT_ID_QR_INVITE, 0));
}
}
}
@@ -307,7 +308,6 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter
else if (sharedChats!=null && dcContact!=null) {
boolean chatIsDeviceTalk = dcChat != null && dcChat.isDeviceTalk();
itemDataContact = dcContact;
if (!chatIsDeviceTalk) {
int verifierId = dcContact.getVerifierId();
if (verifierId != 0) {
@@ -320,7 +320,7 @@ public class ProfileSettingsAdapter extends RecyclerView.Adapter
itemData.add(new ItemData(ItemData.CATEGORY_INFO, INFO_VERIFIED, verifiedInfo, 0, R.drawable.ic_verified));
}
long lastSeenTimestamp = (itemDataContact!=null? itemDataContact.getLastSeen() : 0);
long lastSeenTimestamp = dcContact.getLastSeen();
String lastSeenTxt;
if (lastSeenTimestamp == 0) {
lastSeenTxt = context.getString(R.string.last_seen_unknown);
@@ -47,7 +47,6 @@ public class ProfileSettingsFragment extends Fragment
private static final int REQUEST_CODE_PICK_CONTACT = 2;
private RecyclerView list;
private StickyHeaderDecoration listDecoration;
private ProfileSettingsAdapter adapter;
private ActionMode actionMode;
@@ -66,17 +65,17 @@ public class ProfileSettingsFragment extends Fragment
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
chatId = getArguments().getInt(CHAT_ID_EXTRA, -1);
chatId = getArguments() != null ? getArguments().getInt(CHAT_ID_EXTRA, -1) : -1;
contactId = getArguments().getInt(CONTACT_ID_EXTRA, -1);
dcContext = DcHelper.getContext(getContext());
dcContext = DcHelper.getContext(requireContext());
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.profile_settings_fragment, container, false);
adapter = new ProfileSettingsAdapter(getContext(), GlideApp.with(this), this);
adapter = new ProfileSettingsAdapter(requireContext(), GlideApp.with(this), this);
list = ViewUtil.findById(view, R.id.recycler_view);
RecyclerView list = ViewUtil.findById(view, R.id.recycler_view);
list.setAdapter(adapter);
list.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
listDecoration = new StickyHeaderDecoration(adapter, false, true);
@@ -84,7 +83,7 @@ public class ProfileSettingsFragment extends Fragment
update();
DcEventCenter eventCenter = DcHelper.getEventCenter(getContext());
DcEventCenter eventCenter = DcHelper.getEventCenter(requireContext());
eventCenter.addObserver(DcContext.DC_EVENT_CHAT_MODIFIED, this);
eventCenter.addObserver(DcContext.DC_EVENT_CONTACTS_CHANGED, this);
eventCenter.addObserver(DcContext.DC_EVENT_MSGS_CHANGED, this);
@@ -94,12 +93,12 @@ public class ProfileSettingsFragment extends Fragment
@Override
public void onDestroyView() {
DcHelper.getEventCenter(getContext()).removeObservers(this);
DcHelper.getEventCenter(requireContext()).removeObservers(this);
super.onDestroyView();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
listDecoration.onConfigurationChanged(newConfig);
}
@@ -148,7 +147,7 @@ public class ProfileSettingsFragment extends Fragment
@Override
public void onStatusLongClicked() {
Context context = getContext();
Context context = requireContext();
new AlertDialog.Builder(context)
.setTitle(R.string.pref_default_status_label)
.setItems(new CharSequence[]{
@@ -169,7 +168,7 @@ public class ProfileSettingsFragment extends Fragment
DcChat dcChat = dcContext.getChat(chatId);
if (dcChat.canSend()) {
adapter.toggleMemberSelection(contactId);
actionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(actionModeCallback);
actionMode = ((AppCompatActivity) requireActivity()).startSupportActionMode(actionModeCallback);
}
} else {
onMemberClicked(contactId);
@@ -225,8 +224,8 @@ public class ProfileSettingsFragment extends Fragment
public void onSharedChatClicked(int chatId) {
Intent intent = new Intent(getContext(), ConversationActivity.class);
intent.putExtra(ConversationActivity.CHAT_ID_EXTRA, chatId);
getContext().startActivity(intent);
getActivity().finish();
requireContext().startActivity(intent);
requireActivity().finish();
}
private void onVerifiedByClicked() {
@@ -245,8 +244,8 @@ public class ProfileSettingsFragment extends Fragment
if (chatId != 0) {
Intent intent = new Intent(getActivity(), ConversationActivity.class);
intent.putExtra(ConversationActivity.CHAT_ID_EXTRA, chatId);
getActivity().startActivity(intent);
getActivity().finish();
requireActivity().startActivity(intent);
requireActivity().finish();
}
}
@@ -266,7 +265,7 @@ public class ProfileSettingsFragment extends Fragment
menu.findItem(R.id.menu_select_all).setVisible(false);
mode.setTitle("1");
Window window = getActivity().getWindow();
Window window = requireActivity().getWindow();
originalStatusBarColor = window.getStatusBarColor();
window.setStatusBarColor(getResources().getColor(R.color.action_mode_status_bar));
return true;
@@ -289,7 +288,7 @@ public class ProfileSettingsFragment extends Fragment
readableToDelList.append(dcContext.getContact(toDelId).getDisplayName());
}
DcChat dcChat = dcContext.getChat(chatId);
AlertDialog dialog = new AlertDialog.Builder(getContext())
AlertDialog dialog = new AlertDialog.Builder(requireContext())
.setPositiveButton(R.string.remove_desktop, (d, which) -> {
for (Integer toDelId : toDelIds) {
dcContext.removeContactFromChat(chatId, toDelId);
@@ -309,7 +308,7 @@ public class ProfileSettingsFragment extends Fragment
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
adapter.clearSelection();
getActivity().getWindow().setStatusBarColor(originalStatusBarColor);
requireActivity().getWindow().setStatusBarColor(originalStatusBarColor);
}
}
@@ -519,11 +519,6 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
return BuildConfig.VERSION_NAME;
}
@JavascriptInterface
public boolean isCommunity() {
return dcContext.isCommunity();
}
@JavascriptInterface
public int sendUpdateMaxSize() {
return WebxdcActivity.this.sendUpdateMaxSize;
@@ -536,24 +531,13 @@ public class WebxdcActivity extends WebViewActivity implements DcEventCenter.DcE
@JavascriptInterface
public String selfAddr() {
if (dcContext.isCommunity() && !TextUtils.isEmpty(dcContext.getCommunityUser())) {
int flags = Base64.NO_WRAP | Base64.NO_PADDING | Base64.URL_SAFE;
return Base64.encodeToString(dcContext.getCommunityUser().getBytes(), flags);
}
return WebxdcActivity.this.selfAddr;
}
/** @noinspection unused*/
@JavascriptInterface
public String selfName() {
if (dcContext.isCommunity() && !TextUtils.isEmpty(dcContext.getCommunityUser())) {
return dcContext.getCommunityUser();
}
String name = WebxdcActivity.this.dcContext.getConfig("displayname");
if (TextUtils.isEmpty(name)) {
name = selfAddr();
}
return name;
return WebxdcActivity.this.dcContext.getName();
}
/** @noinspection unused*/
@@ -49,7 +49,6 @@ import java.io.OutputStream;
public class WelcomeActivity extends BaseActionBarActivity implements DcEventCenter.DcEventDelegate {
public static final String BACKUP_QR_EXTRA = "backup_qr_extra";
public static final String COMMUNITY_EXTRA = "community_extra";
public static final int PICK_BACKUP = 20574;
private final static String TAG = WelcomeActivity.class.getSimpleName();
public static final String TMP_BACKUP_FILE = "tmp-backup-file";
@@ -59,7 +58,6 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
private boolean imexUserAborted;
DcContext dcContext;
private NotificationController notificationController;
private Uri communityUri;
@Override
public void onCreate(Bundle bundle) {
@@ -120,10 +118,6 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
@Override
public void onStart() {
super.onStart();
communityUri = getIntent().getParcelableExtra(COMMUNITY_EXTRA);
if (communityUri != null) {
startImport(null, communityUri);
}
String backupQr = getIntent().getStringExtra(BACKUP_QR_EXTRA);
if (backupQr != null) {
getIntent().removeExtra(BACKUP_QR_EXTRA);
@@ -263,15 +257,9 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
private void progressSuccess() {
DcHelper.getEventCenter(this).endCaptureNextError();
progressDialog.dismiss();
if (dcContext.isCommunity()) {
Intent intent = new Intent(getApplicationContext(), CreateProfileActivity.class);
intent.putExtra(CreateProfileActivity.FROM_WELCOME, true);
startActivity(intent);
} else {
Intent intent = new Intent(getApplicationContext(), ConversationListActivity.class);
intent.putExtra(ConversationListActivity.FROM_WELCOME, true);
startActivity(intent);
}
Intent intent = new Intent(getApplicationContext(), ConversationListActivity.class);
intent.putExtra(ConversationListActivity.FROM_WELCOME, true);
startActivity(intent);
finish();
}
@@ -318,10 +306,6 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
notificationController.setProgress(1000, progress, String.format(" %d%%", (int) progress / 10));
}
else if (progress==1000/*done*/) {
if (communityUri != null) dcContext.setCommunityMode(true);
if (dcContext.isCommunity()) {
dcContext.setCommunityUser(null);
}
DcHelper.getAccounts(this).startIo();
progressSuccess();
notificationController.close();
@@ -87,12 +87,8 @@ public class AccountSelectionListItem extends LinearLayout {
}
addrOrTag = dcContext.getConfig(CONFIG_PRIVATE_TAG);
if ("".equals(addrOrTag)) {
if (dcContext.isCommunity()) {
addrOrTag = getContext().getString(R.string.community);
} else if (!dcContext.isChatmail()) {
addrOrTag = self.getAddr();
}
if ("".equals(addrOrTag) && !dcContext.isChatmail()) {
addrOrTag = self.getAddr();
}
unreadCount = dcContext.getFreshMsgs().length;
@@ -180,9 +180,8 @@ public class QuoteView extends FrameLayout implements RecipientForeverObserver {
authorView.setTextColor(getResources().getColor(R.color.core_dark_05));
quoteBarView.setBackgroundColor(getResources().getColor(R.color.core_dark_05));
} else {
int color = author.getColor()==0? contact.getColor() : author.getColor();
authorView.setTextColor(Util.rgbToArgbColor(color));
quoteBarView.setBackgroundColor(Util.rgbToArgbColor(color));
authorView.setTextColor(Util.rgbToArgbColor(contact.getColor()));
quoteBarView.setBackgroundColor(Util.rgbToArgbColor(contact.getColor()));
}
}
}
@@ -32,7 +32,6 @@ public class WebxdcView extends FrameLayout {
private final @NonNull TextView appSubtitle;
private @Nullable SlideClickListener viewListener;
private boolean isCommunity;
public WebxdcView(@NonNull Context context) {
this(context, null);
@@ -67,7 +66,6 @@ public class WebxdcView extends FrameLayout {
public void setWebxdc(final @NonNull DcMsg dcMsg, String defaultSummary)
{
JSONObject info = dcMsg.getWebxdcInfo();
isCommunity = JsonUtils.optBoolean(info, "community");
setOnClickListener(new OpenClickedListener(getContext(), dcMsg));
// icon
@@ -86,17 +84,13 @@ public class WebxdcView extends FrameLayout {
// subtitle
String summary = info.optString("summary");
if (summary.isEmpty()) {
summary = isCommunity? getContext().getString(R.string.community) : defaultSummary;
summary = defaultSummary;
}
appSubtitle.setText(summary);
}
public boolean isCommunity() {
return isCommunity;
}
public String getDescription() {
String type = getContext().getString(isCommunity? R.string.community : R.string.webxdc_app);
String type = getContext().getString( R.string.webxdc_app);
String desc = type;
desc += "\n" + appName.getText();
if (appSubtitle.getText() != null && !appSubtitle.getText().toString().isEmpty() && !appSubtitle.getText().toString().equals(type)) {
@@ -5,7 +5,6 @@ import static org.thoughtcrime.securesms.connect.DcHelper.CONFIG_VERIFIED_ONE_ON
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import androidx.annotation.Nullable;
@@ -22,7 +21,6 @@ import org.thoughtcrime.securesms.ConversationListActivity;
import org.thoughtcrime.securesms.InstantOnboardingActivity;
import org.thoughtcrime.securesms.WelcomeActivity;
import org.thoughtcrime.securesms.accounts.AccountSelectionListFragment;
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
import java.io.File;
@@ -127,10 +125,10 @@ public class AccountManager {
}
public void switchAccountAndStartActivity(Activity activity, int destAccountId) {
switchAccountAndStartActivity(activity, destAccountId, null, null);
switchAccountAndStartActivity(activity, destAccountId, null);
}
private void switchAccountAndStartActivity(Activity activity, int destAccountId, @Nullable String backupQr, @Nullable byte[] communityBlob) {
private void switchAccountAndStartActivity(Activity activity, int destAccountId, @Nullable String backupQr) {
if (destAccountId==0) {
beginAccountCreation(activity);
} else {
@@ -143,12 +141,6 @@ public class AccountManager {
if (backupQr != null) {
intent.putExtra(WelcomeActivity.BACKUP_QR_EXTRA, backupQr);
}
if (communityBlob != null) {
String mimeType = "application/octet-stream";
Uri uri = PersistentBlobProvider.getInstance().create(activity, communityBlob, mimeType, "backup.tar");
intent.setType(mimeType);
intent.putExtra(WelcomeActivity.COMMUNITY_EXTRA, uri);
}
activity.startActivity(intent);
} else {
activity.startActivity(new Intent(activity.getApplicationContext(), ConversationListActivity.class));
@@ -170,11 +162,7 @@ public class AccountManager {
activity.startActivity(intent);
}
public void addAccountFromCommunity(Activity activity, byte[] communityBlob) {
switchAccountAndStartActivity(activity, 0, null, communityBlob);
}
public void addAccountFromSecondDevice(Activity activity, String backupQr) {
switchAccountAndStartActivity(activity, 0, backupQr, null);
switchAccountAndStartActivity(activity, 0, backupQr);
}
}
@@ -24,21 +24,17 @@ import com.b44t.messenger.DcLot;
import com.b44t.messenger.DcMsg;
import com.b44t.messenger.rpc.Rpc;
import org.json.JSONObject;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.LocalHelpActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.ShareActivity;
import org.thoughtcrime.securesms.WebxdcActivity;
import org.thoughtcrime.securesms.database.model.ThreadRecord;
import org.thoughtcrime.securesms.notifications.NotificationCenter;
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
import org.thoughtcrime.securesms.qr.QrActivity;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.IntentUtils;
import org.thoughtcrime.securesms.util.FileUtils;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.MediaUtil;
import java.io.File;
@@ -506,28 +502,6 @@ public class DcHelper {
.show();
}
public static void openWebxdc(Context context, DcMsg dcMsg) {
JSONObject info = dcMsg.getWebxdcInfo();
if (JsonUtils.optBoolean(info, "community")) {
String name = JsonUtils.optString(info, "name");
new AlertDialog.Builder(context)
.setMessage(context.getString(R.string.ask_join_community, name))
.setPositiveButton(R.string.yes, (dialog, which) -> {
String filename = "backup.tar";
byte[] blob = dcMsg.getWebxdcBlob(filename);
if (blob == null) {
Toast.makeText(context, "invalid community file", Toast.LENGTH_SHORT).show();
return;
}
AccountManager.getInstance().addAccountFromCommunity((Activity) context, blob);
})
.setNegativeButton(R.string.no, null)
.show();
} else {
WebxdcActivity.openWebxdcActivity(context, dcMsg);
}
}
public static void openHelp(Context context, String section) {
Intent intent = new Intent(context, LocalHelpActivity.class);
if (section != null) { intent.putExtra(LocalHelpActivity.SECTION_EXTRA, section); }
@@ -49,6 +49,7 @@ import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.MediaPreviewActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.ShareLocationDialog;
import org.thoughtcrime.securesms.WebxdcActivity;
import org.thoughtcrime.securesms.WebxdcStoreActivity;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.UriAttachment;
@@ -313,7 +314,7 @@ public class AttachmentManager {
DcMsg instance = msg != null ? msg : DcHelper.getContext(context).getMsg(slide.dcMsgId);
webxdcView.setWebxdc(instance, context.getString(R.string.videochat_tap_to_open));
webxdcView.setWebxdcClickListener((v, s) -> {
DcHelper.openWebxdc(context, instance);
WebxdcActivity.openWebxdcActivity(context, instance);
});
removableMediaView.display(webxdcView, false);
} else {
@@ -154,10 +154,8 @@ public class PrivacyPreferenceFragment extends ListSummaryPreferenceFragment {
.setView(gl)
.setPositiveButton(android.R.string.ok, (dialog, whichButton) -> {
if (confirmCheckbox.isChecked()) {
if (!dcContext.isCommunity() || timeout >= 86400) {
dcContext.setConfigInt(coreKey, timeout);
initAutodelFromCore();
}
dcContext.setConfigInt(coreKey, timeout);
initAutodelFromCore();
} else {
onPreferenceChange(preference, newValue);
}
@@ -18,7 +18,6 @@ import androidx.appcompat.app.AlertDialog;
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
import org.thoughtcrime.securesms.BaseActionBarActivity;
import org.thoughtcrime.securesms.ConversationListActivity;
import org.thoughtcrime.securesms.CreateProfileActivity;
import org.thoughtcrime.securesms.LogViewActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.connect.DcHelper;
@@ -183,14 +182,7 @@ public class BackupTransferActivity extends BaseActionBarActivity {
notificationControllerClosed = true;
if (transferMode == TransferMode.RECEIVER_SCAN_QR && transferState == TransferState.TRANSFER_SUCCESS) {
if (DcHelper.getContext(this).isCommunity()) {
DcHelper.getContext(this).setCommunityUser(null);
Intent intent = new Intent(getApplicationContext(), CreateProfileActivity.class);
intent.putExtra(CreateProfileActivity.FROM_WELCOME, true);
startActivity(intent);
} else {
startActivity(new Intent(getApplicationContext(), ConversationListActivity.class));
}
startActivity(new Intent(getApplicationContext(), ConversationListActivity.class));
} else if (transferMode == TransferMode.SENDER_SHOW_QR) {
// restart the activities that were removed when BackupTransferActivity was started at (**2)
// (we removed the activity backstack as otherwise a tap on the ArcaneChat icon on the home screen would
@@ -66,7 +66,6 @@ public class Recipient {
private final @Nullable DcChat dcChat;
private @Nullable DcContact dcContact;
private int color = 0;
private final @Nullable VcardContact vContact;
public static @NonNull Recipient fromChat(@NonNull Context context, int dcMsgId) {
@@ -104,19 +103,10 @@ public class Recipient {
this(context, null, dcContact, null, null);
}
public Recipient(@NonNull Context context, @NonNull DcContact dcContact, int color) {
this(context, dcContact, null, color);
}
public Recipient(@NonNull Context context, @NonNull DcContact dcContact, @NonNull String profileName) {
this(context, null, dcContact, profileName, null);
}
public Recipient(@NonNull Context context, @NonNull DcContact dcContact, @NonNull String profileName, int color) {
this(context, null, dcContact, profileName, null);
this.color = color;
}
private Recipient(@NonNull Context context, @Nullable DcChat dcChat, @Nullable DcContact dcContact, @Nullable String profileName, @Nullable VcardContact vContact) {
this.dcChat = dcChat;
this.dcContact = dcContact;
@@ -205,9 +195,6 @@ public class Recipient {
if(dcChat!=null) {
rgb = dcChat.getColor();
}
else if(color!=0) {
rgb = color;
}
else if(dcContact!=null) {
rgb = dcContact.getColor();
}
@@ -233,10 +220,6 @@ public class Recipient {
}
public synchronized @Nullable ContactPhoto getContactPhoto(Context context) {
if (color != 0) { // community nick
return null;
}
LocalFileContactPhoto contactPhoto = null;
if (dcChat!=null) {
contactPhoto = new GroupRecordContactPhoto(context, address, dcChat);
@@ -315,11 +298,6 @@ public class Recipient {
return dcChat!=null? dcChat : new DcChat(0, 0);
}
public int getColor()
{
return color;
}
@NonNull
@Override
public String toString() {
@@ -47,7 +47,6 @@ public class SearchFragment extends BaseConversationListFragment
public static final String TAG = "SearchFragment";
private TextView noResultsView;
private RecyclerView listView;
private StickyHeaderDecoration listDecoration;
private SearchViewModel viewModel;
@@ -93,7 +92,7 @@ public class SearchFragment extends BaseConversationListFragment
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
noResultsView = view.findViewById(R.id.search_no_results);
listView = view.findViewById(R.id.search_list);
RecyclerView listView = view.findViewById(R.id.search_list);
fab = view.findViewById(R.id.fab);
listAdapter = new SearchListAdapter(getContext(), GlideApp.with(this), this);
@@ -1,146 +0,0 @@
package org.thoughtcrime.securesms.util;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import java.util.Iterator;
public abstract class BreakIteratorCompat implements Iterable<CharSequence> {
public static final int DONE = -1;
private CharSequence charSequence;
public abstract int first();
public abstract int next();
public void setText(CharSequence charSequence) {
this.charSequence = charSequence;
}
public static BreakIteratorCompat getInstance() {
if (Build.VERSION.SDK_INT >= 24) {
return new AndroidIcuBreakIterator();
} else {
return new FallbackBreakIterator();
}
}
public int countBreaks() {
int breakCount = 0;
first();
while (next() != DONE) {
breakCount++;
}
return breakCount;
}
@Override
public @NonNull Iterator<CharSequence> iterator() {
return new Iterator<CharSequence>() {
int index1 = BreakIteratorCompat.this.first();
int index2 = BreakIteratorCompat.this.next();
@Override
public boolean hasNext() {
return index2 != DONE;
}
@Override
public CharSequence next() {
CharSequence c = index2 != DONE ? charSequence.subSequence(index1, index2) : "";
index1 = index2;
index2 = BreakIteratorCompat.this.next();
return c;
}
};
}
/**
* Take {@param atMost} graphemes from the start of string.
*/
public final CharSequence take(int atMost) {
if (atMost <= 0) return "";
StringBuilder stringBuilder = new StringBuilder(charSequence.length());
int count = 0;
for (CharSequence grapheme : this) {
stringBuilder.append(grapheme);
count++;
if (count >= atMost) break;
}
return stringBuilder.toString();
}
/**
* An BreakIteratorCompat implementation that delegates calls to `android.icu.text.BreakIterator`.
* This class handles grapheme clusters fine but requires Android API >= 24.
*/
@RequiresApi(24)
private static class AndroidIcuBreakIterator extends BreakIteratorCompat {
private final android.icu.text.BreakIterator breakIterator = android.icu.text.BreakIterator.getCharacterInstance();
@Override
public int first() {
return breakIterator.first();
}
@Override
public int next() {
return breakIterator.next();
}
@Override
public void setText(CharSequence charSequence) {
super.setText(charSequence);
if (Build.VERSION.SDK_INT >= 29) {
breakIterator.setText(charSequence);
} else {
breakIterator.setText(charSequence.toString());
}
}
}
/**
* An BreakIteratorCompat implementation that delegates calls to `java.text.BreakIterator`.
* This class may or may not handle grapheme clusters well depending on the underlying implementation.
* In the emulator, API 23 implements ICU version of the BreakIterator so that it handles grapheme
* clusters fine. But API 21 implements RuleBasedIterator which does not handle grapheme clusters.
* <p>
* If it doesn't handle grapheme clusters correctly, in most cases the combined characters are
* broken up into pieces when the code tries to trim a string. For example, an emoji that is
* a combination of a person, gender and skin tone, trimming the character using this class may result
* in trimming the parts of the character, e.g. a dark skin frowning woman emoji may result in
* a neutral skin frowning woman emoji.
*/
private static class FallbackBreakIterator extends BreakIteratorCompat {
private final java.text.BreakIterator breakIterator = java.text.BreakIterator.getCharacterInstance();
@Override
public int first() {
return breakIterator.first();
}
@Override
public int next() {
return breakIterator.next();
}
@Override
public void setText(CharSequence charSequence) {
super.setText(charSequence);
breakIterator.setText(charSequence.toString());
}
}
}
@@ -1,15 +0,0 @@
package org.thoughtcrime.securesms.util;
import androidx.annotation.NonNull;
public final class StringUtil {
/**
* @return The number of graphemes in the provided string.
*/
public static int getGraphemeCount(@NonNull CharSequence text) {
BreakIteratorCompat iterator = BreakIteratorCompat.getInstance();
iterator.setText(text);
return iterator.countBreaks();
}
}
@@ -24,33 +24,7 @@
android:textSize="16sp"
android:textColor="?android:attr/textColorPrimary" />
<LinearLayout
android:id="@+id/community_user_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="40dp"
android:orientation="horizontal"
android:visibility="gone">
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp">
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/overriden_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/pref_your_name"
android:inputType="textCapWords" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
<LinearLayout android:id="@+id/avatar_and_name"
android:layout_width="match_parent"
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
+1 -1
View File
@@ -45,7 +45,7 @@ window.webxdc = (() => {
arcanechat: InternalJSApi.arcanechat(),
deltalab: InternalJSApi.arcanechat(),
isCommunity: InternalJSApi.isCommunity(),
isCommunity: false,
sendUpdateMaxSize: InternalJSApi.sendUpdateMaxSize(),
sendUpdateInterval: InternalJSApi.sendUpdateInterval(),
-3
View File
@@ -1,10 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<!-- custom strings -->
<string name="community">Comunidad</string>
<string name="description">Descripción</string>
<string name="ask_join_community">¿Quieres unirte a la comunidad \"%1$s\"?</string>
<string name="community_set_name_explain">Establece un nombre que otros puedan reconocer.</string>
<string name="or_separator">o</string>
<string name="online">en línea</string>
<string name="pink">Rosa</string>
+13 -13
View File
@@ -52,7 +52,7 @@
<string name="mute">Silenzia</string>
<string name="muted">Disattivato</string>
<string name="ephemeral_messages">Messaggi a Scomparsa</string>
<string name="ephemeral_messages_hint">Si applica a tutti i membri di questa chat se utilizzano Delta Chat; possono comunque copiare, salvare e inoltrare messaggi o utilizzare altri client e-mail.</string>
<string name="ephemeral_messages_hint">Si applica a tutti i membri di questa chat; possono comunque copiare, salvare e inoltrare i messaggi.</string>
<string name="save">Salva</string>
<string name="chat">Chat</string>
<string name="media">Media</string>
@@ -479,7 +479,7 @@
<!-- title shown above a list contacts where one should be selected (eg. when a webxdc attempts to send a message to a chat) -->
<string name="send_message_to">Invia Messaggio a...</string>
<string name="enable_realtime">Apps in Tempo Reale</string>
<string name="enable_realtime_explain">Abilitando connessioni in tempo reale per app condivise nelle chat. Se abilitato, i partner della chat potrebbero essere in grado di scoprire il tuo indirizzo IP quando avvii un\'app.</string>
<string name="enable_realtime_explain">Abilita connessioni in tempo reale per app condivise nelle chat. Se abilitato, i partner della chat potrebbero essere in grado di scoprire il tuo indirizzo IP quando avvii un\'app.</string>
<!-- map -->
<string name="filter_map_on_time">Mostra le posizioni nell\'intervallo di tempo</string>
@@ -661,7 +661,7 @@
<string name="proxy_share_link">Condividi Collegamento</string>
<string name="login_info_oauth2_title">Continuare con la configurazione semplificata?</string>
<string name="login_info_oauth2_text">L\'indirizzo e-mail inserito supporta una configurazione semplificata (OAuth 2.0).\n\nNel passaggio successivo, per piacere consenti a Delta Chat di fungere da app Chat tramite e-mail.\n\nDelta Chat non raccoglie dati utente, tutto rimane sul tuo dispositivo.</string>
<string name="login_info_oauth2_text">L\'indirizzo e-mail inserito supporta una configurazione semplificata (OAuth 2.0).\n\nNel passaggio successivo, per favore consenti a Delta Chat di inviare e ricevere messaggi.\n\nDelta Chat non raccoglie dati utente, tutto rimane sul tuo dispositivo.</string>
<string name="login_certificate_checks">Controlli Certificato</string>
<string name="login_error_mail">Per piacere Inserisci un indirizzo e-mail valido</string>
<string name="login_error_server">Per piacere inserisci un server / indirizzo IP valido</string>
@@ -671,7 +671,7 @@
<string name="import_backup_ask">Backup trovato in \"%1$s\".\n\nVuoi importarlo e usare tutti i dati e le impostazioni salvate?</string>
<string name="import_backup_no_backup_found">Nessun backup trovato\n\nCopia il backup in \"%1$s\" e riprova ancora. Altimenti premi \"Inizia a messaggiare\" per procedere con le impostazioni normali.</string>
<!-- %1$s will be replaced by the failing address -->
<string name="login_error_cannot_login">Impossibile accedere come \"%1$s\". Per piacere verifica che l\'indirizzo e-mail e la password siano corretti.</string>
<string name="login_error_cannot_login">Impossibile accedere come \"%1$s\". Per favore verifica che l\'indirizzo e-mail e la password siano corretti.</string>
<!-- TLS certificate checks -->
<string name="accept_invalid_certificates">Accetta certificati non validi</string>
<string name="switch_account">Cambia Profilo</string>
@@ -757,7 +757,7 @@
<string name="pref_use_system_emoji">Usa Emoji di Sistema</string>
<string name="pref_use_system_emoji_explain">Disattiva il supporto delle emoji integrato in Delta Chat</string>
<string name="pref_show_system_contacts">Leggi Rubrica di Sistema</string>
<string name="pref_show_system_contacts_explain">Offri la possibilità di creare chat con i contatti della rubrica. Alcuni provider necessitano prima della configurazione della crittografia end-to-end.</string>
<string name="pref_show_system_contacts_explain">Offri la possibilità di creare chat con i contatti della rubrica.</string>
<!-- deprecated -->
<string name="pref_app_access">Accesso App</string>
<string name="pref_chats">Chats</string>
@@ -858,9 +858,9 @@
<!-- %1$d will be replaced by the number of messages, you can assume plural/lots here. %2$s will be replaced by a timespan option. -->
<string name="autodel_device_ask">Vuoi eliminare %1$d messaggi ora e tutti i nuovi messaggi recuperati \"%2$s\" d\'ora in poi?\n\n• Questo include tutti i media\n\n• I messaggi verranno eliminati anche se non sono stati letti\n\n• I \"Messaggi salvati\" vengono preservati dalla cancellazione locale.</string>
<!-- %1$d will be replaced by the number of messages, you can assume plural/lots here. %2$s will be replaced by a timespan option. -->
<string name="autodel_server_ask">Vuoi eliminare %1$d messaggi ora e tutti i messaggi appena recuperati \"%2$s\" d\'ora in poi?\n\n⚠️ Ciò include e-mails, contenuti multimediali e \"Messaggi salvati\" in tutte le cartelle del server\n\n⚠️ Non utilizzare questa funzione se vuoi mantenere i dati sul server\n\n⚠️ Non utilizzare questa funzione se stai utilizzando altri client e-mail oltre a Delta Chat</string>
<string name="autodel_server_ask">Vuoi eliminare %1$d messaggi ora e tutti i messaggi non appena recuperati \"%2$s\" d\'ora in poi?\n\n⚠️ Ciò include e-mails, contenuti multimediali e \"Messaggi salvati\" in tutte le cartelle del server\n\n⚠️ Non utilizzare questa funzione se vuoi mantenere i dati sul server o se stai utilizzando anche altri client e-mail</string>
<!-- shown below enabled autodel_server-option, should be a summary of autodel_server_ask and remind about the impact -->
<string name="autodel_server_enabled_hint">Questo include e-mail, media e \"Messaggi salvati\" in tutte le cartelle del server. Non utilizzare questa funzione se desideri mantenere i dati sul server o se stai utilizzando altri client e-mail oltre a Delta Chat.</string>
<string name="autodel_server_enabled_hint">Questo include e-mail, media e \"Messaggi salvati\" in tutte le cartelle del server. Non utilizzare questa funzione se desideri mantenere i dati sul server o se stai utilizzando anche altri client e-mail</string>
<string name="autodel_server_warn_multi_device_title">Attiva l\'eliminazione immediata</string>
<string name="autodel_server_warn_multi_device">Se abiliti l\'eliminazione immediata non potrai utilizzare questo profilo su più dispositivi.</string>
<string name="autodel_confirm">Ho capito, elimina tutti questi messaggi</string>
@@ -878,7 +878,7 @@
<!-- autocrypt -->
<string name="autocrypt_send_asm_title">Invia Messaggio Configurazione Autocrypt</string>
<string name="autocrypt_send_asm_explain_before">Un Messaggio Configurazione Autocrypt condivide in modo sicuro la configurazione end-to-end con altre app compatibili con Autocrypt.\n\nLa configurazione verrà crittografata tramite un codice di configurazione visualizzato qui e dovrà essere digitato sull\'altro dispositivo.</string>
<string name="autocrypt_send_asm_explain_before">Un Messaggio Configurazione Autocrypt condivide in modo sicuro la configurazione end-to-end con altre app compatibili con Autocrypt.\n\nSe usi Delta Chat anche su altri dispositivi usa invece \"Impostazioni / Aggiungi Secondo Dispositivo\".</string>
<string name="autocrypt_send_asm_button">Invia Messaggio Configurazione Autocrypt</string>
<string name="autocrypt_send_asm_explain_after">La tua configurazione ti è stata inviata. Passa all\'altro dispositivo e apri il messaggio. Dovrebbe venirti richiesto un codice. Inserisci il seguente codice:</string>
<string name="autocrypt_prefer_e2ee">Preferisci Cifratura End-To-End</string>
@@ -958,7 +958,7 @@
<!-- this may be shown instead of the chat's input field, with buttons "More Info" and "OK" -->
<string name="chat_protection_broken">%1$s ha inviato un messaggio da un altro dispositivo.</string>
<string name="chat_protection_enabled_tap_to_learn_more">D\'ora in poi i messaggi saranno garantiti crittografati end-to-end. Tocca per saperne di più.</string>
<string name="chat_protection_enabled_explanation">Ora è garantito che tutti i messaggi in questa chat siano cifrati end-to-end.\n\nLa crittografia end-to-end mantiene i messaggi privati tra te e i tuoi partner di chat. Nemmeno il tuo provider email può leggerli.</string>
<string name="chat_protection_enabled_explanation">Ora è garantito che tutti i messaggi in questa chat siano cifrati end-to-end.\n\nLa crittografia end-to-end mantiene privati i messaggi tra te e i tuoi partner di chat. Nemmeno il server, il fornitore o il trasmettitore di e-mail può leggerli.</string>
<string name="chat_protection_broken_tap_to_learn_more">%1$s ha inviato un messaggio da un altro dispositivo. Tocca per saperne di più.</string>
<string name="chat_protection_broken_explanation">La crittografia end-to-end non può più essere garantita, probabilmente perché %1$s ha reinstallato Delta Chat o inviato un messaggio da un altro dispositivo.\n\nPuoi incontrarlo di persona e scansionare nuovamente il suo Codice QR per ristabilire la crittografia end-to-end garantita.</string>
<string name="invalid_unencrypted_tap_to_learn_more">⚠️ %1$s richiede la crittografia end-to-end che non è ancora configurata per questa chat. Tocca per saperne di più.</string>
@@ -984,7 +984,7 @@
<string name="qrscan_failed">Impossibile decodificare il codice QR</string>
<string name="qrscan_ask_join_group">Vuoi entrare nel gruppo \"%1$s\"?</string>
<string name="qrscan_fingerprint_mismatch">L\'impronta digitale scansionata non corrisponde all\'ultima visualizzata per %1$s.</string>
<string name="qrscan_no_addr_found">Questo codice QR contiene un\'impronta digitale, ma non un indirizzo email.\n\nPer una verifica a due fattori efficace, per piacere prima stabilisci una connessione cifrata col destinatario.</string>
<string name="qrscan_no_addr_found">Questo codice QR contiene un\'impronta ma non un indirizzo email.\n\nPer una verifica efficace, per favore prima stabilisci una connessione cifrata col destinatario.</string>
<string name="qrscan_contains_text">Testo codice QR scansionato:\n\n%1$s</string>
<string name="qrscan_contains_url">URL del codice QR scansionato:\n\n%1$s</string>
<string name="qrscan_fingerprint_label">Impronta digitale</string>
@@ -1021,7 +1021,7 @@
<string name="secure_join_wait">Creazione della crittografia end-to-end garantita, per piacere attendere...</string>
<!-- deprecated -->
<string name="secure_join_wait_timeout">Non è ancora possibile stabilire la crittografia end-to-end garantita, ma potresti già inviare un messaggio.</string>
<string name="secure_join_takes_longer">Sembra metterci molto, forse tu o il contatto non siete in linea.\n\nComunque, il processo continua in sottofondo, puoi fare qualcos\'altro...</string>
<string name="secure_join_takes_longer">Il contatto deve essere in linea per proseguire.\n\nQuesto processo continuerà automaticamente in sottofondo.</string>
<string name="contact_verified">%1$s verificato.</string>
<string name="contact_not_verified">Impossibile stabilire una crittografia end-to-end garantita con %1$s.</string>
<!-- Shown in contact profile. The placeholder will be replaced by the name of the contact that introduced the contact. -->
@@ -1181,7 +1181,7 @@
<string name="add_to_widget">Aggiungi al Widget</string>
<!-- iOS permissions, copy from "deltachat-ios/Info.plist", which is used on missing translations in "deltachat-ios/LANG.lproj/InfoPlist.strings" -->
<string name="InfoPlist_NSCameraUsageDescription">Delta Chat utilizza la tua fotocamera per scattare e inviare foto e video e per scansionare i codici QR.</string>
<string name="InfoPlist_NSContactsUsageDescription">Delta Chat usa i tuoi contatti per mostrare una lista di indirizzi e-mail a cui puoi scrivere. Delta Chat non ha un server, i tuoi contatti non vengono inviati da nessuna parte.</string>
<string name="InfoPlist_NSContactsUsageDescription">Delta Chat usa i tuoi contatti per mostrare una lista di indirizzi e-mail a cui puoi scrivere. Delta Chat non ha alcun server, i tuoi contatti non vengono inviati da nessuna parte.</string>
<string name="InfoPlist_NSLocationAlwaysAndWhenInUseUsageDescription">Delta Chat necessita dell\'autorizzazione per condividere la tua posizione per il periodo di tempo in cui hai abilitato la condivisione della posizione.</string>
<string name="InfoPlist_NSLocationWhenInUseUsageDescription">Delta Chat ha bisogno dell\'autorizzazione di localizzazione per condividere la vostra posizione per il periodo di tempo in cui avete abilitato la condivisione della posizione.</string>
<string name="InfoPlist_NSMicrophoneUsageDescription">Delta Chat utilizza il tuo microfono per registrare e inviare messaggi vocali e video con audio.</string>
@@ -1197,7 +1197,7 @@
<string name="pref_reliable_service">Forza Connessione Secondo Piano</string>
<string name="pref_reliable_service_explain">Provoca una notifica permanente</string>
<string name="pref_background_notifications_rationale">Per mantenere la connessione al tuo server e-mail e ricevere messaggi in secondo piano, ignora le ottimizzazioni della batteria nel passaggio successivo.\n\nDelta Chat utilizza poche risorse e fa attenzione a non consumare la tua batteria.</string>
<string name="pref_background_notifications_rationale">Per mantenere la connessione in sottofondo e ricevere messaggi, ignora le ottimizzazioni della batteria nel prossimo passaggio.\n\nDelta Chat utilizza poche risorse e fa in modo di non prosciugarti la batteria.</string>
<!-- disabling "Reliable service" will hide a the maybe annoying permanent-notification with the drawback that new-message-notifications get potentially unreliable -->
<string name="perm_enable_bg_reminder_title">Tocca qui per ricevere messaggi mentre Delta Chat è in secondo piano.</string>
<string name="perm_enable_bg_already_done">Hai già autorizzato Delta Chat a ricevere messaggi in secondo piano.\n\nSe i messaggi non arrivano in secondo piano, per piacere controlla anche le impostazioni di sistema.</string>
+2 -2
View File
@@ -861,7 +861,7 @@
<!-- autocrypt -->
<string name="autocrypt_send_asm_title">Autocrypt Ayarlama İletisi Gönder</string>
<string name="autocrypt_send_asm_explain_before">Bir Autocrypt Ayarlama İletisi, uçtan uca ayarlamanızı diğer Autocrypt uyumlu uygulamalarla güvenli olarak paylaşır.\n\nAyarlama, burada görüntülenen ve diğer aygıtta yazılması gereken bir ayarlama kodu tarafından şifrelenecek.</string>
<string name="autocrypt_send_asm_explain_before">Bir Autocrypt Ayarlama İletisi, uçtan uca ayarlamanızı diğer Autocrypt uyumlu uygulamalarla güvenli olarak paylaşır.\n\nDelta Chat\'i diğer aygıtta da kullanmak istiyorsanız, bunun yerine “Ayarlar / İkinci Aygıt Ekle”yi kullanın.</string>
<string name="autocrypt_send_asm_button">Autocrypt Ayarlama İletisi Gönder</string>
<string name="autocrypt_send_asm_explain_after">Ayarlamanız kendinize gönderildi. Diğer aygıta geçin ve ayarlama iletisini açın. Size bir ayarlama kodu sorulmalı. Aşağıdaki sayıları girin:</string>
<string name="autocrypt_prefer_e2ee">Uçtan Uca Şifrelemeyi Yeğle</string>
@@ -1004,7 +1004,7 @@
<string name="secure_join_wait">Güvencelenen uçtan uca şifreleme kuruluyor, lütfen bekleyin…</string>
<!-- deprecated -->
<string name="secure_join_wait_timeout">Henüz güvencelenen uçtan uca şifreleme kurulamadı; ama zaten bir ileti gönderebilirsiniz.</string>
<string name="secure_join_takes_longer">Bu daha uzun sürüyor gibi görünüyor, belki kişi ya da siz çevrimdışısınız.\n\nAncak işlem arka planda sürüyor, başka bir şey yapabilirsiniz…</string>
<string name="secure_join_takes_longer">Sürdürmek için kişi çevrimiçi olmalıdır.\n\nBu işlem, arka planda otomatik olarak sürecek.</string>
<string name="contact_verified">%1$s tanıtıldı.</string>
<string name="contact_not_verified">%1$s ile güvencelenen uçtan uca şifreleme kurulamıyor.</string>
<!-- Shown in contact profile. The placeholder will be replaced by the name of the contact that introduced the contact. -->
+3 -3
View File
@@ -690,7 +690,7 @@
<!-- TLS certificate checks -->
<string name="accept_invalid_certificates">Приймати недійсні сертифікати</string>
<string name="switch_account">Перемкнути профіль</string>
<string name="add_account">Додати обліковий запис</string>
<string name="add_account">Додати профіль</string>
<!-- for translations, you can also think of "Profile Tag" or "Profile Description" as the source string -->
<string name="profile_tag">Опис профілю</string>
<string name="profile_tag_hint">наприклад \"Робота\", \"Сім\'я\"</string>
@@ -701,7 +701,7 @@
<string name="delete_account_ask">Ви впевнені, що хочете видалити дані вашого профілю?</string>
<string name="delete_account_explain_with_name">Дані профілю \"%s\" на цьому пристрої будуть видалені, включаючи налаштування наскрізного шифрування, контакти, чати, повідомлення та медіа. Ця дія не може бути скасована.</string>
<string name="unconfigured_account">Неналаштований профіль</string>
<string name="unconfigured_account_hint">Відкрити обліковий запис для налаштування.</string>
<string name="unconfigured_account_hint">Відкрити профіль для налаштування.</string>
<string name="try_connect_now">Спробувати підключитися негайно</string>
<string name="sync_all">Синхронізувати все</string>
<!-- Translations: %1$s will be replaced by a more detailed error message -->
@@ -893,7 +893,7 @@
<!-- autocrypt -->
<string name="autocrypt_send_asm_title">Надіслати повідомлення з налаштуваннями Autocrypt</string>
<string name="autocrypt_send_asm_explain_before">Повідомлення з налаштуваннямм Autocrypt слугує безпечній передачі параметрів наскрізного шифрування між власними додатками для роботи з електронною поштою, що підтримують протокол Autocrypt.\n\nЦі параметри шифруються з використанням спеціального інсталяційного коду, що показаний тут і має бути введений на іншому пристрої.</string>
<string name="autocrypt_send_asm_explain_before">Повідомлення про налаштування Autocrypt безпечно передає ваші налаштування наскрізного шифрування іншим програмам, що підтримують Autocrypt.\n\nЯкщо ви використовуєте Delta Chat і на іншому пристрої, скористайтеся \"Налаштування / Додати другий пристрій\" замість цього.</string>
<string name="autocrypt_send_asm_button">Надіслати повідомлення з налаштуваннями Autocrypt</string>
<string name="autocrypt_send_asm_explain_after">Налаштування було Вам надіслано. Перейдіть на інший пристрій і відкрийте повідомлення про налаштування. У Вас має з\'явитися запит на введення коду налаштування. Введіть наступні цифри:</string>
<string name="autocrypt_prefer_e2ee">Віддавати перевагу наскрізному шифруванню</string>
+2 -4
View File
@@ -1,10 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<!-- custom strings -->
<string name="community">Community</string>
<string name="description">Description</string>
<string name="ask_join_community">Do you want to join the Community \"%1$s\"?</string>
<string name="community_set_name_explain">Set a name that other will recognize.</string>
<string name="could_not_open_file">Could not open file</string>
<string name="menu_export_image">Export Image</string>
<!-- the word "or" to separate blocks in the user interface that are mutually exclusive -->
@@ -1060,7 +1057,8 @@
<string name="perm_required_title">Permission required</string>
<string name="perm_continue">Continue</string>
<string name="perm_explain_access_to_camera_denied">To take photos or capture videos, go to the app settings, select \"Permissions\", and enable \"Camera\".</string>
<string name="perm_explain_access_to_mic_denied">To send audio messages, go to the app settings, select \"Permissions\", and enable \"Microphone\".</string>
<!-- give the user an idea where to find the "Microphone" option. the hint is only shown if access was initially denied by the user. pick up wordings really used on the systems, but do not be overly precise: things shift around often and there are too many system we support to track every detail and click path -->
<string name="perm_explain_access_to_mic_denied">To send audio messages, go to system or app settings, select "Permissions" or "Privacy &amp; Security", and enable \"Microphone\".</string>
<string name="perm_explain_access_to_storage_denied">To receive or send files, go to the app settings, select \"Permissions\", and enable \"Storage\".</string>
<string name="perm_explain_access_to_location_denied">To attach a location, go to the app settings, select \"Permissions\", and enable \"Location\".</string>
<string name="perm_explain_access_to_notifications_denied">To receive notifications, go to \"System Settings / Apps / Delta Chat\" and enable \"Notifications\".</string>