From 15ca16e06f34a33c803c6235f06964a48a99aabf Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Fri, 11 Jan 2019 20:05:15 +0100 Subject: [PATCH] fix long toots not collapsing correctly in timelines (#976) --- .../tusky/adapter/StatusBaseViewHolder.java | 27 ------------ .../tusky/adapter/StatusViewHolder.java | 41 +++++++++++++++++-- 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java index 8535184f..bdcd10c1 100644 --- a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java +++ b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java @@ -45,8 +45,6 @@ import at.connyduck.sparkbutton.SparkButton; import at.connyduck.sparkbutton.SparkEventListener; abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder { - private static final InputFilter[] COLLAPSE_INPUT_FILTER = new InputFilter[]{SmartLengthInputFilter.INSTANCE}; - private static final InputFilter[] NO_INPUT_FILTER = new InputFilter[0]; private TextView displayName; private TextView username; @@ -62,7 +60,6 @@ abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder { private View sensitiveMediaShow; private TextView mediaLabel; private ToggleButton contentWarningButton; - private ToggleButton contentCollapseButton; ImageView avatar; TextView timestampInfo; @@ -103,7 +100,6 @@ abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder { mediaLabel = itemView.findViewById(R.id.status_media_label); contentWarningDescription = itemView.findViewById(R.id.status_content_warning_description); contentWarningButton = itemView.findViewById(R.id.status_content_warning_button); - contentCollapseButton = itemView.findViewById(R.id.button_toggle_content); this.useAbsoluteTime = useAbsoluteTime; shortSdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()); @@ -541,28 +537,5 @@ abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder { setSpoilerAndContent(status, listener); - // When viewing threads this ViewHolder is used and the main post does not have a collapse - // button by design so avoid crashing the app when that happens - if (contentCollapseButton != null) { - if (status.isCollapsible() && (status.isExpanded() || status.getSpoilerText() == null || status.getSpoilerText().isEmpty())) { - contentCollapseButton.setOnCheckedChangeListener((buttonView, isChecked) -> { - int position = getAdapterPosition(); - if (position != RecyclerView.NO_POSITION) - listener.onContentCollapsedChange(isChecked, position); - }); - - contentCollapseButton.setVisibility(View.VISIBLE); - if (status.isCollapsed()) { - contentCollapseButton.setChecked(true); - content.setFilters(COLLAPSE_INPUT_FILTER); - } else { - contentCollapseButton.setChecked(false); - content.setFilters(NO_INPUT_FILTER); - } - } else { - contentCollapseButton.setVisibility(View.GONE); - content.setFilters(NO_INPUT_FILTER); - } - } } } diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusViewHolder.java b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusViewHolder.java index 572f621b..eae9709b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusViewHolder.java +++ b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusViewHolder.java @@ -17,25 +17,35 @@ package com.keylesspalace.tusky.adapter; import android.content.Context; import androidx.annotation.Nullable; + +import android.text.InputFilter; import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import android.widget.ToggleButton; import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.interfaces.StatusActionListener; +import com.keylesspalace.tusky.util.SmartLengthInputFilter; import com.keylesspalace.tusky.viewdata.StatusViewData; import com.squareup.picasso.Picasso; +import androidx.recyclerview.widget.RecyclerView; import at.connyduck.sparkbutton.helpers.Utils; public class StatusViewHolder extends StatusBaseViewHolder { + private static final InputFilter[] COLLAPSE_INPUT_FILTER = new InputFilter[]{SmartLengthInputFilter.INSTANCE}; + private static final InputFilter[] NO_INPUT_FILTER = new InputFilter[0]; + private ImageView avatarReblog; private TextView rebloggedBar; + private ToggleButton contentCollapseButton; StatusViewHolder(View itemView, boolean useAbsoluteTime) { super(itemView, useAbsoluteTime); avatarReblog = itemView.findViewById(R.id.status_avatar_reblog); rebloggedBar = itemView.findViewById(R.id.status_reblogged); + contentCollapseButton = itemView.findViewById(R.id.button_toggle_content); } @Override @@ -71,6 +81,7 @@ public class StatusViewHolder extends StatusBaseViewHolder { showContent(false); } else { showContent(true); + setupCollapsedState(status, listener); super.setupWithStatus(status, listener, mediaPreviewEnabled); String rebloggedByDisplayName = status.getRebloggedByUsername(); @@ -80,14 +91,13 @@ public class StatusViewHolder extends StatusBaseViewHolder { setRebloggedByDisplayName(rebloggedByDisplayName); } - // I think it's not efficient to create new object every time we bind a holder. - // More efficient approach would be creating View.OnClickListener during holder creation - // and storing StatusActionListener in a variable after binding. rebloggedBar.setOnClickListener(v -> listener.onOpenReblog(getAdapterPosition())); + } + } - private void setRebloggedByDisplayName(String name) { + private void setRebloggedByDisplayName(final String name) { Context context = rebloggedBar.getContext(); String boostedText = context.getString(R.string.status_boosted_format, name); rebloggedBar.setText(boostedText); @@ -100,4 +110,27 @@ public class StatusViewHolder extends StatusBaseViewHolder { } rebloggedBar.setVisibility(View.GONE); } + + private void setupCollapsedState(final StatusViewData.Concrete status, final StatusActionListener listener) { + /* input filter for TextViews have to be set before text */ + if (status.isCollapsible() && (status.isExpanded() || status.getSpoilerText() == null || status.getSpoilerText().isEmpty())) { + contentCollapseButton.setOnCheckedChangeListener((buttonView, isChecked) -> { + int position = getAdapterPosition(); + if (position != RecyclerView.NO_POSITION) + listener.onContentCollapsedChange(isChecked, position); + }); + + contentCollapseButton.setVisibility(View.VISIBLE); + if (status.isCollapsed()) { + contentCollapseButton.setChecked(true); + content.setFilters(COLLAPSE_INPUT_FILTER); + } else { + contentCollapseButton.setChecked(false); + content.setFilters(NO_INPUT_FILTER); + } + } else { + contentCollapseButton.setVisibility(View.GONE); + content.setFilters(NO_INPUT_FILTER); + } + } } \ No newline at end of file