split out FilteredStatusViewHolder from StatusBaseViewHolder (#4543)

This is way more efficient than before as less views need to be inflated
and bound for a filtered status to be rendered. It also should fix the
bug where sometimes a `StatusViewHolder` that is set up for showing a
status gets bound to a status that is filtered, leading to a crash.
This commit is contained in:
Konrad Pozniak 2024-07-05 10:13:37 +02:00 committed by GitHub
commit 326676a9c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 107 additions and 96 deletions

View file

@ -0,0 +1,57 @@
/* Copyright 2024 Tusky Contributors
*
* This file is a part of Tusky.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU 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 General
* Public License for more details.
*
* 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.adapter
import androidx.recyclerview.widget.RecyclerView
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.components.notifications.NotificationsViewHolder
import com.keylesspalace.tusky.databinding.ItemStatusFilteredBinding
import com.keylesspalace.tusky.entity.Filter
import com.keylesspalace.tusky.entity.FilterResult
import com.keylesspalace.tusky.interfaces.StatusActionListener
import com.keylesspalace.tusky.util.StatusDisplayOptions
import com.keylesspalace.tusky.viewdata.NotificationViewData
import com.keylesspalace.tusky.viewdata.StatusViewData
class FilteredStatusViewHolder(
private val binding: ItemStatusFilteredBinding,
listener: StatusActionListener
) : NotificationsViewHolder, RecyclerView.ViewHolder(binding.root) {
init {
binding.statusFilterShowAnyway.setOnClickListener {
listener.clearWarningAction(bindingAdapterPosition)
}
}
override fun bind(
viewData: NotificationViewData.Concrete,
payloads: List<*>,
statusDisplayOptions: StatusDisplayOptions
) = bind(viewData.statusViewData!!)
fun bind(viewData: StatusViewData.Concrete) {
val matchedFilterResult: FilterResult? = viewData.actionable.filtered.orEmpty().find { filterResult ->
filterResult.filter.action == Filter.Action.WARN
}
val matchedFilterTitle = matchedFilterResult?.filter?.title.orEmpty()
binding.statusFilterLabel.text = itemView.context.getString(
R.string.status_filter_placeholder_label_format,
matchedFilterTitle
)
}
}

View file

@ -45,8 +45,6 @@ import com.keylesspalace.tusky.entity.Attachment.Focus;
import com.keylesspalace.tusky.entity.Attachment.MetaData;
import com.keylesspalace.tusky.entity.Card;
import com.keylesspalace.tusky.entity.Emoji;
import com.keylesspalace.tusky.entity.Filter;
import com.keylesspalace.tusky.entity.FilterResult;
import com.keylesspalace.tusky.entity.HashTag;
import com.keylesspalace.tusky.entity.Status;
import com.keylesspalace.tusky.entity.Translation;
@ -120,9 +118,6 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
private final TextView cardDescription;
private final TextView cardUrl;
private final PollAdapter pollAdapter;
protected final LinearLayout filteredPlaceholder;
protected final TextView filteredPlaceholderLabel;
protected final Button filteredPlaceholderShowButton;
protected final ConstraintLayout statusContainer;
private final TextView translationStatusView;
private final Button untranslateButton;
@ -179,9 +174,6 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
cardDescription = itemView.findViewById(R.id.card_description);
cardUrl = itemView.findViewById(R.id.card_link);
filteredPlaceholder = itemView.findViewById(R.id.status_filtered_placeholder);
filteredPlaceholderLabel = itemView.findViewById(R.id.status_filter_label);
filteredPlaceholderShowButton = itemView.findViewById(R.id.status_filter_show_anyway);
statusContainer = itemView.findViewById(R.id.status_container);
pollAdapter = new PollAdapter();
@ -822,8 +814,6 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
setSpoilerAndContent(status, statusDisplayOptions, listener);
setupFilterPlaceholder(status, listener, statusDisplayOptions);
setDescriptionForStatus(status, statusDisplayOptions);
// Workaround for RecyclerView 1.0.0 / androidx.core 1.0.0
@ -866,35 +856,6 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
}
}
private void setupFilterPlaceholder(StatusViewData.Concrete status, StatusActionListener listener, StatusDisplayOptions displayOptions) {
if (status.getFilterAction() != Filter.Action.WARN) {
showFilteredPlaceholder(false);
return;
}
showFilteredPlaceholder(true);
Filter matchedFilter = null;
for (FilterResult result : status.getActionable().getFiltered()) {
Filter filter = result.getFilter();
if (filter.getAction() == Filter.Action.WARN) {
matchedFilter = filter;
break;
}
}
final String matchedFilterTitle;
if (matchedFilter == null) {
matchedFilterTitle = "";
} else {
matchedFilterTitle = matchedFilter.getTitle();
}
filteredPlaceholderLabel.setText(itemView.getContext().getString(R.string.status_filter_placeholder_label_format, matchedFilterTitle));
filteredPlaceholderShowButton.setOnClickListener(view -> listener.clearWarningAction(getBindingAdapterPosition()));
}
protected static boolean hasPreviewableAttachment(@NonNull List<Attachment> attachments) {
for (Attachment attachment : attachments) {
if (attachment.getType() == Attachment.Type.AUDIO || attachment.getType() == Attachment.Type.UNKNOWN) {
@ -1306,13 +1267,4 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
bookmarkButton.setVisibility(visibility);
moreButton.setVisibility(visibility);
}
public void showFilteredPlaceholder(boolean show) {
if (statusContainer != null) {
statusContainer.setVisibility(show ? View.GONE : View.VISIBLE);
}
if (filteredPlaceholder != null) {
filteredPlaceholder.setVisibility(show ? View.VISIBLE : View.GONE);
}
}
}