mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Merge remote-tracking branch 'upstream/master' into lite
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
[submodule "jni/deltachat-core-rust"]
|
||||
path = jni/deltachat-core-rust
|
||||
url = https://github.com/adbenitez/deltalab-core
|
||||
|
||||
@@ -277,6 +277,11 @@
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".FullMsgActivity"
|
||||
android:theme="@style/TextSecure.LightTheme"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize">
|
||||
</activity>
|
||||
|
||||
<activity android:name=".map.MapActivity" />
|
||||
|
||||
<service android:name=".connect.KeepAliveService" android:enabled="true" />
|
||||
|
||||
@@ -506,6 +506,15 @@ JNIEXPORT jstring Java_com_b44t_messenger_DcContext_getMsgInfo(JNIEnv *env, jobj
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_DcContext_getMsgHtml(JNIEnv *env, jobject obj, jint msg_id)
|
||||
{
|
||||
char* temp = dc_get_msg_html(get_dc_context(env, obj), msg_id);
|
||||
jstring ret = JSTRING_NEW(temp);
|
||||
dc_str_unref(temp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_DcContext_deleteMsgs(JNIEnv *env, jobject obj, jintArray msg_ids)
|
||||
{
|
||||
int msg_ids_cnt = 0;
|
||||
@@ -1337,6 +1346,12 @@ JNIEXPORT jboolean Java_com_b44t_messenger_DcMsg_isSetupMessage(JNIEnv *env, job
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jboolean Java_com_b44t_messenger_DcMsg_hasHtml(JNIEnv *env, jobject obj)
|
||||
{
|
||||
return dc_msg_has_html(get_dc_msg(env, obj))!=0;
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jstring Java_com_b44t_messenger_DcMsg_getSetupCodeBegin(JNIEnv *env, jobject obj)
|
||||
{
|
||||
char* temp = dc_msg_get_setupcodebegin(get_dc_msg(env, obj));
|
||||
|
||||
Submodule jni/deltachat-core-rust deleted from 724ef8a395
@@ -151,6 +151,23 @@
|
||||
app:scaleEmojis="true"
|
||||
tools:text="Mango pickle lorem ipsum"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/show_full_message"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="28dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp"
|
||||
android:background="@drawable/conversation_item_update_background"
|
||||
android:minWidth="20dp"
|
||||
android:text="@string/show_full_message"
|
||||
android:textAllCaps="false"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ConversationItemFooter
|
||||
android:id="@+id/conversation_item_footer"
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -129,10 +129,22 @@
|
||||
app:scaleEmojis="true"
|
||||
tools:text="Mango pickle lorem ipsum"/>
|
||||
|
||||
<TextView
|
||||
<Button
|
||||
android:id="@+id/show_full_message"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone" />
|
||||
android:layout_height="28dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingRight="12dp"
|
||||
android:background="@drawable/conversation_item_update_background"
|
||||
android:minWidth="20dp"
|
||||
android:text="@string/show_full_message"
|
||||
android:textAllCaps="false"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ConversationItemFooter
|
||||
android:id="@+id/conversation_item_footer"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item android:title="@string/load_remote_content"
|
||||
android:id="@+id/load_remote_content" />
|
||||
|
||||
</menu>
|
||||
+1
-23
@@ -2,28 +2,6 @@
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item android:title="@string/search"
|
||||
android:id="@+id/menu_search_localhelp"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:showAsAction="collapseActionView|never" />
|
||||
|
||||
<item android:title="0/0"
|
||||
android:id="@+id/menu_search_counter"
|
||||
android:visible="false"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item android:title="@string/back"
|
||||
android:id="@+id/menu_search_up"
|
||||
android:icon="@drawable/ic_search_up"
|
||||
android:visible="false"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item android:title="@string/next"
|
||||
android:id="@+id/menu_search_down"
|
||||
android:icon="@drawable/ic_search_down"
|
||||
android:visible="false"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item android:title="@string/menu_scroll_to_top"
|
||||
android:id="@+id/log_scroll_up" />
|
||||
|
||||
@@ -39,4 +17,4 @@
|
||||
android:id="@+id/report_issue"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
</menu>
|
||||
</menu>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item android:title="@string/search"
|
||||
android:id="@+id/menu_search_web_view"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:showAsAction="collapseActionView|never" />
|
||||
|
||||
<item android:title="0/0"
|
||||
android:id="@+id/menu_search_counter"
|
||||
android:visible="false"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item android:title="@string/back"
|
||||
android:id="@+id/menu_search_up"
|
||||
android:icon="@drawable/ic_search_up"
|
||||
android:visible="false"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item android:title="@string/next"
|
||||
android:id="@+id/menu_search_down"
|
||||
android:icon="@drawable/ic_search_down"
|
||||
android:visible="false"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
</menu>
|
||||
@@ -187,6 +187,7 @@
|
||||
<string name="menu_scroll_to_top">Rul til toppen</string>
|
||||
<string name="menu_help">Hjælp</string>
|
||||
<string name="menu_select_all">Vælg alle</string>
|
||||
<string name="select_more">Vælg flere</string>
|
||||
<string name="menu_expand">Udvid</string>
|
||||
<string name="menu_edit_name">Rediger navn</string>
|
||||
<string name="menu_settings">Opsætning</string>
|
||||
@@ -600,7 +601,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Tidsudløb for beskeder sat til 1 dag.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Tidsudløb for beskeder sat til 1 uge.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Tidsudløb for beskeder sat til 4 uger.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Chat-beskyttelse slået fra.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Chat-beskyttelse sluttet til.</string>
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
<string name="profile">Profil</string>
|
||||
<string name="main_menu">Hauptmenü</string>
|
||||
<string name="start_chat">Chat starten</string>
|
||||
<string name="show_full_message">Ganze Nachricht anzeigen…</string>
|
||||
<string name="load_remote_content">Bilder nachladen</string>
|
||||
<!-- possible answers to the question are: Never, Always, Once -->
|
||||
<string name="load_remote_content_ask">Das Nachladen von Bildern kann dazu verwendet werden, Sie zu tracken.\n\nDie Option erlaubt auch das Laden von Schriftarten und anderen Inhalten; wenn sie deaktiviert ist, werden eingebettete oder zwischengespeicherte Bilder dennoch angezeigt.\n\nBilder nachladen?</string>
|
||||
<string name="always">Immer</string>
|
||||
<string name="once">Einmal</string>
|
||||
<string name="show_password">Passwort anzeigen</string>
|
||||
<string name="hide_password">Passwort verstecken</string>
|
||||
<string name="not_now">Nicht jetzt</string>
|
||||
@@ -554,6 +560,8 @@ Einige Anbieter platzieren zusätzliche Informationen im Posteingang, die Sie z.
|
||||
<string name="autodel_at_once">Sofort</string>
|
||||
<string name="after_30_seconds">Nach 30 Sekunden</string>
|
||||
<string name="after_1_minute">Nach 1 Minute</string>
|
||||
<string name="after_5_minutes">Nach 5 Minuten</string>
|
||||
<string name="after_30_minutes">Nach 30 Minuten</string>
|
||||
<string name="autodel_after_1_hour">Nach 1 Stunde</string>
|
||||
<string name="autodel_after_1_day">Nach 1 Tag</string>
|
||||
<string name="autodel_after_1_week">Nach 1 Woche</string>
|
||||
@@ -603,6 +611,10 @@ Einige Anbieter platzieren zusätzliche Informationen im Posteingang, die Sie z.
|
||||
<string name="systemmsg_ephemeral_timer_day">Ablaufzeit verschwindender Nachrichten auf 1 Tag festgelegt.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Ablaufzeit verschwindender Nachrichten auf 1 Woche festgelegt.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Ablaufzeit verschwindender Nachrichten auf 4 Wochen festgelegt.</string>
|
||||
<string name="systemmsg_ephemeral_timer_minutes">Ablaufzeit verschwindender Nachrichten auf %1$s Minuten festgelegt.</string>
|
||||
<string name="systemmsg_ephemeral_timer_hours">Ablaufzeit verschwindender Nachrichten auf %1$s Stunden festgelegt.</string>
|
||||
<string name="systemmsg_ephemeral_timer_days">Ablaufzeit verschwindender Nachrichten auf %1$s Tage festgelegt.</string>
|
||||
<string name="systemmsg_ephemeral_timer_weeks">Ablaufzeit verschwindender Nachrichten auf %1$s Wochen festgelegt.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Chat-Absicherung ausgeschaltet.</string>
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
<string name="profile">Perfil</string>
|
||||
<string name="main_menu">Menú principal</string>
|
||||
<string name="start_chat">Comienza un chat</string>
|
||||
<string name="show_full_message">Mostrar el mensaje completo...</string>
|
||||
<string name="load_remote_content">Cargar imágenes remotas</string>
|
||||
<!-- possible answers to the question are: Never, Always, Once -->
|
||||
<string name="load_remote_content_ask">Las imágenes remotas pueden ser usadas para seguirte.\n\nLos ajustes también te permiten cargar fuentes y otros contenidos. Inclusive si están deshabilitadas, quizás puedas ver imágenes embebidas o en caché.\n\n¿Cargar imágenes remotas?</string>
|
||||
<string name="always">Siempre</string>
|
||||
<string name="once">Una vez</string>
|
||||
<string name="show_password">Mostrar contraseña</string>
|
||||
<string name="hide_password">Ocultar contraseña</string>
|
||||
<string name="not_now">Ahora no</string>
|
||||
@@ -187,6 +193,7 @@
|
||||
<string name="menu_scroll_to_top">Desplazarse al inicio</string>
|
||||
<string name="menu_help">Ayuda</string>
|
||||
<string name="menu_select_all">Seleccionar todo</string>
|
||||
<string name="select_more">Selecciona más</string>
|
||||
<string name="menu_expand">Expandir</string>
|
||||
<string name="menu_edit_name">Editar nombre</string>
|
||||
<string name="menu_settings">Ajustes</string>
|
||||
@@ -600,7 +607,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Temporizador de borrado de mensaje dispuesto en 1 día</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Temporizador de borrado de mensaje dispuesto en 1 semana</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Temporizador de borrado de mensaje dispuesto en 4 semanas</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Protección de chat desactivada</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Protección de chat activa</string>
|
||||
|
||||
@@ -601,7 +601,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">زمان سنج پیام های ناپدید شونده برای 1 روز تنظیم شد.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">زمان سنج پیام های ناپدید شونده برای 1 هفته تنظیم شد.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">زمان سنج پیام های ناپدید شونده برای 4 هفته تنظیم شد.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">محافظت از گفنگو غیرفعال شد.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">محافظت از گفتگو فعال شد.</string>
|
||||
|
||||
@@ -600,7 +600,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Temporisation des messages éphémères réglée à 1 journée.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Temporisation des messages éphémères réglée à 1 semaine.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Temporisation des messages éphémères réglée à 4 semaines.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Protection de la discussion désactivée.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Protection de la discussion activée.</string>
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
<string name="profile">Perfil</string>
|
||||
<string name="main_menu">Menú principal</string>
|
||||
<string name="start_chat">Inciar chat</string>
|
||||
<string name="show_full_message">Mostrar mensaxe completa...</string>
|
||||
<string name="load_remote_content">Cargar imaxes remotas</string>
|
||||
<!-- possible answers to the question are: Never, Always, Once -->
|
||||
<string name="load_remote_content_ask">As imaxes remotas poden ser utilizadas para rastrexarte.\n\nO axuste tamén permite cargar tipografías e outro contido. Incluso estando desactivado, é posible ver as imaxes gardadas na caché.\n\nCargar imaxes remotas?</string>
|
||||
<string name="always">Sempre</string>
|
||||
<string name="once">Unha vez</string>
|
||||
<string name="show_password">Mostrar contrasinal</string>
|
||||
<string name="hide_password">Agochar contrasinal</string>
|
||||
<string name="not_now">Agora non</string>
|
||||
@@ -187,6 +193,7 @@
|
||||
<string name="menu_scroll_to_top">Moverse arriba</string>
|
||||
<string name="menu_help">Axuda</string>
|
||||
<string name="menu_select_all">Escoller todo</string>
|
||||
<string name="select_more">Elexir máis</string>
|
||||
<string name="menu_expand">Despregar</string>
|
||||
<string name="menu_edit_name">Editar nome</string>
|
||||
<string name="menu_settings">Axustes</string>
|
||||
@@ -600,7 +607,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">As mensaxes desaparecerán após 1 día.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">As mensaxes desaparecerán após 1 semana.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">As mensaxes desaparecerán após 4 semanas.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Protección do chat desactivada.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Protección do chat activada.</string>
|
||||
|
||||
@@ -71,23 +71,23 @@
|
||||
<string name="last_month">Bulan lalu</string>
|
||||
<!-- Translators: show beside messages that are "N minutes old". prefer a short string, prefer abbreviations if they're well-known -->
|
||||
<plurals name="n_minutes">
|
||||
<item quantity="other">%dmenit</item>
|
||||
<item quantity="other">%d menit</item>
|
||||
</plurals>
|
||||
<!-- Translators: show beside messages that are "N hours old". prefer a short string, prefer abbreviations if they're well-known -->
|
||||
<plurals name="n_hours">
|
||||
<item quantity="other">%djam</item>
|
||||
<item quantity="other">%d jam</item>
|
||||
</plurals>
|
||||
<plurals name="n_chats">
|
||||
<item quantity="other">%d obrolan</item>
|
||||
</plurals>
|
||||
<plurals name="n_contacts">
|
||||
<item quantity="other">%dkontak</item>
|
||||
<item quantity="other">%d kontak</item>
|
||||
</plurals>
|
||||
<plurals name="n_messages">
|
||||
<item quantity="other">%dpesan</item>
|
||||
<item quantity="other">%d pesan</item>
|
||||
</plurals>
|
||||
<plurals name="n_members">
|
||||
<item quantity="other">%danggota</item>
|
||||
<item quantity="other">%d anggota</item>
|
||||
</plurals>
|
||||
|
||||
<string name="self">Saya</string>
|
||||
@@ -561,6 +561,7 @@
|
||||
<string name="qrshow_join_contact_no_connection_hint">Pengaturan kode QR membutuhkan koneksi internet. Mohon nyalakan koneksi ke jaringan sebelum mulai proses.</string>
|
||||
<string name="qrshow_join_contact_no_connection_toast">Tidak ada koneksi internet, tidak bisa menjalankan kode pengaturan QR.</string>
|
||||
<string name="qraccount_ask_create_and_login">Buat alamat email baru di \"%1$s\" dan login di sana?</string>
|
||||
<string name="qraccount_ask_create_and_login_another">Buat alamat email baru di\"%1$s\" dan masuk ke sana?\n\nAkun yang sudah ada tidak akan di hapus. Gunakankan item \"Ganti akun\" untuk mengganti akun anda</string>
|
||||
<string name="qraccount_success_enter_name">Login berhasil—alamat surel Anda %1$s\n\nKalau mau, masukkan satu nama dan gambar avatar yang dapat dilihat oleh orang yang ngobrol dengan Anda.</string>
|
||||
<string name="qraccount_qr_code_cannot_be_used">Kode QR yang dipindai tidak dapat digunakan untuk mengatur akun baru.</string>
|
||||
<string name="qraccount_use_on_new_install">Kode QR yang dipindai adalah untuk mengatur akun baru. Anda dapat memindai kode QR saat mengatur instalasi Delta Chat baru.</string>
|
||||
@@ -666,6 +667,7 @@
|
||||
|
||||
<!-- accessibility, the general idea is to use the normal strings for accessibility hints wherever possible -->
|
||||
<string name="a11y_delivery_status_error">Status pengiriman: Kesalahan</string>
|
||||
<string name="a11y_encryption_padlock">Enkripsi padlock</string>
|
||||
<string name="a11y_delivery_status_sending">Status pengiriman: Mengirim</string>
|
||||
<string name="a11y_delivery_status_draft">Status pengiriman: Draft</string>
|
||||
<string name="a11y_delivery_status_delivered">Status pengiriman: Terkirim</string>
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
<string name="profile">Profilo</string>
|
||||
<string name="main_menu">Menu principale</string>
|
||||
<string name="start_chat">Inizia una chat</string>
|
||||
<string name="show_full_message">Mostra messaggio completo...</string>
|
||||
<string name="load_remote_content">Carica immagini remote</string>
|
||||
<!-- possible answers to the question are: Never, Always, Once -->
|
||||
<string name="load_remote_content_ask">Le immagini remote possono essere utilizzate per tracciarti.\n\nL\'impostazione consente anche di caricare caratteri e altri contenuti. Anche se è disabilitato, potresti comunque vedere immagini incorporate o memorizzate nella cache.\n\nCaricare immagini remote?</string>
|
||||
<string name="always">Sempre</string>
|
||||
<string name="once">Una volta</string>
|
||||
<string name="show_password">Mostra password</string>
|
||||
<string name="hide_password">Nascondi password</string>
|
||||
<string name="not_now">Non ora</string>
|
||||
@@ -187,6 +193,7 @@
|
||||
<string name="menu_scroll_to_top">Scorri in cima</string>
|
||||
<string name="menu_help">Aiuto</string>
|
||||
<string name="menu_select_all">Seleziona tutto</string>
|
||||
<string name="select_more">Seleziona di più</string>
|
||||
<string name="menu_expand">Espandi</string>
|
||||
<string name="menu_edit_name">Modifica nome</string>
|
||||
<string name="menu_settings">Impostazioni</string>
|
||||
@@ -600,7 +607,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Il timer per la scomparsa dei messaggi è impostato su 1 giorno.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Il timer per la scomparsa dei messaggi è impostato su 1 settimana.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Il timer per la scomparsa dei messaggi è impostato su 4 settimane.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Protezione chat disattivata.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Protezione chat abilitata.</string>
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
<string name="profile">Profiel</string>
|
||||
<string name="main_menu">Hoofdmenu</string>
|
||||
<string name="start_chat">Gesprek beginnen</string>
|
||||
<string name="show_full_message">Volledige bericht tonen…</string>
|
||||
<string name="load_remote_content">Externe afbeeldingen laden</string>
|
||||
<!-- possible answers to the question are: Never, Always, Once -->
|
||||
<string name="load_remote_content_ask">Externe afbeeldingen kunnen worden gebruikt om je gedrag te volgen.\n\nDeze instelling staat tevens toe om andere externe inhoud, zoals lettertypen, te laden, en zelfs na uitschakeling kunnen er ingesloten of gecachte afbeeldingen worden getoond.\n\nWeet je het zeker?</string>
|
||||
<string name="always">Altijd</string>
|
||||
<string name="once">Eenmalig</string>
|
||||
<string name="show_password">Wachtwoord tonen</string>
|
||||
<string name="hide_password">Wachtwoord verbergen</string>
|
||||
<string name="not_now">Niet nu</string>
|
||||
@@ -187,6 +193,7 @@
|
||||
<string name="menu_scroll_to_top">Ga naar het begin</string>
|
||||
<string name="menu_help">Hulp</string>
|
||||
<string name="menu_select_all">Alles selecteren</string>
|
||||
<string name="select_more">Meer selecteren</string>
|
||||
<string name="menu_expand">Uitvouwen</string>
|
||||
<string name="menu_edit_name">Naam wijzigen</string>
|
||||
<string name="menu_settings">Instellingen</string>
|
||||
@@ -600,7 +607,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">De tijdklok van verdwijnende berichten is ingesteld op 1 dag.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">De tijdklok van verdwijnende berichten is ingesteld op 1 week.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">De tijdklok van verdwijnende berichten is ingesteld op 4 weken.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Gespreksbeveiliging is uitgeschakeld.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Gespreksbeveiliging is ingeschakeld.</string>
|
||||
|
||||
@@ -597,7 +597,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Ustawiono zegar znikających wiadomości na 1 dzień.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Ustawiono zegar znikających wiadomości na 1 tydzień.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Ustawiono zegar znikających wiadomości na 4 tygodnie.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Ochrona czatu wyłączona.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Ochrona czatu włączona.</string>
|
||||
|
||||
@@ -600,7 +600,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Temporizador de desaparecimento de mensagens definido para 1 dia.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Temporizador de desaparecimento de mensagens definido para 1 semana.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Temporizador de desaparecimento de mensagens definido para 4 semanas.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Proteção da conversa desligada.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Proteção da conversa ligada.</string>
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
<string name="profile">Профиль</string>
|
||||
<string name="main_menu">Главное меню</string>
|
||||
<string name="start_chat">Начать чат</string>
|
||||
<string name="show_full_message">Показать сообщение…</string>
|
||||
<string name="load_remote_content">Загружать удаленные изображения</string>
|
||||
<!-- possible answers to the question are: Never, Always, Once -->
|
||||
<string name="load_remote_content_ask">Удаленные изображения могут использоваться для отслеживания вас.\n\nЭта настройка также позволяет загружать удаленные шрифты и другое содержимое. Даже если она отключена, вы все равно сможете видеть встроенные или кешированные изображения.\n\nЗагружать удаленные изображения?</string>
|
||||
<string name="always">Всегда</string>
|
||||
<string name="once">Только сейчас</string>
|
||||
<string name="show_password">Показать пароль</string>
|
||||
<string name="hide_password">Скрыть пароль</string>
|
||||
<string name="not_now">Не сейчас</string>
|
||||
@@ -199,6 +205,7 @@
|
||||
<string name="menu_scroll_to_top">Прокрутить вверх</string>
|
||||
<string name="menu_help">Помощь</string>
|
||||
<string name="menu_select_all">Выбрать всё</string>
|
||||
<string name="select_more">Выбрать больше</string>
|
||||
<string name="menu_expand">Расширить</string>
|
||||
<string name="menu_edit_name">Изменить имя</string>
|
||||
<string name="menu_settings">Настройки</string>
|
||||
@@ -577,6 +584,8 @@
|
||||
<string name="autodel_at_once">Сразу</string>
|
||||
<string name="after_30_seconds">Через 30 секунд</string>
|
||||
<string name="after_1_minute">Через 1 минуту</string>
|
||||
<string name="after_5_minutes">Через 5 минут</string>
|
||||
<string name="after_30_minutes">Через 30 минут</string>
|
||||
<string name="autodel_after_1_hour">Через 1 час</string>
|
||||
<string name="autodel_after_1_day">Через 1 день</string>
|
||||
<string name="autodel_after_1_week">Через 1 неделю</string>
|
||||
@@ -626,6 +635,10 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Таймер исчезающих сообщений установлен на 1 день.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Таймер исчезающих сообщений установлен на 1 неделю.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Таймер исчезающих сообщений установлен на 4 недели.</string>
|
||||
<string name="systemmsg_ephemeral_timer_minutes">Таймер исчезающих сообщений установлен в %1$s минут.</string>
|
||||
<string name="systemmsg_ephemeral_timer_hours">Таймер исчезающих сообщений установлен в %1$s часов.</string>
|
||||
<string name="systemmsg_ephemeral_timer_days">Таймер исчезающих сообщений установлен в %1$s дней.</string>
|
||||
<string name="systemmsg_ephemeral_timer_weeks">Таймер исчезающих сообщений установлен в %1$s недель.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Защита чата отключена.</string>
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
<string name="profile">Profile</string>
|
||||
<string name="main_menu">Menuja kryesore</string>
|
||||
<string name="start_chat">Nisni fjalosje</string>
|
||||
<string name="show_full_message">Shfaq mesazhin e plotë…</string>
|
||||
<string name="load_remote_content">Ngarko figura të largëta</string>
|
||||
<!-- possible answers to the question are: Never, Always, Once -->
|
||||
<string name="load_remote_content_ask">Figurat e largëta mund të përdoren për t’ju ndjekur.\n\nRregullimi lejon gjithashtu të ngarkohen shkronja dhe lëndë tjetër. Edhe nëse është e çaktivizuar, prapë mund të shihni figura të trupëzuara ose të ruajtura në fshehtinë.\n\nTë ngarkohen figura të largëta?</string>
|
||||
<string name="always">Përherë</string>
|
||||
<string name="once">Vetëm njëherë</string>
|
||||
<string name="show_password">Shfaqe fjalëkalimin</string>
|
||||
<string name="hide_password">Fshihe fjalëkalimin</string>
|
||||
<string name="not_now">Jo tani</string>
|
||||
@@ -186,6 +192,7 @@
|
||||
<string name="menu_scroll_to_top">Rrëshqit sipër në krye</string>
|
||||
<string name="menu_help">Nidhmë</string>
|
||||
<string name="menu_select_all">Përzgjidhi krejt</string>
|
||||
<string name="select_more">Përzgjidhni më tepër</string>
|
||||
<string name="menu_expand">Zgjeroje</string>
|
||||
<string name="menu_edit_name">Përpunoni emrin</string>
|
||||
<string name="menu_settings">Rregullime</string>
|
||||
@@ -598,7 +605,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Kohëmatësi për mesazhe që zhduken është vënë në 1 ditë.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Kohëmatësi për mesazhe që zhduken është vënë në 1 javë.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Kohëmatësi për mesazhe që zhduken është vënë në 4 javë.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Mbrojtja e fjalosjes u çaktivizua.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Mbrojtja e fjalosjes u aktivizua.</string>
|
||||
|
||||
@@ -529,7 +529,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Tiduret för meddelandeborttagning är satt till 1 dag.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Tiduret för meddelandeborttagning är satt till 1 vecka.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Tiduret för meddelandeborttagning är satt till 4 veckor.</string>
|
||||
|
||||
<!-- screen lock -->
|
||||
<string name="screenlock_title">Skärmlås</string>
|
||||
<string name="screenlock_explain">Lås åtkomsten med Androids skärmlås eller fingeravtryck. Aktivera även \"Skärmsäkerhet\", för att undvika att visa tidigare innehåll.</string>
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
<string name="profile">Profil</string>
|
||||
<string name="main_menu">Ana menü</string>
|
||||
<string name="start_chat">Sohbete başla</string>
|
||||
<string name="show_full_message">Tam iletiyi göster…</string>
|
||||
<string name="load_remote_content">Uzak görselleri yükle</string>
|
||||
<!-- possible answers to the question are: Never, Always, Once -->
|
||||
<string name="load_remote_content_ask">Uzak görseller sizi izlemek için kullanılabilir.\n\nAyar, yazı tiplerinin ve diğer içeriğin de yüklenmesine izin verir. Etkisizleştirildiyse bile katıştırılan ya da önbelleklenen görselleri hâlâ görebilirsiniz.\n\nUzak görseller yüklensin mi?</string>
|
||||
<string name="always">Her zaman</string>
|
||||
<string name="once">Bir kez</string>
|
||||
<string name="show_password">Parolayı göster</string>
|
||||
<string name="hide_password">Parolayı gizle</string>
|
||||
<string name="not_now">Şimdi değil</string>
|
||||
@@ -187,6 +193,7 @@
|
||||
<string name="menu_scroll_to_top">Üste kaydır</string>
|
||||
<string name="menu_help">Yardım</string>
|
||||
<string name="menu_select_all">Tümünü seç</string>
|
||||
<string name="select_more">Daha fazlasını seç</string>
|
||||
<string name="menu_expand">Genişlet</string>
|
||||
<string name="menu_edit_name">Adı düzenle</string>
|
||||
<string name="menu_settings">Ayarlar</string>
|
||||
@@ -600,7 +607,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Kaybolan iletiler zamanlayıcısı 1 güne ayarlandı.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Kaybolan iletiler zamanlayıcısı 1 haftaya ayarlandı.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Kaybolan iletiler zamanlayıcısı 4 haftaya ayarlandı.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Sohbet koruması etkisizleştirildi.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Sohbet koruması etkinleştirildi.</string>
|
||||
|
||||
@@ -199,6 +199,7 @@
|
||||
<string name="menu_scroll_to_top">Прокрутити на початок</string>
|
||||
<string name="menu_help">Допомога</string>
|
||||
<string name="menu_select_all">Вибрати все</string>
|
||||
<string name="select_more">Вибрати ще</string>
|
||||
<string name="menu_expand">Розширити</string>
|
||||
<string name="menu_edit_name">Редагувати ім\'я</string>
|
||||
<string name="menu_settings">Налаштування</string>
|
||||
@@ -624,7 +625,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Таймер зникнення повідомлень встановлено на 1 день.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Таймер зникнення повідомлень встановлено на 1 тиждень.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Таймер зникнення повідомлень встановлено на 4 тижні.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Захист чату вимкнено.</string>
|
||||
<string name="systemmsg_chat_protection_enabled">Захист чату увімкнено.</string>
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
<string name="profile">概要</string>
|
||||
<string name="main_menu">主菜单</string>
|
||||
<string name="start_chat">开始聊天</string>
|
||||
<string name="show_full_message">显示完整消息… </string>
|
||||
<string name="load_remote_content">加载远程图片</string>
|
||||
<!-- possible answers to the question are: Never, Always, Once -->
|
||||
<string name="load_remote_content_ask">远程图片可被用来跟踪你。\n\n该设置还允许加载字体和其他内容。即使禁用了它,你仍然可以看到嵌入或缓存的图像。\n\n要加载远程图片吗?</string>
|
||||
<string name="always">始终</string>
|
||||
<string name="once">一次</string>
|
||||
<string name="show_password">显示密码</string>
|
||||
<string name="hide_password">隐藏密码</string>
|
||||
<string name="not_now">现在不</string>
|
||||
@@ -181,6 +187,7 @@
|
||||
<string name="menu_scroll_to_top">滚动至顶部</string>
|
||||
<string name="menu_help">帮助</string>
|
||||
<string name="menu_select_all">全选</string>
|
||||
<string name="select_more">选择更多</string>
|
||||
<string name="menu_expand">展开</string>
|
||||
<string name="menu_edit_name">编辑名称</string>
|
||||
<string name="menu_settings">设置</string>
|
||||
@@ -588,7 +595,6 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">设置消息定时销毁计时器为 1 天</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">设置消息定时销毁计时器为 1 周</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">设置消息定时销毁计时器为 4 周</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">聊天保护已禁用</string>
|
||||
<string name="systemmsg_chat_protection_enabled">聊天保护已启用</string>
|
||||
|
||||
@@ -131,13 +131,14 @@
|
||||
</string-array>
|
||||
|
||||
<string-array name="ephemeral_message_durations">
|
||||
<item>@string/off</item>
|
||||
<item>@string/after_30_seconds</item>
|
||||
<item>@string/after_1_minute</item>
|
||||
<item>@string/autodel_after_1_hour</item>
|
||||
<item>@string/autodel_after_1_day</item>
|
||||
<item>@string/autodel_after_1_week</item>
|
||||
<item>@string/autodel_after_4_weeks</item>
|
||||
<!-- 0 --> <item>@string/off</item>
|
||||
<!-- 1 --> <item>@string/after_1_minute</item>
|
||||
<!-- 2 --> <item>@string/after_5_minutes</item>
|
||||
<!-- 3 --> <item>@string/after_30_minutes</item>
|
||||
<!-- 4 --> <item>@string/autodel_after_1_hour</item>
|
||||
<!-- 5 --> <item>@string/autodel_after_1_day</item>
|
||||
<!-- 6 --> <item>@string/autodel_after_1_week</item>
|
||||
<!-- 7 --> <item>@string/autodel_after_4_weeks</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="mute_durations">
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
<string name="profile">Profile</string>
|
||||
<string name="main_menu">Main menu</string>
|
||||
<string name="start_chat">Start chat</string>
|
||||
<string name="show_full_message">Show full message…</string>
|
||||
<string name="load_remote_content">Load remote images</string>
|
||||
<!-- possible answers to the question are: Never, Always, Once -->
|
||||
<string name="load_remote_content_ask">Remote images can be used to track you.\n\nThe setting also allows loading fonts and other content. Even if it is disabled, you may still see embedded or cached images.\n\nLoad remote images?</string>
|
||||
<string name="always">Always</string>
|
||||
<string name="once">Once</string>
|
||||
<string name="show_password">Show password</string>
|
||||
<string name="hide_password">Hide password</string>
|
||||
<string name="not_now">Not now</string>
|
||||
@@ -552,6 +558,8 @@
|
||||
<string name="autodel_at_once">At once</string>
|
||||
<string name="after_30_seconds">After 30 seconds</string>
|
||||
<string name="after_1_minute">After 1 minute</string>
|
||||
<string name="after_5_minutes">After 5 minutes</string>
|
||||
<string name="after_30_minutes">After 30 minutes</string>
|
||||
<string name="autodel_after_1_hour">After 1 hour</string>
|
||||
<string name="autodel_after_1_day">After 1 day</string>
|
||||
<string name="autodel_after_1_week">After 1 week</string>
|
||||
@@ -601,6 +609,10 @@
|
||||
<string name="systemmsg_ephemeral_timer_day">Disappearing messages timer set to 1 day.</string>
|
||||
<string name="systemmsg_ephemeral_timer_week">Disappearing messages timer set to 1 week.</string>
|
||||
<string name="systemmsg_ephemeral_timer_four_weeks">Disappearing messages timer set to 4 weeks.</string>
|
||||
<string name="systemmsg_ephemeral_timer_minutes">Disappearing messages timer set to %1$s minutes.</string>
|
||||
<string name="systemmsg_ephemeral_timer_hours">Disappearing messages timer set to %1$s hours.</string>
|
||||
<string name="systemmsg_ephemeral_timer_days">Disappearing messages timer set to %1$s days.</string>
|
||||
<string name="systemmsg_ephemeral_timer_weeks">Disappearing messages timer set to %1$s weeks.</string>
|
||||
|
||||
<!-- Translators: Protection disabled/enabled messages may be displayed together with a "big shield" and may be suffixed by systemmsg_action_by_user or systemmsg_action_by_me -->
|
||||
<string name="systemmsg_chat_protection_disabled">Chat protection disabled.</string>
|
||||
|
||||
@@ -156,6 +156,7 @@ public class DcContext {
|
||||
public native void deleteChat (int chat_id);
|
||||
public @NonNull DcMsg getMsg (int msg_id) { return new DcMsg(getMsgCPtr(msg_id)); }
|
||||
public native String getMsgInfo (int id);
|
||||
public native String getMsgHtml (int msg_id);
|
||||
public native int getFreshMsgCount (int chat_id);
|
||||
public native int estimateDeletionCount(boolean from_server, long seconds);
|
||||
public native void deleteMsgs (int msg_ids[]);
|
||||
|
||||
@@ -114,6 +114,7 @@ public class DcMsg {
|
||||
public native boolean isForwarded ();
|
||||
public native boolean isInfo ();
|
||||
public native boolean isSetupMessage ();
|
||||
public native boolean hasHtml ();
|
||||
public native String getSetupCodeBegin ();
|
||||
public native String getVideochatUrl ();
|
||||
public native int getVideochatType ();
|
||||
|
||||
@@ -28,5 +28,6 @@ public interface BindableConversationItem extends Unbindable {
|
||||
|
||||
interface EventListener {
|
||||
void onQuoteClicked(DcMsg messageRecord);
|
||||
void onShowFullClicked(DcMsg messageRecord);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -872,6 +872,14 @@ public class ConversationFragment extends Fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowFullClicked(DcMsg messageRecord) {
|
||||
Intent intent = new Intent(getActivity(), FullMsgActivity.class);
|
||||
intent.putExtra(FullMsgActivity.MSG_ID_EXTRA, messageRecord.getId());
|
||||
startActivity(intent);
|
||||
getActivity().overridePendingTransition(R.anim.slide_from_right, R.anim.fade_scale_out);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,6 +32,7 @@ import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
@@ -110,6 +111,7 @@ public class ConversationItem extends LinearLayout
|
||||
private AvatarImageView contactPhoto;
|
||||
protected ViewGroup contactPhotoHolder;
|
||||
private ViewGroup container;
|
||||
private Button showFullMessage;
|
||||
|
||||
private @NonNull Set<DcMsg> batchSelected = new HashSet<>();
|
||||
private @NonNull Recipient conversationRecipient;
|
||||
@@ -162,6 +164,7 @@ public class ConversationItem extends LinearLayout
|
||||
this.quoteView = findViewById(R.id.quote_view);
|
||||
this.container = findViewById(R.id.container);
|
||||
this.replyView = findViewById(R.id.reply_icon);
|
||||
this.showFullMessage = findViewById(R.id.show_full_message);
|
||||
|
||||
setOnClickListener(new ClickListener(null));
|
||||
|
||||
@@ -361,6 +364,18 @@ public class ConversationItem extends LinearLayout
|
||||
bodyText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (messageRecord.hasHtml()) {
|
||||
showFullMessage.setVisibility(View.VISIBLE);
|
||||
showFullMessage.setOnClickListener(view -> {
|
||||
if (eventListener != null && batchSelected.isEmpty()) {
|
||||
eventListener.onShowFullClicked(messageRecord);
|
||||
} else {
|
||||
passthroughClickListener.onClick(view);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showFullMessage.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMediaAttributes(@NonNull DcMsg messageRecord,
|
||||
|
||||
@@ -282,7 +282,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
final ApplicationDcContext dcContext = DcHelper.getContext(this);
|
||||
if (isForwarding(this) && dcContext.getChat(chatId).isSelfTalk()) {
|
||||
SendRelayedMessageUtil.immediatelyRelay(this, chatId);
|
||||
Toast.makeText(this, "✔️ " + getString(R.string.saved), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(this, DynamicTheme.getCheckmarkEmoji(this) + " " + getString(R.string.saved), Toast.LENGTH_SHORT).show();
|
||||
handleResetRelaying();
|
||||
finish();
|
||||
} else {
|
||||
|
||||
@@ -60,12 +60,13 @@ public class EphemeralMessagesDialog {
|
||||
.setPositiveButton(R.string.ok, (dialog, which) -> {
|
||||
final long burnAfter;
|
||||
switch (selectedChoice[0]) {
|
||||
case 1: burnAfter = TimeUnit.SECONDS.toSeconds(30); break;
|
||||
case 2: burnAfter = TimeUnit.MINUTES.toSeconds(1); break;
|
||||
case 3: burnAfter = TimeUnit.HOURS.toSeconds(1); break;
|
||||
case 4: burnAfter = TimeUnit.DAYS.toSeconds(1); break;
|
||||
case 5: burnAfter = TimeUnit.DAYS.toSeconds(7); break;
|
||||
case 6: burnAfter = TimeUnit.DAYS.toSeconds(28); break;
|
||||
case 1: burnAfter = TimeUnit.MINUTES.toSeconds(1); break;
|
||||
case 2: burnAfter = TimeUnit.MINUTES.toSeconds(5); break;
|
||||
case 3: burnAfter = TimeUnit.MINUTES.toSeconds(30); break;
|
||||
case 4: burnAfter = TimeUnit.HOURS.toSeconds(1); break;
|
||||
case 5: burnAfter = TimeUnit.DAYS.toSeconds(1); break;
|
||||
case 6: burnAfter = TimeUnit.DAYS.toSeconds(7); break;
|
||||
case 7: burnAfter = TimeUnit.DAYS.toSeconds(28); break;
|
||||
default: burnAfter = 0; break;
|
||||
}
|
||||
listener.onTimeSelected(burnAfter);
|
||||
@@ -78,25 +79,30 @@ public class EphemeralMessagesDialog {
|
||||
}
|
||||
|
||||
private static int getPreselection(int timespan) {
|
||||
if (timespan == TimeUnit.DAYS.toSeconds(28)) {
|
||||
return 6;
|
||||
} else if (timespan == TimeUnit.DAYS.toSeconds(7)) {
|
||||
return 5;
|
||||
} else if (timespan == TimeUnit.DAYS.toSeconds(1)) {
|
||||
return 4;
|
||||
} else if (timespan == TimeUnit.HOURS.toSeconds(1)) {
|
||||
return 3;
|
||||
} else if (timespan == TimeUnit.MINUTES.toSeconds(1)) {
|
||||
return 2;
|
||||
} else if (timespan == TimeUnit.SECONDS.toSeconds(30)) {
|
||||
return 1;
|
||||
} else {
|
||||
if (timespan != 0) {
|
||||
Log.e(TAG, "Invalid ephemeral messages timespan, falling back to OFF");
|
||||
}
|
||||
return 0;
|
||||
if (timespan == 0) {
|
||||
return 0; // off
|
||||
}
|
||||
|
||||
// Choose timespan close to the current one out of available options.
|
||||
if (timespan < TimeUnit.MINUTES.toSeconds(5)) {
|
||||
return 1; // 1 minute
|
||||
}
|
||||
if (timespan < TimeUnit.MINUTES.toSeconds(30)) {
|
||||
return 2; // 5 minutes
|
||||
}
|
||||
if (timespan < TimeUnit.HOURS.toSeconds(1)) {
|
||||
return 3; // 30 minutes
|
||||
}
|
||||
if (timespan < TimeUnit.DAYS.toSeconds(1)) {
|
||||
return 4; // 1 hour
|
||||
}
|
||||
if (timespan < TimeUnit.DAYS.toSeconds(7)) {
|
||||
return 5; // 1 day
|
||||
}
|
||||
if (timespan < TimeUnit.DAYS.toSeconds(28)) {
|
||||
return 6; // 1 week
|
||||
}
|
||||
return 7; // 4 weeks
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.webkit.WebSettings;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import org.thoughtcrime.securesms.connect.ApplicationDcContext;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.Prefs;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import static android.util.Base64.DEFAULT;
|
||||
import static android.util.Base64.encodeToString;
|
||||
|
||||
public class FullMsgActivity extends WebViewActivity
|
||||
{
|
||||
public static final String MSG_ID_EXTRA = "msg_id";
|
||||
private int msgId;
|
||||
private ApplicationDcContext dcContext;
|
||||
private boolean loadRemoteContent = false;
|
||||
|
||||
enum LoadRemoteContent {
|
||||
NEVER,
|
||||
ONCE,
|
||||
ALWAYS
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle state, boolean ready) {
|
||||
super.onCreate(state, ready);
|
||||
|
||||
loadRemoteContent = Prefs.getAlwaysLoadRemoteContent(this);
|
||||
webView.getSettings().setBlockNetworkLoads(!loadRemoteContent);
|
||||
|
||||
// setBuiltInZoomControls() adds pinch-to-zoom as well as two on-screen zoom control buttons.
|
||||
// The latter are a bit annoying, however, they are deprecated anyway,
|
||||
// and also Android docs recommend to disable them with setDisplayZoomControls().
|
||||
webView.getSettings().setBuiltInZoomControls(true);
|
||||
webView.getSettings().setDisplayZoomControls(false);
|
||||
|
||||
// disable useless and unwanted features:
|
||||
// - JavaScript and Plugins are disabled by default, however,
|
||||
// doing it explicitly here protects against changed base classes or bugs
|
||||
// - Content- and File-access is enabled by default and disabled here
|
||||
// - the other setAllow*() functions are related to enabled JavaScript only
|
||||
// - "safe browsing" comes with privacy issues and already disabled in the base class
|
||||
webView.getSettings().setJavaScriptEnabled(false);
|
||||
webView.getSettings().setPluginState(WebSettings.PluginState.OFF);
|
||||
webView.getSettings().setAllowContentAccess(false);
|
||||
webView.getSettings().setAllowFileAccess(false);
|
||||
|
||||
getSupportActionBar().setTitle(getString(R.string.chat_input_placeholder));
|
||||
|
||||
dcContext = DcHelper.getContext(this);
|
||||
msgId = getIntent().getIntExtra(MSG_ID_EXTRA, 0);
|
||||
|
||||
loadHtmlAsync(new WeakReference<>(this));
|
||||
}
|
||||
|
||||
private static void loadHtmlAsync(final WeakReference<FullMsgActivity> activityReference) {
|
||||
Util.runOnBackground(() -> {
|
||||
// android9 seems to make problems for non-base64-encoded html,
|
||||
// see eg. https://stackoverflow.com/questions/54516798/webview-loaddata-not-working-on-android-9-0-api-29
|
||||
String html;
|
||||
|
||||
try {
|
||||
FullMsgActivity activity = activityReference.get();
|
||||
html = activity.dcContext.getMsgHtml(activity.msgId);
|
||||
html = encodeToString(html.getBytes("UTF-8"), DEFAULT);
|
||||
String finalHtml = html;
|
||||
|
||||
activity.runOnUiThread(() -> {
|
||||
try {
|
||||
activityReference.get().webView.loadData(finalHtml, "text/html; charset=utf-8", "base64");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (isFinishing()) {
|
||||
overridePendingTransition(R.anim.fade_scale_in, R.anim.slide_to_right);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
this.getMenuInflater().inflate(R.menu.full_msg, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
switch (item.getItemId()) {
|
||||
case R.id.load_remote_content:
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this)
|
||||
.setTitle(R.string.load_remote_content)
|
||||
.setMessage(R.string.load_remote_content_ask);
|
||||
|
||||
// we are using the buttons "[Always] [Never][Once]" in that order.
|
||||
// 1. Checkmarks before [Always] and [Never] show the current state.
|
||||
// 2. [Once] is also shown in always-mode and disables always-mode if selected
|
||||
// (there was the idea to hide [Once] in always mode, but that looks more like a bug in the end)
|
||||
// (maybe a usual Always-Checkbox and "[Cancel][OK]" buttons are an alternative, however, a [Once]
|
||||
// would be required as well - probably as the leftmost button which is not that usable in
|
||||
// not-always-mode where the dialog is used more often. Or [Ok] would mean "Once" as well as "Change checkbox setting",
|
||||
// which is also a bit weird. Anyway, let's give the three buttons a try :)
|
||||
final String checkmarkPrefix = DynamicTheme.getCheckmarkEmoji(this) + " ";
|
||||
if (Prefs.getAlwaysLoadRemoteContent(this)) {
|
||||
builder.setNeutralButton(checkmarkPrefix + getString(R.string.always), (dialog, which) -> onChangeLoadRemoteContent(LoadRemoteContent.ALWAYS));
|
||||
builder.setNegativeButton(R.string.never, (dialog, which) -> onChangeLoadRemoteContent(LoadRemoteContent.NEVER));
|
||||
builder.setPositiveButton(R.string.once, (dialog, which) -> onChangeLoadRemoteContent(LoadRemoteContent.ONCE));
|
||||
} else {
|
||||
builder.setNeutralButton(R.string.always, (dialog, which) -> onChangeLoadRemoteContent(LoadRemoteContent.ALWAYS));
|
||||
builder.setNegativeButton((loadRemoteContent? "" : checkmarkPrefix) + getString(R.string.never), (dialog, which) -> onChangeLoadRemoteContent(LoadRemoteContent.NEVER));
|
||||
builder.setPositiveButton((loadRemoteContent? checkmarkPrefix : "") + getString(R.string.once), (dialog, which) -> onChangeLoadRemoteContent(LoadRemoteContent.ONCE));
|
||||
}
|
||||
|
||||
builder.show();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void onChangeLoadRemoteContent(LoadRemoteContent loadRemoteContent) {
|
||||
switch (loadRemoteContent) {
|
||||
case NEVER:
|
||||
this.loadRemoteContent = false;
|
||||
Prefs.setBooleanPreference(this, Prefs.ALWAYS_LOAD_REMOTE_CONTENT, false);
|
||||
break;
|
||||
case ONCE:
|
||||
this.loadRemoteContent = true;
|
||||
Prefs.setBooleanPreference(this, Prefs.ALWAYS_LOAD_REMOTE_CONTENT, false);
|
||||
break;
|
||||
case ALWAYS:
|
||||
this.loadRemoteContent = true;
|
||||
Prefs.setBooleanPreference(this, Prefs.ALWAYS_LOAD_REMOTE_CONTENT, true);
|
||||
break;
|
||||
}
|
||||
webView.getSettings().setBlockNetworkLoads(!this.loadRemoteContent);
|
||||
webView.reload();
|
||||
}
|
||||
}
|
||||
@@ -1,269 +1,80 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.content.res.AssetManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
public class LocalHelpActivity extends PassphraseRequiredActionBarActivity
|
||||
implements SearchView.OnQueryTextListener,
|
||||
WebView.FindListener
|
||||
public class LocalHelpActivity extends WebViewActivity
|
||||
{
|
||||
private static final String TAG = LocalHelpActivity.class.getSimpleName();
|
||||
@Override
|
||||
protected void onCreate(Bundle state, boolean ready) {
|
||||
super.onCreate(state, ready);
|
||||
getSupportActionBar().setTitle(getString(R.string.menu_help));
|
||||
|
||||
private WebView webView;
|
||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
||||
private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme.onCreate(this);
|
||||
dynamicLanguage.onCreate(this);
|
||||
}
|
||||
|
||||
private boolean assetExists(String fileName) {
|
||||
// test using AssetManager.open();
|
||||
// AssetManager.list() is unreliable eg. on my Android 7 Moto G
|
||||
// and also reported to be pretty slow.
|
||||
boolean exists = false;
|
||||
try {
|
||||
AssetManager assetManager = getResources().getAssets();
|
||||
InputStream is = assetManager.open(fileName);
|
||||
exists = true;
|
||||
is.close();
|
||||
} catch(Exception e) {
|
||||
;
|
||||
String helpPath = "help/LANG/help.html";
|
||||
String helpLang = "en";
|
||||
try {
|
||||
Locale locale = dynamicLanguage.getCurrentLocale();
|
||||
String appLang = locale.getLanguage();
|
||||
if (assetExists(helpPath.replace("LANG", appLang))) {
|
||||
helpLang = appLang;
|
||||
} else {
|
||||
appLang = appLang.substring(0, 2);
|
||||
if (assetExists(helpPath.replace("LANG", appLang))) {
|
||||
helpLang = appLang;
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle state, boolean ready) {
|
||||
setContentView(R.layout.local_help_activity);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setTitle(getString(R.string.menu_help));
|
||||
webView.loadUrl("file:///android_asset/" + helpPath.replace("LANG", helpLang));
|
||||
}
|
||||
|
||||
String helpPath = "help/LANG/help.html";
|
||||
String helpLang = "en";
|
||||
try {
|
||||
Locale locale = dynamicLanguage.getCurrentLocale();
|
||||
String appLang = locale.getLanguage();
|
||||
if (assetExists(helpPath.replace("LANG", appLang))) {
|
||||
helpLang = appLang;
|
||||
} else {
|
||||
appLang = appLang.substring(0, 2);
|
||||
if (assetExists(helpPath.replace("LANG", appLang))) {
|
||||
helpLang = appLang;
|
||||
}
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
this.getMenuInflater().inflate(R.menu.local_help, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
webView = findViewById(R.id.webview);
|
||||
webView.setWebViewClient(new WebViewClient(){
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
if (url != null && (url.startsWith("http://") || url.startsWith("https://"))) {
|
||||
openOnlineUrl(url);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
webView.loadUrl("file:///android_asset/" + helpPath.replace("LANG", helpLang));
|
||||
webView.setFindListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
dynamicLanguage.onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = this.getMenuInflater();
|
||||
menu.clear();
|
||||
|
||||
inflater.inflate(R.menu.local_help, menu);
|
||||
|
||||
try {
|
||||
MenuItem searchItem = menu.findItem(R.id.menu_search_localhelp);
|
||||
searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
|
||||
@Override
|
||||
public boolean onMenuItemActionExpand(final MenuItem item) {
|
||||
searchMenu = menu;
|
||||
LocalHelpActivity.this.lastQuery = "";
|
||||
LocalHelpActivity.this.makeSearchMenuVisible(menu, searchItem, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemActionCollapse(final MenuItem item) {
|
||||
LocalHelpActivity.this.makeSearchMenuVisible(menu, searchItem, false);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
SearchView searchView = (SearchView) searchItem.getActionView();
|
||||
searchView.setOnQueryTextListener(this);
|
||||
searchView.setQueryHint(getString(R.string.search));
|
||||
searchView.setIconifiedByDefault(true);
|
||||
|
||||
// hide the [X] beside the search field - this is too much noise, search can be aborted eg. by "back"
|
||||
ImageView closeBtn = searchView.findViewById(R.id.search_close_btn);
|
||||
if (closeBtn!=null) {
|
||||
closeBtn.setEnabled(false);
|
||||
closeBtn.setImageDrawable(null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "cannot set up help-search: ", e);
|
||||
}
|
||||
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
switch (item.getItemId()) {
|
||||
case R.id.log_scroll_up:
|
||||
webView.scrollTo(0, 0);
|
||||
return true;
|
||||
case R.id.learn_more:
|
||||
openOnlineUrl("https://delta.chat");
|
||||
return true;
|
||||
case R.id.contribute:
|
||||
openOnlineUrl("https://github.com/deltachat/deltachat-android");
|
||||
return true;
|
||||
case R.id.report_issue:
|
||||
openOnlineUrl("https://github.com/deltachat/deltachat-android/issues");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// search
|
||||
|
||||
private Menu searchMenu = null;
|
||||
private String lastQuery = "";
|
||||
private Toast lastToast = null;
|
||||
|
||||
private void updateResultCounter(int curr, int total) {
|
||||
if (searchMenu!=null) {
|
||||
MenuItem item = searchMenu.findItem(R.id.menu_search_counter);
|
||||
if (curr!=-1) {
|
||||
item.setTitle(String.format("%d/%d", total==0? 0 : curr+1, total));
|
||||
item.setVisible(true);
|
||||
} else {
|
||||
item.setVisible(false);
|
||||
}
|
||||
}
|
||||
private boolean assetExists(String fileName) {
|
||||
// test using AssetManager.open();
|
||||
// AssetManager.list() is unreliable eg. on my Android 7 Moto G
|
||||
// and also reported to be pretty slow.
|
||||
boolean exists = false;
|
||||
try {
|
||||
AssetManager assetManager = getResources().getAssets();
|
||||
InputStream is = assetManager.open(fileName);
|
||||
exists = true;
|
||||
is.close();
|
||||
} catch(Exception e) {
|
||||
; // a non-existent asset is no error, the function's purpose is to check exactly that.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return true; // action handled by listener
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String query) {
|
||||
String normQuery = query.trim();
|
||||
lastQuery = normQuery;
|
||||
if (lastToast!=null) {
|
||||
lastToast.cancel();
|
||||
lastToast = null;
|
||||
}
|
||||
webView.findAllAsync(normQuery);
|
||||
return true; // action handled by listener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFindResultReceived (int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting)
|
||||
{
|
||||
if (isDoneCounting) {
|
||||
if (numberOfMatches>0) {
|
||||
updateResultCounter(activeMatchOrdinal, numberOfMatches);
|
||||
} else {
|
||||
if (lastQuery.isEmpty()) {
|
||||
updateResultCounter(-1, 0); // hide
|
||||
} else {
|
||||
String msg = getString(R.string.search_no_result_for_x, lastQuery);
|
||||
if (lastToast != null) {
|
||||
lastToast.cancel();
|
||||
}
|
||||
lastToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
|
||||
lastToast.show();
|
||||
updateResultCounter(0, 0); // show as "0/0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// other actions
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
case R.id.menu_search_up:
|
||||
if (lastQuery.isEmpty()) {
|
||||
webView.scrollTo(0, 0);
|
||||
} else {
|
||||
webView.findNext(false);
|
||||
}
|
||||
return true;
|
||||
case R.id.menu_search_down:
|
||||
if (lastQuery.isEmpty()) {
|
||||
webView.scrollTo(0, 1000000000);
|
||||
} else {
|
||||
webView.findNext(true);
|
||||
}
|
||||
return true;
|
||||
case R.id.log_scroll_up:
|
||||
webView.scrollTo(0, 0);
|
||||
return true;
|
||||
case R.id.learn_more:
|
||||
openOnlineUrl("https://delta.chat");
|
||||
return true;
|
||||
case R.id.contribute:
|
||||
openOnlineUrl("https://github.com/deltachat/deltachat-android");
|
||||
return true;
|
||||
case R.id.report_issue:
|
||||
openOnlineUrl("https://github.com/deltachat/deltachat-android/issues");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (webView.canGoBack()) {
|
||||
webView.goBack();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
private void openOnlineUrl(String url) {
|
||||
try {
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Toast.makeText(this, R.string.no_browser_installed, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int reqCode, int resultCode, final Intent data) {
|
||||
super.onActivityResult(reqCode, resultCode, data);
|
||||
}
|
||||
|
||||
return exists;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.widget.SearchView;
|
||||
|
||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
public class WebViewActivity extends PassphraseRequiredActionBarActivity
|
||||
implements SearchView.OnQueryTextListener,
|
||||
WebView.FindListener
|
||||
{
|
||||
private static final String TAG = WebViewActivity.class.getSimpleName();
|
||||
|
||||
protected WebView webView;
|
||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
||||
protected final DynamicLanguage dynamicLanguage = new DynamicLanguage();
|
||||
|
||||
@Override
|
||||
protected void onPreCreate() {
|
||||
dynamicTheme.onCreate(this);
|
||||
dynamicLanguage.onCreate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle state, boolean ready) {
|
||||
setContentView(R.layout.web_view_activity);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
webView = findViewById(R.id.webview);
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
// `shouldOverrideUrlLoading()` is called when the user clicks a URL,
|
||||
// returning `true` means, the URL is passed to `loadUrl()`, `false` aborts loading.
|
||||
// the method is not called for POST request nor for on-page-links.
|
||||
//
|
||||
// nb: from API 24, `shouldOverrideUrlLoading(String)` is deprecated and
|
||||
// `shouldOverrideUrlLoading(WebResourceRequest)` shall be used.
|
||||
// the new one has the same functionality, and the old one still exist,
|
||||
// so, to support all systems, for now, using the old one seems to be the simplest way.
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
if (url != null) {
|
||||
if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("mailto:")) {
|
||||
openOnlineUrl(url);
|
||||
// URL opened externally, returning `true` causes the WebView to abort loading
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// by returning `true`, we also abort loading other URLs in our WebView;
|
||||
// eg. that might be weird or internal protocols.
|
||||
// if we come over really useful things, we should allow that explicitly.
|
||||
return true;
|
||||
}
|
||||
});
|
||||
webView.setFindListener(this);
|
||||
|
||||
// disable "safe browsing" as this has privacy issues,
|
||||
// eg. at least false positives are sent to the "Safe Browsing Lookup API".
|
||||
// as all URLs opened in the WebView are local anyway,
|
||||
// "safe browsing" will never be able to report issues, so it can be disabled.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
webView.getSettings().setSafeBrowsingEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
dynamicLanguage.onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = this.getMenuInflater();
|
||||
menu.clear();
|
||||
|
||||
inflater.inflate(R.menu.web_view, menu);
|
||||
|
||||
try {
|
||||
MenuItem searchItem = menu.findItem(R.id.menu_search_web_view);
|
||||
searchItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
|
||||
@Override
|
||||
public boolean onMenuItemActionExpand(final MenuItem item) {
|
||||
searchMenu = menu;
|
||||
WebViewActivity.this.lastQuery = "";
|
||||
WebViewActivity.this.makeSearchMenuVisible(menu, searchItem, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemActionCollapse(final MenuItem item) {
|
||||
WebViewActivity.this.makeSearchMenuVisible(menu, searchItem, false);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
SearchView searchView = (SearchView) searchItem.getActionView();
|
||||
searchView.setOnQueryTextListener(this);
|
||||
searchView.setQueryHint(getString(R.string.search));
|
||||
searchView.setIconifiedByDefault(true);
|
||||
|
||||
// hide the [X] beside the search field - this is too much noise, search can be aborted eg. by "back"
|
||||
ImageView closeBtn = searchView.findViewById(R.id.search_close_btn);
|
||||
if (closeBtn!=null) {
|
||||
closeBtn.setEnabled(false);
|
||||
closeBtn.setImageDrawable(null);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "cannot set up web-view-search: ", e);
|
||||
}
|
||||
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// search
|
||||
|
||||
private Menu searchMenu = null;
|
||||
private String lastQuery = "";
|
||||
private Toast lastToast = null;
|
||||
|
||||
private void updateResultCounter(int curr, int total) {
|
||||
if (searchMenu!=null) {
|
||||
MenuItem item = searchMenu.findItem(R.id.menu_search_counter);
|
||||
if (curr!=-1) {
|
||||
item.setTitle(String.format("%d/%d", total==0? 0 : curr+1, total));
|
||||
item.setVisible(true);
|
||||
} else {
|
||||
item.setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextSubmit(String query) {
|
||||
return true; // action handled by listener
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onQueryTextChange(String query) {
|
||||
String normQuery = query.trim();
|
||||
lastQuery = normQuery;
|
||||
if (lastToast!=null) {
|
||||
lastToast.cancel();
|
||||
lastToast = null;
|
||||
}
|
||||
webView.findAllAsync(normQuery);
|
||||
return true; // action handled by listener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFindResultReceived (int activeMatchOrdinal, int numberOfMatches, boolean isDoneCounting)
|
||||
{
|
||||
if (isDoneCounting) {
|
||||
if (numberOfMatches>0) {
|
||||
updateResultCounter(activeMatchOrdinal, numberOfMatches);
|
||||
} else {
|
||||
if (lastQuery.isEmpty()) {
|
||||
updateResultCounter(-1, 0); // hide
|
||||
} else {
|
||||
String msg = getString(R.string.search_no_result_for_x, lastQuery);
|
||||
if (lastToast != null) {
|
||||
lastToast.cancel();
|
||||
}
|
||||
lastToast = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
|
||||
lastToast.show();
|
||||
updateResultCounter(0, 0); // show as "0/0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// other actions
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
case R.id.menu_search_up:
|
||||
if (lastQuery.isEmpty()) {
|
||||
webView.scrollTo(0, 0);
|
||||
} else {
|
||||
webView.findNext(false);
|
||||
}
|
||||
return true;
|
||||
case R.id.menu_search_down:
|
||||
if (lastQuery.isEmpty()) {
|
||||
webView.scrollTo(0, 1000000000);
|
||||
} else {
|
||||
webView.findNext(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (webView.canGoBack()) {
|
||||
webView.goBack();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
protected void openOnlineUrl(String url) {
|
||||
try {
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Toast.makeText(this, R.string.no_browser_installed, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int reqCode, int resultCode, final Intent data) {
|
||||
super.onActivityResult(reqCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
@@ -161,13 +161,16 @@ public class ApplicationDcContext extends DcContext {
|
||||
setStockTranslation(78, context.getString(R.string.systemmsg_ephemeral_timer_hour));
|
||||
setStockTranslation(79, context.getString(R.string.systemmsg_ephemeral_timer_day));
|
||||
setStockTranslation(80, context.getString(R.string.systemmsg_ephemeral_timer_week));
|
||||
setStockTranslation(81, context.getString(R.string.systemmsg_ephemeral_timer_four_weeks));
|
||||
setStockTranslation(82, context.getString(R.string.videochat_invitation));
|
||||
setStockTranslation(83, context.getString(R.string.videochat_invitation_body));
|
||||
setStockTranslation(84, context.getString(R.string.configuration_failed_with_error));
|
||||
setStockTranslation(88, context.getString(R.string.systemmsg_chat_protection_enabled));
|
||||
setStockTranslation(89, context.getString(R.string.systemmsg_chat_protection_disabled));
|
||||
setStockTranslation(90, context.getString(R.string.reply_noun));
|
||||
setStockTranslation(93, context.getString(R.string.systemmsg_ephemeral_timer_minutes));
|
||||
setStockTranslation(94, context.getString(R.string.systemmsg_ephemeral_timer_hours));
|
||||
setStockTranslation(95, context.getString(R.string.systemmsg_ephemeral_timer_days));
|
||||
setStockTranslation(96, context.getString(R.string.systemmsg_ephemeral_timer_weeks));
|
||||
}
|
||||
|
||||
public File getImexDir() {
|
||||
|
||||
@@ -80,6 +80,11 @@ public class DynamicTheme {
|
||||
}
|
||||
}
|
||||
|
||||
// return a checkmark emoji that fits to the background of the selected theme.
|
||||
public static String getCheckmarkEmoji(@NonNull Context context) {
|
||||
return isDarkTheme(context) ? "✅" /*blue, white or white in a box*/ : "✔️" /*blue or black*/;
|
||||
}
|
||||
|
||||
private static boolean isSystemInDarkTheme(@NonNull Context context) {
|
||||
return (context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,9 @@ public class Prefs {
|
||||
private static final String MAP_CENTER_LONGITUDE = "pref_map_center_longitude";
|
||||
private static final String MAP_ZOOM = "pref_map_zoom";
|
||||
|
||||
public static final String ALWAYS_LOAD_REMOTE_CONTENT = "pref_always_load_remote_content";
|
||||
public static final boolean ALWAYS_LOAD_REMOTE_CONTENT_DEFAULT = false;
|
||||
|
||||
public enum VibrateState {
|
||||
DEFAULT(0), ENABLED(1), DISABLED(2);
|
||||
private final int id;
|
||||
@@ -303,6 +306,11 @@ public class Prefs {
|
||||
return getBooleanPreference(context, SYSTEM_EMOJI_PREF, false);
|
||||
}
|
||||
|
||||
public static boolean getAlwaysLoadRemoteContent(Context context) {
|
||||
return getBooleanPreference(context, Prefs.ALWAYS_LOAD_REMOTE_CONTENT,
|
||||
Prefs.ALWAYS_LOAD_REMOTE_CONTENT_DEFAULT);
|
||||
}
|
||||
|
||||
// generic preference functions
|
||||
|
||||
public static void setBooleanPreference(Context context, String key, boolean value) {
|
||||
|
||||
Reference in New Issue
Block a user