Compare commits
No commits in common. "f7e92072b768fbc457862cd78f4e75bf9459f6eb" and "94f9738377ff134cbf060fdf8550a9b811b9b2d4" have entirely different histories.
f7e92072b7
...
94f9738377
|
@ -112,37 +112,35 @@ project.tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
|||
|
||||
ext.lifecycleVersion = "2.2.0"
|
||||
ext.roomVersion = '2.2.5'
|
||||
ext.retrofitVersion = '2.9.0'
|
||||
ext.okhttpVersion = '4.7.2'
|
||||
ext.retrofitVersion = '2.8.1'
|
||||
ext.okhttpVersion = '4.4.0'
|
||||
ext.glideVersion = '4.11.0'
|
||||
ext.daggerVersion = '2.27'
|
||||
ext.materialdrawerVersion = '8.1.2'
|
||||
ext.materialdrawerVersion = '8.0.1'
|
||||
|
||||
// if libraries are changed here, they should also be changed in LicenseActivity
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
implementation "androidx.core:core-ktx:1.3.0"
|
||||
implementation "androidx.appcompat:appcompat:1.2.0-rc01"
|
||||
implementation "androidx.fragment:fragment-ktx:1.2.5"
|
||||
implementation "androidx.core:core-ktx:1.2.0"
|
||||
implementation "androidx.appcompat:appcompat:1.2.0-alpha02"
|
||||
implementation "androidx.fragment:fragment-ktx:1.2.2"
|
||||
implementation "androidx.browser:browser:1.2.0"
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||
implementation "androidx.recyclerview:recyclerview:1.1.0"
|
||||
implementation "androidx.exifinterface:exifinterface:1.2.0"
|
||||
implementation "androidx.exifinterface:exifinterface:1.1.0"
|
||||
implementation "androidx.cardview:cardview:1.0.0"
|
||||
implementation "androidx.preference:preference:1.1.1"
|
||||
implementation "androidx.sharetarget:sharetarget:1.0.0"
|
||||
implementation "androidx.emoji:emoji:1.1.0-rc01"
|
||||
implementation "androidx.emoji:emoji-appcompat:1.1.0-rc01"
|
||||
implementation "androidx.emoji:emoji-bundled:1.1.0-rc01"
|
||||
|
||||
implementation "androidx.preference:preference:1.1.0"
|
||||
implementation "androidx.sharetarget:sharetarget:1.0.0-rc01"
|
||||
implementation "androidx.emoji:emoji:1.1.0-beta01"
|
||||
implementation "androidx.emoji:emoji-appcompat:1.1.0-beta01"
|
||||
implementation "androidx.emoji:emoji-bundled:1.1.0-beta01"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion"
|
||||
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycleVersion"
|
||||
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||
implementation "androidx.paging:paging-runtime-ktx:2.1.1"
|
||||
implementation "androidx.viewpager2:viewpager2:1.0.0"
|
||||
implementation "androidx.work:work-runtime:2.3.4"
|
||||
implementation "androidx.room:room-runtime:$roomVersion"
|
||||
implementation "androidx.room:room-rxjava2:$roomVersion"
|
||||
kapt "androidx.room:room-compiler:$roomVersion"
|
||||
|
@ -163,7 +161,7 @@ dependencies {
|
|||
implementation "com.github.bumptech.glide:glide:$glideVersion"
|
||||
implementation "com.github.bumptech.glide:okhttp3-integration:$glideVersion"
|
||||
|
||||
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
|
||||
implementation "io.reactivex.rxjava2:rxjava:2.2.16"
|
||||
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
|
||||
implementation "io.reactivex.rxjava2:rxkotlin:2.4.0"
|
||||
|
||||
|
@ -186,12 +184,14 @@ dependencies {
|
|||
|
||||
implementation "com.theartofdev.edmodo:android-image-cropper:2.8.0"
|
||||
|
||||
implementation "com.evernote:android-job:1.4.2"
|
||||
|
||||
implementation "de.c1710:filemojicompat:1.0.17"
|
||||
implementation 'com.github.Tunous:MarkdownEdit:1.0.0'
|
||||
|
||||
testImplementation "androidx.test.ext:junit:1.1.1"
|
||||
testImplementation "org.robolectric:robolectric:4.3.1"
|
||||
testImplementation "org.mockito:mockito-inline:3.3.3"
|
||||
testImplementation "org.mockito:mockito-inline:3.2.4"
|
||||
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
|
||||
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
|
||||
|
|
|
@ -17,12 +17,12 @@
|
|||
# keep setters in Views so that animations can still work.
|
||||
# see http://proguard.sourceforge.net/manual/examples.html#beans
|
||||
-keepclassmembers public class * extends android.view.View {
|
||||
void set*(***);
|
||||
*** get*();
|
||||
void set*(***);
|
||||
*** get*();
|
||||
}
|
||||
# We want to keep methods in Activity that could be used in the XML attribute onClick
|
||||
-keepclassmembers class * extends android.app.Activity {
|
||||
public void *(android.view.View);
|
||||
public void *(android.view.View);
|
||||
}
|
||||
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
|
||||
-keepclassmembers enum * {
|
||||
|
@ -30,19 +30,43 @@
|
|||
public static ** valueOf(java.lang.String);
|
||||
}
|
||||
-keepclassmembers class * implements android.os.Parcelable {
|
||||
public static final ** CREATOR;
|
||||
public static final android.os.Parcelable$Creator CREATOR;
|
||||
}
|
||||
-keepclassmembers class **.R$* {
|
||||
public static <fields>;
|
||||
}
|
||||
|
||||
# TUSKY SPECIFIC OPTIONS
|
||||
|
||||
# keep members of our model classes, they are used in json de/serialization
|
||||
-keepclassmembers class com.keylesspalace.tusky.entity.* { *; }
|
||||
## for okhttp
|
||||
-dontwarn javax.annotation.**
|
||||
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.*
|
||||
-dontwarn okhttp3.internal.platform.ConscryptPlatform
|
||||
|
||||
##for keep
|
||||
-dontwarn android.arch.util.paging.CountedDataSource
|
||||
-dontwarn android.arch.persistence.room.paging.LimitOffsetDataSource
|
||||
|
||||
## for retrofit
|
||||
-dontwarn retrofit2.**
|
||||
-keep class retrofit2.** { *; }
|
||||
-keepattributes Signature
|
||||
-keepattributes Exceptions
|
||||
-keepattributes *Annotation*
|
||||
|
||||
-keepclasseswithmembers class * {
|
||||
@retrofit2.http.* <methods>;
|
||||
}
|
||||
|
||||
-keep class com.keylesspalace.tusky.entity.** { *; }
|
||||
|
||||
-keep public enum com.keylesspalace.tusky.entity.*$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
|
||||
|
||||
# preserve line numbers for crash reporting
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-renamesourcefileattribute SourceFile
|
||||
|
@ -63,7 +87,17 @@
|
|||
static void throwUninitializedPropertyAccessException(java.lang.String);
|
||||
}
|
||||
|
||||
-dontwarn com.google.errorprone.annotations.*
|
||||
|
||||
# without this emoji font downloading fails with AbstractMethodError
|
||||
-keep class * extends android.os.AsyncTask {
|
||||
public *;
|
||||
}
|
||||
|
||||
# Glide
|
||||
-keep public class * implements com.bumptech.glide.module.GlideModule
|
||||
-keep public class * extends com.bumptech.glide.module.AppGlideModule
|
||||
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
|
||||
**[] $VALUES;
|
||||
public *;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- These are mostly literal translations; I'm not sure what the usual jargon in Spanish for some terms (like "reacting") is --><resources>
|
||||
<!-- These are mostly literal translations; I'm not sure what the usual jargon in Spanish for some terms (like "reacting") is -->
|
||||
|
||||
<resources>
|
||||
<string name="action_reply_to">Responder a</string>
|
||||
<!-- "Unmute" does not have a proper equivalent in Spanish so I chose "Show". Consequently, I used "Hide" instead of "Mute" in the previous one. -->
|
||||
<string name="action_emoji_react">Reaccionar</string>
|
||||
|
@ -7,65 +8,24 @@
|
|||
<string name="action_emoji_reacted_by">Quién ha reaccionado</string>
|
||||
<string name="action_enable_formatting_syntax">Activar %s</string>
|
||||
<string name="action_disable_formatting_syntax">Desactivar %s</string>
|
||||
|
||||
<string name="title_emoji_reacted_by">%s ha reaccionado con</string>
|
||||
|
||||
<string name="hint_appname">Nombre de la aplicación</string>
|
||||
<string name="hint_website">Página web de la aplicación</string>
|
||||
|
||||
<string name="admin">Administrador/a</string>
|
||||
<!-- "Admin" in Spanish is a gendered word. I used "masculine/femenine" since it is the more conservative option and should avoid more complaints than the informal neutral. -->
|
||||
<string name="moderator">Moderador/a</string>
|
||||
|
||||
<string name="error_media_upload_size">El archivo es demasiado grande</string>
|
||||
|
||||
<string name="notification_emoji_format">%s ha reaccionado con %s a tu publicación</string>
|
||||
<string name="notification_emoji_name">Reacciones</string>
|
||||
<string name="notification_emoji_description">Notificaciones acerca de reacciones nuevas</string>
|
||||
|
||||
<string name="pref_title_default_formatting">
|
||||
Sintaxis de formato por defecto(si la instancia los admite)</string>
|
||||
<string name="pref_title_notification_filter_emoji">se pueden enviar reacciones a mis publicaciones</string>
|
||||
<string name="pref_title_hide_muted_users">Ocultar a los usuarios silenciados</string>
|
||||
<string name="error_sticker_fetch">Se produjo un error al buscar la pegatina</string>
|
||||
<string name="pref_title_enable_experimental_stickers">Habilite los adhesivos experimentales de Pleroma-FE (si están disponibles)</string>
|
||||
<string name="dialog_delete_toot_warning">eliminar esta publicación\?</string>
|
||||
<string name="action_hide_reblogs">esconder repeticiones</string>
|
||||
<string name="reblog_private">Repetir la audiencia original</string>
|
||||
<string name="dialog_redraft_toot_warning">eliminar y re-hacer esta publicación\?</string>
|
||||
<string name="error_sender_account_gone">Error al enviar la publicación</string>
|
||||
<string name="notification_favourite_description">Notificaciones cuando tus publicaciones se marcan como favoritas</string>
|
||||
<string name="action_sticker">pegatinas</string>
|
||||
<string name="pref_title_enable_big_emojis">Habilitar emojis personalizados más grandes</string>
|
||||
<string name="action_toggle_visibility">Visibilidad de publicaciones</string>
|
||||
<string name="action_schedule_toot">Programar publicación</string>
|
||||
<string name="action_reblog">repetir</string>
|
||||
<string name="action_unreblog">remover repeticiónes</string>
|
||||
<string name="action_show_reblogs">mostrar repeticiones</string>
|
||||
<string name="action_send">ENVIAR</string>
|
||||
<string name="action_open_reblogger">Abrir autor repetido</string>
|
||||
<string name="action_open_reblogged_by">Mostrar repeticiones</string>
|
||||
<string name="unreblog_private">remover la repetición</string>
|
||||
<string name="action_open_toot">abrir publicación</string>
|
||||
<string name="compose_shortcut_long_label">Redactar publicación</string>
|
||||
<string name="description_status_reblogged">repetido</string>
|
||||
<string name="action_send_public">ENVIAR!</string>
|
||||
<string name="notification_reblog_format">%s repitió tu publicación</string>
|
||||
<string name="notification_favourite_format">%s marcó tu publicación como favorita</string>
|
||||
<string name="notification_boost_name">repeticiónes</string>
|
||||
<string name="notification_boost_description">Notificaciones cuando tus publicaciones se repiten</string>
|
||||
<string name="pref_title_confirm_reblogs">Mostrar diálogo de confirmación antes de repetir</string>
|
||||
<string name="pref_title_notification_filter_reblogs">mis publicaciones se repiten</string>
|
||||
<string name="pref_title_show_boosts">Mostrar repeticiones</string>
|
||||
<string name="pref_title_alway_open_spoiler">Siempre expandir las publicaciones marcadas con advertencias de contenido</string>
|
||||
<plurals name="reblogs">
|
||||
<item quantity="one"><b>%s</b> Repetir</item>
|
||||
<item quantity="other"><b>%s</b> se repite</item>
|
||||
</plurals>
|
||||
<string name="send_status_link_to">Compartir URL de publicación para …</string>
|
||||
<string name="send_status_content_to">Compartir publicación en …</string>
|
||||
<string name="send_toot_notification_title">enviando publicación…</string>
|
||||
<string name="send_toot_notification_channel_name">enviando publicaciones</string>
|
||||
<string name="send_toot_notification_saved_content">Se ha guardado una copia de la publicación en sus borradores</string>
|
||||
<string name="status_share_content">Compartir contenido de la publicación</string>
|
||||
<string name="status_share_link">Compartir enlace para publicar</string>
|
||||
<string name="status_boosted_format">%s repetido</string>
|
||||
<string name="title_reblogged_by">Repetido por</string>
|
||||
<string name="title_view_thread">Enviar</string>
|
||||
<string name="send_toot_notification_error_title">Error al enviar la publicación</string>
|
||||
<string name="title_scheduled_toot">Publicaciones programadas</string>
|
||||
</resources>
|
||||
</resources>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
|
||||
|
||||
<string name="dialog_whats_an_instance"> Sartu hemen helbidea edo mastodon.eus, mastodon.jalgi.eus, shitposter.club bezalako <a href="https://fediverse.network/pleroma?count=peers">edozein instantzia</a>,
|
||||
<string name="dialog_whats_an_instance">Sartu hemen helbidea edo mastodon.eus, mastodon.jalgi.eus, shitposter.club bezalako <a href="https://fediverse.network/pleroma?count=peers">edozein instantzia</a>,
|
||||
\n
|
||||
\n Oraindik ez baduzu konturik, instantziaren izena sartu eta bertan kontua sortu dezakezu.
|
||||
\n
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<resources>
|
||||
|
||||
<string name="about_tusky_license">تاسکی نرمافزاری آزاد است که تحت نگارش ۳ از پروانهٔ جامع همگانی گنو منتشر شده است. پروانه را میتوانید از اینجا ببینید: https://www.gnu.org/licenses/gpl-3.0.en.html</string>
|
||||
<string name="about_tusky_license">Husky یک برنامه آزاد و متنباز است که تحت مجوز GNU General Public License Version 3. منتشر شده است.
|
||||
\n شما میتوانید مجوز را از اینجا ببینید:
|
||||
\n https://www.gnu.org/licenses/gpl-3.0.en.html</string>
|
||||
|
||||
|
||||
<string name="about_tusky_account">نمایهٔ تاسکی</string>
|
||||
|
@ -36,7 +38,7 @@
|
|||
<string name="action_login">ورود با ماستودون</string>
|
||||
|
||||
|
||||
<string name="add_account_description">افزودن حساب جدید ماستودون</string>
|
||||
<string name="add_account_description">افزودن حساب ماستودون جدید</string>
|
||||
|
||||
|
||||
<string name="warning_scheduling_interval">ماستودون، بازهٔ زمانبندیای با کمینهٔ ۵ دقیقه دارد.</string>
|
||||
|
@ -44,13 +46,13 @@
|
|||
|
||||
|
||||
|
||||
<string name="dialog_whats_an_instance">نشانی یا دامنهٔ هر نمونهای میتواند وارد شود، مثل shitposter.club, blob.cat, expired.mentality.rip, و <a href="https://fediverse.network/pleroma?count=peers">بیشتر!</a>.
|
||||
\n
|
||||
\n اگر هنوز حسابی ندارید، میتوانید نام نمونه مورد نظر را وارد کرده و در آن حسابی بسازید.
|
||||
\n
|
||||
\n نمونه، جاییست که حسابتان رویش میزبانی میشود، ولی به راحتی میتوانید با دیگر افراد روی نمونههای دیگر ارتباط داشته و دنبالشان کنید؛ انگار که روی یک پایگاه باشید.
|
||||
\n
|
||||
\nاطّلاعات بیشتر میتواند در <a href="https://joinmastodon.org">joinmastodon.org</a> پیدا شود. </string>
|
||||
<string name="dialog_whats_an_instance">آدرس یا دامنه هر نمونه را میتوانید وارد کنید، مثلا shitposter.club, blob.cat, expired.mentality.rip, و <a href=\"https://fediverse.network/pleroma?count=peers\" >بیشتر!
|
||||
\n
|
||||
\n اگر شما هنوز حساب کاربری ندارید، میتوانید نام نمونه مورد نظر را وارد کنید از اینجا بپیوندید و حساب کاربری ایجاد کنید.
|
||||
\n
|
||||
\n نمونه جایی است که حساب کاربری شما میزبان آن است اما شما به راحتی میتوانید با افراد دیگر در نمونههای دیگر ارتباط برقرار کنید و آنها را دنبال کنید شما درست مثل اینکه در یکجا باشید.
|
||||
\n
|
||||
\n برای اطلاعات بیشتر به اینجا مراجعه کنید <a href="https://joinmastodon.org">joinmastodon.org</a>. </string>
|
||||
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -46,9 +46,9 @@
|
|||
|
||||
<string name="dialog_whats_an_instance">Het adres of domein van elke Mastodonserver kan hier worden ingevoerd, zoals shitposter.club, mastodon.nl, octodon.social en <a href="https://fediverse.network/pleroma?count=peers">nog veel meer!</a>
|
||||
\n
|
||||
\nWanneer je nog geen account hebt, kun je de naam van de Mastodonserver waar jij je graag wil registeren invoeren, waarna je daar een account kunt aanmaken.
|
||||
\n Wanneer je nog geen account hebt, kun je de naam van de Mastodonserver waar jij je graag wil registeren invoeren, waarna je daar een account kunt aanmaken.
|
||||
\n
|
||||
\nEen Mastodonserver (Engels: instance) is een computerserver waar jouw account zich bevindt (vergelijk het met een e-mailserver). Je kan eenvoudig mensen van andere servers volgen en met ze communiceren, alsof jullie met elkaar op dezelfde website zitten.
|
||||
\n Een Mastodonserver (Engels: instance) is een computerserver waar jouw account zich bevindt (vergelijk het met een e-mailserver). Je kan eenvoudig mensen van andere servers volgen en met ze communiceren, alsof jullie met elkaar op dezelfde website zitten.
|
||||
\n
|
||||
\n Meer informatie kun je vinden op <a href="https://joinmastodon.org">joinmastodon.org</a>.</string>
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<string name="add_account_description">Adicionar nova conta Pleroma</string>
|
||||
|
||||
|
||||
<string name="warning_scheduling_interval">Pleroma possui um intervalo mínimo de 5 minutos para agendar.</string>
|
||||
<string name="warning_scheduling_interval">Pleroma possui um intervalo mínimo de agendamento de 5 minutos.</string>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
<resources>
|
||||
|
||||
<string name="license_description">Husky มีโค้ดและสินทรัพย์จากโครงการโอเพนซอร์สต่อไปนี้:</string>
|
||||
|
||||
|
||||
<string name="restart_emoji">จำเป็นต้องเริ่ม Husky ใหม่ เพื่อใช้การเปลี่ยนแปลงเหล่านี้</string>
|
||||
|
||||
|
||||
<string name="about_tusky_account">บัญชีทางการของ Husky</string>
|
||||
|
||||
|
||||
<string name="about_tusky_license">Husky คือซอฟต์แวร์เสรีและโอเพนซอร์ส <!-- --> ภายใต้สัญญาอนุญาต GNU General Public License Version 3 <!-- -->ดูสัญญาที่ : https://www.gnu.org/licenses/gpl-3.0.ja.html</string>
|
||||
|
||||
|
||||
<string name="about_powered_by_tusky">ขับเคลื่อนด้วย Husky</string>
|
||||
|
||||
|
||||
<string name="about_tusky_version">Husky %s</string>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<string name="about_project_site">เว็บไซต์โปรเจกต์:
|
||||
\nhttps://husky.fwgs.ru</string>
|
||||
|
||||
|
||||
|
||||
|
||||
<string name="about_bug_feature_request_site">รายงานช่องโหว่ และ ขอฟีเจอร์ (ภาษาอังกฤษ):
|
||||
\nhttps://git.mentality.rip/FWGS/Husky/issues</string>
|
||||
|
||||
|
||||
|
||||
|
||||
<string name="add_account_description">เพิ่มบัญชี Pleroma ใหม่</string>
|
||||
|
||||
|
||||
<string name="action_login">เข้าสู่ระบบด้วย Pleroma</string>
|
||||
|
||||
|
||||
<string name="warning_scheduling_interval">Pleroma กำหนดเวลาขั้นต่ำ 5 นาที</string>
|
||||
|
||||
|
||||
|
||||
|
||||
<string name="dialog_whats_an_instance">"ใส่ที่อยู่หรือโดเมนของ Instance ได้ที่นี่ เช่น shitposter.club blob.cat expired.mentality.rip และ <a href=\"https://fediverse.network/pleroma?count=peers\">อีกมากมาย!</a>
|
||||
\n
|
||||
\nถ้ายังไม่มีบัญชี สามารถใส่ชื่อ Instance ที่ต้องการจะร่วมแล้วสร้างบัญชีที่นั่น
|
||||
\n
|
||||
\nInstance คือที่ที่หนึ่งไว้โฮสต์บัญชีคุณ แต่คุณยังสามารถสื่อสาร ติดตามบุคคลบน Instance อื่นได้เหมือนอยู่บนไซต์เดียวกัน
|
||||
\n
|
||||
\nพบข้อมูลเพิ่มเติมได้ที่ <a href=\"https://joinmastodon.org\">joinmastodon.org</a> "<a href="https://fediverse.network/pleroma?count=peers">more!</a>
|
||||
\n\nIf you don\'t yet have an account, you can enter the name of the instance you\'d like to
|
||||
join and create an account there.\n\nAn instance is a single place where your account is
|
||||
hosted, but you can easily communicate with and follow folks on other instances as though
|
||||
you were on the same site.
|
||||
\n\nMore info can be found at <a href="https://joinmastodon.org">joinmastodon.org</a>.
|
||||
</string>
|
||||
|
||||
|
||||
</resources>
|
|
@ -174,13 +174,6 @@
|
|||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<!-- disable automatic WorkManager initialization -->
|
||||
<provider
|
||||
android:name="androidx.work.impl.WorkManagerInitializer"
|
||||
android:authorities="${applicationId}.workmanager-init"
|
||||
android:exported="false"
|
||||
tools:node="remove"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -43,18 +43,6 @@ public class EmojiPreference extends Preference {
|
|||
|
||||
private boolean updated, currentNeedsUpdate;
|
||||
|
||||
public EmojiPreference(Context context) {
|
||||
super(context);
|
||||
|
||||
// Find out which font is currently active
|
||||
this.selected = EmojiCompatFont.byId(PreferenceManager
|
||||
.getDefaultSharedPreferences(context)
|
||||
.getInt(FONT_PREFERENCE, 0));
|
||||
// We'll use this later to determine if anything has changed
|
||||
this.original = this.selected;
|
||||
|
||||
setSummary(selected.getDisplay(context));
|
||||
}
|
||||
|
||||
public EmojiPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
|
|
@ -31,7 +31,6 @@ import android.view.View
|
|||
import android.widget.ImageView
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.emoji.text.EmojiCompat
|
||||
|
@ -49,7 +48,6 @@ import com.keylesspalace.tusky.appstore.*
|
|||
import com.keylesspalace.tusky.components.compose.ComposeActivity
|
||||
import com.keylesspalace.tusky.components.compose.ComposeActivity.Companion.canHandleMimeType
|
||||
import com.keylesspalace.tusky.components.conversation.ConversationsRepository
|
||||
import com.keylesspalace.tusky.components.notifications.NotificationHelper
|
||||
import com.keylesspalace.tusky.components.scheduled.ScheduledTootActivity
|
||||
import com.keylesspalace.tusky.components.search.SearchActivity
|
||||
import com.keylesspalace.tusky.db.AccountEntity
|
||||
|
@ -60,10 +58,7 @@ import com.keylesspalace.tusky.interfaces.ActionButtonActivity
|
|||
import com.keylesspalace.tusky.interfaces.ReselectableFragment
|
||||
import com.keylesspalace.tusky.pager.MainPagerAdapter
|
||||
import com.keylesspalace.tusky.util.*
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import com.mikepenz.materialdrawer.iconics.iconicsIcon
|
||||
import com.mikepenz.materialdrawer.model.*
|
||||
import com.mikepenz.materialdrawer.model.interfaces.*
|
||||
|
@ -93,7 +88,8 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
private lateinit var drawerToggle: ActionBarDrawerToggle
|
||||
|
||||
private var notificationTabPosition = 0
|
||||
private var onTabSelectedListener: OnTabSelectedListener? = null
|
||||
|
||||
private var adapter: MainPagerAdapter? = null
|
||||
|
||||
private val emojiInitCallback = object : InitCallback() {
|
||||
override fun onInitialized() {
|
||||
|
@ -163,19 +159,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
val composeIntent = Intent(applicationContext, ComposeActivity::class.java)
|
||||
startActivity(composeIntent)
|
||||
}
|
||||
|
||||
mainToolbar.menu.add(R.string.action_search).apply {
|
||||
setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
|
||||
icon = IconicsDrawable(this@MainActivity, GoogleMaterial.Icon.gmd_search).apply {
|
||||
sizeDp = 20
|
||||
colorInt = ThemeUtils.getColor(this@MainActivity, android.R.attr.textColorPrimary)
|
||||
}
|
||||
setOnMenuItemClickListener {
|
||||
startActivity(SearchActivity.getIntent(this@MainActivity))
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
setupDrawer(savedInstanceState)
|
||||
|
||||
/* Fetch user info while we're doing other things. This has to be done after setting up the
|
||||
|
@ -184,11 +167,35 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
|
||||
setupTabs(showNotificationTab)
|
||||
|
||||
val pageMargin = resources.getDimensionPixelSize(R.dimen.tab_page_margin)
|
||||
viewPager.setPageTransformer(MarginPageTransformer(pageMargin))
|
||||
|
||||
val uswSwipeForTabs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getBoolean("enableSwipeForTabs", true)
|
||||
viewPager.isUserInputEnabled = uswSwipeForTabs
|
||||
|
||||
tabLayout.addOnTabSelectedListener(object : OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||
if (tab.position == notificationTabPosition) {
|
||||
NotificationHelper.clearNotificationsForActiveAccount(this@MainActivity, accountManager)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTabUnselected(tab: TabLayout.Tab) {}
|
||||
|
||||
override fun onTabReselected(tab: TabLayout.Tab) {
|
||||
val fragment = adapter?.getFragment(tab.position)
|
||||
if (fragment is ReselectableFragment) {
|
||||
(fragment as ReselectableFragment).onReselect()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Setup push notifications
|
||||
if (NotificationHelper.areNotificationsEnabled(this, accountManager)) {
|
||||
NotificationHelper.enablePullNotifications(this)
|
||||
NotificationHelper.enablePullNotifications()
|
||||
} else {
|
||||
NotificationHelper.disablePullNotifications(this)
|
||||
NotificationHelper.disablePullNotifications()
|
||||
}
|
||||
eventHub.events
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -369,6 +376,13 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
startActivityWithSlideInAnimation(ListsActivity.newIntent(context))
|
||||
}
|
||||
},
|
||||
primaryDrawerItem {
|
||||
nameRes = R.string.action_search
|
||||
iconicsIcon = GoogleMaterial.Icon.gmd_search
|
||||
onClick = {
|
||||
startActivityWithSlideInAnimation(SearchActivity.getIntent(context))
|
||||
}
|
||||
},
|
||||
primaryDrawerItem {
|
||||
nameRes = R.string.action_access_saved_toot
|
||||
iconRes = R.drawable.ic_notebook
|
||||
|
@ -447,37 +461,20 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
}
|
||||
|
||||
private fun setupTabs(selectNotificationTab: Boolean) {
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
|
||||
val activeTabLayout = if(preferences.getString("mainNavPosition", "top") == "bottom") {
|
||||
val actionBarSize = ThemeUtils.getDimension(this, R.attr.actionBarSize)
|
||||
val fabMargin = resources.getDimensionPixelSize(R.dimen.fabMargin)
|
||||
(composeButton.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = actionBarSize + fabMargin
|
||||
tabLayout.hide()
|
||||
bottomTabLayout
|
||||
} else {
|
||||
bottomNav.hide()
|
||||
(viewPager.layoutParams as CoordinatorLayout.LayoutParams).bottomMargin = 0
|
||||
(composeButton.layoutParams as CoordinatorLayout.LayoutParams).anchorId = R.id.viewPager
|
||||
tabLayout
|
||||
}
|
||||
|
||||
val tabs = accountManager.activeAccount!!.tabPreferences
|
||||
|
||||
val adapter = MainPagerAdapter(tabs, this)
|
||||
adapter = MainPagerAdapter(tabs, this)
|
||||
viewPager.adapter = adapter
|
||||
TabLayoutMediator(activeTabLayout, viewPager, TabConfigurationStrategy { _: TabLayout.Tab?, _: Int -> }).attach()
|
||||
activeTabLayout.removeAllTabs()
|
||||
TabLayoutMediator(tabLayout, viewPager, TabConfigurationStrategy { _: TabLayout.Tab?, _: Int -> }).attach()
|
||||
tabLayout.removeAllTabs()
|
||||
for (i in tabs.indices) {
|
||||
val tab = activeTabLayout.newTab()
|
||||
val tab = tabLayout.newTab()
|
||||
.setIcon(tabs[i].icon)
|
||||
if (tabs[i].id == LIST) {
|
||||
tab.contentDescription = tabs[i].arguments[1]
|
||||
} else {
|
||||
tab.setContentDescription(tabs[i].text)
|
||||
}
|
||||
activeTabLayout.addTab(tab)
|
||||
|
||||
tabLayout.addTab(tab)
|
||||
if (tabs[i].id == NOTIFICATIONS) {
|
||||
notificationTabPosition = i
|
||||
if (selectNotificationTab) {
|
||||
|
@ -485,41 +482,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
val pageMargin = resources.getDimensionPixelSize(R.dimen.tab_page_margin)
|
||||
viewPager.setPageTransformer(MarginPageTransformer(pageMargin))
|
||||
|
||||
val enableSwipeForTabs = preferences.getBoolean("enableSwipeForTabs", true)
|
||||
viewPager.isUserInputEnabled = enableSwipeForTabs
|
||||
|
||||
onTabSelectedListener?.let {
|
||||
activeTabLayout.removeOnTabSelectedListener(it)
|
||||
}
|
||||
|
||||
onTabSelectedListener = object : OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||
if (tab.position == notificationTabPosition) {
|
||||
NotificationHelper.clearNotificationsForActiveAccount(this@MainActivity, accountManager)
|
||||
}
|
||||
|
||||
mainToolbar.title = tabs[tab.position].title(this@MainActivity)
|
||||
}
|
||||
|
||||
override fun onTabUnselected(tab: TabLayout.Tab) {}
|
||||
|
||||
override fun onTabReselected(tab: TabLayout.Tab) {
|
||||
val fragment = adapter.getFragment(tab.position)
|
||||
if (fragment is ReselectableFragment) {
|
||||
(fragment as ReselectableFragment).onReselect()
|
||||
}
|
||||
}
|
||||
}.also {
|
||||
activeTabLayout.addOnTabSelectedListener(it)
|
||||
}
|
||||
|
||||
val activeTabPosition = if (selectNotificationTab) notificationTabPosition else 0
|
||||
mainToolbar.title = tabs[activeTabPosition].title(this@MainActivity)
|
||||
|
||||
}
|
||||
|
||||
private fun handleProfileClick(profile: IProfile, current: Boolean): Boolean {
|
||||
|
@ -563,18 +525,19 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
|||
.setTitle(R.string.action_logout)
|
||||
.setMessage(getString(R.string.action_logout_confirm, activeAccount.fullName))
|
||||
.setPositiveButton(android.R.string.yes) { _: DialogInterface?, _: Int ->
|
||||
NotificationHelper.deleteNotificationChannelsForAccount(activeAccount, this)
|
||||
NotificationHelper.deleteNotificationChannelsForAccount(activeAccount, this@MainActivity)
|
||||
cacheUpdater.clearForUser(activeAccount.id)
|
||||
conversationRepository.deleteCacheForAccount(activeAccount.id)
|
||||
removeShortcut(this, activeAccount)
|
||||
val newAccount = accountManager.logActiveAccountOut()
|
||||
if (!NotificationHelper.areNotificationsEnabled(this, accountManager)) {
|
||||
NotificationHelper.disablePullNotifications(this)
|
||||
if (!NotificationHelper.areNotificationsEnabled(this@MainActivity, accountManager)) {
|
||||
NotificationHelper.disablePullNotifications()
|
||||
}
|
||||
val intent = if (newAccount == null) {
|
||||
LoginActivity.getIntent(this, false)
|
||||
val intent: Intent
|
||||
intent = if (newAccount == null) {
|
||||
LoginActivity.getIntent(this@MainActivity, false)
|
||||
} else {
|
||||
Intent(this, MainActivity::class.java)
|
||||
Intent(this@MainActivity, MainActivity::class.java)
|
||||
}
|
||||
startActivity(intent)
|
||||
finishWithoutSlideOutAnimation()
|
||||
|
|
|
@ -130,7 +130,7 @@ class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreference
|
|||
}
|
||||
"statusTextSize", "absoluteTimeView", "showBotOverlay", "animateGifAvatars",
|
||||
"useBlurhash", "showCardsInTimelines", "confirmReblogs", "hideMutedUsers",
|
||||
"enableSwipeForTabs", "bigEmojis", "mainNavPosition" -> {
|
||||
"enableSwipeForTabs", "bigEmojis" -> {
|
||||
restartActivitiesOnExit = true
|
||||
}
|
||||
"language" -> {
|
||||
|
|
|
@ -21,7 +21,7 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.di.Injectable
|
||||
|
||||
import com.keylesspalace.tusky.components.notifications.NotificationHelper
|
||||
import com.keylesspalace.tusky.util.NotificationHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
class SplashActivity : AppCompatActivity(), Injectable {
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
package com.keylesspalace.tusky
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.fragment.app.Fragment
|
||||
|
@ -37,58 +36,17 @@ data class TabData(val id: String,
|
|||
@StringRes val text: Int,
|
||||
@DrawableRes val icon: Int,
|
||||
val fragment: (List<String>) -> Fragment,
|
||||
val arguments: List<String> = emptyList(),
|
||||
val title: (Context) -> String = { context -> context.getString(text)}
|
||||
)
|
||||
val arguments: List<String> = emptyList())
|
||||
|
||||
fun createTabDataFromId(id: String, arguments: List<String> = emptyList()): TabData {
|
||||
return when (id) {
|
||||
HOME -> TabData(
|
||||
HOME,
|
||||
R.string.title_home,
|
||||
R.drawable.ic_home_24dp,
|
||||
{ TimelineFragment.newInstance(TimelineFragment.Kind.HOME) }
|
||||
)
|
||||
NOTIFICATIONS -> TabData(
|
||||
NOTIFICATIONS,
|
||||
R.string.title_notifications,
|
||||
R.drawable.ic_notifications_24dp,
|
||||
{ NotificationsFragment.newInstance() }
|
||||
)
|
||||
LOCAL -> TabData(
|
||||
LOCAL,
|
||||
R.string.title_public_local,
|
||||
R.drawable.ic_local_24dp,
|
||||
{ TimelineFragment.newInstance(TimelineFragment.Kind.PUBLIC_LOCAL) }
|
||||
)
|
||||
FEDERATED -> TabData(
|
||||
FEDERATED,
|
||||
R.string.title_public_federated,
|
||||
R.drawable.ic_public_24dp,
|
||||
{ TimelineFragment.newInstance(TimelineFragment.Kind.PUBLIC_FEDERATED) }
|
||||
)
|
||||
DIRECT -> TabData(
|
||||
DIRECT,
|
||||
R.string.title_direct_messages,
|
||||
R.drawable.ic_reblog_direct_24dp,
|
||||
{ ConversationsFragment.newInstance() }
|
||||
)
|
||||
HASHTAG -> TabData(
|
||||
HASHTAG,
|
||||
R.string.hashtags,
|
||||
R.drawable.ic_hashtag,
|
||||
{ args -> TimelineFragment.newHashtagInstance(args) },
|
||||
arguments,
|
||||
{ context -> arguments.joinToString(separator = " ") { context.getString(R.string.title_tag, it) }}
|
||||
)
|
||||
LIST -> TabData(
|
||||
LIST,
|
||||
R.string.list,
|
||||
R.drawable.ic_list,
|
||||
{ args -> TimelineFragment.newInstance(TimelineFragment.Kind.LIST, args.getOrNull(0).orEmpty()) },
|
||||
arguments,
|
||||
{ arguments.getOrNull(1).orEmpty() }
|
||||
)
|
||||
HOME -> TabData(HOME, R.string.title_home, R.drawable.ic_home_24dp, { TimelineFragment.newInstance(TimelineFragment.Kind.HOME) })
|
||||
NOTIFICATIONS -> TabData(NOTIFICATIONS, R.string.title_notifications, R.drawable.ic_notifications_24dp, { NotificationsFragment.newInstance() })
|
||||
LOCAL -> TabData(LOCAL, R.string.title_public_local, R.drawable.ic_local_24dp, { TimelineFragment.newInstance(TimelineFragment.Kind.PUBLIC_LOCAL) })
|
||||
FEDERATED -> TabData(FEDERATED, R.string.title_public_federated, R.drawable.ic_public_24dp, { TimelineFragment.newInstance(TimelineFragment.Kind.PUBLIC_FEDERATED) })
|
||||
DIRECT -> TabData(DIRECT, R.string.title_direct_messages, R.drawable.ic_reblog_direct_24dp, { ConversationsFragment.newInstance() })
|
||||
HASHTAG -> TabData(HASHTAG, R.string.hashtags, R.drawable.ic_hashtag, { args -> TimelineFragment.newHashtagInstance(args) }, arguments)
|
||||
LIST -> TabData(LIST, R.string.list, R.drawable.ic_list, { args -> TimelineFragment.newInstance(TimelineFragment.Kind.LIST, args.getOrNull(0).orEmpty()) }, arguments)
|
||||
else -> throw IllegalArgumentException("unknown tab type")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,10 +21,12 @@ import android.content.res.Configuration
|
|||
import android.util.Log
|
||||
import androidx.emoji.text.EmojiCompat
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.work.WorkManager
|
||||
import com.keylesspalace.tusky.components.notifications.NotificationWorkerFactory
|
||||
import com.evernote.android.job.JobManager
|
||||
import com.keylesspalace.tusky.di.AppInjector
|
||||
import com.keylesspalace.tusky.util.*
|
||||
import com.keylesspalace.tusky.util.EmojiCompatFont
|
||||
import com.keylesspalace.tusky.util.LocaleManager
|
||||
import com.keylesspalace.tusky.util.NotificationPullJobCreator
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import com.uber.autodispose.AutoDisposePlugins
|
||||
import dagger.android.DispatchingAndroidInjector
|
||||
import dagger.android.HasAndroidInjector
|
||||
|
@ -38,7 +40,7 @@ class TuskyApplication : Application(), HasAndroidInjector {
|
|||
@Inject
|
||||
lateinit var androidInjector: DispatchingAndroidInjector<Any>
|
||||
@Inject
|
||||
lateinit var notificationWorkerFactory: NotificationWorkerFactory
|
||||
lateinit var notificationPullJobCreator: NotificationPullJobCreator
|
||||
|
||||
override fun onCreate() {
|
||||
|
||||
|
@ -63,12 +65,7 @@ class TuskyApplication : Application(), HasAndroidInjector {
|
|||
val theme = preferences.getString("appTheme", ThemeUtils.APP_THEME_DEFAULT)
|
||||
ThemeUtils.setAppNightMode(theme)
|
||||
|
||||
WorkManager.initialize(
|
||||
this,
|
||||
androidx.work.Configuration.Builder()
|
||||
.setWorkerFactory(notificationWorkerFactory)
|
||||
.build()
|
||||
)
|
||||
JobManager.create(this).addJobCreator(notificationPullJobCreator)
|
||||
|
||||
RxJavaPlugins.setErrorHandler {
|
||||
Log.w("RxJava", "undeliverable exception", it)
|
||||
|
|
|
@ -1023,7 +1023,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
|||
status.getAttachments().size() == 0 &&
|
||||
status.getCard() != null &&
|
||||
!TextUtils.isEmpty(status.getCard().getUrl()) &&
|
||||
(!status.isCollapsible() || !status.isCollapsed())) {
|
||||
!status.isCollapsed()) {
|
||||
final Card card = status.getCard();
|
||||
cardView.setVisibility(View.VISIBLE);
|
||||
cardTitle.setText(card.getTitle());
|
||||
|
|
|
@ -14,7 +14,6 @@ data class UnfollowEvent(val accountId: String) : Dispatchable
|
|||
data class BlockEvent(val accountId: String) : Dispatchable
|
||||
data class MuteEvent(val accountId: String) : Dispatchable
|
||||
data class StatusDeletedEvent(val statusId: String) : Dispatchable
|
||||
data class StatusPreviewEvent(val status: Status) : Dispatchable
|
||||
data class StatusComposedEvent(val status: Status) : Dispatchable
|
||||
data class StatusScheduledEvent(val status: Status) : Dispatchable
|
||||
data class ProfileEditedEvent(val newProfileData: Account) : Dispatchable
|
||||
|
|
|
@ -70,7 +70,6 @@ import com.keylesspalace.tusky.R
|
|||
import com.keylesspalace.tusky.adapter.ComposeAutoCompleteAdapter
|
||||
import com.keylesspalace.tusky.adapter.EmojiAdapter
|
||||
import com.keylesspalace.tusky.adapter.OnEmojiSelectedListener
|
||||
import com.keylesspalace.tusky.appstore.*
|
||||
import com.keylesspalace.tusky.components.compose.dialog.makeCaptionDialog
|
||||
import com.keylesspalace.tusky.components.compose.dialog.showAddPollDialog
|
||||
import com.keylesspalace.tusky.components.compose.view.ComposeOptionsListener
|
||||
|
@ -109,16 +108,12 @@ class ComposeActivity : BaseActivity(),
|
|||
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelFactory
|
||||
|
||||
@Inject
|
||||
lateinit var eventHub: EventHub
|
||||
|
||||
private lateinit var composeOptionsBehavior: BottomSheetBehavior<*>
|
||||
private lateinit var addMediaBehavior: BottomSheetBehavior<*>
|
||||
private lateinit var emojiBehavior: BottomSheetBehavior<*>
|
||||
private lateinit var scheduleBehavior: BottomSheetBehavior<*>
|
||||
private lateinit var stickerBehavior: BottomSheetBehavior<*>
|
||||
private lateinit var previewBehavior: BottomSheetBehavior<*>
|
||||
|
||||
// this only exists when a status is trying to be sent, but uploads are still occurring
|
||||
private var finishingUploadDialog: ProgressDialog? = null
|
||||
|
@ -197,12 +192,6 @@ class ComposeActivity : BaseActivity(),
|
|||
viewModel.setupComplete.value = true
|
||||
|
||||
stickerKeyboard.isSticky = true
|
||||
|
||||
eventHub.events.subscribe { event ->
|
||||
when(event) {
|
||||
is StatusPreviewEvent -> onStatusPreviewReady(event.status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun uriToFilename(uri: Uri): String {
|
||||
|
@ -267,22 +256,25 @@ class ComposeActivity : BaseActivity(),
|
|||
for (uri in uriList) {
|
||||
pickMedia(uri)
|
||||
}
|
||||
} else if (type == "text/plain" && intent.action == Intent.ACTION_SEND) {
|
||||
} else if (type == "text/plain") {
|
||||
val action = intent.action
|
||||
if (action != null && action == Intent.ACTION_SEND) {
|
||||
val subject = intent.getStringExtra(Intent.EXTRA_SUBJECT)
|
||||
val text = intent.getStringExtra(Intent.EXTRA_TEXT)
|
||||
val shareBody = text ?: subject
|
||||
|
||||
val subject = intent.getStringExtra(Intent.EXTRA_SUBJECT)
|
||||
val text = intent.getStringExtra(Intent.EXTRA_TEXT).orEmpty()
|
||||
val shareBody = if (!subject.isNullOrBlank() && subject !in text) {
|
||||
subject + '\n' + text
|
||||
} else {
|
||||
text
|
||||
}
|
||||
if (shareBody != null) {
|
||||
if (!subject.isNullOrBlank() && subject !in shareBody) {
|
||||
composeContentWarningField.setText(subject)
|
||||
viewModel.showContentWarning.value = true
|
||||
}
|
||||
|
||||
if (shareBody.isNotBlank()) {
|
||||
val start = composeEditField.selectionStart.coerceAtLeast(0)
|
||||
val end = composeEditField.selectionEnd.coerceAtLeast(0)
|
||||
val left = min(start, end)
|
||||
val right = max(start, end)
|
||||
composeEditField.text.replace(left, right, shareBody, 0, shareBody.length)
|
||||
val start = composeEditField.selectionStart.coerceAtLeast(0)
|
||||
val end = composeEditField.selectionEnd.coerceAtLeast(0)
|
||||
val left = min(start, end)
|
||||
val right = max(start, end)
|
||||
composeEditField.text.replace(left, right, shareBody, 0, shareBody.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -394,7 +386,6 @@ class ComposeActivity : BaseActivity(),
|
|||
}
|
||||
|
||||
if(instanceData.software.equals("pleroma")) {
|
||||
composePreviewButton.visibility = View.VISIBLE
|
||||
reenableAttachments()
|
||||
}
|
||||
}
|
||||
|
@ -467,15 +458,13 @@ class ComposeActivity : BaseActivity(),
|
|||
scheduleBehavior = BottomSheetBehavior.from(composeScheduleView)
|
||||
emojiBehavior = BottomSheetBehavior.from(emojiView)
|
||||
stickerBehavior = BottomSheetBehavior.from(stickerKeyboard)
|
||||
previewBehavior = BottomSheetBehavior.from(previewScroll)
|
||||
|
||||
emojiView.layoutManager = GridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, false)
|
||||
enableButton(composeEmojiButton, clickable = false, colorActive = false)
|
||||
enableButton(composeStickerButton, false, false)
|
||||
|
||||
// Setup the interface buttons.
|
||||
composeTootButton.setOnClickListener { onSendClicked(false) }
|
||||
composePreviewButton.setOnClickListener { onSendClicked(true) }
|
||||
composeTootButton.setOnClickListener { onSendClicked() }
|
||||
composeAddMediaButton.setOnClickListener { openPickDialog() }
|
||||
composeToggleVisibilityButton.setOnClickListener { showComposeOptions() }
|
||||
composeContentWarningButton.setOnClickListener { onContentWarningChanged() }
|
||||
|
@ -785,7 +774,6 @@ class ComposeActivity : BaseActivity(),
|
|||
composeScheduleButton.isClickable = enable
|
||||
composeFormattingSyntax.isClickable = enable
|
||||
composeTootButton.isEnabled = enable
|
||||
composePreviewButton.isEnabled = enable
|
||||
composeStickerButton.isEnabled = enable
|
||||
}
|
||||
|
||||
|
@ -811,7 +799,6 @@ class ComposeActivity : BaseActivity(),
|
|||
emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
stickerBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
previewBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
} else {
|
||||
composeOptionsBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
|
@ -832,7 +819,6 @@ class ComposeActivity : BaseActivity(),
|
|||
addMediaBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
stickerBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
previewBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
} else {
|
||||
scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
|
@ -850,7 +836,6 @@ class ComposeActivity : BaseActivity(),
|
|||
composeOptionsBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
addMediaBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
previewBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
} else {
|
||||
emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
|
@ -865,7 +850,6 @@ class ComposeActivity : BaseActivity(),
|
|||
emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
stickerBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
previewBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
} else {
|
||||
addMediaBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
|
@ -966,31 +950,13 @@ class ComposeActivity : BaseActivity(),
|
|||
return composeScheduleView.verifyScheduledTime(composeScheduleView.getDateTime(viewModel.scheduledAt.value))
|
||||
}
|
||||
|
||||
private fun onSendClicked(preview: Boolean) {
|
||||
if(preview && previewBehavior.state == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
previewBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
return
|
||||
}
|
||||
|
||||
private fun onSendClicked() {
|
||||
if (verifyScheduledTime()) {
|
||||
sendStatus(preview)
|
||||
sendStatus()
|
||||
} else {
|
||||
showScheduleView()
|
||||
}
|
||||
}
|
||||
|
||||
private fun onStatusPreviewReady(status: Status) {
|
||||
enableButtons(true)
|
||||
previewView.setupWithStatus(status)
|
||||
previewBehavior.state = BottomSheetBehavior.STATE_EXPANDED
|
||||
addMediaBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
composeOptionsBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
stickerBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
|
||||
// Log.d("ComposeActivityPreview", "Preview: " + status.content)
|
||||
}
|
||||
|
||||
/** This is for the fancy keyboards which can insert images and stuff. */
|
||||
override fun onCommitContent(inputContentInfo: InputContentInfoCompat, flags: Int, opts: Bundle?): Boolean {
|
||||
|
@ -1014,7 +980,7 @@ class ComposeActivity : BaseActivity(),
|
|||
return false
|
||||
}
|
||||
|
||||
private fun sendStatus(preview: Boolean) {
|
||||
private fun sendStatus() {
|
||||
enableButtons(false)
|
||||
val contentText = composeEditField.text.toString()
|
||||
var spoilerText = ""
|
||||
|
@ -1030,10 +996,9 @@ class ComposeActivity : BaseActivity(),
|
|||
this, getString(R.string.dialog_title_finishing_media_upload),
|
||||
getString(R.string.dialog_message_uploading_media), true, true)
|
||||
|
||||
viewModel.sendStatus(contentText, spoilerText, preview).observe(this, Observer {
|
||||
viewModel.sendStatus(contentText, spoilerText).observe(this, Observer {
|
||||
finishingUploadDialog?.dismiss()
|
||||
if(!preview)
|
||||
deleteDraftAndFinish()
|
||||
deleteDraftAndFinish()
|
||||
})
|
||||
|
||||
} else {
|
||||
|
@ -1194,7 +1159,6 @@ class ComposeActivity : BaseActivity(),
|
|||
emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
stickerBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
previewBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1207,7 +1171,7 @@ class ComposeActivity : BaseActivity(),
|
|||
if (event.isCtrlPressed) {
|
||||
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
||||
// send toot by pressing CTRL + ENTER
|
||||
this.onSendClicked(false)
|
||||
this.onSendClicked()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -1268,7 +1232,6 @@ class ComposeActivity : BaseActivity(),
|
|||
composeOptionsBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
emojiBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
scheduleBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
previewBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
} else {
|
||||
stickerBehavior.state = BottomSheetBehavior.STATE_HIDDEN
|
||||
}
|
||||
|
|
|
@ -302,8 +302,7 @@ class ComposeViewModel
|
|||
*/
|
||||
fun sendStatus(
|
||||
content: String,
|
||||
spoilerText: String,
|
||||
preview: Boolean
|
||||
spoilerText: String
|
||||
): LiveData<Unit> {
|
||||
return media
|
||||
.filter { items -> items.all { it.uploadPercent == -1 } }
|
||||
|
@ -331,7 +330,6 @@ class ComposeViewModel
|
|||
replyingStatusContent = null,
|
||||
replyingStatusAuthorUsername = null,
|
||||
formattingSyntax = formattingSyntax,
|
||||
preview = preview,
|
||||
savedJsonUrls = null,
|
||||
accountId = accountManager.activeAccount!!.id,
|
||||
savedTootUid = 0,
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
/* Copyright 2020 Tusky Contributors
|
||||
*
|
||||
* This file is part of Tusky.
|
||||
*
|
||||
* Tusky is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with Tusky. If
|
||||
* not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
package com.keylesspalace.tusky.components.notifications
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.work.ListenableWorker
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerFactory
|
||||
import androidx.work.WorkerParameters
|
||||
import com.keylesspalace.tusky.db.AccountEntity
|
||||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.entity.Notification
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.util.isLessThan
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
|
||||
class NotificationWorker(
|
||||
private val context: Context,
|
||||
params: WorkerParameters,
|
||||
private val mastodonApi: MastodonApi,
|
||||
private val accountManager: AccountManager
|
||||
) : Worker(context, params) {
|
||||
|
||||
override fun doWork(): Result {
|
||||
val accountList = accountManager.getAllAccountsOrderedByActive()
|
||||
for (account in accountList) {
|
||||
if (account.notificationsEnabled) {
|
||||
try {
|
||||
Log.d(TAG, "getting Notifications for " + account.fullName)
|
||||
// don't care about withMuted because they are always silently ignored
|
||||
val notificationsResponse = mastodonApi.notificationsWithAuth(
|
||||
String.format("Bearer %s", account.accessToken),
|
||||
account.domain, true
|
||||
).execute()
|
||||
val notifications = notificationsResponse.body()
|
||||
if (notificationsResponse.isSuccessful && notifications != null) {
|
||||
onNotificationsReceived(account, notifications)
|
||||
} else {
|
||||
Log.w(TAG, "error receiving notifications")
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
Log.w(TAG, "error receiving notifications", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
private fun onNotificationsReceived(account: AccountEntity, notificationList: List<Notification>) {
|
||||
val newId = account.lastNotificationId
|
||||
var newestId = ""
|
||||
var isFirstOfBatch = true
|
||||
notificationList.reversed().forEach { notification ->
|
||||
val currentId = notification.id
|
||||
if (newestId.isLessThan(currentId)) {
|
||||
newestId = currentId
|
||||
}
|
||||
if (newId.isLessThan(currentId)) {
|
||||
NotificationHelper.make(context, notification, account, isFirstOfBatch)
|
||||
isFirstOfBatch = false
|
||||
}
|
||||
}
|
||||
account.lastNotificationId = newestId
|
||||
accountManager.saveAccount(account)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "NotificationWorker"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class NotificationWorkerFactory @Inject constructor(
|
||||
val api: MastodonApi,
|
||||
val accountManager: AccountManager
|
||||
): WorkerFactory() {
|
||||
|
||||
override fun createWorker(appContext: Context, workerClassName: String, workerParameters: WorkerParameters): ListenableWorker? {
|
||||
if(workerClassName == NotificationWorker::class.java.name) {
|
||||
return NotificationWorker(appContext, workerParameters, api, accountManager)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
|
@ -30,8 +30,7 @@ data class Instance (
|
|||
@SerializedName("contact_account") val contactAccount: Account,
|
||||
@SerializedName("max_toot_chars") val maxTootChars: Int?,
|
||||
@SerializedName("max_bio_chars") val maxBioChars: Int?,
|
||||
@SerializedName("poll_limits") val pollLimits: PollLimits?,
|
||||
val pleroma: InstancePleroma
|
||||
@SerializedName("poll_limits") val pollLimits: PollLimits?
|
||||
) {
|
||||
override fun hashCode(): Int {
|
||||
return uri.hashCode()
|
||||
|
@ -46,14 +45,6 @@ data class Instance (
|
|||
}
|
||||
}
|
||||
|
||||
data class InstancePleroma (
|
||||
val metadata: InstancePleromaMetadata
|
||||
)
|
||||
|
||||
data class InstancePleromaMetadata (
|
||||
val features: List<String>
|
||||
)
|
||||
|
||||
data class PollLimits (
|
||||
@SerializedName("max_options") val maxOptions: Int?,
|
||||
@SerializedName("max_option_chars") val maxOptionChars: Int?
|
||||
|
|
|
@ -28,8 +28,7 @@ data class NewStatus(
|
|||
@SerializedName("media_ids") val mediaIds: List<String>?,
|
||||
@SerializedName("scheduled_at") val scheduledAt: String?,
|
||||
val poll: NewPoll?,
|
||||
var content_type: String?,
|
||||
val preview: Boolean?
|
||||
var content_type: String?
|
||||
)
|
||||
|
||||
@Parcelize
|
||||
|
|
|
@ -18,7 +18,6 @@ package com.keylesspalace.tusky.fragment;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -63,7 +62,6 @@ import com.keylesspalace.tusky.repository.TimelineRepository;
|
|||
import com.keylesspalace.tusky.repository.TimelineRequestMode;
|
||||
import com.keylesspalace.tusky.util.CardViewMode;
|
||||
import com.keylesspalace.tusky.util.Either;
|
||||
import com.keylesspalace.tusky.util.HttpHeaderLink;
|
||||
import com.keylesspalace.tusky.util.LinkHelper;
|
||||
import com.keylesspalace.tusky.util.ListStatusAccessibilityDelegate;
|
||||
import com.keylesspalace.tusky.util.ListUtils;
|
||||
|
@ -153,10 +151,6 @@ public class TimelineFragment extends SFragment implements
|
|||
private Kind kind;
|
||||
private String id;
|
||||
private List<String> tags;
|
||||
/**
|
||||
* For some timeline kinds we must use LINK headers and not just status ids.
|
||||
*/
|
||||
private String nextId;
|
||||
private LinearLayoutManager layoutManager;
|
||||
private EndlessOnScrollListener scrollListener;
|
||||
private boolean filterRemoveReplies;
|
||||
|
@ -226,7 +220,7 @@ public class TimelineFragment extends SFragment implements
|
|||
|| kind == Kind.LIST) {
|
||||
id = arguments.getString(ID_ARG);
|
||||
}
|
||||
if (kind == Kind.TAG) {
|
||||
if(kind == Kind.TAG) {
|
||||
tags = arguments.getStringArrayList(HASHTAGS_ARG);
|
||||
}
|
||||
|
||||
|
@ -980,17 +974,13 @@ public class TimelineFragment extends SFragment implements
|
|||
updateAdapter();
|
||||
|
||||
String bottomId = null;
|
||||
if (kind == Kind.FAVOURITES || kind == Kind.BOOKMARKS) {
|
||||
bottomId = this.nextId;
|
||||
} else {
|
||||
final ListIterator<Either<Placeholder, Status>> iterator =
|
||||
this.statuses.listIterator(this.statuses.size());
|
||||
while (iterator.hasPrevious()) {
|
||||
Either<Placeholder, Status> previous = iterator.previous();
|
||||
if (previous.isRight()) {
|
||||
bottomId = previous.asRight().getId();
|
||||
break;
|
||||
}
|
||||
final ListIterator<Either<Placeholder, Status>> iterator =
|
||||
this.statuses.listIterator(this.statuses.size());
|
||||
while (iterator.hasPrevious()) {
|
||||
Either<Placeholder, Status> previous = iterator.previous();
|
||||
if (previous.isRight()) {
|
||||
bottomId = previous.asRight().getId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
sendFetchTimelineRequest(bottomId, null, null, FetchEnd.BOTTOM, -1);
|
||||
|
@ -1073,14 +1063,6 @@ public class TimelineFragment extends SFragment implements
|
|||
@Override
|
||||
public void onResponse(@NonNull Call<List<Status>> call, @NonNull Response<List<Status>> response) {
|
||||
if (response.isSuccessful()) {
|
||||
@Nullable
|
||||
String newNextId = extractNextId(response);
|
||||
if (newNextId != null) {
|
||||
// when we reach the bottom of the list, we won't have a new link. If
|
||||
// we blindly write `null` here we will start loading from the top
|
||||
// again.
|
||||
nextId = newNextId;
|
||||
}
|
||||
onFetchTimelineSuccess(liftStatusList(response.body()), fetchEnd, pos);
|
||||
} else {
|
||||
onFetchTimelineFailure(new Exception(response.message()), fetchEnd, pos);
|
||||
|
@ -1099,24 +1081,6 @@ public class TimelineFragment extends SFragment implements
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String extractNextId(Response<?> response) {
|
||||
String linkHeader = response.headers().get("Link");
|
||||
if (linkHeader == null) {
|
||||
return null;
|
||||
}
|
||||
List<HttpHeaderLink> links = HttpHeaderLink.parse(linkHeader);
|
||||
HttpHeaderLink nextHeader = HttpHeaderLink.findByRelationType(links, "next");
|
||||
if (nextHeader == null) {
|
||||
return null;
|
||||
}
|
||||
Uri nextLink = nextHeader.uri;
|
||||
if (nextLink == null) {
|
||||
return null;
|
||||
}
|
||||
return nextLink.getQueryParameter("max_id");
|
||||
}
|
||||
|
||||
private void onFetchTimelineSuccess(List<Either<Placeholder, Status>> statuses,
|
||||
FetchEnd fetchEnd, int pos) {
|
||||
|
||||
|
|
|
@ -19,23 +19,23 @@ import android.content.Intent
|
|||
import android.graphics.drawable.Drawable
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.preference.*
|
||||
import com.keylesspalace.tusky.*
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.appstore.EventHub
|
||||
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent
|
||||
import com.keylesspalace.tusky.components.notifications.NotificationHelper
|
||||
import com.keylesspalace.tusky.components.instancemute.InstanceListActivity
|
||||
import com.keylesspalace.tusky.db.AccountEntity
|
||||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.entity.Account
|
||||
import com.keylesspalace.tusky.entity.Filter
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.settings.*
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import com.keylesspalace.tusky.util.NotificationHelper
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
|
@ -45,7 +45,11 @@ import retrofit2.Callback
|
|||
import retrofit2.Response
|
||||
import javax.inject.Inject
|
||||
|
||||
class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable {
|
||||
|
||||
class AccountPreferencesFragment : PreferenceFragmentCompat(),
|
||||
Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
|
||||
Injectable {
|
||||
|
||||
@Inject
|
||||
lateinit var accountManager: AccountManager
|
||||
|
||||
|
@ -55,247 +59,206 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable {
|
|||
@Inject
|
||||
lateinit var eventHub: EventHub
|
||||
|
||||
private lateinit var notificationPreference: Preference
|
||||
private lateinit var tabPreference: Preference
|
||||
private lateinit var mutedUsersPreference: Preference
|
||||
private lateinit var blockedUsersPreference: Preference
|
||||
private lateinit var mutedDomainsPreference: Preference
|
||||
|
||||
private lateinit var defaultPostPrivacyPreference: ListPreference
|
||||
private lateinit var defaultMediaSensitivityPreference: SwitchPreferenceCompat
|
||||
private lateinit var defaultFormattingSyntaxPreference: ListPreference
|
||||
private lateinit var alwaysShowSensitiveMediaPreference: SwitchPreferenceCompat
|
||||
private lateinit var alwaysOpenSpoilerPreference: SwitchPreferenceCompat
|
||||
private lateinit var mediaPreviewEnabledPreference: SwitchPreferenceCompat
|
||||
private lateinit var homeFiltersPreference: Preference
|
||||
private lateinit var notificationFiltersPreference: Preference
|
||||
private lateinit var publicFiltersPreference: Preference
|
||||
private lateinit var threadFiltersPreference: Preference
|
||||
private lateinit var accountFiltersPreference: Preference
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
val context = requireContext()
|
||||
makePreferenceScreen {
|
||||
preference {
|
||||
setTitle(R.string.pref_title_edit_notification_settings)
|
||||
icon = IconicsDrawable(context, GoogleMaterial.Icon.gmd_notifications).apply {
|
||||
sizeRes = R.dimen.preference_icon_size
|
||||
colorInt = ThemeUtils.getColor(context, R.attr.iconColor)
|
||||
}
|
||||
setOnPreferenceClickListener {
|
||||
openNotificationPrefs()
|
||||
true
|
||||
}
|
||||
}
|
||||
addPreferencesFromResource(R.xml.account_preferences)
|
||||
|
||||
preference {
|
||||
setTitle(R.string.title_tab_preferences)
|
||||
setOnPreferenceClickListener {
|
||||
val intent = Intent(context, TabPreferenceActivity::class.java)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right,
|
||||
R.anim.slide_to_left)
|
||||
true
|
||||
}
|
||||
}
|
||||
notificationPreference = requirePreference("notificationPreference")
|
||||
tabPreference = requirePreference("tabPreference")
|
||||
mutedUsersPreference = requirePreference("mutedUsersPreference")
|
||||
blockedUsersPreference = requirePreference("blockedUsersPreference")
|
||||
mutedDomainsPreference = requirePreference("mutedDomainsPreference")
|
||||
defaultPostPrivacyPreference = requirePreference("defaultPostPrivacy") as ListPreference
|
||||
defaultMediaSensitivityPreference = requirePreference("defaultMediaSensitivity") as SwitchPreferenceCompat
|
||||
defaultFormattingSyntaxPreference = requirePreference("defaultFormattingSyntax") as ListPreference
|
||||
mediaPreviewEnabledPreference = requirePreference("mediaPreviewEnabled") as SwitchPreferenceCompat
|
||||
alwaysShowSensitiveMediaPreference = requirePreference("alwaysShowSensitiveMedia") as SwitchPreferenceCompat
|
||||
alwaysOpenSpoilerPreference = requirePreference("alwaysOpenSpoiler") as SwitchPreferenceCompat
|
||||
homeFiltersPreference = requirePreference("homeFilters")
|
||||
notificationFiltersPreference = requirePreference("notificationFilters")
|
||||
publicFiltersPreference = requirePreference("publicFilters")
|
||||
threadFiltersPreference = requirePreference("threadFilters")
|
||||
accountFiltersPreference = requirePreference("accountFilters")
|
||||
|
||||
preference {
|
||||
setTitle(R.string.action_view_mutes)
|
||||
icon = getTintedIcon(R.drawable.ic_mute_24dp)
|
||||
setOnPreferenceClickListener {
|
||||
val intent = Intent(context, AccountListActivity::class.java)
|
||||
intent.putExtra("type", AccountListActivity.Type.MUTES)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right,
|
||||
R.anim.slide_to_left)
|
||||
true
|
||||
}
|
||||
}
|
||||
notificationPreference.icon = IconicsDrawable(notificationPreference.context, GoogleMaterial.Icon.gmd_notifications).apply { sizeRes = R.dimen.preference_icon_size; colorInt = ThemeUtils.getColor(notificationPreference.context, R.attr.iconColor) }
|
||||
mutedUsersPreference.icon = getTintedIcon(R.drawable.ic_mute_24dp)
|
||||
blockedUsersPreference.icon = IconicsDrawable(blockedUsersPreference.context, GoogleMaterial.Icon.gmd_block).apply { sizeRes = R.dimen.preference_icon_size; colorInt = ThemeUtils.getColor(blockedUsersPreference.context, R.attr.iconColor) }
|
||||
mutedDomainsPreference.icon = getTintedIcon(R.drawable.ic_mute_24dp)
|
||||
|
||||
preference {
|
||||
setTitle(R.string.action_view_blocks)
|
||||
icon = IconicsDrawable(context, GoogleMaterial.Icon.gmd_block).apply {
|
||||
sizeRes = R.dimen.preference_icon_size
|
||||
colorInt = ThemeUtils.getColor(context, R.attr.iconColor)
|
||||
}
|
||||
setOnPreferenceClickListener {
|
||||
val intent = Intent(context, AccountListActivity::class.java)
|
||||
intent.putExtra("type", AccountListActivity.Type.BLOCKS)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right,
|
||||
R.anim.slide_to_left)
|
||||
true
|
||||
}
|
||||
}
|
||||
notificationPreference.onPreferenceClickListener = this
|
||||
tabPreference.onPreferenceClickListener = this
|
||||
mutedUsersPreference.onPreferenceClickListener = this
|
||||
blockedUsersPreference.onPreferenceClickListener = this
|
||||
mutedDomainsPreference.onPreferenceClickListener = this
|
||||
homeFiltersPreference.onPreferenceClickListener = this
|
||||
notificationFiltersPreference.onPreferenceClickListener = this
|
||||
publicFiltersPreference.onPreferenceClickListener = this
|
||||
threadFiltersPreference.onPreferenceClickListener = this
|
||||
accountFiltersPreference.onPreferenceClickListener = this
|
||||
|
||||
preference {
|
||||
setTitle(R.string.title_domain_mutes)
|
||||
icon = getTintedIcon(R.drawable.ic_mute_24dp)
|
||||
setOnPreferenceClickListener {
|
||||
val intent = Intent(context, InstanceListActivity::class.java)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right,
|
||||
R.anim.slide_to_left)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
preferenceCategory(R.string.pref_publishing) {
|
||||
listPreference {
|
||||
setTitle(R.string.pref_default_post_privacy)
|
||||
setEntries(R.array.post_privacy_names)
|
||||
setEntryValues(R.array.post_privacy_values)
|
||||
key = PrefKeys.DEFAULT_POST_PRIVACY
|
||||
setSummaryProvider { entry }
|
||||
val visibility = accountManager.activeAccount?.defaultPostPrivacy
|
||||
?: Status.Visibility.PUBLIC
|
||||
value = visibility.serverString()
|
||||
icon = getIconForVisibility(visibility)
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
icon = getIconForVisibility(
|
||||
Status.Visibility.byString(newValue as String)
|
||||
)
|
||||
syncWithServer(visibility = newValue)
|
||||
eventHub.dispatch(PreferenceChangedEvent(key))
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
listPreference {
|
||||
setTitle(R.string.pref_title_default_formatting)
|
||||
setEntries(R.array.formatting_syntax_values)
|
||||
setEntryValues(R.array.formatting_syntax_values)
|
||||
key = PrefKeys.DEFAULT_FORMATTING_SYNTAX
|
||||
setSummaryProvider { entry }
|
||||
val syntax = accountManager.activeAccount?.defaultFormattingSyntax
|
||||
?: ""
|
||||
value = when(syntax) {
|
||||
"text/markdown" -> "Markdown"
|
||||
"text/bbcode" -> "BBCode"
|
||||
"text/html" -> "HTML"
|
||||
else -> "Plaintext"
|
||||
}
|
||||
icon = getIconForSyntax(value)
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
val syntax = when(newValue) {
|
||||
"Markdown" -> "text/markdown"
|
||||
"BBCode" -> "text/bbcode"
|
||||
"HTML" -> "text/html"
|
||||
else -> ""
|
||||
}
|
||||
icon = getIconForSyntax(syntax)
|
||||
updateAccount { it.defaultFormattingSyntax = syntax }
|
||||
eventHub.dispatch(PreferenceChangedEvent(key))
|
||||
true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_default_media_sensitivity)
|
||||
setIcon(R.drawable.ic_eye_24dp)
|
||||
key = PrefKeys.DEFAULT_MEDIA_SENSITIVITY
|
||||
isSingleLineTitle = false
|
||||
val sensitivity = accountManager.activeAccount?.defaultMediaSensitivity
|
||||
?: false
|
||||
setDefaultValue(sensitivity)
|
||||
icon = getIconForSensitivity(sensitivity)
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
icon = getIconForSensitivity(newValue as Boolean)
|
||||
syncWithServer(sensitive = newValue)
|
||||
eventHub.dispatch(PreferenceChangedEvent(key))
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preferenceCategory(R.string.pref_title_timelines) {
|
||||
switchPreference {
|
||||
key = PrefKeys.MEDIA_PREVIEW_ENABLED
|
||||
setTitle(R.string.pref_title_show_media_preview)
|
||||
isSingleLineTitle = false
|
||||
isChecked = accountManager.activeAccount?.mediaPreviewEnabled ?: true
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.mediaPreviewEnabled = newValue as Boolean }
|
||||
eventHub.dispatch(PreferenceChangedEvent(key))
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
key = PrefKeys.ALWAYS_SHOW_SENSITIVE_MEDIA
|
||||
setTitle(R.string.pref_title_alway_show_sensitive_media)
|
||||
isSingleLineTitle = false
|
||||
isChecked = accountManager.activeAccount?.alwaysShowSensitiveMedia ?: false
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.alwaysShowSensitiveMedia = newValue as Boolean }
|
||||
eventHub.dispatch(PreferenceChangedEvent(key))
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
key = PrefKeys.ALWAYS_OPEN_SPOILER
|
||||
setTitle(R.string.pref_title_alway_open_spoiler)
|
||||
isSingleLineTitle = false
|
||||
isChecked = accountManager.activeAccount?.alwaysOpenSpoiler ?: false
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.alwaysOpenSpoiler = newValue as Boolean }
|
||||
eventHub.dispatch(PreferenceChangedEvent(key))
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preferenceCategory(R.string.pref_title_timeline_filters) {
|
||||
preference {
|
||||
setTitle(R.string.pref_title_public_filter_keywords)
|
||||
setOnPreferenceClickListener {
|
||||
launchFilterActivity(Filter.THREAD,
|
||||
R.string.pref_title_thread_filter_keywords)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
preference {
|
||||
setTitle(R.string.title_notifications)
|
||||
setOnPreferenceClickListener {
|
||||
launchFilterActivity(Filter.NOTIFICATIONS, R.string.title_notifications)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
preference {
|
||||
setTitle(R.string.title_home)
|
||||
setOnPreferenceClickListener {
|
||||
launchFilterActivity(Filter.HOME, R.string.title_home)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
preference {
|
||||
setTitle(R.string.pref_title_thread_filter_keywords)
|
||||
setOnPreferenceClickListener {
|
||||
launchFilterActivity(Filter.THREAD,
|
||||
R.string.pref_title_thread_filter_keywords)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
preference {
|
||||
setTitle(R.string.title_accounts)
|
||||
setOnPreferenceClickListener {
|
||||
launchFilterActivity(Filter.ACCOUNT, R.string.title_accounts)
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
defaultPostPrivacyPreference.onPreferenceChangeListener = this
|
||||
defaultMediaSensitivityPreference.onPreferenceChangeListener = this
|
||||
defaultFormattingSyntaxPreference.onPreferenceChangeListener = this
|
||||
mediaPreviewEnabledPreference.onPreferenceChangeListener = this
|
||||
alwaysShowSensitiveMediaPreference.onPreferenceChangeListener = this
|
||||
alwaysOpenSpoilerPreference.onPreferenceChangeListener = this
|
||||
}
|
||||
|
||||
private fun openNotificationPrefs() {
|
||||
if (NotificationHelper.NOTIFICATION_USE_CHANNELS) {
|
||||
val intent = Intent()
|
||||
intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
|
||||
intent.putExtra("android.provider.extra.APP_PACKAGE", BuildConfig.APPLICATION_ID)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
activity?.let {
|
||||
val intent = PreferencesActivity.newIntent(it, PreferencesActivity.NOTIFICATION_PREFERENCES)
|
||||
it.startActivity(intent)
|
||||
it.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
accountManager.activeAccount?.let {
|
||||
|
||||
defaultPostPrivacyPreference.value = it.defaultPostPrivacy.serverString()
|
||||
defaultPostPrivacyPreference.icon = getIconForVisibility(it.defaultPostPrivacy)
|
||||
|
||||
defaultFormattingSyntaxPreference.value = when(it.defaultFormattingSyntax) {
|
||||
"text/markdown" -> "Markdown"
|
||||
"text/bbcode" -> "BBCode"
|
||||
"text/html" -> "HTML"
|
||||
else -> "Plaintext"
|
||||
}
|
||||
defaultFormattingSyntaxPreference.icon = getIconForSyntax(it.defaultFormattingSyntax)
|
||||
|
||||
defaultMediaSensitivityPreference.isChecked = it.defaultMediaSensitivity
|
||||
defaultMediaSensitivityPreference.icon = getIconForSensitivity(it.defaultMediaSensitivity)
|
||||
|
||||
mediaPreviewEnabledPreference.isChecked = it.mediaPreviewEnabled
|
||||
alwaysShowSensitiveMediaPreference.isChecked = it.alwaysShowSensitiveMedia
|
||||
alwaysOpenSpoilerPreference.isChecked = it.alwaysOpenSpoiler
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun updateAccount(changer: (AccountEntity) -> Unit) {
|
||||
accountManager.activeAccount?.let { account ->
|
||||
changer(account)
|
||||
accountManager.saveAccount(account)
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
when (preference) {
|
||||
defaultPostPrivacyPreference -> {
|
||||
preference.icon = getIconForVisibility(Status.Visibility.byString(newValue as String))
|
||||
syncWithServer(visibility = newValue)
|
||||
}
|
||||
defaultMediaSensitivityPreference -> {
|
||||
preference.icon = getIconForSensitivity(newValue as Boolean)
|
||||
syncWithServer(sensitive = newValue)
|
||||
}
|
||||
defaultFormattingSyntaxPreference -> {
|
||||
val syntax = when(newValue) {
|
||||
"Markdown" -> "text/markdown"
|
||||
"BBCode" -> "text/bbcode"
|
||||
"HTML" -> "text/html"
|
||||
else -> ""
|
||||
}
|
||||
preference.icon = getIconForSyntax(syntax)
|
||||
accountManager.activeAccount?.let {
|
||||
it.defaultFormattingSyntax = syntax
|
||||
accountManager.saveAccount(it)
|
||||
}
|
||||
}
|
||||
mediaPreviewEnabledPreference -> {
|
||||
accountManager.activeAccount?.let {
|
||||
it.mediaPreviewEnabled = newValue as Boolean
|
||||
accountManager.saveAccount(it)
|
||||
}
|
||||
}
|
||||
alwaysShowSensitiveMediaPreference -> {
|
||||
accountManager.activeAccount?.let {
|
||||
it.alwaysShowSensitiveMedia = newValue as Boolean
|
||||
accountManager.saveAccount(it)
|
||||
}
|
||||
}
|
||||
alwaysOpenSpoilerPreference -> {
|
||||
accountManager.activeAccount?.let {
|
||||
it.alwaysOpenSpoiler = newValue as Boolean
|
||||
accountManager.saveAccount(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eventHub.dispatch(PreferenceChangedEvent(preference.key))
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPreferenceClick(preference: Preference): Boolean {
|
||||
|
||||
return when (preference) {
|
||||
notificationPreference -> {
|
||||
if (NotificationHelper.NOTIFICATION_USE_CHANNELS) {
|
||||
val intent = Intent()
|
||||
intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
|
||||
intent.putExtra("android.provider.extra.APP_PACKAGE", BuildConfig.APPLICATION_ID)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
activity?.let {
|
||||
val intent = PreferencesActivity.newIntent(it, PreferencesActivity.NOTIFICATION_PREFERENCES)
|
||||
it.startActivity(intent)
|
||||
it.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
|
||||
}
|
||||
true
|
||||
}
|
||||
tabPreference -> {
|
||||
val intent = Intent(context, TabPreferenceActivity::class.java)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
true
|
||||
}
|
||||
mutedUsersPreference -> {
|
||||
val intent = Intent(context, AccountListActivity::class.java)
|
||||
intent.putExtra("type", AccountListActivity.Type.MUTES)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
true
|
||||
}
|
||||
blockedUsersPreference -> {
|
||||
val intent = Intent(context, AccountListActivity::class.java)
|
||||
intent.putExtra("type", AccountListActivity.Type.BLOCKS)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
true
|
||||
}
|
||||
mutedDomainsPreference -> {
|
||||
val intent = Intent(context, InstanceListActivity::class.java)
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
true
|
||||
}
|
||||
homeFiltersPreference -> {
|
||||
launchFilterActivity(Filter.HOME, R.string.title_home)
|
||||
}
|
||||
notificationFiltersPreference -> {
|
||||
launchFilterActivity(Filter.NOTIFICATIONS, R.string.title_notifications)
|
||||
}
|
||||
publicFiltersPreference -> {
|
||||
launchFilterActivity(Filter.PUBLIC, R.string.pref_title_public_filter_keywords)
|
||||
}
|
||||
threadFiltersPreference -> {
|
||||
launchFilterActivity(Filter.THREAD, R.string.pref_title_thread_filter_keywords)
|
||||
}
|
||||
accountFiltersPreference -> {
|
||||
launchFilterActivity(Filter.ACCOUNT, R.string.title_accounts)
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun syncWithServer(visibility: String? = null, sensitive: Boolean? = null) {
|
||||
|
@ -371,15 +334,17 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable {
|
|||
return ThemeUtils.getTintedDrawable(requireContext(), iconId, R.attr.iconColor)
|
||||
}
|
||||
|
||||
private fun launchFilterActivity(filterContext: String, titleResource: Int) {
|
||||
private fun launchFilterActivity(filterContext: String, titleResource: Int): Boolean {
|
||||
val intent = Intent(context, FiltersActivity::class.java)
|
||||
intent.putExtra(FiltersActivity.FILTERS_CONTEXT, filterContext)
|
||||
intent.putExtra(FiltersActivity.FILTERS_TITLE, getString(titleResource))
|
||||
activity?.startActivity(intent)
|
||||
activity?.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance() = AccountPreferencesFragment()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,159 +16,82 @@
|
|||
package com.keylesspalace.tusky.fragment.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.SwitchPreferenceCompat
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.components.notifications.NotificationHelper
|
||||
import com.keylesspalace.tusky.db.AccountEntity
|
||||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.di.Injectable
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.makePreferenceScreen
|
||||
import com.keylesspalace.tusky.settings.preferenceCategory
|
||||
import com.keylesspalace.tusky.settings.switchPreference
|
||||
import com.keylesspalace.tusky.util.NotificationHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
class NotificationPreferencesFragment : PreferenceFragmentCompat(), Injectable {
|
||||
class NotificationPreferencesFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChangeListener, Injectable {
|
||||
|
||||
@Inject
|
||||
lateinit var accountManager: AccountManager
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
val activeAccount = accountManager.activeAccount ?: return
|
||||
val context = requireContext()
|
||||
makePreferenceScreen {
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_notifications_enabled)
|
||||
key = PrefKeys.NOTIFICATIONS_ENABLED
|
||||
isIconSpaceReserved = false
|
||||
isChecked = activeAccount.notificationsEnabled
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.notificationsEnabled = newValue as Boolean }
|
||||
if (NotificationHelper.areNotificationsEnabled(context, accountManager)) {
|
||||
NotificationHelper.enablePullNotifications(context)
|
||||
} else {
|
||||
NotificationHelper.disablePullNotifications(context)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
addPreferencesFromResource(R.xml.notification_preferences)
|
||||
}
|
||||
|
||||
preferenceCategory(R.string.pref_title_notification_filters) { category ->
|
||||
category.dependency = PrefKeys.NOTIFICATIONS_ENABLED
|
||||
category.isIconSpaceReserved = false
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_notification_filter_follows)
|
||||
key = PrefKeys.NOTIFICATIONS_FILTER_FOLLOWS
|
||||
isIconSpaceReserved = false
|
||||
isChecked = activeAccount.notificationsFollowed
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.notificationsFollowed = newValue as Boolean }
|
||||
true
|
||||
}
|
||||
}
|
||||
val activeAccount = accountManager.activeAccount
|
||||
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_notification_filter_follow_requests)
|
||||
key = PrefKeys.NOTIFICATION_FILTER_FOLLOW_REQUESTS
|
||||
isIconSpaceReserved = false
|
||||
isChecked = activeAccount.notificationsFollowRequested
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.notificationsFollowRequested = newValue as Boolean }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_notification_filter_reblogs)
|
||||
key = PrefKeys.NOTIFICATION_FILTER_REBLOGS
|
||||
isIconSpaceReserved = false
|
||||
isChecked = activeAccount.notificationsReblogged
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.notificationsReblogged = newValue as Boolean }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_notification_filter_favourites)
|
||||
key = PrefKeys.NOTIFICATION_FILTER_FAVS
|
||||
isIconSpaceReserved = false
|
||||
isChecked = activeAccount.notificationsFavorited
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.notificationsFavorited = newValue as Boolean }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_notification_filter_emoji)
|
||||
key = PrefKeys.NOTIFICATION_FILTER_EMOJI_REACTIONS
|
||||
isIconSpaceReserved = false
|
||||
isChecked = activeAccount.notificationsEmojiReactions
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.notificationsEmojiReactions = newValue as Boolean }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_notification_filter_poll)
|
||||
key = PrefKeys.NOTIFICATION_FILTER_POLLS
|
||||
isIconSpaceReserved = false
|
||||
isChecked = activeAccount.notificationsPolls
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.notificationsPolls = newValue as Boolean }
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preferenceCategory(R.string.pref_title_notification_alerts) { category ->
|
||||
category.dependency = PrefKeys.NOTIFICATIONS_ENABLED
|
||||
category.isIconSpaceReserved = false
|
||||
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_notification_alert_sound)
|
||||
key = PrefKeys.NOTIFICATION_ALERT_SOUND
|
||||
isIconSpaceReserved = false
|
||||
isChecked = activeAccount.notificationSound
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.notificationSound = newValue as Boolean }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_notification_alert_vibrate)
|
||||
key = PrefKeys.NOTIFICATION_ALERT_VIBRATE
|
||||
isIconSpaceReserved = false
|
||||
isChecked = activeAccount.notificationVibration
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.notificationVibration = newValue as Boolean }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_notification_alert_light)
|
||||
key = PrefKeys.NOTIFICATION_ALERT_LIGHT
|
||||
isIconSpaceReserved = false
|
||||
isChecked = activeAccount.notificationLight
|
||||
setOnPreferenceChangeListener { _, newValue ->
|
||||
updateAccount { it.notificationLight = newValue as Boolean }
|
||||
true
|
||||
}
|
||||
if (activeAccount != null) {
|
||||
for (pair in mapOf(
|
||||
"notificationsEnabled" to activeAccount.notificationsEnabled,
|
||||
"notificationFilterMentions" to activeAccount.notificationsMentioned,
|
||||
"notificationFilterFollows" to activeAccount.notificationsFollowed,
|
||||
"notificationFilterFollowRequests" to activeAccount.notificationsFollowRequested,
|
||||
"notificationFilterReblogs" to activeAccount.notificationsReblogged,
|
||||
"notificationFilterFavourites" to activeAccount.notificationsFavorited,
|
||||
"notificationFilterPolls" to activeAccount.notificationsPolls,
|
||||
"notificationFilterEmojis" to activeAccount.notificationsEmojiReactions,
|
||||
"notificationAlertSound" to activeAccount.notificationSound,
|
||||
"notificationAlertVibrate" to activeAccount.notificationVibration,
|
||||
"notificationAlertLight" to activeAccount.notificationLight
|
||||
)) {
|
||||
(requirePreference(pair.key) as SwitchPreferenceCompat).apply {
|
||||
isChecked = pair.value
|
||||
onPreferenceChangeListener = this@NotificationPreferencesFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun updateAccount(changer: (AccountEntity) -> Unit) {
|
||||
accountManager.activeAccount?.let { account ->
|
||||
changer(account)
|
||||
accountManager.saveAccount(account)
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
|
||||
val activeAccount = accountManager.activeAccount
|
||||
|
||||
if (activeAccount != null) {
|
||||
when (preference.key) {
|
||||
"notificationsEnabled" -> {
|
||||
activeAccount.notificationsEnabled = newValue as Boolean
|
||||
if (NotificationHelper.areNotificationsEnabled(preference.context, accountManager)) {
|
||||
NotificationHelper.enablePullNotifications()
|
||||
} else {
|
||||
NotificationHelper.disablePullNotifications()
|
||||
}
|
||||
}
|
||||
"notificationFilterMentions" -> activeAccount.notificationsMentioned = newValue as Boolean
|
||||
"notificationFilterFollows" -> activeAccount.notificationsFollowed = newValue as Boolean
|
||||
"notificationFilterFollowRequests" -> activeAccount.notificationsFollowRequested = newValue as Boolean
|
||||
"notificationFilterReblogs" -> activeAccount.notificationsReblogged = newValue as Boolean
|
||||
"notificationFilterFavourites" -> activeAccount.notificationsFavorited = newValue as Boolean
|
||||
"notificationFilterPolls" -> activeAccount.notificationsPolls = newValue as Boolean
|
||||
"notificationFilterEmojis" -> activeAccount.notificationsEmojiReactions = newValue as Boolean
|
||||
"notificationAlertSound" -> activeAccount.notificationSound = newValue as Boolean
|
||||
"notificationAlertVibrate" -> activeAccount.notificationVibration = newValue as Boolean
|
||||
"notificationAlertLight" -> activeAccount.notificationLight = newValue as Boolean
|
||||
}
|
||||
accountManager.saveAccount(activeAccount)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -20,201 +20,58 @@ import androidx.preference.Preference
|
|||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.keylesspalace.tusky.PreferencesActivity
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.settings.*
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import com.keylesspalace.tusky.util.getNonNullString
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizePx
|
||||
import com.mikepenz.iconics.utils.sizeRes
|
||||
|
||||
fun PreferenceFragmentCompat.requirePreference(key: String): Preference {
|
||||
return findPreference(key)!!
|
||||
}
|
||||
|
||||
class PreferencesFragment : PreferenceFragmentCompat() {
|
||||
|
||||
private val iconSize by lazy { resources.getDimensionPixelSize(R.dimen.preference_icon_size) }
|
||||
private var httpProxyPref: Preference? = null
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
val context = requireContext()
|
||||
makePreferenceScreen {
|
||||
preferenceCategory(R.string.pref_title_appearance_settings) {
|
||||
listPreference {
|
||||
setDefaultValue(AppTheme.NIGHT.value)
|
||||
setEntries(R.array.app_theme_names)
|
||||
entryValues = AppTheme.stringValues()
|
||||
key = PrefKeys.APP_THEME
|
||||
setSummaryProvider { entry }
|
||||
setTitle(R.string.pref_title_app_theme)
|
||||
icon = makeIcon(GoogleMaterial.Icon.gmd_palette)
|
||||
}
|
||||
|
||||
emojiPreference {
|
||||
setDefaultValue("system_default")
|
||||
setIcon(R.drawable.ic_emoji_24dp)
|
||||
key = PrefKeys.EMOJI
|
||||
setSummary(R.string.system_default)
|
||||
setTitle(R.string.emoji_style)
|
||||
icon = makeIcon(GoogleMaterial.Icon.gmd_sentiment_satisfied)
|
||||
}
|
||||
addPreferencesFromResource(R.xml.preferences)
|
||||
|
||||
listPreference {
|
||||
setDefaultValue("default")
|
||||
setEntries(R.array.language_entries)
|
||||
setEntryValues(R.array.language_values)
|
||||
key = PrefKeys.LANGUAGE
|
||||
setSummaryProvider { entry }
|
||||
setTitle(R.string.pref_title_language)
|
||||
icon = makeIcon(GoogleMaterial.Icon.gmd_translate)
|
||||
}
|
||||
val themePreference: Preference = requirePreference("appTheme")
|
||||
themePreference.icon = IconicsDrawable(themePreference.context, GoogleMaterial.Icon.gmd_palette).apply { sizeRes = R.dimen.preference_icon_size; colorInt = ThemeUtils.getColor(themePreference.context, R.attr.iconColor) }
|
||||
|
||||
listPreference {
|
||||
setDefaultValue("medium")
|
||||
setEntries(R.array.status_text_size_names)
|
||||
setEntryValues(R.array.status_text_size_values)
|
||||
key = PrefKeys.STATUS_TEXT_SIZE
|
||||
setSummaryProvider { entry }
|
||||
setTitle(R.string.pref_status_text_size)
|
||||
icon = makeIcon(GoogleMaterial.Icon.gmd_format_size)
|
||||
}
|
||||
val emojiPreference: Preference = requirePreference("emojiCompat")
|
||||
emojiPreference.icon = IconicsDrawable(emojiPreference.context, GoogleMaterial.Icon.gmd_sentiment_satisfied).apply { sizeRes = R.dimen.preference_icon_size; colorInt = ThemeUtils.getColor(themePreference.context, R.attr.iconColor) }
|
||||
|
||||
listPreference {
|
||||
setDefaultValue("top")
|
||||
setEntries(R.array.pref_main_nav_position_options)
|
||||
setEntryValues(R.array.pref_main_nav_position_values)
|
||||
key = PrefKeys.MAIN_NAV_POSITION
|
||||
setSummaryProvider { entry }
|
||||
setTitle(R.string.pref_main_nav_position)
|
||||
}
|
||||
val textSizePreference: Preference = requirePreference("statusTextSize")
|
||||
textSizePreference.icon = IconicsDrawable(textSizePreference.context, GoogleMaterial.Icon.gmd_format_size).apply { sizeRes = R.dimen.preference_icon_size; colorInt = ThemeUtils.getColor(themePreference.context, R.attr.iconColor) }
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(false)
|
||||
key = PrefKeys.FAB_HIDE
|
||||
setTitle(R.string.pref_title_hide_follow_button)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(false)
|
||||
key = PrefKeys.ABSOLUTE_TIME_VIEW
|
||||
setTitle(R.string.pref_title_absolute_time)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(true)
|
||||
key = PrefKeys.SHOW_BOT_OVERLAY
|
||||
setTitle(R.string.pref_title_bot_overlay)
|
||||
isSingleLineTitle = false
|
||||
icon = ThemeUtils.getTintedDrawable(
|
||||
context,
|
||||
R.drawable.ic_bot_24dp,
|
||||
R.attr.iconColor
|
||||
)
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(false)
|
||||
key = PrefKeys.ANIMATE_GIF_AVATARS
|
||||
setTitle(R.string.pref_title_animate_gif_avatars)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(true)
|
||||
key = PrefKeys.USE_BLURHASH
|
||||
setTitle(R.string.pref_title_gradient_for_media)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(true)
|
||||
key = PrefKeys.SHOW_NOTIFICATIONS_FILTER
|
||||
setTitle(R.string.pref_title_show_notifications_filter)
|
||||
isSingleLineTitle = false
|
||||
setOnPreferenceClickListener {
|
||||
activity?.let { activity ->
|
||||
val intent = PreferencesActivity.newIntent(activity, PreferencesActivity.TAB_FILTER_PREFERENCES)
|
||||
activity.startActivity(intent)
|
||||
activity.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(false)
|
||||
key = PrefKeys.SHOW_CARDS_IN_TIMELINES
|
||||
setTitle(R.string.pref_title_confirm_reblogs)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(true)
|
||||
key = PrefKeys.ENABLE_SWIPE_FOR_TABS
|
||||
setTitle(R.string.pref_title_enable_swipe_for_tabs)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(true)
|
||||
key = PrefKeys.BIG_EMOJIS
|
||||
setTitle(R.string.pref_title_enable_big_emojis)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
setDefaultValue(false)
|
||||
key = PrefKeys.STICKERS
|
||||
setTitle(R.string.pref_title_enable_experimental_stickers)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
val timelineFilterPreferences: Preference = requirePreference("timelineFilterPreferences")
|
||||
timelineFilterPreferences.setOnPreferenceClickListener {
|
||||
activity?.let { activity ->
|
||||
val intent = PreferencesActivity.newIntent(activity, PreferencesActivity.TAB_FILTER_PREFERENCES)
|
||||
activity.startActivity(intent)
|
||||
activity.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
|
||||
preferenceCategory(R.string.pref_title_browser_settings) {
|
||||
switchPreference {
|
||||
setDefaultValue(false)
|
||||
key = PrefKeys.CUSTOM_TABS
|
||||
setTitle(R.string.pref_title_custom_tabs)
|
||||
isSingleLineTitle = false
|
||||
}
|
||||
}
|
||||
|
||||
preferenceCategory(R.string.pref_title_timeline_filters) {
|
||||
preference {
|
||||
setTitle(R.string.pref_title_status_tabs)
|
||||
setOnPreferenceClickListener {
|
||||
activity?.let { activity ->
|
||||
val intent = PreferencesActivity.newIntent(activity, PreferencesActivity.TAB_FILTER_PREFERENCES)
|
||||
activity.startActivity(intent)
|
||||
activity.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preferenceCategory(R.string.pref_title_proxy_settings) {
|
||||
httpProxyPref = preference {
|
||||
setTitle(R.string.pref_title_http_proxy_settings)
|
||||
setOnPreferenceClickListener {
|
||||
activity?.let { activity ->
|
||||
val intent = PreferencesActivity.newIntent(activity, PreferencesActivity.PROXY_PREFERENCES)
|
||||
activity.startActivity(intent)
|
||||
activity.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeIcon(icon: GoogleMaterial.Icon): IconicsDrawable {
|
||||
val context = requireContext()
|
||||
return IconicsDrawable(context, icon).apply {
|
||||
sizePx = iconSize
|
||||
colorInt = ThemeUtils.getColor(context, R.attr.iconColor)
|
||||
true
|
||||
}
|
||||
|
||||
val httpProxyPreferences: Preference = requirePreference("httpProxyPreferences")
|
||||
httpProxyPreferences.setOnPreferenceClickListener {
|
||||
activity?.let { activity ->
|
||||
val intent = PreferencesActivity.newIntent(activity, PreferencesActivity.PROXY_PREFERENCES)
|
||||
activity.startActivity(intent)
|
||||
activity.overridePendingTransition(R.anim.slide_from_right, R.anim.slide_to_left)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
val languagePreference: Preference = requirePreference("language")
|
||||
languagePreference.icon = IconicsDrawable(languagePreference.context, GoogleMaterial.Icon.gmd_translate).apply { sizeRes = R.dimen.preference_icon_size; colorInt = ThemeUtils.getColor(themePreference.context, R.attr.iconColor) }
|
||||
|
||||
val botIndicatorPreference = requirePreference("showBotOverlay")
|
||||
|
||||
botIndicatorPreference.icon = ThemeUtils.getTintedDrawable(requireContext(), R.drawable.ic_bot_24dp, R.attr.iconColor)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -223,23 +80,28 @@ class PreferencesFragment : PreferenceFragmentCompat() {
|
|||
}
|
||||
|
||||
private fun updateHttpProxySummary() {
|
||||
|
||||
val httpProxyPref: Preference = requirePreference("httpProxyPreferences")
|
||||
|
||||
val sharedPreferences = preferenceManager.sharedPreferences
|
||||
val httpProxyEnabled = sharedPreferences.getBoolean(PrefKeys.HTTP_PROXY_ENABLED, false)
|
||||
val httpServer = sharedPreferences.getNonNullString(PrefKeys.HTTP_PROXY_SERVER, "")
|
||||
|
||||
val httpProxyEnabled = sharedPreferences.getBoolean("httpProxyEnabled", false)
|
||||
|
||||
val httpServer = sharedPreferences.getNonNullString("httpProxyServer", "")
|
||||
|
||||
try {
|
||||
val httpPort = sharedPreferences.getNonNullString(PrefKeys.HTTP_PROXY_PORT, "-1")
|
||||
.toInt()
|
||||
val httpPort = sharedPreferences.getNonNullString("httpProxyPort", "-1").toInt()
|
||||
|
||||
if (httpProxyEnabled && httpServer.isNotBlank() && httpPort > 0 && httpPort < 65535) {
|
||||
httpProxyPref?.summary = "$httpServer:$httpPort"
|
||||
httpProxyPref.summary = "$httpServer:$httpPort"
|
||||
return
|
||||
}
|
||||
} catch (e: NumberFormatException) {
|
||||
// user has entered wrong port, fall back to empty summary
|
||||
}
|
||||
|
||||
httpProxyPref?.summary = ""
|
||||
httpProxyPref.summary = ""
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -15,53 +15,61 @@
|
|||
|
||||
package com.keylesspalace.tusky.fragment.preference
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.editTextPreference
|
||||
import com.keylesspalace.tusky.settings.makePreferenceScreen
|
||||
import com.keylesspalace.tusky.settings.switchPreference
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
class ProxyPreferencesFragment : PreferenceFragmentCompat() {
|
||||
class ProxyPreferencesFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
||||
private var pendingRestart = false
|
||||
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
makePreferenceScreen {
|
||||
switchPreference {
|
||||
setTitle(R.string.pref_title_http_proxy_enable)
|
||||
isIconSpaceReserved = false
|
||||
key = PrefKeys.HTTP_PROXY_ENABLED
|
||||
setDefaultValue(false)
|
||||
}
|
||||
addPreferencesFromResource(R.xml.http_proxy_preferences)
|
||||
|
||||
editTextPreference {
|
||||
setTitle(R.string.pref_title_http_proxy_server)
|
||||
key = PrefKeys.HTTP_PROXY_SERVER
|
||||
isIconSpaceReserved = false
|
||||
setSummaryProvider { text }
|
||||
}
|
||||
sharedPreferences = preferenceManager.sharedPreferences
|
||||
|
||||
editTextPreference {
|
||||
setTitle(R.string.pref_title_http_proxy_port)
|
||||
key = PrefKeys.HTTP_PROXY_PORT
|
||||
isIconSpaceReserved = false
|
||||
setSummaryProvider { text }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
||||
|
||||
updateSummary("httpProxyServer")
|
||||
updateSummary("httpProxyPort")
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
|
||||
|
||||
if (pendingRestart) {
|
||||
pendingRestart = false
|
||||
exitProcess(0)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
updateSummary (key)
|
||||
}
|
||||
|
||||
private fun updateSummary(key: String) {
|
||||
when (key) {
|
||||
"httpProxyServer", "httpProxyPort" -> {
|
||||
val editTextPreference = requirePreference(key) as EditTextPreference
|
||||
editTextPreference.summary = editTextPreference.text
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): ProxyPreferencesFragment {
|
||||
return ProxyPreferencesFragment()
|
||||
}
|
||||
|
|
|
@ -15,38 +15,22 @@
|
|||
|
||||
package com.keylesspalace.tusky.fragment.preference
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.settings.PrefKeys
|
||||
import com.keylesspalace.tusky.settings.checkBoxPreference
|
||||
import com.keylesspalace.tusky.settings.makePreferenceScreen
|
||||
import com.keylesspalace.tusky.settings.preferenceCategory
|
||||
|
||||
class TabFilterPreferencesFragment : PreferenceFragmentCompat() {
|
||||
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
makePreferenceScreen {
|
||||
preferenceCategory(R.string.title_home) { category ->
|
||||
category.isIconSpaceReserved = false
|
||||
|
||||
checkBoxPreference {
|
||||
setTitle(R.string.pref_title_show_boosts)
|
||||
key = PrefKeys.TAB_FILTER_HOME_BOOSTS
|
||||
setDefaultValue(true)
|
||||
isIconSpaceReserved = false
|
||||
}
|
||||
|
||||
checkBoxPreference {
|
||||
setTitle(R.string.pref_title_show_replies)
|
||||
key = PrefKeys.TAB_FILTER_HOME_REPLIES
|
||||
setDefaultValue(false)
|
||||
isIconSpaceReserved = false
|
||||
}
|
||||
}
|
||||
}
|
||||
addPreferencesFromResource(R.xml.timeline_filter_preferences)
|
||||
sharedPreferences = preferenceManager.sharedPreferences
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): TabFilterPreferencesFragment {
|
||||
return TabFilterPreferencesFragment()
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
|
||||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.components.notifications.NotificationHelper
|
||||
import com.keylesspalace.tusky.util.NotificationHelper
|
||||
import dagger.android.AndroidInjection
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import com.keylesspalace.tusky.db.AccountManager
|
|||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.service.SendTootService
|
||||
import com.keylesspalace.tusky.service.TootToSend
|
||||
import com.keylesspalace.tusky.components.notifications.NotificationHelper
|
||||
import com.keylesspalace.tusky.util.NotificationHelper
|
||||
import com.keylesspalace.tusky.util.randomAlphanumericString
|
||||
import dagger.android.AndroidInjection
|
||||
import javax.inject.Inject
|
||||
|
@ -103,7 +103,6 @@ class SendStatusBroadcastReceiver : BroadcastReceiver() {
|
|||
null,
|
||||
null,
|
||||
"",
|
||||
false,
|
||||
account.id,
|
||||
0,
|
||||
randomAlphanumericString(16),
|
||||
|
|
|
@ -16,8 +16,8 @@ import androidx.core.app.ServiceCompat
|
|||
import androidx.core.content.ContextCompat
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.appstore.EventHub
|
||||
import com.keylesspalace.tusky.appstore.*
|
||||
import com.keylesspalace.tusky.components.notifications.NotificationHelper
|
||||
import com.keylesspalace.tusky.appstore.StatusComposedEvent
|
||||
import com.keylesspalace.tusky.appstore.StatusScheduledEvent
|
||||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.db.AppDatabase
|
||||
import com.keylesspalace.tusky.di.Injectable
|
||||
|
@ -26,6 +26,7 @@ import com.keylesspalace.tusky.entity.NewStatus
|
|||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.util.SaveTootHelper
|
||||
import com.keylesspalace.tusky.util.NotificationHelper
|
||||
import dagger.android.AndroidInjection
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import retrofit2.Call
|
||||
|
@ -131,7 +132,6 @@ class SendTootService : Service(), Injectable {
|
|||
tootToSend.retries++
|
||||
|
||||
val contentType : String? = if(tootToSend.formattingSyntax.length == 0) null else tootToSend.formattingSyntax
|
||||
val preview : Boolean? = if(tootToSend.preview) tootToSend.preview else null
|
||||
|
||||
val newStatus = NewStatus(
|
||||
tootToSend.text,
|
||||
|
@ -142,8 +142,7 @@ class SendTootService : Service(), Injectable {
|
|||
tootToSend.mediaIds,
|
||||
tootToSend.scheduledAt,
|
||||
tootToSend.poll,
|
||||
contentType,
|
||||
preview
|
||||
contentType
|
||||
)
|
||||
|
||||
val sendCall = mastodonApi.createStatus(
|
||||
|
@ -167,9 +166,7 @@ class SendTootService : Service(), Injectable {
|
|||
saveTootHelper.deleteDraft(tootToSend.savedTootUid)
|
||||
}
|
||||
|
||||
if (tootToSend.preview) {
|
||||
response.body()?.let(::StatusPreviewEvent)?.let(eventHub::dispatch)
|
||||
} else if (scheduled) {
|
||||
if (scheduled) {
|
||||
response.body()?.let(::StatusScheduledEvent)?.let(eventHub::dispatch)
|
||||
} else {
|
||||
response.body()?.let(::StatusComposedEvent)?.let(eventHub::dispatch)
|
||||
|
@ -331,7 +328,6 @@ data class TootToSend(
|
|||
val replyingStatusAuthorUsername: String?,
|
||||
val savedJsonUrls: List<String>?,
|
||||
val formattingSyntax: String,
|
||||
val preview: Boolean,
|
||||
val accountId: Long,
|
||||
val savedTootUid: Int,
|
||||
val idempotencyKey: String,
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
package com.keylesspalace.tusky.settings
|
||||
|
||||
enum class AppTheme(val value: String) {
|
||||
NIGHT("night"),
|
||||
DAY("day"),
|
||||
BLACK("black"),
|
||||
AUTO("auto"),
|
||||
AUTO_SYSTEM("auto_system");
|
||||
|
||||
companion object {
|
||||
fun stringValues() = values().map { it.value }.toTypedArray()
|
||||
}
|
||||
}
|
||||
|
||||
object PrefKeys {
|
||||
// Note: not all of these keys are actually used as SharedPreferences keys but we must give
|
||||
// each preference a key for it to work.
|
||||
|
||||
const val APP_THEME = "appTheme"
|
||||
const val EMOJI = "emojiCompat"
|
||||
const val FAB_HIDE = "fabHide"
|
||||
const val LANGUAGE = "language"
|
||||
const val STATUS_TEXT_SIZE = "statusTextSize"
|
||||
const val MAIN_NAV_POSITION = "mainNavPosition"
|
||||
const val ABSOLUTE_TIME_VIEW = "absoluteTimeView"
|
||||
const val SHOW_BOT_OVERLAY = "showBotOverlay"
|
||||
const val ANIMATE_GIF_AVATARS = "animateGifAvatars"
|
||||
const val USE_BLURHASH = "useBlurhash"
|
||||
const val SHOW_NOTIFICATIONS_FILTER = "showNotificationsFilter"
|
||||
const val SHOW_CARDS_IN_TIMELINES = "showCardsInTimelines"
|
||||
const val ENABLE_SWIPE_FOR_TABS = "enableSwipeForTabs"
|
||||
const val BIG_EMOJIS = "bigEmojis"
|
||||
const val STICKERS = "stickers"
|
||||
|
||||
const val CUSTOM_TABS = "customTabs"
|
||||
|
||||
const val HTTP_PROXY_ENABLED = "httpProxyEnabled"
|
||||
const val HTTP_PROXY_SERVER = "httpProxyServer"
|
||||
const val HTTP_PROXY_PORT = "httpProxyPort"
|
||||
|
||||
const val DEFAULT_POST_PRIVACY = "defaultPostPrivacy"
|
||||
const val DEFAULT_MEDIA_SENSITIVITY = "defaultMediaSensitivity"
|
||||
const val DEFAULT_FORMATTING_SYNTAX = "defaultFormattingSyntax"
|
||||
const val MEDIA_PREVIEW_ENABLED = "mediaPreviewEnabled"
|
||||
const val ALWAYS_SHOW_SENSITIVE_MEDIA = "alwaysShowSensitiveMedia"
|
||||
const val ALWAYS_OPEN_SPOILER = "alwaysOpenSpoiler"
|
||||
|
||||
const val NOTIFICATIONS_ENABLED = "notificationsEnabled"
|
||||
const val NOTIFICATION_ALERT_LIGHT = "notificationAlertLight"
|
||||
const val NOTIFICATION_ALERT_VIBRATE = "notificationAlertVibrate"
|
||||
const val NOTIFICATION_ALERT_SOUND = "notificationAlertSound"
|
||||
const val NOTIFICATION_FILTER_POLLS = "notificationFilterPolls"
|
||||
const val NOTIFICATION_FILTER_FAVS = "notificationFilterFavourites"
|
||||
const val NOTIFICATION_FILTER_REBLOGS = "notificationFilterReblogs"
|
||||
const val NOTIFICATION_FILTER_FOLLOW_REQUESTS = "notificationFilterFollowRequests"
|
||||
const val NOTIFICATION_FILTER_EMOJI_REACTIONS = "notificationFilterEmojis"
|
||||
const val NOTIFICATIONS_FILTER_FOLLOWS = "notificationFilterFollows"
|
||||
|
||||
const val TAB_FILTER_HOME_REPLIES = "tabFilterHomeBoosts"
|
||||
const val TAB_FILTER_HOME_BOOSTS = "tabFilterHomeReplies"
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
package com.keylesspalace.tusky.settings
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.preference.*
|
||||
import com.keylesspalace.tusky.EmojiPreference
|
||||
|
||||
class PreferenceParent(
|
||||
val context: Context,
|
||||
val addPref: (pref: Preference) -> Unit
|
||||
)
|
||||
|
||||
inline fun PreferenceParent.preference(builder: Preference.() -> Unit): Preference {
|
||||
val pref = Preference(context)
|
||||
builder(pref)
|
||||
addPref(pref)
|
||||
return pref
|
||||
}
|
||||
|
||||
inline fun PreferenceParent.listPreference(builder: ListPreference.() -> Unit): ListPreference {
|
||||
val pref = ListPreference(context)
|
||||
builder(pref)
|
||||
addPref(pref)
|
||||
return pref
|
||||
}
|
||||
|
||||
inline fun PreferenceParent.emojiPreference(builder: EmojiPreference.() -> Unit): EmojiPreference {
|
||||
val pref = EmojiPreference(context)
|
||||
builder(pref)
|
||||
addPref(pref)
|
||||
return pref
|
||||
}
|
||||
|
||||
inline fun PreferenceParent.switchPreference(
|
||||
builder: SwitchPreference.() -> Unit
|
||||
): SwitchPreference {
|
||||
val pref = SwitchPreference(context)
|
||||
builder(pref)
|
||||
addPref(pref)
|
||||
return pref
|
||||
}
|
||||
|
||||
inline fun PreferenceParent.editTextPreference(
|
||||
builder: EditTextPreference.() -> Unit
|
||||
): EditTextPreference {
|
||||
val pref = EditTextPreference(context)
|
||||
builder(pref)
|
||||
addPref(pref)
|
||||
return pref
|
||||
}
|
||||
|
||||
inline fun PreferenceParent.checkBoxPreference(
|
||||
builder: CheckBoxPreference.() -> Unit
|
||||
): CheckBoxPreference {
|
||||
val pref = CheckBoxPreference(context)
|
||||
builder(pref)
|
||||
addPref(pref)
|
||||
return pref
|
||||
}
|
||||
|
||||
inline fun PreferenceParent.preferenceCategory(
|
||||
@StringRes title: Int,
|
||||
builder: PreferenceParent.(PreferenceCategory) -> Unit
|
||||
) {
|
||||
val category = PreferenceCategory(context)
|
||||
addPref(category)
|
||||
category.setTitle(title)
|
||||
val newParent = PreferenceParent(context) { category.addPreference(it) }
|
||||
builder(newParent, category)
|
||||
}
|
||||
|
||||
inline fun PreferenceFragmentCompat.makePreferenceScreen(
|
||||
builder: PreferenceParent.() -> Unit
|
||||
): PreferenceScreen {
|
||||
val context = requireContext()
|
||||
val screen = preferenceManager.createPreferenceScreen(context)
|
||||
val parent = PreferenceParent(context) { screen.addPreference(it) }
|
||||
// For some functions (like dependencies) it's much easier for us if we attach screen first
|
||||
// and change it later
|
||||
preferenceScreen = screen
|
||||
builder(parent)
|
||||
return screen
|
||||
}
|
|
@ -87,7 +87,7 @@ object BlurHashDecoder {
|
|||
numCompX: Int, numCompY: Int,
|
||||
colors: Array<FloatArray>
|
||||
): Bitmap {
|
||||
val imageArray = IntArray(width * height)
|
||||
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
|
||||
for (y in 0 until height) {
|
||||
for (x in 0 until width) {
|
||||
var r = 0f
|
||||
|
@ -102,10 +102,10 @@ object BlurHashDecoder {
|
|||
b += color[2] * basis
|
||||
}
|
||||
}
|
||||
imageArray[x + width * y] = Color.rgb(linearToSrgb(r), linearToSrgb(g), linearToSrgb(b))
|
||||
bitmap.setPixel(x, y, Color.rgb(linearToSrgb(r), linearToSrgb(g), linearToSrgb(b)))
|
||||
}
|
||||
}
|
||||
return Bitmap.createBitmap(imageArray, width, height, Bitmap.Config.ARGB_8888)
|
||||
return bitmap
|
||||
}
|
||||
|
||||
private fun linearToSrgb(value: Float): Int {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* You should have received a copy of the GNU General Public License along with Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
package com.keylesspalace.tusky.components.notifications;
|
||||
package com.keylesspalace.tusky.util;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationChannelGroup;
|
||||
|
@ -38,15 +38,12 @@ import androidx.core.app.RemoteInput;
|
|||
import androidx.core.app.TaskStackBuilder;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.text.BidiFormatter;
|
||||
import androidx.work.Constraints;
|
||||
import androidx.work.NetworkType;
|
||||
import androidx.work.PeriodicWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
import androidx.work.WorkRequest;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.FutureTarget;
|
||||
import com.evernote.android.job.JobManager;
|
||||
import com.evernote.android.job.JobRequest;
|
||||
import com.keylesspalace.tusky.BuildConfig;
|
||||
import com.keylesspalace.tusky.MainActivity;
|
||||
import com.keylesspalace.tusky.R;
|
||||
|
@ -68,7 +65,6 @@ import java.util.Collections;
|
|||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
@ -123,11 +119,11 @@ public class NotificationHelper {
|
|||
public static final String CHANNEL_POLL = "CHANNEL_POLL";
|
||||
public static final String CHANNEL_EMOJI_REACTION = "CHANNEL_EMOJI_REACTION";
|
||||
|
||||
|
||||
/**
|
||||
* WorkManager Tag
|
||||
* time in minutes between notification checks
|
||||
* note that this cannot be less than 15 minutes due to Android battery saving constraints
|
||||
*/
|
||||
private static final String NOTIFICATION_PULL_TAG = "pullNotifications";
|
||||
private static final int NOTIFICATION_CHECK_INTERVAL_MINUTES = 15;
|
||||
|
||||
/**
|
||||
* by setting this as false, it's possible to test legacy notification channels on newer devices
|
||||
|
@ -135,6 +131,7 @@ public class NotificationHelper {
|
|||
//public static final boolean NOTIFICATION_USE_CHANNELS = false;
|
||||
public static final boolean NOTIFICATION_USE_CHANNELS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
||||
|
||||
|
||||
/**
|
||||
* Takes a given Mastodon notification and either creates a new Android notification or updates
|
||||
* the state of the existing notification to reflect the new interaction.
|
||||
|
@ -149,12 +146,12 @@ public class NotificationHelper {
|
|||
if (!filterNotification(account, body, context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Pleroma extension: don't notify about seen notifications
|
||||
if (body.getPleroma() != null && body.getPleroma().getSeen() == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (body.getStatus() != null &&
|
||||
(body.getStatus().isUserMuted() == true ||
|
||||
body.getStatus().isThreadMuted() == true)) {
|
||||
|
@ -479,27 +476,23 @@ public class NotificationHelper {
|
|||
|
||||
}
|
||||
|
||||
public static void enablePullNotifications(Context context) {
|
||||
WorkManager workManager = WorkManager.getInstance(context);
|
||||
workManager.cancelAllWorkByTag(NOTIFICATION_PULL_TAG);
|
||||
public static void enablePullNotifications() {
|
||||
long checkInterval = 1000 * 60 * NOTIFICATION_CHECK_INTERVAL_MINUTES;
|
||||
|
||||
WorkRequest workRequest = new PeriodicWorkRequest.Builder(
|
||||
NotificationWorker.class,
|
||||
PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS, TimeUnit.MILLISECONDS,
|
||||
PeriodicWorkRequest.MIN_PERIODIC_FLEX_MILLIS, TimeUnit.MILLISECONDS
|
||||
)
|
||||
.addTag(NOTIFICATION_PULL_TAG)
|
||||
.setConstraints(new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
|
||||
.build();
|
||||
new JobRequest.Builder(NotificationPullJobCreator.NOTIFICATIONS_JOB_TAG)
|
||||
.setPeriodic(checkInterval)
|
||||
.setUpdateCurrent(true)
|
||||
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
|
||||
.build()
|
||||
.scheduleAsync();
|
||||
|
||||
workManager.enqueue(workRequest);
|
||||
|
||||
Log.d(TAG, "enabled notification checks with "+ PeriodicWorkRequest.MIN_PERIODIC_INTERVAL_MILLIS + "ms interval");
|
||||
Log.d(TAG, "enabled notification checks with "+ NOTIFICATION_CHECK_INTERVAL_MINUTES + "min interval");
|
||||
}
|
||||
|
||||
public static void disablePullNotifications(Context context) {
|
||||
WorkManager.getInstance(context).cancelAllWorkByTag(NOTIFICATION_PULL_TAG);
|
||||
public static void disablePullNotifications() {
|
||||
JobManager.instance().cancelAllForTag(NotificationPullJobCreator.NOTIFICATIONS_JOB_TAG);
|
||||
Log.d(TAG, "disabled notification checks");
|
||||
|
||||
}
|
||||
|
||||
public static void clearNotificationsForActiveAccount(@NonNull Context context, @NonNull AccountManager accountManager) {
|
||||
|
@ -514,8 +507,8 @@ public class NotificationHelper {
|
|||
notificationManager.cancel((int) account.getId());
|
||||
return true;
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe();
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -555,8 +548,7 @@ public class NotificationHelper {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getChannelId(AccountEntity account, Notification notification) {
|
||||
private static @Nullable String getChannelId(AccountEntity account, Notification notification) {
|
||||
switch (notification.getType()) {
|
||||
case MENTION:
|
||||
return CHANNEL_MENTION + account.getIdentifier();
|
|
@ -0,0 +1,137 @@
|
|||
/* Copyright 2017 Andrew Dawson
|
||||
*
|
||||
* This file is part of Tusky.
|
||||
*
|
||||
* Tusky is free software: you can redistribute it and/or modify it under the terms of the GNU
|
||||
* Lesser General Public License as published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License along with Tusky. If
|
||||
* not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
package com.keylesspalace.tusky.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.evernote.android.job.Job;
|
||||
import com.evernote.android.job.JobCreator;
|
||||
import com.keylesspalace.tusky.db.AccountEntity;
|
||||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.entity.Notification;
|
||||
import com.keylesspalace.tusky.network.MastodonApi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import retrofit2.Response;
|
||||
|
||||
import static com.keylesspalace.tusky.util.StringUtils.isLessThan;
|
||||
|
||||
/**
|
||||
* Created by charlag on 31/10/17.
|
||||
*/
|
||||
|
||||
public final class NotificationPullJobCreator implements JobCreator {
|
||||
|
||||
private static final String TAG = "NotificationPJC";
|
||||
|
||||
static final String NOTIFICATIONS_JOB_TAG = "notifications_job_tag";
|
||||
|
||||
private final MastodonApi api;
|
||||
private final Context context;
|
||||
private final AccountManager accountManager;
|
||||
|
||||
@Inject NotificationPullJobCreator(MastodonApi api, Context context,
|
||||
AccountManager accountManager) {
|
||||
this.api = api;
|
||||
this.context = context;
|
||||
this.accountManager = accountManager;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Job create(@NonNull String tag) {
|
||||
if (tag.equals(NOTIFICATIONS_JOB_TAG)) {
|
||||
return new NotificationPullJob(context, accountManager, api);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private final static class NotificationPullJob extends Job {
|
||||
|
||||
private final Context context;
|
||||
private final AccountManager accountManager;
|
||||
private final MastodonApi mastodonApi;
|
||||
|
||||
NotificationPullJob(Context context, AccountManager accountManager,
|
||||
MastodonApi mastodonApi) {
|
||||
this.context = context;
|
||||
this.accountManager = accountManager;
|
||||
this.mastodonApi = mastodonApi;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected Result onRunJob(@NonNull Params params) {
|
||||
List<AccountEntity> accountList = new ArrayList<>(accountManager.getAllAccountsOrderedByActive());
|
||||
boolean withMuted = true; // TODO: configurable
|
||||
for (AccountEntity account : accountList) {
|
||||
if (account.getNotificationsEnabled()) {
|
||||
try {
|
||||
Log.d(TAG, "getting Notifications for " + account.getFullName());
|
||||
Response<List<Notification>> notifications =
|
||||
mastodonApi.notificationsWithAuth(
|
||||
String.format("Bearer %s", account.getAccessToken()),
|
||||
account.getDomain(),
|
||||
withMuted
|
||||
)
|
||||
.execute();
|
||||
if (notifications.isSuccessful()) {
|
||||
onNotificationsReceived(account, notifications.body());
|
||||
} else {
|
||||
Log.w(TAG, "error receiving notifications");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "error receiving notifications", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Result.SUCCESS;
|
||||
}
|
||||
|
||||
private void onNotificationsReceived(AccountEntity account, List<Notification> notificationList) {
|
||||
Collections.reverse(notificationList);
|
||||
String newId = account.getLastNotificationId();
|
||||
String newestId = "";
|
||||
boolean isFirstOfBatch = true;
|
||||
|
||||
for (Notification notification : notificationList) {
|
||||
String currentId = notification.getId();
|
||||
if (isLessThan(newestId, currentId)) {
|
||||
newestId = currentId;
|
||||
}
|
||||
if (isLessThan(newId, currentId)) {
|
||||
NotificationHelper.make(context, notification, account, isFirstOfBatch);
|
||||
isFirstOfBatch = false;
|
||||
}
|
||||
}
|
||||
|
||||
account.setLastNotificationId(newestId);
|
||||
accountManager.saveAccount(account);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -29,7 +29,6 @@ import androidx.core.graphics.drawable.IconCompat
|
|||
import com.bumptech.glide.Glide
|
||||
import com.keylesspalace.tusky.MainActivity
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.components.notifications.NotificationHelper
|
||||
import com.keylesspalace.tusky.db.AccountEntity
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
package com.keylesspalace.tusky.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
@ -52,13 +51,6 @@ public class ThemeUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static int getDimension(@NonNull Context context, @AttrRes int attribute) {
|
||||
TypedArray array = context.obtainStyledAttributes(new int[] { attribute });
|
||||
int dimen = array.getDimensionPixelSize(0, -1);
|
||||
array.recycle();
|
||||
return dimen;
|
||||
}
|
||||
|
||||
/** this can be replaced with drawableTint in xml once minSdkVersion >= 23 */
|
||||
@Nullable
|
||||
public static Drawable getTintedDrawable(@NonNull Context context, @DrawableRes int drawableId, @AttrRes int colorAttr) {
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
package com.keylesspalace.tusky.view
|
||||
|
||||
import android.view.*
|
||||
import android.content.*
|
||||
import android.util.*
|
||||
import android.widget.*
|
||||
import android.app.*
|
||||
import android.text.*
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.preference.PreferenceManager
|
||||
|
||||
import com.keylesspalace.tusky.adapter.StatusViewHolder
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener
|
||||
import com.keylesspalace.tusky.util.CardViewMode
|
||||
import com.keylesspalace.tusky.util.ViewDataUtils
|
||||
import com.keylesspalace.tusky.util.StatusDisplayOptions
|
||||
import com.keylesspalace.tusky.R
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class StatusView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0)
|
||||
: ConstraintLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private var viewHolder : StatusViewHolder
|
||||
private var statusDisplayOptions : StatusDisplayOptions
|
||||
init {
|
||||
View.inflate(context, R.layout.item_status, this)
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
statusDisplayOptions = StatusDisplayOptions(
|
||||
animateAvatars = preferences.getBoolean("animateGifAvatars", false),
|
||||
mediaPreviewEnabled = true,
|
||||
useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false),
|
||||
showBotOverlay = false,
|
||||
useBlurhash = preferences.getBoolean("useBlurhash", true),
|
||||
cardViewMode = CardViewMode.NONE,
|
||||
confirmReblogs = preferences.getBoolean("confirmReblogs", true)
|
||||
)
|
||||
viewHolder = StatusViewHolder(this)
|
||||
}
|
||||
|
||||
fun setupWithStatus(status: Status) {
|
||||
val concrete = ViewDataUtils.statusToViewData(status, false, false)
|
||||
viewHolder.setupWithStatus(concrete, DummyStatusActionListener(), statusDisplayOptions)
|
||||
}
|
||||
|
||||
class DummyStatusActionListener: StatusActionListener {
|
||||
override fun onReply(position: Int) { }
|
||||
override fun onReblog(reblog: Boolean, position: Int) { }
|
||||
override fun onFavourite(favourite: Boolean, position: Int) { }
|
||||
override fun onBookmark(bookmark: Boolean, position: Int) { }
|
||||
override fun onMore(view: View, position: Int) { }
|
||||
override fun onViewMedia(position: Int, attachmentIndex: Int, view: View?) { }
|
||||
override fun onViewThread(position: Int) { }
|
||||
override fun onOpenReblog(position: Int) { }
|
||||
override fun onExpandedChange(expanded: Boolean, position: Int) { }
|
||||
override fun onContentHiddenChange(isShowing: Boolean, position: Int) { }
|
||||
override fun onLoadMore(position: Int) { }
|
||||
override fun onContentCollapsedChange(isCollapsed: Boolean, position: Int) { }
|
||||
override fun onVoteInPoll(position: Int, choices: MutableList<Int>) { }
|
||||
override fun onViewAccount(id: String) { }
|
||||
override fun onViewTag(id: String) { }
|
||||
override fun onViewUrl(id: String) { }
|
||||
}
|
||||
}
|
|
@ -145,12 +145,12 @@
|
|||
android:layout_height="16sp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:contentDescription="@string/description_account_locked"
|
||||
android:tint="?android:textColorSecondary"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/accountUsernameTextView"
|
||||
app:layout_constraintStart_toEndOf="@+id/accountUsernameTextView"
|
||||
app:layout_constraintTop_toTopOf="@+id/accountUsernameTextView"
|
||||
app:srcCompat="@drawable/ic_reblog_private_24dp"
|
||||
app:tint="?android:textColorSecondary"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -301,29 +301,10 @@
|
|||
android:layout_height="300dp"
|
||||
android:background="?attr/colorSurface"
|
||||
android:elevation="12dp"
|
||||
android:paddingBottom="60dp"
|
||||
android:layout_marginBottom="56dp"
|
||||
app:behavior_hideable="true"
|
||||
app:behavior_peekHeight="0dp"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" />
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/previewScroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorSurface"
|
||||
android:elevation="12dp"
|
||||
android:paddingBottom="60dp"
|
||||
app:behavior_hideable="true"
|
||||
app:behavior_peekHeight="0dp"
|
||||
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
|
||||
>
|
||||
<com.keylesspalace.tusky.view.StatusView
|
||||
android:id="@+id/previewView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorSurface"
|
||||
/>
|
||||
</ScrollView>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -448,29 +429,16 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:textColor="?android:textColorTertiary"
|
||||
android:textSize="?attr/status_text_medium"
|
||||
android:layout_toLeftOf="@+id/composePreviewButton"
|
||||
android:layout_toLeftOf="@+id/composeTootButton"
|
||||
android:layout_centerVertical="true"
|
||||
tools:text="500" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/composePreviewButton"
|
||||
style="@style/TuskyButton"
|
||||
android:padding="4dp"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
app:icon="@drawable/ic_eye_24dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:visibility="gone"
|
||||
android:layout_toLeftOf="@+id/composeTootButton"
|
||||
android:layout_centerVertical="true"/>
|
||||
|
||||
<com.keylesspalace.tusky.components.compose.view.TootButton
|
||||
android:id="@+id/composeTootButton"
|
||||
style="@style/TuskyButton"
|
||||
android:layout_width="@dimen/toot_button_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textSize="?attr/status_text_medium"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"/>
|
||||
|
|
|
@ -22,17 +22,19 @@
|
|||
android:id="@+id/mainToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:contentInsetStartWithNavigation="0dp"
|
||||
app:layout_scrollFlags="scroll|enterAlways" />
|
||||
app:contentInsetStartWithNavigation="0dp">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
style="@style/TuskyTabAppearance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabGravity="fill"
|
||||
app:tabMaxWidth="0dp"
|
||||
app:tabMode="fixed" />
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
style="@style/TuskyTabAppearance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:tabGravity="fill"
|
||||
app:tabMaxWidth="0dp"
|
||||
app:tabMode="fixed"
|
||||
app:tabUnboundedRipple="false" />
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
|
@ -40,32 +42,15 @@
|
|||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="?attr/actionBarSize"
|
||||
android:layout_below="@id/tabLayout"
|
||||
android:background="?attr/windowBackgroundColor"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
|
||||
<com.google.android.material.bottomappbar.BottomAppBar
|
||||
android:id="@+id/bottomNav"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
app:contentInsetStart="0dp"
|
||||
app:fabAlignmentMode="end">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/bottomTabLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:tabIndicator="@null"
|
||||
app:tabMode="fixed" />
|
||||
|
||||
</com.google.android.material.bottomappbar.BottomAppBar>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/composeButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/fabMargin"
|
||||
android:layout_margin="16dp"
|
||||
android:contentDescription="@string/action_compose"
|
||||
app:layout_anchor="@id/viewPager"
|
||||
app:layout_anchorGravity="bottom|end"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/account_avatar"
|
||||
app:layout_constraintEnd_toEndOf="@id/account_avatar"
|
||||
tools:src="#000"
|
||||
tools:src="@color/accent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.emoji.widget.EmojiTextView
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/status_avatar"
|
||||
app:layout_constraintEnd_toEndOf="@id/status_avatar"
|
||||
tools:src="#000"
|
||||
tools:src="@color/accent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.emoji.widget.EmojiTextView
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
|
||||
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
|
||||
|
||||
<com.keylesspalace.tusky.view.MediaPreviewImageView
|
||||
android:id="@+id/status_media_preview_0"
|
||||
|
@ -25,11 +25,13 @@
|
|||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
|
||||
<com.keylesspalace.tusky.view.MediaPreviewImageView
|
||||
android:id="@+id/status_media_preview_2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/status_media_preview_height"
|
||||
android:layout_marginTop="4dp"
|
||||
android:background="@drawable/media_preview_outline"
|
||||
android:scaleType="centerCrop"
|
||||
app:layout_constraintEnd_toStartOf="@+id/status_media_preview_3"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
@ -42,7 +44,6 @@
|
|||
android:layout_height="@dimen/status_media_preview_height"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:background="@drawable/media_preview_outline"
|
||||
android:scaleType="centerCrop"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/status_media_preview_2"
|
||||
|
@ -104,18 +105,19 @@
|
|||
android:alpha="0.7"
|
||||
android:contentDescription="@null"
|
||||
android:padding="@dimen/status_sensitive_media_button_padding"
|
||||
android:tint="@color/white"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/status_media_preview_container"
|
||||
app:layout_constraintTop_toTopOf="@+id/status_media_preview_container"
|
||||
app:srcCompat="@drawable/ic_eye_24dp"
|
||||
app:tint="@color/white" />
|
||||
app:srcCompat="@drawable/ic_eye_24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status_sensitive_media_warning"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/media_warning_bg"
|
||||
android:gravity="center"
|
||||
android:importantForAccessibility="no"
|
||||
android:lineSpacingMultiplier="1.2"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="12dp"
|
||||
|
@ -183,4 +185,5 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/status_media_label_2" />
|
||||
|
||||
|
||||
</merge>
|
||||
|
|
|
@ -194,12 +194,12 @@
|
|||
android:alpha="0.7"
|
||||
android:contentDescription="@null"
|
||||
android:padding="@dimen/status_sensitive_media_button_padding"
|
||||
android:tint="@color/white"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/status_media_preview_container"
|
||||
app:layout_constraintTop_toTopOf="@+id/status_media_preview_container"
|
||||
app:srcCompat="@drawable/ic_eye_24dp"
|
||||
tools:visibility="visible"
|
||||
app:tint="@color/white" />
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status_sensitive_media_warning"
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/status_avatar"
|
||||
app:layout_constraintEnd_toEndOf="@id/status_avatar"
|
||||
tools:src="#000"
|
||||
tools:src="@color/accent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.emoji.widget.EmojiTextView
|
||||
|
@ -269,7 +269,7 @@
|
|||
android:importantForAccessibility="noHideDescendants"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@id/status_display_name"
|
||||
app:layout_constraintTop_toBottomOf="@id/status_card_view"
|
||||
app:layout_constraintTop_toBottomOf="@id/button_toggle_content"
|
||||
tools:visibility="visible">
|
||||
|
||||
<include layout="@layout/item_media_preview" />
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/status_avatar"
|
||||
app:layout_constraintEnd_toEndOf="@id/status_avatar"
|
||||
tools:src="#000"
|
||||
tools:src="@color/accent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.emoji.widget.EmojiTextView
|
||||
|
|
|
@ -211,7 +211,7 @@
|
|||
<string name="notification_favourite_name">المفضلة</string>
|
||||
<string name="notification_favourite_description">الإشعار عندما يقوم أحدهم بإضافة تبويقاتك إلى مفضلاته</string>
|
||||
<string name="notification_mention_format">%s أشار إليك</string>
|
||||
<string name="notification_summary_large">%1$s, %2$s, %3$s و %4$d آخرون</string>
|
||||
<string name="notification_summary_large">%1$s, %2$s, %3$s و %4$d أخرى</string>
|
||||
<string name="notification_summary_medium">%1$s, %2$s, و %3$s</string>
|
||||
<string name="notification_summary_small">%1$s و %2$s</string>
|
||||
<string name="notification_title_summary">%d تفاعلات جديدة</string>
|
||||
|
@ -492,6 +492,4 @@
|
|||
<string name="action_unmute_conversation">ألغِ كتم المحادثة</string>
|
||||
<string name="action_mute_conversation">اكتم المحادثة</string>
|
||||
<string name="notification_follow_request_format">%s طلبَ متابعتك</string>
|
||||
<string name="hashtags">الوسوم</string>
|
||||
<string name="add_hashtag_title">إضافة وسم</string>
|
||||
</resources>
|
|
@ -357,6 +357,7 @@
|
|||
<string name="description_visiblity_direct">সরাসরি</string>
|
||||
<string name="description_poll">পছন্দগুলি সহ নর্বাচন: %1$s, %2$s, %3$s, %4$s; %5$s</string>
|
||||
<string name="hint_list_name">নামের তালিকা</string>
|
||||
|
||||
<string name="edit_hashtag_hint"># ছাড়া হ্যাশট্যাগ</string>
|
||||
<string name="notifications_clear">পরিষ্কার</string>
|
||||
<string name="notifications_apply_filter">ফিল্টার</string>
|
||||
|
@ -366,14 +367,33 @@
|
|||
<string name="notification_clear_text">আপনি কি আপনার সমস্ত বিজ্ঞপ্তি স্থায়ীভাবে মুছে ফেলতে চান\?</string>
|
||||
<string name="compose_preview_image_description">ছবি %s এর জন্য ক্রিয়া</string>
|
||||
<string name="poll_info_format"> <!-- ১৫ ভোট • ১ ঘন্টা বাকি --> %1$s • %2$s</string>
|
||||
|
||||
<plurals name="poll_info_votes">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<string name="poll_info_time_relative">%s বাকি</string>
|
||||
<string name="poll_info_time_absolute">%s এ শেষ হবে</string>
|
||||
<string name="poll_info_closed">বন্ধ</string>
|
||||
<string name="poll_vote">ভোট</string>
|
||||
<string name="poll_ended_voted">আপনি ভোট দিয়েছেন যে নির্বাচন এ সেটি শেষ হয়েছে</string>
|
||||
<string name="poll_ended_created">আপনি তৈরি একটি নির্বাচন শেষ হয়েছে</string>
|
||||
|
||||
<!--These are for timestamps on polls -->
|
||||
<plurals name="poll_timespan_days">
|
||||
<item quantity="one">%d দিন</item>
|
||||
<item quantity="other">%d দিন</item>
|
||||
</plurals>
|
||||
<plurals name="poll_timespan_hours">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<plurals name="poll_timespan_minutes">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<plurals name="poll_timespan_seconds">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<string name="button_continue">চালিয়ে যান</string>
|
||||
<string name="button_back">পিছনে যান</string>
|
||||
<string name="button_done">সম্পন্ন</string>
|
||||
|
|
|
@ -4,16 +4,16 @@
|
|||
<string name="error_empty">Això no pot estar buit.</string>
|
||||
<string name="error_invalid_domain">El domini introduït no és vàlid</string>
|
||||
<string name="error_failed_app_registration">L\'autenticació en aquesta instància ha fallat.</string>
|
||||
<string name="error_no_web_browser_found">No s\'ha trobat cap navegador web per a utilitzar.</string>
|
||||
<string name="error_no_web_browser_found">No s\'ha trobat cap navegador web per a usar.</string>
|
||||
<string name="error_authorization_unknown">S\'ha produït un error d\'autorització no identificat.</string>
|
||||
<string name="error_authorization_denied">S\'ha denegat l\'autorització.</string>
|
||||
<string name="error_retrieving_oauth_token">L\'obtenció del token d\'inici de sessió ha fallat.</string>
|
||||
<string name="error_retrieving_oauth_token">L\'obtenció del testimoni d\'inici de sessió ha fallat.</string>
|
||||
<string name="error_compose_character_limit">L\'estat és massa llarg!</string>
|
||||
<string name="error_image_upload_size">El fitxer ha de ser inferior a 8MB.</string>
|
||||
<string name="error_media_upload_type">Aquest tipus de fitxer no es pot pujar.</string>
|
||||
<string name="error_media_upload_opening">Aquest tipus de fitxer no es pot obrir.</string>
|
||||
<string name="error_media_upload_permission">Cal permís d\'accés al emmagatzematge.</string>
|
||||
<string name="error_media_download_permission">Cal permís d\'escriptura en el dispositiu.</string>
|
||||
<string name="error_media_download_permission">Cal permís d\'escriptura en el mitjà.</string>
|
||||
<string name="error_media_upload_image_or_video">No es poden adjuntar imatges i vídeos en el mateix estat.</string>
|
||||
<string name="error_media_upload_sending">La pujada ha fallat.</string>
|
||||
<string name="title_home">Inici</string>
|
||||
|
@ -202,15 +202,15 @@
|
|||
<string name="title_direct_messages">Missatges directes</string>
|
||||
<string name="message_empty">No hi ha res aquí.</string>
|
||||
<string name="action_unreblog">Elimina l\'impuls</string>
|
||||
<string name="error_network">S\'ha produït un error de connexió! Comprova la connexió i torna-ho a provar!</string>
|
||||
<string name="error_video_upload_size">Els fitxers de vídeo han de pesar menys de 40 MB.</string>
|
||||
<string name="error_network">S\'ha produït un error de connexió! Comprova la connexió!</string>
|
||||
<string name="error_video_upload_size">Els fitxers de vídeo han de tenir menys de 40 MB.</string>
|
||||
<string name="status_media_hidden_title">Multimèdia amagada</string>
|
||||
<string name="status_content_show_less">Amaga</string>
|
||||
<string name="action_logout_confirm">Estàs segur de tancar la sessió de %1$s\?</string>
|
||||
<string name="action_hide_reblogs">Amaga els impulsos</string>
|
||||
<string name="action_show_reblogs">Mostra els impulsos</string>
|
||||
<string name="action_delete_and_redraft">Elimina i reecririu</string>
|
||||
<string name="action_open_drawer">Calaix obert</string>
|
||||
<string name="action_open_drawer">Open drawer</string>
|
||||
<string name="action_toggle_visibility">Visibilitat del toot</string>
|
||||
<string name="action_content_warning">Contingut sensible</string>
|
||||
<string name="action_add_tab">Afegeix una pestanya</string>
|
||||
|
@ -226,7 +226,7 @@
|
|||
<string name="send_media_to">Compartir la imatge a …</string>
|
||||
<string name="status_sent">Enviat!</string>
|
||||
<string name="state_follow_requested">Petició de seguiment enviada</string>
|
||||
<string name="title_statuses_with_replies">Amb respostes</string>
|
||||
<string name="title_statuses_with_replies">Amb resposta</string>
|
||||
<string name="action_emoji_keyboard">Teclat d\'emojis</string>
|
||||
<string name="action_open_media_n">Obrir el media #%d</string>
|
||||
<string name="action_open_as">Obrir com %s</string>
|
||||
|
@ -351,6 +351,7 @@
|
|||
<string name="description_visiblity_private">Seguidors</string>
|
||||
<string name="description_visiblity_direct">Directe</string>
|
||||
<string name="hint_list_name">Nom de la llista</string>
|
||||
|
||||
<string name="edit_hashtag_hint">Hashtag sense #</string>
|
||||
<string name="notifications_clear">Netejar</string>
|
||||
<string name="notifications_apply_filter">Filtrar</string>
|
||||
|
@ -444,24 +445,8 @@
|
|||
<string name="post_lookup_error_format">S\'ha produït un error en cercar la publicació %s</string>
|
||||
<string name="gradient_for_media">Mostra degradats de colors per a contingut multimèdia ocult</string>
|
||||
<string name="no_scheduled_status">No tens cap estat planificat.</string>
|
||||
<string name="error_audio_upload_size">Els fitxers d\'àudio han de ser més petits que 40MB.</string>
|
||||
<string name="error_audio_upload_size">Els fitxers d\'àudio han de ser més petits de 40MB.</string>
|
||||
<string name="no_saved_status">No tens cap esborrany.</string>
|
||||
<string name="warning_scheduling_interval">L\'interval mínim de planificació a Mastodon és de 5 minuts.</string>
|
||||
<string name="notification_follow_request_name">Peticions de seguiment</string>
|
||||
<string name="pref_title_confirm_reblogs">Mostra el diàleg de confirmació abans de promoure</string>
|
||||
<string name="pref_title_show_cards_in_timelines">Mostra les previsualitzacions dels enllaços en els fils</string>
|
||||
<string name="pref_title_enable_swipe_for_tabs">Habilita el gest de desplaçament per despleçar-te entre pestanyes</string>
|
||||
<plurals name="poll_info_people">
|
||||
<item quantity="one">%s persona</item>
|
||||
<item quantity="other">%s persones</item>
|
||||
</plurals>
|
||||
<string name="hashtags">Hashtags</string>
|
||||
<string name="add_hashtag_title">Afegir hashtag</string>
|
||||
<string name="notification_follow_request_description">Notificacions sobre sol·licituds de seguiment</string>
|
||||
<string name="pref_title_notification_filter_follow_requests">sol·licitació de seguiment</string>
|
||||
<string name="dialog_mute_warning">Silenciar @%s\?</string>
|
||||
<string name="dialog_block_warning">Bloquejar @%s\?</string>
|
||||
<string name="action_unmute_conversation">No silenciar la conversació</string>
|
||||
<string name="action_mute_conversation">Conversació muda</string>
|
||||
<string name="notification_follow_request_format">%s ha sol·licitat seguir-te</string>
|
||||
</resources>
|
|
@ -362,7 +362,9 @@
|
|||
</string>
|
||||
<string name="hint_list_name">Název seznamu</string>
|
||||
<string name="edit_hashtag_hint">Hashtag bez #</string>
|
||||
|
||||
<string name="compose_shortcut_long_label">Napsat toot</string>
|
||||
|
||||
<string name="compose_shortcut_short_label">Napsat</string>
|
||||
<string name="notifications_clear">Vymazat</string>
|
||||
<string name="notifications_apply_filter">Filtrovat</string>
|
||||
|
@ -424,7 +426,7 @@
|
|||
<string name="report_remote_instance">Přeposlat na %s</string>
|
||||
<string name="failed_report">Nahlášení selhalo</string>
|
||||
<string name="failed_fetch_statuses">Stahování tootů neuspělo</string>
|
||||
<string name="report_description_1">Nahlášení bude zasláno moderátorovi vašeho serveru. Níže můžete uvést, proč tento účet nahlašujete:</string>
|
||||
<string name="report_description_1">Nahlášení bude zasláno moderátorům vašeho serveru. Níže můžete uvést, proč tento účet nahlašujete:</string>
|
||||
<string name="report_description_remote_instance">Tento účet je z jiného serveru. Chcete na něj také poslat anonymizovanou kopii\?</string>
|
||||
<string name="pref_title_show_notifications_filter">Zobrazit filtr oznámení</string>
|
||||
<string name="create_poll_title">Anketa</string>
|
||||
|
|
|
@ -290,5 +290,4 @@
|
|||
<string name="action_links">Cysylltiadau</string>
|
||||
<string name="title_links_dialog">Cysylltiadau</string>
|
||||
<string name="action_open_reblogged_by">Dangos hybiadau</string>
|
||||
<string name="notification_follow_request_name">Dilyn ceisiadau</string>
|
||||
</resources>
|
|
@ -330,7 +330,9 @@
|
|||
<string name="hint_search_people_list">Suche nach Leuten denen du folgst</string>
|
||||
<string name="action_remove_from_list">Von der Liste entfernen</string>
|
||||
<string name="edit_hashtag_hint">Hashtag ohne #</string>
|
||||
|
||||
<string name="action_open_reblogger">Öffne Autor des geteilten Beitrages</string>
|
||||
|
||||
<string name="pref_title_public_filter_keywords">Öffentliche Zeitleisten</string>
|
||||
<plurals name="favs">
|
||||
<item quantity="one"><b>%1$s</b> Favorit</item>
|
||||
|
@ -430,7 +432,10 @@
|
|||
<string name="action_view_bookmarks">Lesezeichen</string>
|
||||
<string name="gradient_for_media">Bunten Farbverlauf für versteckte Medien anzeigen</string>
|
||||
<string name="about_powered_by_tusky">Powered by Tusky</string>
|
||||
|
||||
<plurals name="reblogs">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<string name="description_status_bookmarked">Als Lesezeichen gespeichert</string>
|
||||
<string name="select_list_title">Liste auswählen</string>
|
||||
<string name="list">Liste</string>
|
||||
|
@ -446,6 +451,4 @@
|
|||
<string name="action_unmute_conversation">Stummschaltung der Konversation aufheben</string>
|
||||
<string name="action_mute_conversation">Konversation stummschalten</string>
|
||||
<string name="notification_follow_request_format">"%s möchte dir folgen"</string>
|
||||
<string name="hashtags">Hashtags</string>
|
||||
<string name="add_hashtag_title">Hashtag hinzufügen</string>
|
||||
</resources>
|
|
@ -158,7 +158,7 @@
|
|||
<string name="pref_title_notification_filter_follows">me siguen</string>
|
||||
<string name="pref_title_notification_filter_reblogs">mis posts son impulsados</string>
|
||||
<string name="pref_title_notification_filter_favourites">me dan favorito</string>
|
||||
<string name="pref_title_appearance_settings">Apariencia</string>
|
||||
<string name="pref_title_appearance_settings">Interfaz</string>
|
||||
<string name="pref_title_app_theme">Tema</string>
|
||||
<string name="pref_title_timelines">Cronologia</string>
|
||||
<string name="app_them_dark">Oscuro</string>
|
||||
|
@ -402,7 +402,7 @@
|
|||
<string name="mute_domain_warning_dialog_ok">Ocultar dominio completo</string>
|
||||
<string name="pref_title_animate_gif_avatars">Animar avatares GIF</string>
|
||||
<string name="filter_dialog_whole_word">Toda palabra</string>
|
||||
<string name="filter_dialog_whole_word_description">Cuando la palabra o frase sea solo alfanumérica, solo se aplicará si coincide con toda la palabra</string>
|
||||
<string name="filter_dialog_whole_word_description">Cuando la palabra o frase sea solo alfanumérica, solo se aplicará si coincide con toda la palabra.</string>
|
||||
<string name="caption_notoemoji">Set de emojis actual de Google</string>
|
||||
<string name="description_poll">Encuesta con opciones: %1$s, %2$s, %3$s, %4$s; %5$s</string>
|
||||
<string name="button_continue">Continuar</string>
|
||||
|
@ -451,20 +451,4 @@
|
|||
<string name="no_scheduled_status">No tienes ningún estado programado.</string>
|
||||
<string name="warning_scheduling_interval">Mastodon tiene un intervalo de programación mínimo de 5 minutos.</string>
|
||||
<string name="notification_follow_request_name">Solicitudes</string>
|
||||
<string name="dialog_block_warning">Bloquear @%s\?</string>
|
||||
<string name="dialog_mute_warning">Silenciar @%s\?</string>
|
||||
<string name="action_mute_conversation">Silenciar conversación</string>
|
||||
<string name="action_unmute_conversation">Dejar de silenciar conversación</string>
|
||||
<string name="notification_follow_request_description">Notificaciones de solicitudes</string>
|
||||
<string name="pref_title_notification_filter_follow_requests">solicitud de seguimiento</string>
|
||||
<string name="pref_title_confirm_reblogs">Mostrar diálogo de confirmación antes de impulsar</string>
|
||||
<string name="pref_title_show_cards_in_timelines">Mostrar previsualización de enlaces en la cronología</string>
|
||||
<string name="pref_title_enable_swipe_for_tabs">Habilitar gesto de deslizar para alternar entre pestañas</string>
|
||||
<plurals name="poll_info_people">
|
||||
<item quantity="one">%s persona</item>
|
||||
<item quantity="other">%s personas</item>
|
||||
</plurals>
|
||||
<string name="hashtags">Etiquetas</string>
|
||||
<string name="add_hashtag_title">Añadir etiqueta</string>
|
||||
<string name="notification_follow_request_format">%s solicita seguirte</string>
|
||||
</resources>
|
|
@ -119,7 +119,7 @@
|
|||
<string name="label_header">Goiburua</string>
|
||||
<string name="link_whats_an_instance">Zer da instantzia?</string>
|
||||
<string name="login_connection">Konektatzen…</string>
|
||||
<string name="dialog_whats_an_instance"> Sartu hemen helbidea edo mastodon.eus, mastodon.jalgi.eus, mastodon.social bezalako <a href="https://instances.social">edozein instantzia</a>,
|
||||
<string name="dialog_whats_an_instance">Sartu hemen helbidea edo mastodon.eus, mastodon.jalgi.eus, mastodon.social bezalako <a href="https://instances.social">edozein instantzia</a>,
|
||||
\n
|
||||
\n Oraindik ez baduzu konturik, instantziaren izena sartu eta bertan kontua sortu dezakezu.
|
||||
\n
|
||||
|
@ -388,7 +388,7 @@
|
|||
</plurals>
|
||||
<string name="poll_info_time_absolute">%s amaitzen da</string>
|
||||
<string name="poll_info_closed">itxita</string>
|
||||
<string name="poll_vote">Bozkatu</string>
|
||||
<string name="poll_vote">Botatu</string>
|
||||
<string name="poll_ended_voted">Botoa eman duzun galdeketa amaitu da</string>
|
||||
<string name="poll_ended_created">Sortu duzun galdeketa amaitu da</string>
|
||||
<plurals name="poll_timespan_days">
|
||||
|
@ -448,9 +448,4 @@
|
|||
<string name="no_scheduled_status">Ez duzu tut programaturik.</string>
|
||||
<string name="warning_scheduling_interval">Mastodonek gutxienez 5 minutuko programazio-tartea du.</string>
|
||||
<string name="notification_follow_request_name">Eskariak</string>
|
||||
<string name="notification_follow_request_description">Jarraitzeko eskaereri buruzko jakinarazpenak</string>
|
||||
<string name="dialog_mute_warning">\@%s isildu\?</string>
|
||||
<string name="dialog_block_warning">\@%s blokeatu\?</string>
|
||||
<string name="action_mute_conversation">Elkarrizketa isildu</string>
|
||||
<string name="notification_follow_request_format">%s -k zu jarraitzeko eskatu dizu</string>
|
||||
</resources>
|
|
@ -26,7 +26,7 @@
|
|||
<string name="title_statuses">پستها</string>
|
||||
<string name="title_statuses_with_replies">با پاسخ</string>
|
||||
<string name="title_follows">دنبال شوندهها</string>
|
||||
<string name="title_followers">پیروان</string>
|
||||
<string name="title_followers">پیگیر</string>
|
||||
<string name="title_favourites">علاقهمندیها</string>
|
||||
<string name="title_mutes">کاربرهای بیصدا</string>
|
||||
<string name="title_blocks">کاربرهای مسدود شده</string>
|
||||
|
@ -119,13 +119,13 @@
|
|||
<string name="label_header">سرایند</string>
|
||||
<string name="link_whats_an_instance">یک نمونه چیست؟</string>
|
||||
<string name="login_connection">در حال اتصال …</string>
|
||||
<string name="dialog_whats_an_instance">نشانی یا دامنهٔ هر نمونهای میتواند وارد شود، مثل mastodon.social, icosahedron.website, social.tchncs.de, و <a href="https://instances.social">بیشتر!</a>.
|
||||
\n
|
||||
\n اگر هنوز حسابی ندارید، میتوانید نام نمونه مورد نظر را وارد کرده و در آن حسابی بسازید.
|
||||
\n
|
||||
\n نمونه، جاییست که حسابتان رویش میزبانی میشود، ولی به راحتی میتوانید با دیگر افراد روی نمونههای دیگر ارتباط داشته و دنبالشان کنید؛ انگار که روی یک پایگاه باشید.
|
||||
\n
|
||||
\nاطّلاعات بیشتر میتواند در <a href="https://joinmastodon.org">joinmastodon.org</a> پیدا شود. </string>
|
||||
<string name="dialog_whats_an_instance">آدرس یا دامنه هر نمونه را میتوانید وارد کنید، مثلا mastodon.social, icosahedron.website, social.tchncs.de, و <a href=\"https://instances.social\" >بیشتر!
|
||||
\n
|
||||
\n اگر شما هنوز حساب کاربری ندارید، میتوانید نام نمونه مورد نظر را وارد کنید از اینجا بپیوندید و حساب کاربری ایجاد کنید.
|
||||
\n
|
||||
\n نمونه جایی است که حساب کاربری شما میزبان آن است اما شما به راحتی میتوانید با افراد دیگر در نمونههای دیگر ارتباط برقرار کنید و آنها را دنبال کنید شما درست مثل اینکه در یکجا باشید.
|
||||
\n
|
||||
\n برای اطلاعات بیشتر به اینجا مراجعه کنید <a href="https://joinmastodon.org">joinmastodon.org</a>. </string>
|
||||
<string name="dialog_title_finishing_media_upload">پایان بارگذاری رسانه</string>
|
||||
<string name="dialog_message_uploading_media">در حال بارگذاری…</string>
|
||||
<string name="dialog_download_image">بارگیری</string>
|
||||
|
@ -195,7 +195,9 @@
|
|||
<string name="notification_title_summary">%d برهمکنش جدید</string>
|
||||
<string name="description_account_locked">حساب قفلشده</string>
|
||||
<string name="about_title_activity">درباره</string>
|
||||
<string name="about_tusky_license">تاسکی نرمافزاری آزاد است که تحت نگارش ۳ از پروانهٔ جامع همگانی گنو منتشر شده است. پروانه را میتوانید از اینجا ببینید: https://www.gnu.org/licenses/gpl-3.0.en.html</string>
|
||||
<string name="about_tusky_license">Tusky یک برنامه آزاد و متنباز است که تحت مجوز GNU General Public License Version 3. منتشر شده است.
|
||||
\n شما میتوانید مجوز را از اینجا ببینید:
|
||||
\n https://www.gnu.org/licenses/gpl-3.0.en.html</string>
|
||||
<!-- note to translators:
|
||||
* you should think of “free” as in “free speech,” not as in “free beer”.
|
||||
We sometimes call it “libre software,” borrowing the French or Spanish word for “free” as in freedom,
|
||||
|
@ -224,7 +226,7 @@
|
|||
<string name="replying_to">در حال پاسخ به @%s</string>
|
||||
<string name="load_more_placeholder_text">بارگیری بیشتر</string>
|
||||
<string name="add_account_name">افزودن حساب</string>
|
||||
<string name="add_account_description">افزودن حساب جدید ماستودون</string>
|
||||
<string name="add_account_description">افزودن حساب ماستودون جدید</string>
|
||||
<string name="action_lists">لیستها</string>
|
||||
<string name="title_lists">فهرستها</string>
|
||||
<string name="title_list_timeline">خط زمانی فهرست</string>
|
||||
|
@ -235,7 +237,7 @@
|
|||
<string name="action_remove">برداشتن</string>
|
||||
<string name="lock_account_label">قفل حساب</string>
|
||||
<string name="lock_account_label_description">نیاز دارد پیگیرانتان را به صورت دستی تأیید کنید</string>
|
||||
<string name="compose_save_draft">ذخیرهٔ پیشنویس؟</string>
|
||||
<string name="compose_save_draft">ذخیره به عنوان پیشنویس</string>
|
||||
<string name="send_toot_notification_title">در حال فرستادن بوق…</string>
|
||||
<string name="send_toot_notification_error_title">خطای فرستادن بوق</string>
|
||||
<string name="send_toot_notification_channel_name">در حال فرستادن بوقها</string>
|
||||
|
@ -429,7 +431,7 @@
|
|||
<string name="filter_dialog_whole_word_description">هنگامی که کلیدواژه یا عبارت، فقط حروفعددی باشد، فقط اگر با تمام واژه مطابق باشد، اعمال خواهد شد</string>
|
||||
<string name="filter_add_description">عبارت پالایش</string>
|
||||
<string name="poll_info_format"> <!-- 15 votes • 1 hour left --> %1$s • %2$s</string>
|
||||
<string name="report_description_1">گزارش به ناظر کارسازتان ارسال خواهد شد. میتوانید توضیحی در باب چرایی گزارش این حساب در زیر بنویسید:</string>
|
||||
<string name="report_description_1">گزارش به ناظمهای کارسازتان ارسال خواهد شد. میتوانید توضیحی در باب چرایی گزارش این حساب در زیر بنویسید:</string>
|
||||
<string name="report_description_remote_instance">این حساب از کارسازی دیگر است. رونوشتی ناشناس از گزارش، به آنجا نیز ارسال شود؟</string>
|
||||
<string name="post_lookup_error_format">خطا در یافتن فرستهٔ %s</string>
|
||||
<string name="about_powered_by_tusky">قدرتگرفته از تاسکی</string>
|
||||
|
@ -444,21 +446,4 @@
|
|||
<string name="no_saved_status">هیچ پیشنویسی ندارید.</string>
|
||||
<string name="no_scheduled_status">هیچ وضعیت زمانبستهای ندارید.</string>
|
||||
<string name="warning_scheduling_interval">ماستودون، بازهٔ زمانبندیای با کمینهٔ ۵ دقیقه دارد.</string>
|
||||
<string name="pref_title_confirm_reblogs">نمایش گفتوگوی تأیید پیش از تقویت</string>
|
||||
<string name="pref_title_show_cards_in_timelines">پیشنمایش پیوندها در خطزمانیها</string>
|
||||
<string name="pref_title_enable_swipe_for_tabs">به کار انداختن اشارهٔ کشیدنی برای تعویض بین زبانهها</string>
|
||||
<plurals name="poll_info_people">
|
||||
<item quantity="one">%s نفر</item>
|
||||
<item quantity="other">%s نفر</item>
|
||||
</plurals>
|
||||
<string name="hashtags">هشتگها</string>
|
||||
<string name="add_hashtag_title">افزودن هشتگ</string>
|
||||
<string name="notification_follow_request_description">آگاهیها در مورد درخواستهای پیگیری</string>
|
||||
<string name="notification_follow_request_name">درخواستهای پیگیری</string>
|
||||
<string name="pref_title_notification_filter_follow_requests">درخواست پیگیری</string>
|
||||
<string name="dialog_mute_warning">خموشی @%s؟</string>
|
||||
<string name="dialog_block_warning">انسداد @%s؟</string>
|
||||
<string name="action_unmute_conversation">ناخموشی گفتوگو</string>
|
||||
<string name="action_mute_conversation">خموشی گفتوگو</string>
|
||||
<string name="notification_follow_request_format">%s میخواهد دنبالتان کند</string>
|
||||
</resources>
|
|
@ -69,7 +69,7 @@
|
|||
<string name="action_unfollow">Ne plus suivre</string>
|
||||
<string name="action_block">Bloquer</string>
|
||||
<string name="action_unblock">Débloquer</string>
|
||||
<string name="action_hide_reblogs">Cacher les partages</string>
|
||||
<string name="action_hide_reblogs">Cacher les boosts</string>
|
||||
<string name="action_show_reblogs">Montrer les boosts</string>
|
||||
<string name="action_report">Signaler</string>
|
||||
<string name="action_delete">Supprimer</string>
|
||||
|
@ -369,7 +369,7 @@
|
|||
<string name="compose_shortcut_long_label">Rédiger un pouet</string>
|
||||
<string name="compose_shortcut_short_label">Écrire</string>
|
||||
<string name="pref_title_bot_overlay">Afficher l\'indicateur de robots</string>
|
||||
<string name="notification_clear_text">Désirez-vous nettoyer toutes vos notifications de façon permanente \?</string>
|
||||
<string name="notification_clear_text">"Nettoyer toutes les notifications de façon permanente\? "</string>
|
||||
<string name="action_delete_and_redraft">Effacer et ré-écrire</string>
|
||||
<string name="dialog_redraft_toot_warning">Effacer et ré-écrire ce pouet \?</string>
|
||||
<plurals name="poll_info_votes">
|
||||
|
@ -449,7 +449,7 @@
|
|||
<string name="post_lookup_error_format">Erreur lors de la récupération du message %s</string>
|
||||
<string name="about_powered_by_tusky">Propulsé par Tusky</string>
|
||||
<string name="title_bookmarks">Signets</string>
|
||||
<string name="action_bookmark">Ajouter aux marque-pages</string>
|
||||
<string name="action_bookmark">Marquer comme signet</string>
|
||||
<string name="action_view_bookmarks">Marque-pages</string>
|
||||
<string name="description_status_bookmarked">Ajouté aux marque-pages</string>
|
||||
<string name="select_list_title">Sélectionner la liste</string>
|
||||
|
@ -474,6 +474,4 @@
|
|||
<string name="action_unmute_conversation">Enlever la sourdine à la conversation</string>
|
||||
<string name="action_mute_conversation">Silencer la conversation</string>
|
||||
<string name="pref_title_enable_swipe_for_tabs">Activer les gestes de glissement pour passer d’un onglet à l’autre</string>
|
||||
<string name="hashtags">Hashtags</string>
|
||||
<string name="add_hashtag_title">Ajouter hashtag</string>
|
||||
</resources>
|
|
@ -345,7 +345,14 @@
|
|||
<string name="label_remote_account">Ekki er víst að upplýsingarnar hér að neðan endurspegli notandasniðið að fullu. Opnaðu fullt notandasnið í vafra.</string>
|
||||
<string name="unpin_action">Losa</string>
|
||||
<string name="pin_action">Festa</string>
|
||||
|
||||
<plurals name="favs">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<plurals name="reblogs">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<string name="title_reblogged_by">Endurbirt af</string>
|
||||
<string name="title_favourited_by">Sett í eftirlæti af</string>
|
||||
<string name="conversation_1_recipients">%1$s</string>
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
<string name="action_edit_profile">Ẓreg amaɣnu</string>
|
||||
<string name="action_search">Nadi</string>
|
||||
<string name="about_title_activity">Ɣef</string>
|
||||
<string name="action_lists">Tabdart</string>
|
||||
<string name="title_lists">Tabdarin</string>
|
||||
<string name="action_lists">Umuɣen</string>
|
||||
<string name="title_lists">Umuɣen</string>
|
||||
<string name="error_compose_character_limit">Tijewwiqt-ik aṭas i ɣuzzifet!</string>
|
||||
<string name="title_home">Agejdan</string>
|
||||
<string name="title_tab_preferences">Iccaren</string>
|
||||
|
@ -123,16 +123,16 @@
|
|||
<string name="status_share_link">Bḍu aseɣwen ɣer tijewwiqt</string>
|
||||
<string name="filter_addition_dialog_title">Rnu amsizdeg</string>
|
||||
<string name="filter_edit_dialog_title">Ẓreg amsizdeg</string>
|
||||
<string name="action_create_list">Snulfu-d tabdart</string>
|
||||
<string name="action_rename_list">Snifel isem n tabdart</string>
|
||||
<string name="action_delete_list">Kkes tabdart-a</string>
|
||||
<string name="action_edit_list">Ẓreg tabdart-a</string>
|
||||
<string name="action_add_to_list">Rnu yiwen umiḍan ɣer tabdart</string>
|
||||
<string name="action_remove_from_list">Kkes amiḍan seg tabdart</string>
|
||||
<string name="action_create_list">Snulfu-d umuɣ</string>
|
||||
<string name="action_rename_list">Snifel isem n wumuɣ</string>
|
||||
<string name="action_delete_list">Kkes umuɣ-a</string>
|
||||
<string name="action_edit_list">Ẓreg umuɣ-a</string>
|
||||
<string name="action_add_to_list">Rnu yiwen umiḍan ɣer wummuɣ</string>
|
||||
<string name="action_remove_from_list">Kkes amiḍan seg wumuɣ</string>
|
||||
<string name="profile_metadata_add">Rnu isefka</string>
|
||||
<string name="hint_list_name">Isem n tebdart</string>
|
||||
<string name="hint_list_name">Isem n wumuɣ</string>
|
||||
<string name="select_list_title">Fren tabdart</string>
|
||||
<string name="list">Tabdart</string>
|
||||
<string name="list">Umuɣ</string>
|
||||
<string name="notifications_apply_filter">Sizdeg</string>
|
||||
<string name="title_accounts">Imiḍanen</string>
|
||||
<string name="add_poll_choice">Rnu yiwen wefran</string>
|
||||
|
@ -207,7 +207,7 @@
|
|||
<string name="poll_new_choice_hint">Tafrant %d</string>
|
||||
<string name="title_follows">Ig ṭafaṛ</string>
|
||||
<string name="title_followers">Imeḍfaṛen</string>
|
||||
<string name="hint_search_people_list">Nadi ɣef medden ar at ḍfereḍ</string>
|
||||
<string name="hint_search_people_list">Nadi ɣef medden i teṭafareḍ</string>
|
||||
<string name="description_visiblity_private">Imeḍfaṛen</string>
|
||||
<string name="action_links">Iseɣwan</string>
|
||||
<string name="action_mentions">Tibdarin</string>
|
||||
|
@ -263,8 +263,4 @@
|
|||
<string name="action_block">Cekkel</string>
|
||||
<string name="action_unblock">Kkes tacekkalt</string>
|
||||
<string name="confirmation_unblocked">Tettwakkes tacekkalt ɣef umiḍan-nni</string>
|
||||
<plurals name="poll_info_people">
|
||||
<item quantity="one">%s n wemdan</item>
|
||||
<item quantity="other">%s n yemdanen</item>
|
||||
</plurals>
|
||||
</resources>
|
|
@ -114,7 +114,7 @@
|
|||
<string name="action_mentions">멘션</string>
|
||||
<string name="action_hashtags">해시태그</string>
|
||||
<string name="action_open_reblogger">부스트한 유저의 프로필로 이동</string>
|
||||
<string name="action_open_reblogged_by">이 유저의 부스트 보이기</string>
|
||||
<string name="action_open_reblogged_by">부스트 보이기</string>
|
||||
<string name="action_open_faved_by">즐겨찾기한 유저 보이기</string>
|
||||
<string name="title_hashtags_dialog">해시태그</string>
|
||||
<string name="title_mentions_dialog">멘션</string>
|
||||
|
@ -132,7 +132,7 @@
|
|||
<string name="confirmation_unblocked">차단이 해제됨</string>
|
||||
<string name="confirmation_unmuted">뮤트가 해제됨</string>
|
||||
<string name="confirmation_domain_unmuted">%s 숨김 해제됨</string>
|
||||
<string name="status_sent">신고를 보냈습니다!</string>
|
||||
<string name="status_sent">보냈습니다!</string>
|
||||
<string name="status_sent_long">답장을 보냈습니다.</string>
|
||||
<string name="hint_domain">인스턴스 주소</string>
|
||||
<string name="hint_compose">지금 무엇을 하고 있나요\?</string>
|
||||
|
@ -240,7 +240,7 @@
|
|||
<string name="notification_mention_format">%s님이 당신을 멘션했습니다</string>
|
||||
<string name="notification_summary_large">%1$s님, %2$s님, %3$s님 외 %4$d명</string>
|
||||
<string name="notification_summary_medium">%1$s님, %2$s님, %3$s님</string>
|
||||
<string name="notification_summary_small">%1$s님, %2$s님</string>
|
||||
<string name="notification_summary_small">%1$s, %2$s</string>
|
||||
<string name="notification_title_summary">%d개의 새로운 알림이 있습니다</string>
|
||||
<string name="description_account_locked">계정 잠김</string>
|
||||
<string name="about_title_activity">이 앱에 관하여</string>
|
||||
|
@ -371,7 +371,7 @@
|
|||
<string name="description_visiblity_unlisted">타임라인에 비표시</string>
|
||||
<string name="description_visiblity_private">비공개</string>
|
||||
<string name="description_visiblity_direct">다이렉트</string>
|
||||
<string name="description_poll">투표 선택지: %1$s, %2$s, %3$s, %4$s, %5$s</string>
|
||||
<string name="description_poll">투표: %1$s, %2$s, %3$s, %4$s; %5$s</string>
|
||||
<string name="hint_list_name">리스트 이름</string>
|
||||
<string name="edit_hashtag_hint">#를 제외한 해시태그</string>
|
||||
<string name="notifications_clear">알림 지우기</string>
|
||||
|
|
|
@ -58,5 +58,4 @@
|
|||
<string name="action_retry">വീണ്ടും ശ്രമിക്കുക</string>
|
||||
<string name="action_view_follow_requests">പിന്തുടരുവാനുള്ള അഭ്യര്ത്ഥനകള്</string>
|
||||
<string name="title_domain_mutes">മറയ്ക്കപ്പെട്ട ഡൊമൈനുകൾ</string>
|
||||
<string name="description_visiblity_private">പിന്തുടരുന്നവർ</string>
|
||||
</resources>
|
|
@ -53,7 +53,7 @@
|
|||
<string name="notification_favourite_format">%s markeerde jouw toot als favoriet</string>
|
||||
<string name="notification_follow_format">%s volgt jou</string>
|
||||
<string name="report_username_format">Rapporteer @%s</string>
|
||||
<string name="report_comment_hint">Extra opmerkingen\?</string>
|
||||
<string name="report_comment_hint">Extra opmerkingen</string>
|
||||
<string name="action_quick_reply">Snelle reactie</string>
|
||||
<string name="action_reply">Reageren</string>
|
||||
<string name="action_reblog">Boosten</string>
|
||||
|
@ -120,8 +120,8 @@
|
|||
<string name="action_copy_link">Link kopiëren</string>
|
||||
<string name="action_open_as">Als %s openen</string>
|
||||
<string name="action_share_as">Delen als …</string>
|
||||
<string name="send_status_link_to">Link van de toot delen met…</string>
|
||||
<string name="send_status_content_to">Inhoud van de toot delen met…</string>
|
||||
<string name="send_status_link_to">Link van de toot delen</string>
|
||||
<string name="send_status_content_to">Inhoud van de toot delen</string>
|
||||
<string name="send_media_to">Media delen met …</string>
|
||||
<string name="confirmation_reported">Verzonden!</string>
|
||||
<string name="confirmation_unblocked">Gebruiker is gedeblokkeerd</string>
|
||||
|
@ -133,7 +133,7 @@
|
|||
<string name="hint_content_warning">Waarschuwingstekst</string>
|
||||
<string name="hint_display_name">Weergavenaam</string>
|
||||
<string name="hint_note">Bio</string>
|
||||
<string name="hint_search">Zoeken…</string>
|
||||
<string name="hint_search">Zoeken</string>
|
||||
<string name="search_no_results">Geen resultaten</string>
|
||||
<string name="label_quick_reply">Reageren…</string>
|
||||
<string name="label_avatar">Avatar</string>
|
||||
|
@ -142,9 +142,9 @@
|
|||
<string name="login_connection">Aan het verbinden</string>
|
||||
<string name="dialog_whats_an_instance">Het adres of domein van elke Mastodonserver kan hier worden ingevoerd, zoals mastodon.social, mastodon.nl, octodon.social en <a href="https://instances.social">nog veel meer!</a>
|
||||
\n
|
||||
\nWanneer je nog geen account hebt, kun je de naam van de Mastodonserver waar jij je graag wil registeren invoeren, waarna je daar een account kunt aanmaken.
|
||||
\n Wanneer je nog geen account hebt, kun je de naam van de Mastodonserver waar jij je graag wil registeren invoeren, waarna je daar een account kunt aanmaken.
|
||||
\n
|
||||
\nEen Mastodonserver (Engels: instance) is een computerserver waar jouw account zich bevindt (vergelijk het met een e-mailserver). Je kan eenvoudig mensen van andere servers volgen en met ze communiceren, alsof jullie met elkaar op dezelfde website zitten.
|
||||
\n Een Mastodonserver (Engels: instance) is een computerserver waar jouw account zich bevindt (vergelijk het met een e-mailserver). Je kan eenvoudig mensen van andere servers volgen en met ze communiceren, alsof jullie met elkaar op dezelfde website zitten.
|
||||
\n
|
||||
\n Meer informatie kun je vinden op <a href="https://joinmastodon.org">joinmastodon.org</a>.</string>
|
||||
<string name="dialog_title_finishing_media_upload">Uploaden media bijna voltooid</string>
|
||||
|
@ -368,8 +368,8 @@
|
|||
<string name="notification_clear_text">Weet je zeker dat je alle meldingen permanent wilt verwijderen\?</string>
|
||||
<string name="poll_info_format"> <!-- 15 votes • 1 hour left --> %1$s • %2$s</string>
|
||||
<plurals name="poll_info_votes">
|
||||
<item quantity="one">%s stem</item>
|
||||
<item quantity="other">%s stemmen</item>
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<string name="poll_info_time_relative">%s over</string>
|
||||
<string name="poll_info_time_absolute">eindigt op %s</string>
|
||||
|
@ -391,16 +391,16 @@
|
|||
<string name="description_poll">Poll met keuzes: %1$s, %2$s, %3$s, %4$s; %5$s</string>
|
||||
<string name="compose_preview_image_description">Acties voor afbeelding %s</string>
|
||||
<plurals name="poll_timespan_days">
|
||||
<item quantity="one">%d dag</item>
|
||||
<item quantity="other">%d dagen</item>
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<plurals name="poll_timespan_hours">
|
||||
<item quantity="one">%d uur</item>
|
||||
<item quantity="other">%d uur</item>
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<plurals name="poll_timespan_minutes">
|
||||
<item quantity="one">%d minuut</item>
|
||||
<item quantity="other">%d minuten</item>
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<plurals name="poll_timespan_seconds">
|
||||
<item quantity="one">"%d seconde"</item>
|
||||
|
|
|
@ -340,8 +340,8 @@
|
|||
<string name="dialog_redraft_toot_warning">Vil du slette dette tottet og skrive det på nytt\?</string>
|
||||
<string name="poll_info_format"> <!-- 15 votes • 1 hour left --> %1$s • %2$s</string>
|
||||
<plurals name="poll_info_votes">
|
||||
<item quantity="one">%s stemme</item>
|
||||
<item quantity="other">%s stemmer</item>
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<string name="poll_info_time_relative">%s igjen</string>
|
||||
<string name="poll_info_time_absolute">avsluttes %s</string>
|
||||
|
@ -452,6 +452,5 @@
|
|||
<string name="dialog_block_warning">Blokkere @%s\?</string>
|
||||
<string name="action_unmute_conversation">Fjern demping av samtale</string>
|
||||
<string name="action_mute_conversation">Demp samtale</string>
|
||||
<string name="hashtags">Stikkord</string>
|
||||
<string name="add_hashtag_title">Legg til stikkord</string>
|
||||
<string name="notification_follow_request_format">% ba om å få følge deg</string>
|
||||
</resources>
|
|
@ -164,7 +164,7 @@
|
|||
<string name="pref_title_http_proxy_port">Pòrt del servidor proxy HTTP</string>
|
||||
<string name="pref_default_post_privacy">Privacitat predeterminada dels tuts</string>
|
||||
<string name="pref_publishing">Publicacion</string>
|
||||
<string name="post_privacy_public">Public</string>
|
||||
<string name="post_privacy_public">Publica</string>
|
||||
<string name="post_privacy_unlisted">Pas listada</string>
|
||||
<string name="post_privacy_followers_only">Seguidors solament</string>
|
||||
<string name="pref_status_text_size">Talha de text de l\'estatut</string>
|
||||
|
@ -332,8 +332,8 @@
|
|||
<item quantity="other"><b>%1$s</b> Favorits</item>
|
||||
</plurals>
|
||||
<plurals name="reblogs">
|
||||
<item quantity="one"/>
|
||||
<item quantity="other"/>
|
||||
<item quantity="one"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<string name="title_reblogged_by">Partejat per</string>
|
||||
<string name="title_favourited_by">Aimat per</string>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="error_generic">Wystąpił błąd.</string>
|
||||
<string name="error_empty">To pole nie może być puste.</string>
|
||||
<string name="error_empty">To nie może pozostać puste.</string>
|
||||
<string name="error_invalid_domain">Wprowadzono nieprawidłową domenę</string>
|
||||
<string name="error_failed_app_registration">Nie udało się uwierzytelnić z tą instancją.</string>
|
||||
<string name="error_no_web_browser_found">Nie znaleziono przeglądarki internetowej.</string>
|
||||
|
@ -293,7 +293,7 @@
|
|||
<string name="action_mute_domain">Wycisz %s</string>
|
||||
<string name="action_add_tab">Dodaj zakładkę</string>
|
||||
<string name="action_open_reblogger">Otwórz konto osoby podbijającej</string>
|
||||
<string name="action_open_reblogged_by">Pokaż podbicia</string>
|
||||
<string name="action_open_reblogged_by">Pokazuj podbicia</string>
|
||||
<string name="action_open_media_n">Otwórz media #%d</string>
|
||||
<string name="download_media">Pobierz media</string>
|
||||
<string name="downloading_media">Pobieranie mediów</string>
|
||||
|
@ -368,7 +368,7 @@
|
|||
<string name="description_status_reblogged">Podbity</string>
|
||||
<string name="description_status_favourited">Polubiony</string>
|
||||
<string name="description_visiblity_public">Publiczny</string>
|
||||
<string name="description_visiblity_unlisted">Niewidoczne</string>
|
||||
<string name="description_visiblity_unlisted">Niewidoczny</string>
|
||||
<string name="description_visiblity_private">Śledzący</string>
|
||||
<string name="description_visiblity_direct">Bezpośrednio</string>
|
||||
<string name="description_poll">Głosowanie z opcjami: %1$s, %2$s, %3$s, %4$s; %5$s</string>
|
||||
|
@ -457,10 +457,4 @@
|
|||
<string name="no_scheduled_status">Nie masz żadnych zaplanowanych wpisów.</string>
|
||||
<string name="warning_scheduling_interval">Mastodon umożliwia wysłanie minimalnie 5 minut od zaplanowania</string>
|
||||
<string name="notification_follow_request_name">Prośby o możliwość śledzenia</string>
|
||||
<string name="pref_title_confirm_reblogs">Pytaj o potwierdzenie przed podbiciem</string>
|
||||
<string name="add_hashtag_title">Dodaj hashtag</string>
|
||||
<string name="dialog_mute_warning">Wyciszyć @%s\?</string>
|
||||
<string name="dialog_block_warning">Zablokować @%s\?</string>
|
||||
<string name="action_unmute_conversation">Cofnij wyciszenie rozmowy</string>
|
||||
<string name="action_mute_conversation">Wycisz rozmowę</string>
|
||||
</resources>
|
|
@ -32,25 +32,25 @@
|
|||
<string name="title_favourites">Favoritos</string>
|
||||
<string name="title_mutes">Usuários silenciados</string>
|
||||
<string name="title_blocks">Usuários bloqueados</string>
|
||||
<string name="title_follow_requests">Seguidores pendentes</string>
|
||||
<string name="title_follow_requests">Solicitações de seguidor</string>
|
||||
<string name="title_edit_profile">Editar seu perfil</string>
|
||||
<string name="title_saved_toot">Rascunhos</string>
|
||||
<string name="title_licenses">Licenças</string>
|
||||
<string name="status_boosted_format">%s deu boost</string>
|
||||
<string name="status_sensitive_media_title">Mídia sensível</string>
|
||||
<string name="status_boosted_format">%s compartilhou</string>
|
||||
<string name="status_sensitive_media_title">Conteúdo sensível</string>
|
||||
<string name="status_media_hidden_title">Mídia oculta</string>
|
||||
<string name="status_sensitive_media_directions">Toque para ver</string>
|
||||
<string name="status_sensitive_media_directions">Clique para exibir</string>
|
||||
<string name="status_content_warning_show_more">Mostrar mais</string>
|
||||
<string name="status_content_warning_show_less">Mostrar menos</string>
|
||||
<string name="footer_empty">Nada aqui. Arraste para atualizar!</string>
|
||||
<string name="notification_reblog_format">%s compartilhou o seu toot</string>
|
||||
<string name="notification_favourite_format">%s favoritou seu toot</string>
|
||||
<string name="notification_follow_format">%s te seguiu</string>
|
||||
<string name="notification_favourite_format">%s curtiu o seu toot</string>
|
||||
<string name="notification_follow_format">%s seguiu você</string>
|
||||
<string name="report_username_format">Denunciar @%s</string>
|
||||
<string name="report_comment_hint">Comentários adicionais?</string>
|
||||
<string name="action_quick_reply">Resposta rápida</string>
|
||||
<string name="action_reply">Responder</string>
|
||||
<string name="action_reblog">Boost</string>
|
||||
<string name="action_reblog">Compartilhar</string>
|
||||
<string name="action_unreblog">Desfazer boost</string>
|
||||
<string name="action_favourite">Favoritar</string>
|
||||
<string name="action_unfavourite">Desfavoritar</string>
|
||||
|
@ -76,7 +76,7 @@
|
|||
<string name="action_view_favourites">Favoritos</string>
|
||||
<string name="action_view_mutes">Usuários silenciados</string>
|
||||
<string name="action_view_blocks">Usuários bloqueados</string>
|
||||
<string name="action_view_follow_requests">Seguidores pendentes</string>
|
||||
<string name="action_view_follow_requests">Solicitações de seguidor</string>
|
||||
<string name="action_view_media">Mídia</string>
|
||||
<string name="action_open_in_web">Abrir no navegador</string>
|
||||
<string name="action_add_media">Adicionar mídia</string>
|
||||
|
@ -170,7 +170,7 @@
|
|||
<string name="pref_title_hide_follow_button">Esconder compositor ao rolar a página</string>
|
||||
<string name="pref_title_status_filter">Filtro da linha do tempo</string>
|
||||
<string name="pref_title_status_tabs">Abas</string>
|
||||
<string name="pref_title_show_boosts">Mostrar boosts</string>
|
||||
<string name="pref_title_show_boosts">Mostrar compartilhamentos</string>
|
||||
<string name="pref_title_show_replies">Mostrar respostas</string>
|
||||
<string name="pref_title_show_media_preview">Mostrar prévias de mídia</string>
|
||||
<string name="pref_title_proxy_settings">Proxy</string>
|
||||
|
@ -178,7 +178,7 @@
|
|||
<string name="pref_title_http_proxy_enable">Ativar proxy HTTP</string>
|
||||
<string name="pref_title_http_proxy_server">Servidor do proxy HTTP</string>
|
||||
<string name="pref_title_http_proxy_port">Porta do proxy HTTP</string>
|
||||
<string name="pref_default_post_privacy">Privacidade padrão dos toots</string>
|
||||
<string name="pref_default_post_privacy">Privacidade padrão dos posts</string>
|
||||
<string name="pref_default_media_sensitivity">Sempre marcar mídia como sensível</string>
|
||||
<string name="pref_publishing">Publicação</string>
|
||||
<string name="pref_failed_to_sync">Falha ao sincronizar configurações</string>
|
||||
|
@ -190,15 +190,15 @@
|
|||
<string name="status_text_size_medium">Médio</string>
|
||||
<string name="status_text_size_large">Grande</string>
|
||||
<string name="status_text_size_largest">Maior</string>
|
||||
<string name="notification_mention_name">Menções</string>
|
||||
<string name="notification_mention_descriptions">Notificar sobre novas menções</string>
|
||||
<string name="notification_follow_name">Seguidores</string>
|
||||
<string name="notification_follow_description">Notificar sobre novos seguidores</string>
|
||||
<string name="notification_mention_name">Novas Menções</string>
|
||||
<string name="notification_mention_descriptions">Notificações sobre novas menções</string>
|
||||
<string name="notification_follow_name">Novos Seguidores</string>
|
||||
<string name="notification_follow_description">Notificações sobre novos seguidores</string>
|
||||
<string name="notification_boost_name">Boosts</string>
|
||||
<string name="notification_boost_description">Notificar quando derem boost nos seus toots</string>
|
||||
<string name="notification_favourite_name">Favoritos</string>
|
||||
<string name="notification_favourite_description">Notificar quando favoritarem seus toots</string>
|
||||
<string name="notification_mention_format">%s te mencionou</string>
|
||||
<string name="notification_mention_format">%s mencionou você</string>
|
||||
<string name="notification_summary_large">%1$s, %2$s, %3$s e %4$d outros</string>
|
||||
<string name="notification_summary_medium">%1$s, %2$s, e %3$s</string>
|
||||
<string name="notification_summary_small">%1$s e %2$s</string>
|
||||
|
@ -237,7 +237,7 @@
|
|||
<string name="abbreviated_minutes_ago">%dm</string>
|
||||
<string name="abbreviated_seconds_ago">%ds</string>
|
||||
<string name="follows_you">Segue você</string>
|
||||
<string name="pref_title_alway_show_sensitive_media">Sempre mostrar mídia sensível</string>
|
||||
<string name="pref_title_alway_show_sensitive_media">Sempre mostrar conteúdo sensível</string>
|
||||
<string name="title_media">Mídia</string>
|
||||
<string name="replying_to">Respondendo a @%s</string>
|
||||
<string name="load_more_placeholder_text">carregar mais</string>
|
||||
|
@ -330,7 +330,7 @@
|
|||
<string name="action_add_to_list">Adicionar conta à lista</string>
|
||||
<string name="action_remove_from_list">Remover conta da lista</string>
|
||||
<string name="hint_describe_for_visually_impaired">Descrever para deficientes visuais
|
||||
\n(até %d caracteres)</string>
|
||||
\n(limite de %d caracteres)</string>
|
||||
<string name="license_cc_by_4">CC-BY 4.0</string>
|
||||
<string name="license_cc_by_sa_4">CC-BY-SA 4.0</string>
|
||||
<string name="label_remote_account">As informações abaixo podem refletir incompletamente o perfil do usuário. Toque aqui para abrir o perfil completo no navegador.</string>
|
||||
|
@ -403,7 +403,7 @@
|
|||
<string name="report_remote_instance">Encaminhar para %s</string>
|
||||
<string name="failed_report">Falha na denúncia</string>
|
||||
<string name="failed_fetch_statuses">Falha ao carregar toots</string>
|
||||
<string name="report_description_1">A denúncia será enviada aos moderadores da instância. Você pode explicar por que você denunciou a conta:</string>
|
||||
<string name="report_description_1">A denúncia será enviada para o seu administrador da instância. Você pode explicar por que você denunciou a conta:</string>
|
||||
<string name="report_description_remote_instance">A conta está em outra instância. Enviar uma cópia anônima da denúncia para lá\?</string>
|
||||
<string name="title_domain_mutes">Instâncias bloqueadas</string>
|
||||
<string name="action_view_domain_mutes">Instâncias bloqueadas</string>
|
||||
|
@ -430,14 +430,14 @@
|
|||
<string name="poll_allow_multiple_choices">Múltiplas opções</string>
|
||||
<string name="poll_new_choice_hint">Opção %d</string>
|
||||
<string name="edit_poll">Editar</string>
|
||||
<string name="title_scheduled_toot">Agendados</string>
|
||||
<string name="title_scheduled_toot">Toots agendados</string>
|
||||
<string name="action_edit">Editar</string>
|
||||
<string name="action_access_scheduled_toot">Agendados</string>
|
||||
<string name="action_access_scheduled_toot">Toots agendados</string>
|
||||
<string name="action_schedule_toot">Agendar toot</string>
|
||||
<string name="action_reset_schedule">Cancelar</string>
|
||||
<string name="post_lookup_error_format">Erro ao pesquisar %s</string>
|
||||
<string name="title_bookmarks">Salvos</string>
|
||||
<string name="action_bookmark">Salvar</string>
|
||||
<string name="action_bookmark">Salvo</string>
|
||||
<string name="action_view_bookmarks">Salvos</string>
|
||||
<string name="about_powered_by_tusky">Desenvolvido por Tusky</string>
|
||||
<string name="description_status_bookmarked">Salvo</string>
|
||||
|
@ -447,22 +447,6 @@
|
|||
<string name="no_scheduled_status">Sem toots agendados.</string>
|
||||
<string name="error_audio_upload_size">Áudios devem ser menores que 40MB.</string>
|
||||
<string name="no_saved_status">Sem rascunhos.</string>
|
||||
<string name="warning_scheduling_interval">Mastodon possui um intervalo mínimo de 5 minutos para agendar.</string>
|
||||
<string name="notification_follow_request_name">Seguidores pendentes</string>
|
||||
<string name="notification_follow_request_format">%s quer te seguir</string>
|
||||
<string name="action_mute_conversation">Silenciar conversa</string>
|
||||
<string name="action_unmute_conversation">Desfazer silêncio</string>
|
||||
<string name="dialog_block_warning">Bloquear @%s\?</string>
|
||||
<string name="dialog_mute_warning">Silenciar @%s\?</string>
|
||||
<string name="pref_title_notification_filter_follow_requests">pedirem para me seguir</string>
|
||||
<string name="notification_follow_request_description">Notificar sobre seguidores pendentes</string>
|
||||
<plurals name="poll_info_people">
|
||||
<item quantity="one">%s pessoa</item>
|
||||
<item quantity="other">%s pessoas</item>
|
||||
</plurals>
|
||||
<string name="pref_title_enable_swipe_for_tabs">Ativar deslizar para alternar entre abas</string>
|
||||
<string name="pref_title_show_cards_in_timelines">Mostrar prévias de links nas linhas</string>
|
||||
<string name="pref_title_confirm_reblogs">Solicitar confirmação antes de dar boost</string>
|
||||
<string name="hashtags">Hashtags</string>
|
||||
<string name="add_hashtag_title">Adicionar hashtag</string>
|
||||
<string name="warning_scheduling_interval">Mastodon possui um intervalo mínimo de agendamento de 5 minutos.</string>
|
||||
<string name="notification_follow_request_name">Solicitações de seguidor</string>
|
||||
</resources>
|
|
@ -474,7 +474,7 @@
|
|||
<string name="gradient_for_media">Показывать цветные градиенты для скрытых медиа</string>
|
||||
<string name="post_lookup_error_format">Ошибка поиска поста %s</string>
|
||||
<string name="no_saved_status">У вас нет черновиков.</string>
|
||||
<string name="no_scheduled_status">У вас нет запланированных постов.</string>
|
||||
<string name="no_scheduled_status">У вас нет запланированный постов.</string>
|
||||
<string name="warning_scheduling_interval">Минимальный интервал планирования в Mastodon составляет 5 минут.</string>
|
||||
<string name="pref_title_confirm_reblogs">Показвать диалог подтверждения перед продвижением</string>
|
||||
<string name="pref_title_show_cards_in_timelines">Показывать предосмотр ссылок в лентах</string>
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
<string name="title_saved_toot">Osnutki</string>
|
||||
<string name="title_licenses">Licence</string>
|
||||
<string name="status_username_format">\@%s</string>
|
||||
<string name="status_boosted_format">% spodbudil</string>
|
||||
<string name="status_sensitive_media_title">Občutljiva vsebina</string>
|
||||
<string name="status_media_hidden_title">Medij je skrit</string>
|
||||
<string name="status_sensitive_media_directions">Kliknite za ogled</string>
|
||||
|
@ -283,7 +284,7 @@
|
|||
<string name="restart_emoji">Če želite uveljaviti te spremembe, morate znova zagnati Tusky</string>
|
||||
<string name="later">Kasneje</string>
|
||||
<string name="restart">Znova zaženi</string>
|
||||
<string name="caption_systememoji">"Privzeti komplet emotikonov vaše naprave "</string>
|
||||
<string name="caption_systememoji">Privzeti komplet emotikonov vaše naprave</string>
|
||||
<string name="caption_blobmoji">Blob emotikoni so znani od Android 4.4-7.1</string>
|
||||
<string name="caption_twemoji">Mastodonov privzeti komplet emotikonov</string>
|
||||
<string name="download_failed">Prenos ni uspel</string>
|
||||
|
@ -303,7 +304,12 @@
|
|||
<string name="label_remote_account">Spodnje informacije lahko nepopolno odražajo profil uporabnika. Pritisnite, da odprete polni profil v brskalniku.</string>
|
||||
<string name="unpin_action">Odpni</string>
|
||||
<string name="pin_action">Pripni</string>
|
||||
|
||||
<plurals name="favs">
|
||||
<item quantity="one"></item>
|
||||
<item quantity="two"></item>
|
||||
<item quantity="few"></item>
|
||||
<item quantity="other"></item>
|
||||
</plurals>
|
||||
<plurals name="reblogs">
|
||||
<item quantity="one"><b>%s</b> Spodbuda</item>
|
||||
<item quantity="two"><b>%s</b> Spodbudi</item>
|
||||
|
|
|
@ -470,6 +470,4 @@
|
|||
<string name="dialog_block_warning">Blockera @%s\?</string>
|
||||
<string name="action_unmute_conversation">Aktivera ljud på konversation</string>
|
||||
<string name="notification_follow_request_format">%s vill följa dig</string>
|
||||
<string name="add_hashtag_title">Lägg till hashtag</string>
|
||||
<string name="hashtags">Hashtaggar</string>
|
||||
</resources>
|
|
@ -123,7 +123,7 @@
|
|||
<string name="visibility_unlisted">அனைவருக்கும் காட்டாதே</string>
|
||||
<string name="visibility_private">பின்பற்றுபவர்களுக்கு மட்டும் காண்பி</string>
|
||||
<string name="visibility_direct">குறிபிடபட்டுள்ள பயனர்களுக்கு மட்டும் காண்பி</string>
|
||||
<string name="pref_title_edit_notification_settings">அறிவிப்புகள்</string>
|
||||
<string name="pref_title_edit_notification_settings">அறிவிப்புகளை திருத்த</string>
|
||||
<string name="pref_title_notifications_enabled">அறிவிப்புகள்</string>
|
||||
<string name="pref_title_notification_alerts">எச்சரிக்கைகள்</string>
|
||||
<string name="pref_title_notification_alert_sound">ஒலி மூலம் தெரிவிக்கவும்</string>
|
||||
|
@ -259,7 +259,7 @@
|
|||
<string name="unpin_action">விடுவி</string>
|
||||
<string name="pin_action">பொருத்து</string>
|
||||
<string name="action_view_account_preferences">கணக்கரின் முன்னுரிமைகள்</string>
|
||||
<string name="error_network">"பிணைய பிழை ஏற்பட்டது! உங்கள் இணைப்பைச் சரிபார்த்து மீண்டும் முயற்சிக்கவும்!"</string>
|
||||
<string name="error_network">பிணைய பிழை ஏற்பட்டது! உங்கள் இணைப்பைச் சரிபார்த்து மீண்டும் முயற்சிக்கவும்!</string>
|
||||
<string name="error_video_upload_size">காணொளி 40MB க்கும் குறைவாக இருக்க வேண்டும்.</string>
|
||||
<string name="error_sender_account_gone">டூத் அனுப்ப இயலவில்லை</string>
|
||||
<string name="title_direct_messages">நேரடி தகவல்</string>
|
||||
|
|
|
@ -1,457 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="add_poll_choice">เพิ่มตัวเลือก</string>
|
||||
<string name="poll_duration_7_days">7 วัน</string>
|
||||
<string name="poll_duration_3_days">3 วัน</string>
|
||||
<string name="poll_duration_1_day">1 วัน</string>
|
||||
<string name="poll_duration_6_hours">6 ชั่วโมง</string>
|
||||
<string name="poll_duration_1_hour">1 ชั่วโมง</string>
|
||||
<string name="poll_duration_30_min">30 นาที</string>
|
||||
<string name="poll_duration_5_min">5 นาที</string>
|
||||
<string name="create_poll_title">โพล</string>
|
||||
<string name="pref_title_enable_swipe_for_tabs">เปิดใช้งานการเลื่อนนิ้วเพื่อสลับระหว่างแท็บ</string>
|
||||
<string name="pref_title_show_notifications_filter">แสดงตัวกรองการแจ้งเตือน</string>
|
||||
<string name="failed_search">ค้นหาล้มเหลว</string>
|
||||
<string name="title_accounts">บัญชี</string>
|
||||
<string name="report_description_remote_instance">บัญชีนี้มาจากเซิร์ฟเวอร์อื่น ส่งสำเนารายงานที่ไม่ระบุชื่อไปที่นั่นด้วยหรือไม่\?</string>
|
||||
<string name="report_description_1">รายงานจะถูกส่งไปยังผู้ดูแลเซิร์ฟเวอร์ของคุณ สามารถให้คำอธิบายว่าทำไมจึงรายงานบัญชีนี้ด้านล่าง:</string>
|
||||
<string name="failed_fetch_statuses">ดึงข้อมูลสถานะล้มเหลว</string>
|
||||
<string name="failed_report">รายงานล้มเหลว</string>
|
||||
<string name="report_remote_instance">ส่งต่อไปยัง %s</string>
|
||||
<string name="hint_additional_info">ความคิดเห็นเพิ่มเติม</string>
|
||||
<string name="report_sent_success">รายงาน @%s เรียบร้อยแล้ว</string>
|
||||
<string name="button_done">ทำ</string>
|
||||
<string name="button_back">ย้อนกลับ</string>
|
||||
<string name="button_continue">ต่อไป</string>
|
||||
<plurals name="poll_timespan_seconds">
|
||||
<item quantity="other">%d วินาที</item>
|
||||
</plurals>
|
||||
<plurals name="poll_timespan_minutes">
|
||||
<item quantity="other">%d นาที</item>
|
||||
</plurals>
|
||||
<plurals name="poll_timespan_hours">
|
||||
<item quantity="other">%d ชั่วโมง</item>
|
||||
</plurals>
|
||||
<plurals name="poll_timespan_days">
|
||||
<item quantity="other">%d วัน</item>
|
||||
</plurals>
|
||||
<string name="poll_ended_created">โพลที่คุณสร้างสิ้นสุดลงแล้ว</string>
|
||||
<string name="poll_ended_voted">โพลที่คุณโหวตสิ้นสุดลงแล้ว</string>
|
||||
<string name="poll_vote">โหวต</string>
|
||||
<string name="poll_info_closed">สิ้นสุดแล้ว</string>
|
||||
<string name="poll_info_time_absolute">จบที่ %s</string>
|
||||
<string name="poll_info_time_relative">เหลืออีก %s</string>
|
||||
<plurals name="poll_info_people">
|
||||
<item quantity="other">%s คน</item>
|
||||
</plurals>
|
||||
<plurals name="poll_info_votes">
|
||||
<item quantity="other">%s โหวต</item>
|
||||
</plurals>
|
||||
<string name="poll_info_format">" <!-- 15 votes • 1 hour left --> %1$s • %2$s"<!-- 15 votes • 1 hour left -->
|
||||
%1$s • %2$s</string>
|
||||
<string name="compose_preview_image_description">การกระทำสำหรับภาพ %s</string>
|
||||
<string name="notification_clear_text">ต้องการลบการแจ้งเตือนทั้งหมดอย่างสมบูรณ์\?</string>
|
||||
<string name="compose_shortcut_short_label">เขียน</string>
|
||||
<string name="compose_shortcut_long_label">เขียน Toot</string>
|
||||
<string name="filter_apply">ใช้งาน</string>
|
||||
<string name="notifications_apply_filter">คัดกรอง</string>
|
||||
<string name="notifications_clear">ล้างการแจ้งเตือน</string>
|
||||
<string name="list">รายการ</string>
|
||||
<string name="select_list_title">เลือกรายการ</string>
|
||||
<string name="hashtags">แฮชแท็ก</string>
|
||||
<string name="edit_hashtag_hint">แฮชแท็กโดยไม่มี #</string>
|
||||
<string name="add_hashtag_title">เพิ่มแฮชแท็ก</string>
|
||||
<string name="hint_list_name">ชื่อรายการ</string>
|
||||
<string name="description_poll">โพลกับตัวเลือก: %1$s, %2$s, %3$s, %4$s; %5$s</string>
|
||||
<string name="description_visiblity_direct">ไดเร็กต์</string>
|
||||
<string name="description_visiblity_private">ผู้ติดตาม</string>
|
||||
<string name="description_visiblity_unlisted">ไม่อยู่ในรายการ</string>
|
||||
<string name="description_visiblity_public">สาธารณะ</string>
|
||||
<string name="description_status_bookmarked">คั่นหน้า</string>
|
||||
<string name="description_status_favourited">ชื่นชอบ</string>
|
||||
<string name="description_status_reblogged">ได้ถูกเขียนใหม่</string>
|
||||
<string name="description_status_media_no_description_placeholder">ไม่มีคำอธิบาย</string>
|
||||
<string name="description_status_cw">เตือนเนื้อหา : %s</string>
|
||||
<string name="description_status_media">สื่อ: %s</string>
|
||||
<string name="max_tab_number_reached">ถึงจำนวนแท็บสูงสุดคือ %1$d แล้ว</string>
|
||||
<string name="conversation_more_recipients">%1$s, %2$s และอีก %3$d</string>
|
||||
<string name="conversation_2_recipients">%1$s และ %2$s</string>
|
||||
<string name="conversation_1_recipients">%1$s</string>
|
||||
<string name="title_favourited_by">ชื่นชอบโดย</string>
|
||||
<string name="title_reblogged_by">บูสต์โดย</string>
|
||||
<plurals name="reblogs">
|
||||
<item quantity="other"><b>%1$s</b> บูสต์</item>
|
||||
</plurals>
|
||||
<plurals name="favs">
|
||||
<item quantity="other"><b>%1$s</b> ชื่นชอบ</item>
|
||||
</plurals>
|
||||
<string name="pin_action">ปักหมุด</string>
|
||||
<string name="unpin_action">เลิกปักหมุด</string>
|
||||
<string name="label_remote_account">ข้อมูลต่อไปนี้อาจไม่ถูกต้อง แตะเพื่อเปิดโปรไฟล์ในเบราว์เซอร์</string>
|
||||
<string name="pref_title_absolute_time">แสดงเวลาแบบเที่ยงตรง</string>
|
||||
<string name="profile_metadata_content_label">เนื้อหา</string>
|
||||
<string name="profile_metadata_label_label">ป้าย</string>
|
||||
<string name="profile_metadata_add">เพิ่มข้อมูล</string>
|
||||
<string name="profile_metadata_label">ข้อมูลอภิพันธุ์</string>
|
||||
<string name="license_cc_by_sa_4">CC-BY-SA 4.0</string>
|
||||
<string name="license_cc_by_4">CC-BY 4.0</string>
|
||||
<string name="license_apache_2">ภายใต้สัญญาอนุญาต Apache License (คัดลอกด้านล่าง)</string>
|
||||
<string name="license_description">Tusky มีโค้ดและสินทรัพย์จากโครงการโอเพนซอร์สต่อไปนี้:</string>
|
||||
<string name="unreblog_private">ยกเลิกบูสต์</string>
|
||||
<string name="reblog_private">บูสต์โพสต์ต้นฉบับ</string>
|
||||
<string name="account_moved_description">%1$s ได้ย้ายไปที่ :</string>
|
||||
<string name="profile_badge_bot_text">บอต</string>
|
||||
<string name="download_failed">ดาวน์โหลดล้มเหลว</string>
|
||||
<string name="caption_notoemoji">ชุดเอโมจิปัจจุบันจากกูเกิล</string>
|
||||
<string name="caption_twemoji">ชุดเอโมจิจาก Mastodon</string>
|
||||
<string name="caption_blobmoji">ที่รู้จักจาก Android 4.4 ถึง 7.1 ชุดเอโมจิ Blob</string>
|
||||
<string name="caption_systememoji">ชุดเริ่มต้นในอุปกรณ์คุณ</string>
|
||||
<string name="restart">เริ่มใหม่</string>
|
||||
<string name="later">ภายหลัง</string>
|
||||
<string name="restart_emoji">จำเป็นต้องเริ่ม Tusky ใหม่ เพื่อใช้การเปลี่ยนแปลงเหล่านี้</string>
|
||||
<string name="restart_required">จำเป็นต้องเริ่มแอปใหม่</string>
|
||||
<string name="action_open_toot">เปิด Toot</string>
|
||||
<string name="expand_collapse_all_statuses">ขยาย/ย่อทั้งหมด</string>
|
||||
<string name="performing_lookup_title">กำลังค้นหา…</string>
|
||||
<string name="download_fonts">ต้องดาวน์โหลดชุดเอโมจิเหล่านี้ก่อน</string>
|
||||
<string name="system_default">ค่าปริยายของระบบ</string>
|
||||
<string name="emoji_style">รูปแบบเอโมจิ</string>
|
||||
<string name="copy_to_clipboard_success">คัดลอกไปยังคลิบบอร์ดแล้ว</string>
|
||||
<string name="error_no_custom_emojis">Instance %s ไม่มีเอโมจิแบบกำหนดเอง</string>
|
||||
<string name="action_compose_shortcut">เขียน</string>
|
||||
<string name="send_toot_notification_saved_content">สำเนา Toot บันทึกเป็นฉบับร่างแล้ว</string>
|
||||
<string name="send_toot_notification_cancel_title">การส่งถูกยกเลิก</string>
|
||||
<string name="send_toot_notification_channel_name">ส่ง Toot</string>
|
||||
<string name="send_toot_notification_error_title">การส่ง Toot เกิดข้อผิดผลาด</string>
|
||||
<string name="send_toot_notification_title">กำลังส่ง Toot…</string>
|
||||
<string name="compose_save_draft">บันทึกฉบับร่าง\?</string>
|
||||
<string name="lock_account_label_description">ต้องอนุมัติผู้ติดตามด้วยตัวเอง</string>
|
||||
<string name="lock_account_label">ล็อกบัญชี</string>
|
||||
<string name="action_remove">ลบ</string>
|
||||
<string name="error_failed_set_caption">ตั้งคำอธิบายล้มเหลว</string>
|
||||
<string name="action_set_caption">ตั้งคำอธิบาย</string>
|
||||
<string name="hint_describe_for_visually_impaired">อธิบายเพื่อผู้บกพร่องทางสายตา
|
||||
\n(จำกัด %d ตัวอักขระ)</string>
|
||||
<string name="compose_active_account_description">โพสต์ด้วยบัญชี %1$s</string>
|
||||
<string name="action_remove_from_list">ลบบัญชีออกจากรายการ</string>
|
||||
<string name="action_add_to_list">เพิ่มบัญชีไปใส่รายการ</string>
|
||||
<string name="hint_search_people_list">ค้นหาผู้ติดตาม</string>
|
||||
<string name="action_edit_list">แก้ไขรายการ</string>
|
||||
<string name="action_delete_list">ลบรายการ</string>
|
||||
<string name="action_rename_list">เปลี่ยนชื่อรายการ</string>
|
||||
<string name="action_create_list">สร้างรายการ</string>
|
||||
<string name="error_delete_list">ไม่สามารถลบรายการได้</string>
|
||||
<string name="error_rename_list">ไม่สามารถเปลี่ยนชื่อรายการได้</string>
|
||||
<string name="error_create_list">ไม่สามารถสร้างรายการได้</string>
|
||||
<string name="title_list_timeline">ไทม์ไลน์ในรายการ</string>
|
||||
<string name="add_account_description">เพิ่มบัญชี Mastodon ใหม่</string>
|
||||
<string name="add_account_name">เพิ่มบัญชี</string>
|
||||
<string name="filter_add_description">วลีที่ต้องการกรอง</string>
|
||||
<string name="filter_dialog_whole_word_description">ถ้าคำหลักหรือวลีเป็นอักษรผสมตัวเลข จะใช้ได้ผลเมื่อตรงทั้งคำเท่านั้น</string>
|
||||
<string name="filter_dialog_whole_word">ทั้งคำ</string>
|
||||
<string name="filter_dialog_update_button">อัปเดต</string>
|
||||
<string name="filter_dialog_remove_button">ลบ</string>
|
||||
<string name="filter_edit_dialog_title">แก้ไขตัวคัดกรอง</string>
|
||||
<string name="filter_addition_dialog_title">เพิ่มตัวคัดกรอง</string>
|
||||
<string name="pref_title_thread_filter_keywords">การสนทนา</string>
|
||||
<string name="pref_title_public_filter_keywords">ไทม์ไลน์สาธารณะ</string>
|
||||
<string name="load_more_placeholder_text">โหลดเพิ่ม</string>
|
||||
<string name="replying_to">ตอบกลับไป @%s</string>
|
||||
<string name="title_media">สื่อ</string>
|
||||
<string name="pref_title_alway_open_spoiler">ขยาย Toot ที่มีเครื่องหมายเนื้อหาอ่อนไหวเสมอ</string>
|
||||
<string name="pref_title_alway_show_sensitive_media">แสดงเนื้อหาอ่อนไหวเสมอ</string>
|
||||
<string name="follows_you">กำลังติดตามคุณ</string>
|
||||
<string name="abbreviated_seconds_ago">%d วินาทีที่แล้ว</string>
|
||||
<string name="abbreviated_minutes_ago">%d นาทีที่แล้ว</string>
|
||||
<string name="abbreviated_hours_ago">%d ชั่วโมงที่แล้ว</string>
|
||||
<string name="abbreviated_days_ago">%d วันที่แล้ว</string>
|
||||
<string name="abbreviated_years_ago">%d ปีที่แล้ว</string>
|
||||
<string name="abbreviated_in_seconds">ใน %d วินาที</string>
|
||||
<string name="abbreviated_in_minutes">ใน %d นาที</string>
|
||||
<string name="abbreviated_in_hours">ใน %d ชั่วโมง</string>
|
||||
<string name="abbreviated_in_days">ใน %d วัน</string>
|
||||
<string name="abbreviated_in_years">ใน %d ปี</string>
|
||||
<string name="state_follow_requested">กำลังขอติดตาม</string>
|
||||
<string name="status_media_video">วิดีทัศน์</string>
|
||||
<string name="status_media_images">ภาพ</string>
|
||||
<string name="status_share_link">แบ่งปันลิงก์ Toot</string>
|
||||
<string name="status_share_content">แบ่งปันเนื้อหา Toot</string>
|
||||
<string name="about_tusky_account">บัญชีทางการของ Tusky</string>
|
||||
<string name="about_bug_feature_request_site">รายงานช่องโหว่ และ ขอฟีเจอร์ (ภาษาอังกฤษ):
|
||||
\nhttps://github.com/tuskyapp/Tusky/issues</string>
|
||||
<string name="about_project_site">เว็บไซต์โปรเจกต์:
|
||||
\nhttps://tusky.app</string>
|
||||
<string name="about_tusky_license">Tusky คือซอฟต์แวร์เสรีและโอเพนซอร์ส <!-- --> ภายใต้สัญญาอนุญาต GNU General Public License Version 3 <!-- -->ดูสัญญาที่ : https://www.gnu.org/licenses/gpl-3.0.ja.html</string>
|
||||
<string name="about_powered_by_tusky">ขับเคลื่อนด้วย Tusky</string>
|
||||
<string name="about_tusky_version">Tusky %s</string>
|
||||
<string name="description_account_locked">บัญชีไม่สาธารณะ</string>
|
||||
<string name="notification_title_summary">การโต้ตอบใหม่จำนวน %d</string>
|
||||
<string name="notification_summary_small">%1$s และ %2$s</string>
|
||||
<string name="notification_summary_medium">%1$s, %2$s, และ %3$s</string>
|
||||
<string name="notification_summary_large">%1$s, %2$s, %3$s และอีก %4$d คน</string>
|
||||
<string name="notification_mention_format">%s ตอบกลับคุณ</string>
|
||||
<string name="notification_poll_description">การแจ้งเตือนเมื่อโพลได้สิ้นสุดลงแล้ว</string>
|
||||
<string name="notification_poll_name">โพล</string>
|
||||
<string name="notification_favourite_description">การแจ้งเตือนเมื่อ Toot คุณถูกชื่นชอบ</string>
|
||||
<string name="notification_favourite_name">ชื่นชอบ</string>
|
||||
<string name="notification_boost_description">การแจ้งเตือนเมื่อ Toot คุณถูกบูสต์</string>
|
||||
<string name="notification_boost_name">บูสต์</string>
|
||||
<string name="notification_follow_request_description">การแจ้งเตือนคำขอติดตามใหม่</string>
|
||||
<string name="notification_follow_request_name">คำขอติดตาม</string>
|
||||
<string name="notification_follow_description">การแจ้งเตือนเกี่ยวกับผู้ติดตามใหม่</string>
|
||||
<string name="notification_follow_name">ผู้ติดตามใหม่</string>
|
||||
<string name="notification_mention_name">การกล่าวถึงใหม่</string>
|
||||
<string name="notification_mention_descriptions">การแจ้งเตือนเกี่ยวกับการกล่าวถึงใหม่</string>
|
||||
<string name="status_text_size_largest">ใหญ่มาก</string>
|
||||
<string name="status_text_size_large">ใหญ่</string>
|
||||
<string name="status_text_size_medium">กลาง</string>
|
||||
<string name="status_text_size_small">เล็ก</string>
|
||||
<string name="status_text_size_smallest">เล็กสุด</string>
|
||||
<string name="pref_status_text_size">ขนาดอักษร Toot</string>
|
||||
<string name="post_privacy_followers_only">เฉพาะผู้ติดตาม</string>
|
||||
<string name="post_privacy_unlisted">ไม่อยู่ในรายการ</string>
|
||||
<string name="post_privacy_public">สาธารณะ</string>
|
||||
<string name="pref_failed_to_sync">ซิงค์การตั้งค่าล้มเหลว</string>
|
||||
<string name="pref_publishing">กำลังเผยแพร่ (synced with server)</string>
|
||||
<string name="pref_default_media_sensitivity">ใส่เครื่องหมายว่าเป็นสื่ออ่อนไหวเสมอ</string>
|
||||
<string name="pref_default_post_privacy">ความเป็นส่วนตัวโพสต์ปริยาย</string>
|
||||
<string name="pref_title_http_proxy_port">พอร์ตพร็อกซี่ HTTP</string>
|
||||
<string name="pref_title_http_proxy_server">เซิร์ฟเวอร์พร็อกซี่ HTTP</string>
|
||||
<string name="pref_title_http_proxy_enable">เปิดใช้งานพร็อกซี่ HTTP</string>
|
||||
<string name="pref_title_http_proxy_settings">พร็อกซี่ HTTP</string>
|
||||
<string name="pref_title_proxy_settings">พร็อกซี่</string>
|
||||
<string name="pref_title_show_media_preview">ดาวน์โหลดตัวอย่างสื่อ</string>
|
||||
<string name="pref_title_show_replies">แสดงการตอบกลับ</string>
|
||||
<string name="pref_title_show_boosts">แสดงบูสต์</string>
|
||||
<string name="pref_title_status_tabs">แท็บ</string>
|
||||
<string name="pref_title_status_filter">คัดกรองไทม์ไลน์</string>
|
||||
<string name="gradient_for_media">แสดงสื่อที่ซ่อนไว้แบบไล่หลากสี</string>
|
||||
<string name="pref_title_animate_gif_avatars">อวตาร GIF เคลื่อนไหวได้</string>
|
||||
<string name="pref_title_bot_overlay">แสดงสัญลักษณ์ว่าเป็นบอต</string>
|
||||
<string name="pref_title_language">ภาษา</string>
|
||||
<string name="pref_title_hide_follow_button">ซ่อนปุ่มเขียนเมื่อกำลังเลื่อนจอ</string>
|
||||
<string name="pref_title_custom_tabs">ใช้ Chrome Custom Tabs</string>
|
||||
<string name="pref_title_browser_settings">เบราว์เซอร์</string>
|
||||
<string name="app_theme_system">ใช้ตามแบบระบบ</string>
|
||||
<string name="app_theme_auto">ปรับตามเวลา</string>
|
||||
<string name="app_theme_black">ดำ</string>
|
||||
<string name="app_theme_light">สว่าง</string>
|
||||
<string name="app_them_dark">มืด</string>
|
||||
<string name="pref_title_timeline_filters">คัดกรอง</string>
|
||||
<string name="pref_title_timelines">ไทม์ไลน์</string>
|
||||
<string name="pref_title_app_theme">ธีมแอป</string>
|
||||
<string name="pref_title_appearance_settings">ลักษณะ</string>
|
||||
<string name="pref_title_notification_filter_poll">โพลสิ้นสุดแล้ว</string>
|
||||
<string name="pref_title_notification_filter_favourites">โพสต์ถูกชื่นชอบ</string>
|
||||
<string name="pref_title_notification_filter_reblogs">โพสต์ถูกบูสต์</string>
|
||||
<string name="pref_title_notification_filter_follow_requests">คำขอติดตาม</string>
|
||||
<string name="pref_title_notification_filter_follows">ติดตาม</string>
|
||||
<string name="pref_title_notification_filter_mentions">กล่าวถึง</string>
|
||||
<string name="pref_title_notification_filters">แจ้งฉันเมื่อ</string>
|
||||
<string name="pref_title_notification_alert_sound">แจ้งด้วยเสียง</string>
|
||||
<string name="pref_title_notification_alert_vibrate">แจ้งด้วยการสั่น</string>
|
||||
<string name="pref_title_notification_alert_light">แจ้งด้วยแสง</string>
|
||||
<string name="pref_title_notification_alerts">เตือน</string>
|
||||
<string name="pref_title_notifications_enabled">การแจ้งเตือนแบบ Push</string>
|
||||
<string name="pref_title_edit_notification_settings">ตั้งค่าการแจ้งเตือน</string>
|
||||
<string name="visibility_direct">ไดเร็กต์:โพสต์ให้เฉพาะผู้ที่ถูกกล่าวถึงเห็น</string>
|
||||
<string name="visibility_private">เฉพาะผู้ติดตาม:โพสต์ให้เฉพาะผู้ติดตามเห็น</string>
|
||||
<string name="visibility_unlisted">ไม่อยู่ในรายการ:ไม่แสดงในไทม์ไลน์สาธารณะ</string>
|
||||
<string name="visibility_public">สาธารณะ:โพสต์ในไทม์ไลน์สาธารณะ</string>
|
||||
<string name="dialog_mute_warning">ปิดเสียง @%s\?</string>
|
||||
<string name="dialog_block_warning">บล็อก @%s\?</string>
|
||||
<string name="mute_domain_warning_dialog_ok">ซ่อนทั้งโดเมน</string>
|
||||
<string name="mute_domain_warning">ต้องการบล็อกทุกอย่างจาก %s \? คุณจะไม่เห็นเนื้อหาจากโดเมนนั้นในไทม์ไลน์สาธารณะหรือในการแจ้งเตือน ผู้ติดตามของคุณจากโดเมนนั้นจะถูกลบออก</string>
|
||||
<string name="dialog_redraft_toot_warning">ลบ แล้ว ร่าง Toot นี้ใหม่\?</string>
|
||||
<string name="dialog_delete_toot_warning">ลบ Toot นี้\?</string>
|
||||
<string name="dialog_unfollow_warning">เลิกติดตามผู้ใช้นี้\?</string>
|
||||
<string name="dialog_message_cancel_follow_request">ยกเลิกคำขอติดตาม\?</string>
|
||||
<string name="dialog_download_image">ดาวน์โหลด</string>
|
||||
<string name="dialog_message_uploading_media">กำลังอัปโหลด…</string>
|
||||
<string name="dialog_title_finishing_media_upload">กำลังอัปโหลดสื่อใกล้เสร็จ</string>
|
||||
<string name="dialog_whats_an_instance">"ใส่ที่อยู่หรือโดเมนของ Instance ได้ที่นี่ เช่น mastodon.social icosahedron.website social.tchncs.de และ <a href=\"https://instances.social\">อีกมากมาย!</a>
|
||||
\n
|
||||
\nถ้ายังไม่มีบัญชี สามารถใส่ชื่อ Instance ที่ต้องการจะร่วมแล้วสร้างบัญชีที่นั่น
|
||||
\n
|
||||
\nInstance คือที่ที่หนึ่งไว้โฮสต์บัญชีคุณ แต่คุณยังสามารถสื่อสาร ติดตามบุคคลบน Instance อื่นได้เหมือนอยู่บนไซต์เดียวกัน
|
||||
\n
|
||||
\nพบข้อมูลเพิ่มเติมได้ที่ <a href=\"https://joinmastodon.org\">joinmastodon.org</a> "<a href="https://instances.social">more!</a>
|
||||
\n\nIf you don\'t yet have an account, you can enter the name of the instance you\'d like to
|
||||
join and create an account there.\n\nAn instance is a single place where your account is
|
||||
hosted, but you can easily communicate with and follow folks on other instances as though
|
||||
you were on the same site.
|
||||
\n\nMore info can be found at <a href="https://joinmastodon.org">joinmastodon.org</a>.
|
||||
</string>
|
||||
<string name="label_header">ภาพหัวบน</string>
|
||||
<string name="login_connection">กำลังเชื่อมต่อ…</string>
|
||||
<string name="label_avatar">อวตาร</string>
|
||||
<string name="label_quick_reply">ตอบกลับ…</string>
|
||||
<string name="search_no_results">ไม่มีผลลัพธ์</string>
|
||||
<string name="hint_search">ค้นหา…</string>
|
||||
<string name="hint_note">ข้อมูลส่วนตัว</string>
|
||||
<string name="hint_display_name">ชื่อที่ใช้แสดง</string>
|
||||
<string name="hint_content_warning">คำเตือนเนื้อหา</string>
|
||||
<string name="hint_compose">เกิดอะไรขึ้นเอย\?</string>
|
||||
<string name="hint_domain">Instance ไหน\?</string>
|
||||
<string name="status_sent_long">ตอบกลับสำเร็จ</string>
|
||||
<string name="status_sent">ส่งแล้ว!</string>
|
||||
<string name="confirmation_domain_unmuted">เลิกซ่อน %s แล้ว</string>
|
||||
<string name="confirmation_unblocked">เลิกบล็อกผู้ใช้แล้ว</string>
|
||||
<string name="confirmation_unmuted">เลิกปิดเสียงผู้ใช้นี้แล้ว</string>
|
||||
<string name="confirmation_reported">ส่งแล้ว!</string>
|
||||
<string name="send_media_to">แบ่งปันสื่อไป…</string>
|
||||
<string name="send_status_content_to">แบ่งปัน Toot ไป…</string>
|
||||
<string name="send_status_link_to">แชร์ URL Toot ไป…</string>
|
||||
<string name="downloading_media">กำลังดาวน์โหลดสื่อ</string>
|
||||
<string name="download_media">ดาวน์โหลดสื่อ</string>
|
||||
<string name="action_share_as">แบ่งปันโดย…</string>
|
||||
<string name="action_open_as">เปิดเป็น %s</string>
|
||||
<string name="action_copy_link">คัดลอกลิงก์</string>
|
||||
<string name="download_image">กำลังดาวน์โหลด %1$s</string>
|
||||
<string name="action_open_media_n">เปิดสื่อ #%d</string>
|
||||
<string name="title_links_dialog">ลิงก์</string>
|
||||
<string name="title_mentions_dialog">โต้ตอบ</string>
|
||||
<string name="title_hashtags_dialog">แฮชแท็ก</string>
|
||||
<string name="action_open_faved_by">ดูชื่นชอบ</string>
|
||||
<string name="action_open_reblogged_by">ดูบสต์</string>
|
||||
<string name="action_open_reblogger">ดูต้นตอบูสต์</string>
|
||||
<string name="action_hashtags">แฮชแท็ก</string>
|
||||
<string name="action_mentions">โต้ตอบ</string>
|
||||
<string name="action_links">ลิงก์</string>
|
||||
<string name="action_add_tab">เพิ่มแท็บ</string>
|
||||
<string name="action_schedule_toot">Toot แบบตั้งเวลา</string>
|
||||
<string name="action_emoji_keyboard">คีย์บอร์ดเอโมจิ</string>
|
||||
<string name="action_content_warning">เตือนเนื้อหา</string>
|
||||
<string name="action_toggle_visibility">การมองเห็น Toot</string>
|
||||
<string name="action_access_scheduled_toot">Toot แบบตั้งเวลา</string>
|
||||
<string name="action_access_saved_toot">ฉบับร่าง</string>
|
||||
<string name="action_reject">ปฏิเสธ</string>
|
||||
<string name="action_accept">ยอมรับ</string>
|
||||
<string name="action_undo">ย้อนการกระทำ</string>
|
||||
<string name="action_edit_own_profile">แก้ไข</string>
|
||||
<string name="action_save">บันทึก</string>
|
||||
<string name="action_open_drawer">เปิดเมนู</string>
|
||||
<string name="action_hide_media">ซ่อนสื่อ</string>
|
||||
<string name="action_mention">กล่าวถึง</string>
|
||||
<string name="action_unmute_conversation">เลิกปิดเสียงการสนทนา</string>
|
||||
<string name="action_mute_conversation">ปิดเสียงการสนทนานี้</string>
|
||||
<string name="action_mute_domain">ปิดเสียง %s</string>
|
||||
<string name="action_unmute">เลิกปิดเสียง</string>
|
||||
<string name="action_mute">ปิดเสียง</string>
|
||||
<string name="action_share">แบ่งปัน</string>
|
||||
<string name="action_photo_take">ถ่ายภาพ</string>
|
||||
<string name="action_add_poll">เพิ่มโพล</string>
|
||||
<string name="action_add_media">เพิ่มสื่อ</string>
|
||||
<string name="action_open_in_web">เปิดในเบราว์เซอร์</string>
|
||||
<string name="action_view_media">สื่อ</string>
|
||||
<string name="action_view_follow_requests">คำขอติดตาม</string>
|
||||
<string name="action_view_domain_mutes">โดเมนที่ซ่อนไว้</string>
|
||||
<string name="action_view_blocks">ผู้ใช้ที่ถูกบล็อกไว้</string>
|
||||
<string name="action_view_mutes">ผู้ใช้ที่ปิดเสียงไว้</string>
|
||||
<string name="action_view_bookmarks">คั่นหน้า</string>
|
||||
<string name="action_view_favourites">ชื่นชอบ</string>
|
||||
<string name="action_view_profile">โปรไฟล์</string>
|
||||
<string name="action_close">ปิด</string>
|
||||
<string name="action_retry">ลองอีกครั้ง</string>
|
||||
<string name="action_send_public">TOOT!</string>
|
||||
<string name="action_send">TOOT</string>
|
||||
<string name="action_delete_and_redraft">ลบ แล้ว ร่างใหม่</string>
|
||||
<string name="action_delete">ลบ</string>
|
||||
<string name="action_edit">แก้ไข</string>
|
||||
<string name="action_report">รายงาน</string>
|
||||
<string name="action_show_reblogs">แสดงบูสต์</string>
|
||||
<string name="action_hide_reblogs">ซ่อนบูสต์</string>
|
||||
<string name="action_unblock">เลิกบล็อก</string>
|
||||
<string name="action_block">บล็อก</string>
|
||||
<string name="action_unfollow">เลิกติดตาม</string>
|
||||
<string name="action_follow">ติดตาม</string>
|
||||
<string name="action_logout_confirm">ต้องการออกจากระบบของบัญชี %1$s \?</string>
|
||||
<string name="action_compose">เขียนโพสต์ใหม่</string>
|
||||
<string name="action_more">อื่น ๆ</string>
|
||||
<string name="action_unfavourite">เลิกชื่นชอบ</string>
|
||||
<string name="action_bookmark">คั่นหน้า</string>
|
||||
<string name="action_favourite">ชื่นชอบ</string>
|
||||
<string name="action_unreblog">ลบบูสต์</string>
|
||||
<string name="action_reblog">บูสต์</string>
|
||||
<string name="action_reply">ตอบกลับ</string>
|
||||
<string name="action_quick_reply">ตอบกลับด่วน</string>
|
||||
<string name="report_comment_hint">ความคิดเห็นเพิ่มเติม\?</string>
|
||||
<string name="report_username_format">รายงาน @%s</string>
|
||||
<string name="notification_follow_request_format">%s ต้องการติดตามคุณ</string>
|
||||
<string name="notification_follow_format">%s ได้ติดตามคุณ</string>
|
||||
<string name="notification_favourite_format">%s ได้ชื่นชอบ Toot คุณ</string>
|
||||
<string name="notification_reblog_format">%s ได้บูสต์ Toot คุณ</string>
|
||||
<string name="footer_empty">ไม่อะไรเลย ลากลงเพื่อรีเฟรช!</string>
|
||||
<string name="message_empty">ไม่มีอะไร</string>
|
||||
<string name="status_content_show_less">ย่อ</string>
|
||||
<string name="status_content_show_more">ขยาย</string>
|
||||
<string name="status_content_warning_show_less">แสดงน้อยลง</string>
|
||||
<string name="status_content_warning_show_more">แสดงเพิ่มเติม</string>
|
||||
<string name="status_sensitive_media_directions">แตะเพื่อดู</string>
|
||||
<string name="status_media_hidden_title">สื่อที่ซ่อนไว้</string>
|
||||
<string name="status_sensitive_media_title">เนื้อหาอ่อนไหว</string>
|
||||
<string name="status_boosted_format">%s ได้บูสต์</string>
|
||||
<string name="status_username_format">\@%s</string>
|
||||
<string name="title_licenses">สัญญาอนุญาต</string>
|
||||
<string name="title_scheduled_toot">Toot แบบกำหนดเวลา</string>
|
||||
<string name="title_edit_profile">แก้ไขโปรไฟล์</string>
|
||||
<string name="title_follow_requests">คำขอติดตาม</string>
|
||||
<string name="title_domain_mutes">โดเมนที่ซ่อนไว้</string>
|
||||
<string name="title_blocks">ผู้ใช้ที่ถูกบล็อก</string>
|
||||
<string name="title_mutes">ผู้ใช้ที่ทำให้เป็นใบ้</string>
|
||||
<string name="title_bookmarks">คั่นหน้า</string>
|
||||
<string name="title_followers">ผู้ติดตาม</string>
|
||||
<string name="title_follows">ติดตาม</string>
|
||||
<string name="title_statuses_pinned">ปักหมุด</string>
|
||||
<string name="title_statuses_with_replies">โพสต์และตอบกลับ</string>
|
||||
<string name="title_statuses">โพสต์</string>
|
||||
<string name="title_view_thread">เธรด</string>
|
||||
<string name="title_tab_preferences">แท็บ</string>
|
||||
<string name="title_direct_messages">ข้อความแบบไดเร็กต์</string>
|
||||
<string name="title_public_federated">สหพันธ์</string>
|
||||
<string name="title_public_local">ท้องถิ่น</string>
|
||||
<string name="title_notifications">แจ้งเตือน</string>
|
||||
<string name="title_home">หน้าหลัก</string>
|
||||
<string name="error_sender_account_gone">การส่ง Toot เกิดความผิดพลาด</string>
|
||||
<string name="error_media_upload_sending">อัปโหลดล้มเหลว</string>
|
||||
<string name="error_media_upload_image_or_video">ไม่สามารถแนบรูปภาพและวิดีทัศน์ในโพสต์เดียวกันได้</string>
|
||||
<string name="error_media_download_permission">ต้องมีสิทธิ์เขียนบนสื่อ</string>
|
||||
<string name="error_media_upload_permission">ต้องมีสิทธิ์อ่านสื่อ</string>
|
||||
<string name="error_media_upload_opening">ไม่สามารถเปิดไฟล์ได้</string>
|
||||
<string name="error_media_upload_type">ไม่สามารถอัปโหลดไฟล์ประเภทนี้ได้</string>
|
||||
<string name="error_audio_upload_size">ไฟล์เสียงต้องมีขนาดน้อยกว่า 40MB</string>
|
||||
<string name="error_video_upload_size">ไฟล์วีดิทัศน์ต้องมีขนาดน้อยกว่า 40MB</string>
|
||||
<string name="error_image_upload_size">ไฟล์ต้องมีขนาดน้อยกว่า 8MB</string>
|
||||
<string name="error_compose_character_limit">ข้อความสถานะยาวเกินไป!</string>
|
||||
<string name="error_retrieving_oauth_token">ไม่สามารถรับโทเค็นการเข้าสู่ระบบ</string>
|
||||
<string name="error_authorization_denied">การขออนุญาตสิทธิถูกปฏิเสธ</string>
|
||||
<string name="error_authorization_unknown">เกิดข้อผิดพลาดในการขออนุญาตสิทธิโดยไม่ทราบสาเหตุ</string>
|
||||
<string name="error_no_web_browser_found">ไม่พบเว็บเบราว์เซอร์</string>
|
||||
<string name="error_invalid_domain">โดเมนที่ป้อนไม่ถูกต้อง</string>
|
||||
<string name="error_empty">ไม่สามารถโพสต์โดยไร้ข้อความได้</string>
|
||||
<string name="error_network">เครือข่ายมีข้อผิดพลาดเกิดขึ้น! กรุณาตรวจสอบการเชื่อมต่อและลองอีกครั้ง!</string>
|
||||
<string name="error_generic">เกิดข้อผิดพลาด</string>
|
||||
<string name="title_lists">รายการ</string>
|
||||
<string name="action_lists">รายการ</string>
|
||||
<string name="about_title_activity">เกี่ยวกับแอปนี้</string>
|
||||
<string name="action_reset_schedule">ล้างค่า</string>
|
||||
<string name="action_search">ค้นหา</string>
|
||||
<string name="action_edit_profile">แก้ไขโปรไฟล์</string>
|
||||
<string name="action_view_account_preferences">ตั้งค่าบัญชี</string>
|
||||
<string name="action_view_preferences">ตั้งค่า</string>
|
||||
<string name="action_logout">ออกจากระบบ</string>
|
||||
<string name="title_saved_toot">ฉบับร่าง</string>
|
||||
<string name="title_favourites">ชื่นชอบ</string>
|
||||
<string name="error_failed_app_registration">การยืนยันตัวตนทางอิเล็กทรอนิกส์กับ Instance นั้นล้มเหลว</string>
|
||||
<string name="link_whats_an_instance">Instance คือ\?</string>
|
||||
<string name="action_login">เข้าสู่ระบบด้วย Mastodon</string>
|
||||
<string name="poll_allow_multiple_choices">เลือกได้หลายตัวเลือก</string>
|
||||
<string name="pref_title_confirm_reblogs">แสดงข้อความยืนยันก่อนที่จะบูสต์</string>
|
||||
<string name="pref_title_show_cards_in_timelines">แสดงตัวอย่างลิงก์ในไทม์ไลน์</string>
|
||||
<string name="warning_scheduling_interval">Mastodon กำหนดเวลาขั้นต่ำ 5 นาที</string>
|
||||
<string name="no_scheduled_status">ไม่มีสถานะแบบตั้งเวลาใด ๆ</string>
|
||||
<string name="no_saved_status">ไม่มีฉบับร่างใด ๆ</string>
|
||||
<string name="post_lookup_error_format">การค้นหาโพสต์ %s เกิดข้อผิดผลาด</string>
|
||||
<string name="edit_poll">แก้ไข</string>
|
||||
<string name="poll_new_choice_hint">ตัวเลือกที่ %d</string>
|
||||
</resources>
|
|
@ -184,7 +184,7 @@
|
|||
<string name="post_privacy_unlisted">Liste dışı</string>
|
||||
<string name="post_privacy_followers_only">Sadece takipçiler</string>
|
||||
<string name="pref_status_text_size">Durum metin boyutu</string>
|
||||
<string name="status_text_size_smallest">Çok küçük</string>
|
||||
<string name="status_text_size_smallest">En küçük</string>
|
||||
<string name="status_text_size_small">Küçük</string>
|
||||
<string name="status_text_size_medium">Orta</string>
|
||||
<string name="status_text_size_large">Büyük</string>
|
||||
|
@ -392,7 +392,7 @@
|
|||
<string name="hint_additional_info">Ek Yorumlar</string>
|
||||
<string name="report_remote_instance">%s adresine ilet</string>
|
||||
<string name="failed_fetch_statuses">Durumlar getirilemedi</string>
|
||||
<string name="report_description_1">"Bildirim sunucu yöneticinize gönderilecektir. Bu hesabı neden bildirdiğinizle ilgili açıklama yapabilirsiniz:"</string>
|
||||
<string name="report_description_1">"Bildirim sunucu yöneticinize gönderilecektir. Bu hesabı neden bildirdiğinle ilgili açıklama yapabilirsin:"</string>
|
||||
<string name="report_description_remote_instance">Hesap başka bir sunucudan. Raporun anonim bir kopyasını da oraya gönderilsin mi\?</string>
|
||||
<string name="pref_title_show_notifications_filter">Bildirim filtresini göster</string>
|
||||
<string name="action_mentions">Bahsedenler</string>
|
||||
|
|
|
@ -108,6 +108,4 @@
|
|||
<string name="hint_content_warning">Попередження про контент</string>
|
||||
<string name="edit_poll">Змінити</string>
|
||||
<string name="compose_shortcut_short_label">Написати</string>
|
||||
<string name="action_unmute_conversation">Скасувати приглушення бесіди</string>
|
||||
<string name="action_mute_conversation">Приглушити бесіду</string>
|
||||
</resources>
|
|
@ -413,9 +413,11 @@
|
|||
<string name="action_view_bookmarks">书签</string>
|
||||
<string name="action_view_domain_mutes">隐藏域名</string>
|
||||
<string name="action_add_poll">新增意见调查</string>
|
||||
<string name="action_mute_domain">隐藏</string>
|
||||
<string name="action_access_scheduled_toot">定时嘟文</string>
|
||||
<string name="action_schedule_toot">定时嘟文</string>
|
||||
<string name="confirmation_domain_unmuted">%s 已解除静音</string>
|
||||
<string name="mute_domain_warning">您确定要封锁 %s 域名吗?您将不会在任何联邦时间轴或通知中看到该域名中的内容,并且来自该域名的关注者将被删除。</string>
|
||||
<string name="mute_domain_warning_dialog_ok">隐藏整个域</string>
|
||||
<string name="pref_title_animate_gif_avatars">动画GIF头像</string>
|
||||
<string name="gradient_for_media">显示隐藏媒体的彩色渐变</string>
|
||||
|
@ -428,10 +430,11 @@
|
|||
<string name="description_poll">使用以下选项创建投票:%1$s, %2$s, %3$s, %4$s; %5$s</string>
|
||||
<string name="select_list_title">选择清单</string>
|
||||
<string name="list">清单</string>
|
||||
<string name="compose_preview_image_description">图片 %s 的动作</string>
|
||||
<string name="button_continue">继续</string>
|
||||
<string name="button_back">返回</string>
|
||||
<string name="button_done">完成</string>
|
||||
<string name="report_sent_success">"成功回报 @%s"</string>
|
||||
<string name="report_sent_success">成功回报 @%s</string>
|
||||
<string name="hint_additional_info">附加留言</string>
|
||||
<string name="report_remote_instance">转发到 %s</string>
|
||||
<string name="failed_report">回报失败</string>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<string name="error_media_upload_sending">媒體檔案上傳失敗</string>
|
||||
<string name="error_sender_account_gone">嘟文發送時出錯</string>
|
||||
<string name="title_home">主頁</string>
|
||||
<string name="title_notifications">通知設定</string>
|
||||
<string name="title_notifications">通知</string>
|
||||
<string name="title_public_local">本站時間軸</string>
|
||||
<string name="title_public_federated">跨站公開時間軸</string>
|
||||
<string name="title_direct_messages">私信</string>
|
||||
|
@ -30,7 +30,7 @@
|
|||
<string name="title_statuses_with_replies">嘟文和回覆</string>
|
||||
<string name="title_statuses_pinned">已置頂</string>
|
||||
<string name="title_follows">正在關注</string>
|
||||
<string name="title_followers">關注者</string>
|
||||
<string name="title_followers">僅關注者</string>
|
||||
<string name="title_favourites">我的收藏</string>
|
||||
<string name="title_mutes">被靜音的使用者</string>
|
||||
<string name="title_blocks">被封鎖的使用者</string>
|
||||
|
@ -104,7 +104,7 @@
|
|||
<string name="action_search">搜尋</string>
|
||||
<string name="action_access_saved_toot">草稿</string>
|
||||
<string name="action_toggle_visibility">設定嘟文可見範圍</string>
|
||||
<string name="action_content_warning">敏感內容警告</string>
|
||||
<string name="action_content_warning">設定敏感內容警告</string>
|
||||
<string name="action_emoji_keyboard">插入表情符號</string>
|
||||
<string name="action_add_tab">新增標籤頁</string>
|
||||
<string name="action_links">連結</string>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<dimen name="compose_media_preview_margin">8dp</dimen>
|
||||
<dimen name="compose_media_preview_margin_bottom">0dp</dimen>
|
||||
<dimen name="compose_media_preview_size">120dp</dimen>
|
||||
<dimen name="compose_options_margin">8dp</dimen>
|
||||
<dimen name="account_avatar_margin">14dp</dimen>
|
||||
<dimen name="tab_page_margin">16dp</dimen>
|
||||
<dimen name="status_line_margin_start">36dp</dimen>
|
||||
|
@ -48,6 +49,4 @@
|
|||
|
||||
<dimen name="adaptive_bitmap_inner_size">72dp</dimen>
|
||||
<dimen name="adaptive_bitmap_outer_size">108dp</dimen>
|
||||
|
||||
<dimen name="fabMargin">16dp</dimen>
|
||||
</resources>
|
||||
|
|
|
@ -110,15 +110,6 @@
|
|||
<item>ja</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_main_nav_position_options">
|
||||
<item>@string/pref_main_nav_position_option_top</item>
|
||||
<item>@string/pref_main_nav_position_option_bottom</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="pref_main_nav_position_values">
|
||||
<item>top</item>
|
||||
<item>bottom</item>
|
||||
</string-array>
|
||||
|
||||
<string name="description_status" translatable="false">
|
||||
<!-- Display name, cw?, content?, poll? relative date, reposted by?, reposted?, favorited?, bookmarked?, username, media?; visibility, fav number?, reblog number?-->
|
||||
|
|
|
@ -234,7 +234,7 @@
|
|||
<string name="pref_title_language">Language</string>
|
||||
<string name="pref_title_bot_overlay">Show indicator for bots</string>
|
||||
<string name="pref_title_animate_gif_avatars">Animate GIF avatars</string>
|
||||
<string name="pref_title_gradient_for_media">Show colorful gradients for hidden media</string>
|
||||
<string name="gradient_for_media">Show colorful gradients for hidden media</string>
|
||||
|
||||
<string name="pref_title_status_filter">Timeline filtering</string>
|
||||
<string name="pref_title_status_tabs">Tabs</string>
|
||||
|
@ -252,11 +252,6 @@
|
|||
<string name="pref_publishing">Publishing (synced with server)</string>
|
||||
<string name="pref_failed_to_sync">Failed to sync settings</string>
|
||||
|
||||
<string name="pref_main_nav_position">Main navigation position</string>
|
||||
<string name="pref_main_nav_position_option_top">Top</string>
|
||||
<string name="pref_main_nav_position_option_bottom">Bottom</string>
|
||||
|
||||
|
||||
<string name="post_privacy_public">Public</string>
|
||||
<string name="post_privacy_unlisted">Unlisted</string>
|
||||
<string name="post_privacy_followers_only">Followers-only</string>
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:key="@string/preferences_file_key">
|
||||
|
||||
<Preference
|
||||
android:key="notificationPreference"
|
||||
android:title="@string/pref_title_edit_notification_settings" />
|
||||
|
||||
<Preference
|
||||
android:key="tabPreference"
|
||||
android:title="@string/title_tab_preferences" />
|
||||
|
||||
<Preference
|
||||
android:key="mutedUsersPreference"
|
||||
android:title="@string/action_view_mutes" />
|
||||
|
||||
<Preference
|
||||
android:key="blockedUsersPreference"
|
||||
android:title="@string/action_view_blocks" />
|
||||
|
||||
<Preference
|
||||
android:key="mutedDomainsPreference"
|
||||
android:title="@string/action_view_domain_mutes" />
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_publishing">
|
||||
<ListPreference
|
||||
android:defaultValue="public"
|
||||
android:entries="@array/post_privacy_names"
|
||||
android:entryValues="@array/post_privacy_values"
|
||||
android:key="defaultPostPrivacy"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_default_post_privacy" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="Plaintext"
|
||||
android:entries="@array/formatting_syntax_values"
|
||||
android:entryValues="@array/formatting_syntax_values"
|
||||
android:key="defaultFormattingSyntax"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_default_formatting" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:icon="@drawable/ic_eye_24dp"
|
||||
android:key="defaultMediaSensitivity"
|
||||
android:title="@string/pref_default_media_sensitivity"
|
||||
app:singleLineTitle="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_timelines">
|
||||
<SwitchPreferenceCompat
|
||||
android:key="mediaPreviewEnabled"
|
||||
android:title="@string/pref_title_show_media_preview"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="alwaysShowSensitiveMedia"
|
||||
android:title="@string/pref_title_alway_show_sensitive_media"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:key="alwaysOpenSpoiler"
|
||||
android:title="@string/pref_title_alway_open_spoiler"
|
||||
app:singleLineTitle="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_timeline_filters">
|
||||
<Preference
|
||||
android:key="publicFilters"
|
||||
android:title="@string/pref_title_public_filter_keywords" />
|
||||
|
||||
<Preference
|
||||
android:key="notificationFilters"
|
||||
android:title="@string/title_notifications" />
|
||||
|
||||
<Preference
|
||||
android:key="homeFilters"
|
||||
android:title="@string/title_home" />
|
||||
|
||||
<Preference
|
||||
android:key="threadFilters"
|
||||
android:title="@string/pref_title_thread_filter_keywords" />
|
||||
|
||||
<Preference
|
||||
android:key="accountFilters"
|
||||
android:title="@string/title_accounts" />
|
||||
</PreferenceCategory>
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/pref_title_http_proxy_settings">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="httpProxyEnabled"
|
||||
android:title="@string/pref_title_http_proxy_enable"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="httpProxyServer"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_http_proxy_server"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="httpProxyPort"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_http_proxy_port"
|
||||
app:iconSpaceReserved="false" />
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:key="notificationSettings"
|
||||
android:title="@string/pref_title_edit_notification_settings">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="notificationsEnabled"
|
||||
android:title="@string/pref_title_notifications_enabled"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<PreferenceCategory
|
||||
android:dependency="notificationsEnabled"
|
||||
android:title="@string/pref_title_notification_filters"
|
||||
app:iconSpaceReserved="false">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="notificationFilterMentions"
|
||||
android:title="@string/pref_title_notification_filter_mentions"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="notificationFilterFollows"
|
||||
android:title="@string/pref_title_notification_filter_follows"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="notificationFilterFollowRequests"
|
||||
android:title="@string/pref_title_notification_filter_follow_requests"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="notificationFilterReblogs"
|
||||
android:title="@string/pref_title_notification_filter_reblogs"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="notificationFilterFavourites"
|
||||
android:title="@string/pref_title_notification_filter_favourites"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="notificationFilterEmojis"
|
||||
android:title="@string/pref_title_notification_filter_emoji"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="notificationFilterPolls"
|
||||
android:title="@string/pref_title_notification_filter_poll"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:dependency="notificationsEnabled"
|
||||
android:title="@string/pref_title_notification_alerts"
|
||||
app:iconSpaceReserved="false">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="notificationAlertSound"
|
||||
android:title="@string/pref_title_notification_alert_sound"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="notificationAlertVibrate"
|
||||
android:title="@string/pref_title_notification_alert_vibrate"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="notificationAlertLight"
|
||||
android:title="@string/pref_title_notification_alert_light"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -0,0 +1,136 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:key="@string/preferences_file_key">
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_appearance_settings">
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="night"
|
||||
android:entries="@array/app_theme_names"
|
||||
android:entryValues="@array/app_theme_values"
|
||||
android:key="appTheme"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_app_theme" />
|
||||
|
||||
<com.keylesspalace.tusky.EmojiPreference
|
||||
android:defaultValue="@string/system_default"
|
||||
android:icon="@drawable/ic_emoji_24dp"
|
||||
android:key="emojiCompat"
|
||||
android:summary="@string/system_default"
|
||||
android:title="@string/emoji_style" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="default"
|
||||
android:entries="@array/language_entries"
|
||||
android:entryValues="@array/language_values"
|
||||
android:key="language"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_language" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="medium"
|
||||
android:entries="@array/status_text_size_names"
|
||||
android:entryValues="@array/status_text_size_values"
|
||||
android:key="statusTextSize"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_status_text_size" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="fabHide"
|
||||
android:title="@string/pref_title_hide_follow_button"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="absoluteTimeView"
|
||||
android:title="@string/pref_title_absolute_time"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="showBotOverlay"
|
||||
android:title="@string/pref_title_bot_overlay"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="animateGifAvatars"
|
||||
android:title="@string/pref_title_animate_gif_avatars"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="useBlurhash"
|
||||
android:title="@string/gradient_for_media"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="showNotificationsFilter"
|
||||
android:title="@string/pref_title_show_notifications_filter"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="showCardsInTimelines"
|
||||
android:title="@string/pref_title_show_cards_in_timelines"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="confirmReblogs"
|
||||
android:title="@string/pref_title_confirm_reblogs"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="hideMutedUsers"
|
||||
android:title="@string/pref_title_hide_muted_users"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="enableSwipeForTabs"
|
||||
android:title="@string/pref_title_enable_swipe_for_tabs"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="bigEmojis"
|
||||
android:title="@string/pref_title_enable_big_emojis"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="stickers"
|
||||
android:title="@string/pref_title_enable_experimental_stickers"
|
||||
app:singleLineTitle="false" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_browser_settings">
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="customTabs"
|
||||
android:title="@string/pref_title_custom_tabs"
|
||||
app:singleLineTitle="false" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_status_filter">
|
||||
|
||||
<Preference
|
||||
android:key="timelineFilterPreferences"
|
||||
android:title="@string/pref_title_status_tabs" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_title_proxy_settings">
|
||||
|
||||
<Preference
|
||||
android:key="httpProxyPreferences"
|
||||
android:summary="%s"
|
||||
android:title="@string/pref_title_http_proxy_settings" />
|
||||
</PreferenceCategory>
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:title="@string/pref_title_status_tabs">
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/title_home"
|
||||
app:iconSpaceReserved="false">
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="tabFilterHomeBoosts"
|
||||
android:title="@string/pref_title_show_boosts"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="tabFilterHomeReplies"
|
||||
android:title="@string/pref_title_show_replies"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
</androidx.preference.PreferenceScreen>
|
|
@ -5,7 +5,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.0'
|
||||
classpath 'com.android.tools.build:gradle:3.6.3'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -82,7 +82,6 @@ esac
|
|||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
|
@ -130,7 +129,6 @@ fi
|
|||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
|
|
|
@ -81,7 +81,6 @@ set CMD_LINE_ARGS=%*
|
|||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
|
|
Loading…
Reference in New Issue