mirror of
https://github.com/pachli/pachli-android.git
synced 2025-02-09 00:18:56 +01:00
feat: Edit a matching filter directly from the timeline (#819)
Previously, if a status was filtered with "WARN" and was shown in the timeline with the name of the filter, and the user then decided to change that filter, they had to: 1. Open the left navigation menu 2. Navigate to "Account preferences" 3. Open "Filters" 4. Find the filter they want to edit, tap it 5. Make the change, and save 6. "Back" to the list of filters 7. "Back" to "Account preferences" 8. "Back" to the timeline That's a lot of clicks for a simple action. Change this. Now the filtered status includes an "Edit filter" button that takes the user directly to step 5, and when they press "Back" they return directly to the timeline. To do this create a new filter action, `onEditFilterById`. Update the listeners to launch `EditFilterActivity` if appropriate. Modify `item_status_filtered.xml` to show the new button. Update the accessibility delegate to show just the "Show anyway" and "Edit filter" actions. Modify `FilterableStatusViewHolder` to expose the information it needs to do this.
This commit is contained in:
parent
7ef692c2c8
commit
6b55d107c1
@ -18,6 +18,7 @@
|
||||
package app.pachli.adapter
|
||||
|
||||
import android.view.View
|
||||
import androidx.core.text.HtmlCompat
|
||||
import app.pachli.R
|
||||
import app.pachli.core.data.model.StatusDisplayOptions
|
||||
import app.pachli.core.network.model.Filter
|
||||
@ -28,6 +29,8 @@ import app.pachli.viewdata.IStatusViewData
|
||||
open class FilterableStatusViewHolder<T : IStatusViewData>(
|
||||
private val binding: ItemStatusWrapperBinding,
|
||||
) : StatusViewHolder<T>(binding.statusContainer, binding.root) {
|
||||
/** The filter that matched the status, null if the status is not being filtered. */
|
||||
var matchedFilter: Filter? = null
|
||||
|
||||
override fun setupWithStatus(
|
||||
viewData: T,
|
||||
@ -44,42 +47,38 @@ open class FilterableStatusViewHolder<T : IStatusViewData>(
|
||||
listener: StatusActionListener<T>,
|
||||
) {
|
||||
if (status.filterAction !== Filter.Action.WARN) {
|
||||
showFilteredPlaceholder(false)
|
||||
matchedFilter = null
|
||||
setPlaceholderVisibility(false)
|
||||
return
|
||||
}
|
||||
|
||||
// Shouldn't be necessary given the previous test against getFilterAction(),
|
||||
// but guards against a possible NPE. See the TODO in StatusViewData.filterAction
|
||||
// for more details.
|
||||
val filterResults = status.actionable.filtered
|
||||
if (filterResults.isNullOrEmpty()) {
|
||||
showFilteredPlaceholder(false)
|
||||
return
|
||||
}
|
||||
var matchedFilter: Filter? = null
|
||||
for ((filter) in filterResults) {
|
||||
if (filter.action === Filter.Action.WARN) {
|
||||
matchedFilter = filter
|
||||
break
|
||||
}
|
||||
}
|
||||
status.actionable.filtered?.find { it.filter.action === Filter.Action.WARN }?.let { result ->
|
||||
this.matchedFilter = result.filter
|
||||
setPlaceholderVisibility(true)
|
||||
|
||||
// Guard against a possible NPE
|
||||
if (matchedFilter == null) {
|
||||
showFilteredPlaceholder(false)
|
||||
return
|
||||
}
|
||||
showFilteredPlaceholder(true)
|
||||
binding.statusFilteredPlaceholder.statusFilterLabel.text = context.getString(
|
||||
val label = HtmlCompat.fromHtml(
|
||||
context.getString(
|
||||
R.string.status_filter_placeholder_label_format,
|
||||
matchedFilter.title,
|
||||
result.filter.title,
|
||||
),
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY,
|
||||
)
|
||||
binding.root.contentDescription = label
|
||||
binding.statusFilteredPlaceholder.statusFilterLabel.text = label
|
||||
|
||||
binding.statusFilteredPlaceholder.statusFilterShowAnyway.setOnClickListener {
|
||||
listener.clearWarningAction(status)
|
||||
}
|
||||
binding.statusFilteredPlaceholder.statusFilterEditFilter.setOnClickListener {
|
||||
listener.onEditFilterById(result.filter.id)
|
||||
}
|
||||
} ?: {
|
||||
matchedFilter = null
|
||||
setPlaceholderVisibility(false)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showFilteredPlaceholder(show: Boolean) {
|
||||
private fun setPlaceholderVisibility(show: Boolean) {
|
||||
binding.statusContainer.root.visibility = if (show) View.GONE else View.VISIBLE
|
||||
binding.statusFilteredPlaceholder.root.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.content.res.AppCompatResources
|
||||
@ -100,7 +99,7 @@ abstract class StatusBaseViewHolder<T : IStatusViewData> protected constructor(i
|
||||
private val contentWarningDescription: TextView = itemView.findViewById(R.id.status_content_warning_description)
|
||||
private val pollView: PollView = itemView.findViewById(R.id.status_poll)
|
||||
private val cardView: PreviewCardView? = itemView.findViewById(R.id.status_card_view)
|
||||
private val filteredPlaceholder: LinearLayout? = itemView.findViewById(R.id.status_filtered_placeholder)
|
||||
private val filteredPlaceholder: ConstraintLayout? = itemView.findViewById(R.id.status_filtered_placeholder)
|
||||
private val filteredPlaceholderLabel: TextView? = itemView.findViewById(R.id.status_filter_label)
|
||||
private val filteredPlaceholderShowButton: Button? = itemView.findViewById(R.id.status_filter_show_anyway)
|
||||
private val statusContainer: ConstraintLayout? = itemView.findViewById(R.id.status_container)
|
||||
|
@ -346,6 +346,9 @@ class ConversationsFragment :
|
||||
override fun clearWarningAction(viewData: ConversationViewData) {
|
||||
}
|
||||
|
||||
// Filters don't apply in conversations
|
||||
override fun onEditFilterById(filterId: String) {}
|
||||
|
||||
override fun onReselect() {
|
||||
if (isAdded) {
|
||||
binding.recyclerView.layoutManager?.scrollToPosition(0)
|
||||
|
@ -49,11 +49,14 @@ import app.pachli.R
|
||||
import app.pachli.adapter.StatusBaseViewHolder
|
||||
import app.pachli.components.timeline.TimelineLoadStateAdapter
|
||||
import app.pachli.core.activity.ReselectableFragment
|
||||
import app.pachli.core.activity.extensions.TransitionKind
|
||||
import app.pachli.core.activity.extensions.startActivityWithTransition
|
||||
import app.pachli.core.activity.openLink
|
||||
import app.pachli.core.common.extensions.hide
|
||||
import app.pachli.core.common.extensions.show
|
||||
import app.pachli.core.common.extensions.viewBinding
|
||||
import app.pachli.core.navigation.AttachmentViewData.Companion.list
|
||||
import app.pachli.core.navigation.EditFilterActivityIntent
|
||||
import app.pachli.core.network.model.Filter
|
||||
import app.pachli.core.network.model.Notification
|
||||
import app.pachli.core.network.model.Poll
|
||||
@ -589,6 +592,13 @@ class NotificationsFragment :
|
||||
}
|
||||
}
|
||||
|
||||
override fun onEditFilterById(filterId: String) {
|
||||
requireActivity().startActivityWithTransition(
|
||||
EditFilterActivityIntent.edit(requireContext(), filterId),
|
||||
TransitionKind.SLIDE_FROM_END,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onNotificationContentCollapsedChange(
|
||||
isCollapsed: Boolean,
|
||||
viewData: NotificationViewData,
|
||||
|
@ -40,13 +40,16 @@ import app.pachli.R
|
||||
import app.pachli.components.search.adapter.SearchStatusesAdapter
|
||||
import app.pachli.core.activity.AccountSelectionListener
|
||||
import app.pachli.core.activity.BaseActivity
|
||||
import app.pachli.core.activity.extensions.TransitionKind
|
||||
import app.pachli.core.activity.extensions.startActivityWithDefaultTransition
|
||||
import app.pachli.core.activity.extensions.startActivityWithTransition
|
||||
import app.pachli.core.activity.openLink
|
||||
import app.pachli.core.data.repository.StatusDisplayOptionsRepository
|
||||
import app.pachli.core.database.model.AccountEntity
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.navigation.ComposeActivityIntent
|
||||
import app.pachli.core.navigation.ComposeActivityIntent.ComposeOptions
|
||||
import app.pachli.core.navigation.EditFilterActivityIntent
|
||||
import app.pachli.core.navigation.ReportActivityIntent
|
||||
import app.pachli.core.navigation.ViewMediaActivityIntent
|
||||
import app.pachli.core.network.model.Attachment
|
||||
@ -162,6 +165,13 @@ class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionLis
|
||||
viewModel.reblog(viewData, reblog)
|
||||
}
|
||||
|
||||
override fun onEditFilterById(filterId: String) {
|
||||
requireActivity().startActivityWithTransition(
|
||||
EditFilterActivityIntent.edit(requireContext(), filterId),
|
||||
TransitionKind.SLIDE_FROM_END,
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance() = SearchStatusesFragment()
|
||||
}
|
||||
|
@ -51,7 +51,9 @@ import app.pachli.components.timeline.viewmodel.TimelineViewModel
|
||||
import app.pachli.components.timeline.viewmodel.UiSuccess
|
||||
import app.pachli.core.activity.RefreshableFragment
|
||||
import app.pachli.core.activity.ReselectableFragment
|
||||
import app.pachli.core.activity.extensions.TransitionKind
|
||||
import app.pachli.core.activity.extensions.startActivityWithDefaultTransition
|
||||
import app.pachli.core.activity.extensions.startActivityWithTransition
|
||||
import app.pachli.core.common.extensions.hide
|
||||
import app.pachli.core.common.extensions.show
|
||||
import app.pachli.core.common.extensions.viewBinding
|
||||
@ -59,6 +61,7 @@ import app.pachli.core.database.model.TranslationState
|
||||
import app.pachli.core.model.Timeline
|
||||
import app.pachli.core.navigation.AccountListActivityIntent
|
||||
import app.pachli.core.navigation.AttachmentViewData
|
||||
import app.pachli.core.navigation.EditFilterActivityIntent
|
||||
import app.pachli.core.network.model.Poll
|
||||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.core.ui.ActionButtonScrollListener
|
||||
@ -615,6 +618,13 @@ class TimelineFragment :
|
||||
viewModel.clearWarning(viewData)
|
||||
}
|
||||
|
||||
override fun onEditFilterById(filterId: String) {
|
||||
requireActivity().startActivityWithTransition(
|
||||
EditFilterActivityIntent.edit(requireContext(), filterId),
|
||||
TransitionKind.SLIDE_FROM_END,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onMore(view: View, viewData: StatusViewData) {
|
||||
super.more(view, viewData)
|
||||
}
|
||||
|
@ -33,7 +33,9 @@ import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
||||
import app.pachli.R
|
||||
import app.pachli.components.viewthread.edits.ViewEditsFragment
|
||||
import app.pachli.core.activity.extensions.TransitionKind
|
||||
import app.pachli.core.activity.extensions.startActivityWithDefaultTransition
|
||||
import app.pachli.core.activity.extensions.startActivityWithTransition
|
||||
import app.pachli.core.activity.openLink
|
||||
import app.pachli.core.common.extensions.hide
|
||||
import app.pachli.core.common.extensions.show
|
||||
@ -41,6 +43,7 @@ import app.pachli.core.common.extensions.viewBinding
|
||||
import app.pachli.core.designsystem.R as DR
|
||||
import app.pachli.core.navigation.AccountListActivityIntent
|
||||
import app.pachli.core.navigation.AttachmentViewData.Companion.list
|
||||
import app.pachli.core.navigation.EditFilterActivityIntent
|
||||
import app.pachli.core.network.model.Poll
|
||||
import app.pachli.core.network.model.Status
|
||||
import app.pachli.core.ui.extensions.getErrorString
|
||||
@ -323,6 +326,13 @@ class ViewThreadFragment :
|
||||
// there are no reblogs in threads
|
||||
}
|
||||
|
||||
override fun onEditFilterById(filterId: String) {
|
||||
requireActivity().startActivityWithTransition(
|
||||
EditFilterActivityIntent.edit(requireContext(), filterId),
|
||||
TransitionKind.SLIDE_FROM_END,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onExpandedChange(viewData: StatusViewData, expanded: Boolean) {
|
||||
viewModel.changeExpanded(expanded, viewData)
|
||||
}
|
||||
|
@ -59,4 +59,7 @@ interface StatusActionListener<T : IStatusViewData> : LinkListener {
|
||||
fun onVoteInPoll(viewData: T, poll: Poll, choices: List<Int>)
|
||||
fun onShowEdits(statusId: String) {}
|
||||
fun clearWarningAction(viewData: T)
|
||||
|
||||
/** Edit the filter that matched this status. */
|
||||
fun onEditFilterById(filterId: String)
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.Accessibilit
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate
|
||||
import app.pachli.R
|
||||
import app.pachli.adapter.FilterableStatusViewHolder
|
||||
import app.pachli.adapter.StatusBaseViewHolder
|
||||
import app.pachli.core.activity.openLink
|
||||
import app.pachli.core.network.model.Status.Companion.MAX_MEDIA_ATTACHMENTS
|
||||
@ -48,6 +49,13 @@ class ListStatusAccessibilityDelegate<T : IStatusViewData>(
|
||||
) {
|
||||
super.onInitializeAccessibilityNodeInfo(host, info)
|
||||
|
||||
val viewHolder = recyclerView.findContainingViewHolder(host)
|
||||
if (viewHolder is FilterableStatusViewHolder<*> && viewHolder.matchedFilter != null) {
|
||||
info.addAction(showAnywayAction)
|
||||
info.addAction(editFilterAction)
|
||||
return
|
||||
}
|
||||
|
||||
val pos = recyclerView.getChildAdapterPosition(host)
|
||||
val status = statusProvider.getStatus(pos) ?: return
|
||||
|
||||
@ -183,6 +191,14 @@ class ListStatusAccessibilityDelegate<T : IStatusViewData>(
|
||||
app.pachli.core.ui.R.id.action_more -> {
|
||||
statusActionListener.onMore(host, status)
|
||||
}
|
||||
app.pachli.core.ui.R.id.action_show_anyway -> statusActionListener.clearWarningAction(status)
|
||||
app.pachli.core.ui.R.id.action_edit_filter -> {
|
||||
(recyclerView.findContainingViewHolder(host) as? FilterableStatusViewHolder<*>)?.matchedFilter?.let {
|
||||
statusActionListener.onEditFilterById(it.id)
|
||||
return@let true
|
||||
} ?: false
|
||||
}
|
||||
|
||||
else -> return super.performAccessibilityAction(host, action, args)
|
||||
}
|
||||
return true
|
||||
@ -378,5 +394,15 @@ class ListStatusAccessibilityDelegate<T : IStatusViewData>(
|
||||
context.getString(app.pachli.core.ui.R.string.action_more),
|
||||
)
|
||||
|
||||
private val showAnywayAction = AccessibilityActionCompat(
|
||||
app.pachli.core.ui.R.id.action_show_anyway,
|
||||
context.getString(R.string.status_filtered_show_anyway),
|
||||
)
|
||||
|
||||
private val editFilterAction = AccessibilityActionCompat(
|
||||
app.pachli.core.ui.R.id.action_edit_filter,
|
||||
context.getString(R.string.filter_edit_title),
|
||||
)
|
||||
|
||||
private data class LinkSpanInfo(val text: String, val link: String)
|
||||
}
|
||||
|
@ -1,33 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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"
|
||||
android:id="@+id/status_filtered_placeholder"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="14dp"
|
||||
android:paddingEnd="14dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:minHeight="48dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/status_filter_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:textColor="?android:textColorTertiary"
|
||||
android:textSize="?attr/status_text_medium"
|
||||
android:textAlignment="center"
|
||||
android:textIsSelectable="false"
|
||||
tools:text="Filter: MyFilter"
|
||||
/>
|
||||
tools:text="Filter: MyFilter" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/status_filter_edit_filter"
|
||||
style="@style/AppButton.TextButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:importantForAccessibility="no"
|
||||
android:text="@string/filter_edit_title"
|
||||
android:textSize="?attr/status_text_medium"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/status_filter_show_anyway"
|
||||
app:layout_constraintTop_toTopOf="@+id/status_filter_show_anyway" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/status_filter_show_anyway"
|
||||
android:layout_width="match_parent"
|
||||
style="@style/AppButton.Outlined"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="0dp"
|
||||
style="@style/AppButton.TextButton"
|
||||
android:textStyle="bold"
|
||||
android:textSize="?attr/status_text_medium"
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/status_filtered_show_anyway"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
android:textSize="?attr/status_text_medium"
|
||||
app:layout_constraintStart_toEndOf="@id/status_filter_edit_filter"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/status_filter_label" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
@ -587,7 +587,7 @@
|
||||
<string name="filter_action_warn">تحذير</string>
|
||||
<string name="title_public_trending_links">الروابط الشائعة</string>
|
||||
<string name="title_tab_public_trending_links">الروابط</string>
|
||||
<string name="status_filter_placeholder_label_format">مُصفّى: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">مُصفّى: <b>%1$s</b></string>
|
||||
<string name="update_dialog_neutral">لا تذكرني بهذه النسخة</string>
|
||||
<string name="ui_error_reject_follow_request">فشل رفض طلب المتابعة: %s</string>
|
||||
<string name="reaction_name_and_count">%1$s %2$d</string>
|
||||
|
@ -551,7 +551,7 @@
|
||||
<string name="description_login">Працуе амаль заўсёды. Даныя не ўцякаюць у іншыя праграмы.</string>
|
||||
<string name="notification_unknown_name">Невядома</string>
|
||||
<string name="status_filtered_show_anyway">Усё роўна паказаць</string>
|
||||
<string name="status_filter_placeholder_label_format">Адфільтрована: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Адфільтрована: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Профілі</string>
|
||||
<string name="title_public_trending_hashtags">Папулярныя хэштэгі</string>
|
||||
<string name="description_browser_login">Можа падтрымліваць дадатковыя метады праверкі сапраўднасці, але для гэтага патрэбны адпаведны браузер.</string>
|
||||
|
@ -537,7 +537,7 @@
|
||||
<string name="dialog_follow_hashtag_title">Segueix hashtag</string>
|
||||
<string name="dialog_follow_hashtag_hint">#hashtag</string>
|
||||
<string name="notification_unknown_name">Desconegut</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrat: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrat: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Perfils</string>
|
||||
<string name="status_filtered_show_anyway">Mostra de totes maneres</string>
|
||||
<string name="socket_timeout_exception">El contacte amb el teu servidor ha trigat massa</string>
|
||||
|
@ -585,7 +585,7 @@
|
||||
<string name="dialog_follow_hashtag_hint">#hashnod</string>
|
||||
<string name="notification_unknown_name">Anhysbys</string>
|
||||
<string name="status_filtered_show_anyway">Dangos beth bynnag</string>
|
||||
<string name="status_filter_placeholder_label_format">Hidlwyd: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Hidlwyd: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Proffiliau</string>
|
||||
<string name="socket_timeout_exception">Cymrodd hi\'n rhy hir i gysylltu â\'ch gweinydd</string>
|
||||
<string name="ui_error_bookmark_fmt">Methodd tudalnodi\'r neges: %1$s</string>
|
||||
|
@ -554,7 +554,7 @@
|
||||
<string name="notification_unknown_name">Unbekannt</string>
|
||||
<string name="ui_error_clear_notifications">Löschen der Benachrichtigungen schlug fehl: %s</string>
|
||||
<string name="ui_error_reject_follow_request">Ablehnen der Folgeanfrage schlug fehl: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Gefiltert: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Gefiltert: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Profile</string>
|
||||
<string name="hint_filter_title">Mein Filter</string>
|
||||
<string name="label_filter_title">Titel</string>
|
||||
|
@ -554,7 +554,7 @@
|
||||
<string name="pref_title_account_filter_keywords">Perfiles</string>
|
||||
<string name="notification_unknown_name">Desconocido</string>
|
||||
<string name="status_filtered_show_anyway">Mostrar de todas formas</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrado: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrado: <b>%1$s</b></string>
|
||||
<string name="pref_title_show_stat_inline">Mostrar estadísticas de la entrada en la línea de tiempo</string>
|
||||
<string name="socket_timeout_exception">Contactar con tu servidor ha tardado demasiado tiempo</string>
|
||||
<string name="select_list_empty">Todavía no tienes listas</string>
|
||||
|
@ -551,7 +551,7 @@
|
||||
<string name="ui_error_reblog_fmt">%1$s: تقویت فرسته شکست خورد</string>
|
||||
<string name="ui_error_reject_follow_request">رد کردن درخواست پیگیری شکست خورد: %s</string>
|
||||
<string name="status_filtered_show_anyway">نمایش به هر روی</string>
|
||||
<string name="status_filter_placeholder_label_format">پالوده: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">پالوده: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">نمایهها</string>
|
||||
<string name="hint_filter_title">پالایهام</string>
|
||||
<string name="label_filter_title">عنوان</string>
|
||||
|
@ -364,7 +364,7 @@
|
||||
<string name="send_post_notification_error_title">Julkaisun lähettäminen epäonnistui</string>
|
||||
<string name="pref_title_notification_filter_follow_requests">seuraamista pyydetty</string>
|
||||
<string name="pref_title_notification_filters">Ilmoita kun</string>
|
||||
<string name="status_filter_placeholder_label_format">Suodatettu: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Suodatettu: <b>%1$s</b></string>
|
||||
<string name="pref_main_nav_position_option_bottom">Alareuna</string>
|
||||
<string name="pref_title_notification_filter_poll">päättyneet äänestykset</string>
|
||||
<string name="abbreviated_in_seconds">%ds</string>
|
||||
|
@ -528,7 +528,7 @@
|
||||
<string name="pref_title_notification_filter_reports">il y a un nouveau signalement</string>
|
||||
<string name="pref_title_account_filter_keywords">Profils</string>
|
||||
<string name="status_filtered_show_anyway">Montrer quand même</string>
|
||||
<string name="status_filter_placeholder_label_format">Caché : %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Caché : <b>%1$s</b></string>
|
||||
<string name="title_public_trending_hashtags">Hashtags tendance</string>
|
||||
<string name="send_account_username_to">Partager le nom du compte avec…</string>
|
||||
<string name="status_created_at_now">maintenant</string>
|
||||
|
@ -569,7 +569,7 @@
|
||||
<string name="select_list_empty">Chan eil liosta agad fhathast</string>
|
||||
<string name="error_list_load">Mearachd a’ luchdadh nan liostaichean</string>
|
||||
<string name="status_filtered_show_anyway">Seall e co-dhiù</string>
|
||||
<string name="status_filter_placeholder_label_format">Criathraichte: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Criathraichte: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Pròifilean</string>
|
||||
<string name="hint_filter_title">A’ chriathrag agam</string>
|
||||
<string name="filter_description_warn">Falaich le rabhadh</string>
|
||||
|
@ -550,7 +550,7 @@
|
||||
<string name="ui_success_accepted_follow_request">Aceptado o seguimento</string>
|
||||
<string name="ui_success_rejected_follow_request">Bloqueada a solicitude de seguimento</string>
|
||||
<string name="status_filtered_show_anyway">Mostrar igualmente</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrado: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrado: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Perfís</string>
|
||||
<string name="label_filter_title">Título</string>
|
||||
<string name="filter_action_warn">Aviso</string>
|
||||
|
@ -545,7 +545,7 @@
|
||||
<string name="ui_error_vote_fmt">Szavazat leadása a szavazásba sikertelen: %1$s</string>
|
||||
<string name="ui_error_accept_follow_request">Követési kérelem elfogadása sikertelen: %s</string>
|
||||
<string name="status_filtered_show_anyway">Mutatás mindenképpen</string>
|
||||
<string name="status_filter_placeholder_label_format">Szűrve: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Szűrve: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Profil</string>
|
||||
<string name="socket_timeout_exception">A kapcsolatfelvétel a kiszolgálóddal túl sokáig tartott</string>
|
||||
<string name="ui_error_bookmark_fmt">Bejegyzés könyvjelzőzése sikertelen: %1$s</string>
|
||||
|
@ -534,7 +534,7 @@
|
||||
<string name="dialog_follow_hashtag_hint">#myllumerki</string>
|
||||
<string name="notification_unknown_name">Óþekkt</string>
|
||||
<string name="status_filtered_show_anyway">Birta samt</string>
|
||||
<string name="status_filter_placeholder_label_format">Síað: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Síað: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Notendasnið</string>
|
||||
<string name="pref_title_show_stat_inline">Sýna tölfræði færslu í tímalínu</string>
|
||||
<string name="ui_error_favourite_fmt">Mistókst að setja færslu í eftirlæti: %1$s</string>
|
||||
|
@ -593,7 +593,7 @@
|
||||
<string name="select_list_manage">Gestisci liste</string>
|
||||
<string name="error_list_load">Errore nel caricamento delle liste</string>
|
||||
<string name="status_filtered_show_anyway">Mostra comunque</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrato: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrato: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Profili</string>
|
||||
<string name="hint_filter_title">I miei filtri</string>
|
||||
<string name="action_add">Aggiungi</string>
|
||||
|
@ -595,7 +595,7 @@
|
||||
<string name="pref_title_font_family">フォント</string>
|
||||
<string name="description_poll">選択肢付きの投票: %1$s, %2$s, %3$s, %4$s; %5$s</string>
|
||||
<string name="label_image">画像</string>
|
||||
<string name="status_filter_placeholder_label_format">フィルタ済み: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">フィルタ済み: <b>%1$s</b></string>
|
||||
<string name="pref_title_show_self_boosts_description">自分の投稿をブーストすること</string>
|
||||
<string name="confirmation_hashtag_unmuted">%s を非表示にしました</string>
|
||||
<string name="pref_title_show_self_boosts">セルフブーストを表示</string>
|
||||
|
@ -564,7 +564,7 @@
|
||||
<string name="account_username_copied">Brukernavn kopiert</string>
|
||||
<string name="error_status_source_load">Kunne ikke laste status fra tjeneren.</string>
|
||||
<string name="status_filtered_show_anyway">Vis allikevel</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrert: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrert: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Profiler</string>
|
||||
<string name="action_add">Legg til</string>
|
||||
<string name="filter_keyword_display_format">%s (helt ord)</string>
|
||||
|
@ -543,7 +543,7 @@
|
||||
<string name="select_list_manage">Lijsten beheren</string>
|
||||
<string name="pref_title_account_filter_keywords">Profielen</string>
|
||||
<string name="status_filtered_show_anyway">Toch tonen</string>
|
||||
<string name="status_filter_placeholder_label_format">Gefilterd: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Gefilterd: <b>%1$s</b></string>
|
||||
<string name="hint_filter_title">Mijn filter</string>
|
||||
<string name="label_filter_action">Filteractie</string>
|
||||
<string name="filter_action_warn">Waarschuwen</string>
|
||||
|
@ -546,7 +546,7 @@
|
||||
<string name="ui_success_accepted_follow_request">Demanda d’abonament acceptada</string>
|
||||
<string name="ui_success_rejected_follow_request">Demanda d’abonament blocada</string>
|
||||
<string name="status_filtered_show_anyway">Afichar ça que la</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrat : %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrat : <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Perfils</string>
|
||||
<string name="hint_filter_title">Mon filtre</string>
|
||||
<string name="label_filter_title">Títol</string>
|
||||
|
@ -531,7 +531,7 @@
|
||||
<string name="title_public_trending_links">URL em alta</string>
|
||||
<string name="title_tab_public_trending_links">URL</string>
|
||||
<string name="title_public_trending_hashtags">Hashtags em alta</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrado(s): %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrado(s): <b>%1$s</b></string>
|
||||
<string name="confirmation_hashtag_unfollowed">#%s deixado de seguir</string>
|
||||
<string name="ui_error_vote_fmt">Votar na enquete falhou: %1$s</string>
|
||||
<string name="update_dialog_neutral">Não me lembre desta versão</string>
|
||||
|
@ -556,7 +556,7 @@
|
||||
<string name="select_list_manage">Hantera listor</string>
|
||||
<string name="select_list_empty">Du har inga listor, än</string>
|
||||
<string name="status_filtered_show_anyway">Visa allafall</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrerad: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtrerad: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Profiler</string>
|
||||
<string name="label_filter_action">Filteråtgärd</string>
|
||||
<string name="label_filter_keywords">Nyckelord eller fraser att filtrera</string>
|
||||
|
@ -568,7 +568,7 @@
|
||||
<string name="filter_action_hide">Gizle</string>
|
||||
<string name="filter_description_warn">Bir uyarı ile gizle</string>
|
||||
<string name="status_filtered_show_anyway">Yine de göster</string>
|
||||
<string name="status_filter_placeholder_label_format">Süzgeçlendi: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Süzgeçlendi: <b>%1$s</b></string>
|
||||
<string name="filter_edit_keyword_title">Anahtar kelimeyi düzenle</string>
|
||||
<string name="filter_description_format">%s: %s</string>
|
||||
<string name="pref_title_show_stat_inline">Gönderi istatistiklerini sğ akışında göster</string>
|
||||
|
@ -566,7 +566,7 @@
|
||||
<string name="ui_success_accepted_follow_request">Запит на стеження погоджено</string>
|
||||
<string name="ui_success_rejected_follow_request">Запит на стеження заблоковано</string>
|
||||
<string name="status_filtered_show_anyway">Усе одно показати</string>
|
||||
<string name="status_filter_placeholder_label_format">Відфільтровано: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Відфільтровано: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Профілі</string>
|
||||
<string name="label_filter_title">Заголовок</string>
|
||||
<string name="filter_action_warn">Попередження</string>
|
||||
|
@ -534,7 +534,7 @@
|
||||
<string name="ui_success_accepted_follow_request">Đã chấp nhận yêu cầu theo dõi</string>
|
||||
<string name="ui_success_rejected_follow_request">Đã từ chối yêu cầu theo dõi</string>
|
||||
<string name="status_filtered_show_anyway">Vẫn hiện</string>
|
||||
<string name="status_filter_placeholder_label_format">Đã lọc: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Đã lọc: <b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">Người</string>
|
||||
<string name="hint_filter_title">Bộ lọc của tôi</string>
|
||||
<string name="label_filter_title">Tên bộ lọc</string>
|
||||
|
@ -548,7 +548,7 @@
|
||||
<string name="ui_success_accepted_follow_request">关注请求被接受</string>
|
||||
<string name="ui_success_rejected_follow_request">关注请求被拦截</string>
|
||||
<string name="status_filtered_show_anyway">仍要显示</string>
|
||||
<string name="status_filter_placeholder_label_format">已过滤:%s</string>
|
||||
<string name="status_filter_placeholder_label_format">已过滤:<b>%1$s</b></string>
|
||||
<string name="pref_title_account_filter_keywords">个人资料</string>
|
||||
<string name="hint_filter_title">我的筛选器</string>
|
||||
<string name="label_filter_title">标题</string>
|
||||
|
@ -357,7 +357,7 @@
|
||||
<string name="status_count_one_plus">1+</string>
|
||||
<string name="status_created_at_now">now</string>
|
||||
<string name="status_filtered_show_anyway">Show anyway</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtered: %s</string>
|
||||
<string name="status_filter_placeholder_label_format">Filtered: <b>%1$s</b></string>
|
||||
<string name="state_follow_requested">Follow requested</string>
|
||||
<!--These are for timestamps on posts. For example: "16s" or "2d"-->
|
||||
<string name="abbreviated_in_years">in %dy</string>
|
||||
|
@ -49,4 +49,7 @@
|
||||
|
||||
<item name="action_dismiss_follow_suggestion" type="id" />
|
||||
<item name="action_follow_account" type="id" />
|
||||
|
||||
<item name="action_show_anyway" type="id" />
|
||||
<item name="action_edit_filter" type="id" />
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user