cleanup code in StatusViewHolders (#1418)

* cleanup code in status ViewHolder

* add check for reblogButton back in
This commit is contained in:
Konrad Pozniak 2019-07-27 21:53:28 +02:00 committed by GitHub
parent 57edf86495
commit 588775ff9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 125 additions and 185 deletions

View File

@ -40,7 +40,7 @@ import com.keylesspalace.tusky.entity.Notification;
import com.keylesspalace.tusky.interfaces.LinkListener; import com.keylesspalace.tusky.interfaces.LinkListener;
import com.keylesspalace.tusky.interfaces.StatusActionListener; import com.keylesspalace.tusky.interfaces.StatusActionListener;
import com.keylesspalace.tusky.util.CustomEmojiHelper; import com.keylesspalace.tusky.util.CustomEmojiHelper;
import com.keylesspalace.tusky.util.DateUtils; import com.keylesspalace.tusky.util.TimestampUtils;
import com.keylesspalace.tusky.util.ImageLoadingHelper; import com.keylesspalace.tusky.util.ImageLoadingHelper;
import com.keylesspalace.tusky.util.LinkHelper; import com.keylesspalace.tusky.util.LinkHelper;
import com.keylesspalace.tusky.util.SmartLengthInputFilter; import com.keylesspalace.tusky.util.SmartLengthInputFilter;
@ -435,7 +435,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
if (createdAt != null) { if (createdAt != null) {
long then = createdAt.getTime(); long then = createdAt.getTime();
long now = new Date().getTime(); long now = new Date().getTime();
readout = DateUtils.getRelativeTimeSpanString(timestampInfo.getContext(), then, now); readout = TimestampUtils.getRelativeTimeSpanString(timestampInfo.getContext(), then, now);
readoutAloud = android.text.format.DateUtils.getRelativeTimeSpanString(then, now, readoutAloud = android.text.format.DateUtils.getRelativeTimeSpanString(then, now,
android.text.format.DateUtils.SECOND_IN_MILLIS, android.text.format.DateUtils.SECOND_IN_MILLIS,
android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE); android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE);

View File

@ -4,8 +4,8 @@ import android.content.Context;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.DateUtils;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
@ -29,7 +29,7 @@ import com.keylesspalace.tusky.entity.Emoji;
import com.keylesspalace.tusky.entity.Status; import com.keylesspalace.tusky.entity.Status;
import com.keylesspalace.tusky.interfaces.StatusActionListener; import com.keylesspalace.tusky.interfaces.StatusActionListener;
import com.keylesspalace.tusky.util.CustomEmojiHelper; import com.keylesspalace.tusky.util.CustomEmojiHelper;
import com.keylesspalace.tusky.util.DateUtils; import com.keylesspalace.tusky.util.TimestampUtils;
import com.keylesspalace.tusky.util.HtmlUtils; import com.keylesspalace.tusky.util.HtmlUtils;
import com.keylesspalace.tusky.util.ImageLoadingHelper; import com.keylesspalace.tusky.util.ImageLoadingHelper;
import com.keylesspalace.tusky.util.LinkHelper; import com.keylesspalace.tusky.util.LinkHelper;
@ -63,8 +63,6 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
private SparkButton reblogButton; private SparkButton reblogButton;
private SparkButton favouriteButton; private SparkButton favouriteButton;
private ImageButton moreButton; private ImageButton moreButton;
private boolean favourited;
private boolean reblogged;
protected MediaPreviewImageView[] mediaPreviews; protected MediaPreviewImageView[] mediaPreviews;
private ImageView[] mediaOverlays; private ImageView[] mediaOverlays;
private TextView sensitiveMediaWarning; private TextView sensitiveMediaWarning;
@ -122,10 +120,10 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
sensitiveMediaWarning = itemView.findViewById(R.id.status_sensitive_media_warning); sensitiveMediaWarning = itemView.findViewById(R.id.status_sensitive_media_warning);
sensitiveMediaShow = itemView.findViewById(R.id.status_sensitive_media_button); sensitiveMediaShow = itemView.findViewById(R.id.status_sensitive_media_button);
mediaLabels = new TextView[]{ mediaLabels = new TextView[]{
itemView.findViewById(R.id.status_media_label_0),
itemView.findViewById(R.id.status_media_label_1), itemView.findViewById(R.id.status_media_label_1),
itemView.findViewById(R.id.status_media_label_2), itemView.findViewById(R.id.status_media_label_2),
itemView.findViewById(R.id.status_media_label_3), itemView.findViewById(R.id.status_media_label_3)
itemView.findViewById(R.id.status_media_label_4)
}; };
contentWarningDescription = itemView.findViewById(R.id.status_content_warning_description); contentWarningDescription = itemView.findViewById(R.id.status_content_warning_description);
contentWarningButton = itemView.findViewById(R.id.status_content_warning_button); contentWarningButton = itemView.findViewById(R.id.status_content_warning_button);
@ -141,8 +139,8 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
((DefaultItemAnimator) pollOptions.getItemAnimator()).setSupportsChangeAnimations(false); ((DefaultItemAnimator) pollOptions.getItemAnimator()).setSupportsChangeAnimations(false);
this.useAbsoluteTime = useAbsoluteTime; this.useAbsoluteTime = useAbsoluteTime;
shortSdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault()); this.shortSdf = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
longSdf = new SimpleDateFormat("MM/dd HH:mm:ss", Locale.getDefault()); this.longSdf = new SimpleDateFormat("MM/dd HH:mm:ss", Locale.getDefault());
this.avatarRadius48dp = itemView.getContext().getResources().getDimensionPixelSize(R.dimen.avatar_radius_48dp); this.avatarRadius48dp = itemView.getContext().getResources().getDimensionPixelSize(R.dimen.avatar_radius_48dp);
this.avatarRadius36dp = itemView.getContext().getResources().getDimensionPixelSize(R.dimen.avatar_radius_36dp); this.avatarRadius36dp = itemView.getContext().getResources().getDimensionPixelSize(R.dimen.avatar_radius_36dp);
@ -158,8 +156,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
protected void setUsername(String name) { protected void setUsername(String name) {
Context context = username.getContext(); Context context = username.getContext();
String format = context.getString(R.string.status_username_format); String usernameText = context.getString(R.string.status_username_format, name);
String usernameText = String.format(format, name);
username.setText(usernameText); username.setText(usernameText);
} }
@ -184,7 +181,6 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
contentWarningButton.setVisibility(View.VISIBLE); contentWarningButton.setVisibility(View.VISIBLE);
contentWarningButton.setChecked(expanded); contentWarningButton.setChecked(expanded);
contentWarningButton.setOnCheckedChangeListener((buttonView, isChecked) -> { contentWarningButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
contentWarningDescription.invalidate();
if (getAdapterPosition() != RecyclerView.NO_POSITION) { if (getAdapterPosition() != RecyclerView.NO_POSITION) {
listener.onExpandedChange(isChecked, getAdapterPosition()); listener.onExpandedChange(isChecked, getAdapterPosition());
} }
@ -250,64 +246,37 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} }
protected void setCreatedAt(@Nullable Date createdAt) { protected void setCreatedAt(@NonNull Date createdAt) {
if (useAbsoluteTime) { if (useAbsoluteTime) {
timestampInfo.setText(getAbsoluteTime(createdAt)); timestampInfo.setText(getAbsoluteTime(createdAt));
} else { } else {
String readout; long then = createdAt.getTime();
if (createdAt != null) { long now = System.currentTimeMillis();
long then = createdAt.getTime(); String readout = TimestampUtils.getRelativeTimeSpanString(timestampInfo.getContext(), then, now);
long now = new Date().getTime();
readout = DateUtils.getRelativeTimeSpanString(timestampInfo.getContext(), then, now);
} else {
// unknown minutes~
readout = "?m";
}
timestampInfo.setText(readout); timestampInfo.setText(readout);
} }
} }
private String getAbsoluteTime(@Nullable Date createdAt) { private String getAbsoluteTime(@NonNull Date createdAt) {
String time; if (DateUtils.isToday(createdAt.getTime())) {
if (createdAt != null) { return shortSdf.format(createdAt);
if (android.text.format.DateUtils.isToday(createdAt.getTime())) {
time = shortSdf.format(createdAt);
} else {
time = longSdf.format(createdAt);
}
} else { } else {
time = "??:??:??"; return longSdf.format(createdAt);
} }
return time;
} }
private CharSequence getCreatedAtDescription(@Nullable Date createdAt) { private CharSequence getCreatedAtDescription(@NonNull Date createdAt) {
if (useAbsoluteTime) { if (useAbsoluteTime) {
return getAbsoluteTime(createdAt); return getAbsoluteTime(createdAt);
} else { } else {
/* This one is for screen-readers. Frequently, they would mispronounce timestamps like "17m" /* This one is for screen-readers. Frequently, they would mispronounce timestamps like "17m"
* as 17 meters instead of minutes. */ * as 17 meters instead of minutes. */
if (createdAt != null) { long then = createdAt.getTime();
long then = createdAt.getTime(); long now = System.currentTimeMillis();
long now = new Date().getTime(); return DateUtils.getRelativeTimeSpanString(then, now,
return android.text.format.DateUtils.getRelativeTimeSpanString(then, now, DateUtils.SECOND_IN_MILLIS,
android.text.format.DateUtils.SECOND_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE);
android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE);
} else {
// unknown minutes~
return "? minutes";
}
}
}
protected void showContent(boolean show) {
if (show) {
itemView.setVisibility(View.VISIBLE);
itemView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
} else {
itemView.setVisibility(View.INVISIBLE);
itemView.getLayoutParams().height = Utils.convertDpToPx(itemView.getContext(), 24);
} }
} }
@ -321,7 +290,6 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} }
private void setReblogged(boolean reblogged) { private void setReblogged(boolean reblogged) {
this.reblogged = reblogged;
reblogButton.setChecked(reblogged); reblogButton.setChecked(reblogged);
} }
@ -358,7 +326,6 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} }
protected void setFavourited(boolean favourited) { protected void setFavourited(boolean favourited) {
this.favourited = favourited;
favouriteButton.setChecked(favourited); favouriteButton.setChecked(favourited);
} }
@ -423,18 +390,20 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
setAttachmentClickListener(mediaPreviews[i], listener, i, attachments.get(i), true); setAttachmentClickListener(mediaPreviews[i], listener, i, attachments.get(i), true);
final int mediaPreviewHeight = getMediaPreviewHeight(context);
if (n <= 2) { if (n <= 2) {
mediaPreviews[0].getLayoutParams().height = getMediaPreviewHeight(context) * 2; mediaPreviews[0].getLayoutParams().height = mediaPreviewHeight * 2;
mediaPreviews[1].getLayoutParams().height = getMediaPreviewHeight(context) * 2; mediaPreviews[1].getLayoutParams().height = mediaPreviewHeight * 2;
} else { } else {
mediaPreviews[0].getLayoutParams().height = getMediaPreviewHeight(context); mediaPreviews[0].getLayoutParams().height = mediaPreviewHeight;
mediaPreviews[1].getLayoutParams().height = getMediaPreviewHeight(context); mediaPreviews[1].getLayoutParams().height = mediaPreviewHeight;
mediaPreviews[2].getLayoutParams().height = getMediaPreviewHeight(context); mediaPreviews[2].getLayoutParams().height = mediaPreviewHeight;
mediaPreviews[3].getLayoutParams().height = getMediaPreviewHeight(context); mediaPreviews[3].getLayoutParams().height = mediaPreviewHeight;
} }
} }
String hiddenContentText; final String hiddenContentText;
if (sensitive) { if (sensitive) {
hiddenContentText = context.getString(R.string.status_sensitive_media_template, hiddenContentText = context.getString(R.string.status_sensitive_media_template,
context.getString(R.string.status_sensitive_media_title), context.getString(R.string.status_sensitive_media_title),
@ -514,8 +483,9 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
private void setAttachmentClickListener(View view, StatusActionListener listener, private void setAttachmentClickListener(View view, StatusActionListener listener,
int index, Attachment attachment, boolean animateTransition) { int index, Attachment attachment, boolean animateTransition) {
view.setOnClickListener(v -> { view.setOnClickListener(v -> {
if (getAdapterPosition() != RecyclerView.NO_POSITION) { int position = getAdapterPosition();
listener.onViewMedia(getAdapterPosition(), index, animateTransition ? v : null); if (position != RecyclerView.NO_POSITION) {
listener.onViewMedia(position, index, animateTransition ? v : null);
} }
}); });
view.setOnLongClickListener(v -> { view.setOnLongClickListener(v -> {
@ -525,7 +495,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
}); });
} }
private CharSequence getAttachmentDescription(Context context, Attachment attachment) { private static CharSequence getAttachmentDescription(Context context, Attachment attachment) {
if (TextUtils.isEmpty(attachment.getDescription())) { if (TextUtils.isEmpty(attachment.getDescription())) {
return context return context
.getString(R.string.description_status_media_no_description_placeholder); .getString(R.string.description_status_media_no_description_placeholder);
@ -540,10 +510,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} }
protected void setupButtons(final StatusActionListener listener, final String accountId) { protected void setupButtons(final StatusActionListener listener, final String accountId) {
/* Originally position was passed through to all these listeners, but it caused several
* bugs where other statuses in the list would be removed or added and cause the position
* here to become outdated. So, getting the adapter position at the time the listener is
* actually called is the appropriate solution. */
avatar.setOnClickListener(v -> listener.onViewAccount(accountId)); avatar.setOnClickListener(v -> listener.onViewAccount(accountId));
replyButton.setOnClickListener(v -> { replyButton.setOnClickListener(v -> {
int position = getAdapterPosition(); int position = getAdapterPosition();
@ -551,13 +518,13 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
listener.onReply(position); listener.onReply(position);
} }
}); });
if (reblogButton != null) { if(reblogButton != null) {
reblogButton.setEventListener(new SparkEventListener() { reblogButton.setEventListener(new SparkEventListener() {
@Override @Override
public void onEvent(ImageView button, boolean buttonState) { public void onEvent(ImageView button, boolean buttonState) {
int position = getAdapterPosition(); int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) { if (position != RecyclerView.NO_POSITION) {
listener.onReblog(!reblogged, position); listener.onReblog(buttonState, position);
} }
} }
@ -570,12 +537,13 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} }
}); });
} }
favouriteButton.setEventListener(new SparkEventListener() { favouriteButton.setEventListener(new SparkEventListener() {
@Override @Override
public void onEvent(ImageView button, boolean buttonState) { public void onEvent(ImageView button, boolean buttonState) {
int position = getAdapterPosition(); int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) { if (position != RecyclerView.NO_POSITION) {
listener.onFavourite(!favourited, position); listener.onFavourite(buttonState, position);
} }
} }
@ -608,7 +576,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} }
public void setupWithStatus(StatusViewData.Concrete status, final StatusActionListener listener, public void setupWithStatus(StatusViewData.Concrete status, final StatusActionListener listener,
boolean mediaPreviewEnabled, boolean showBotOverlay, boolean animateAvatar) { boolean mediaPreviewEnabled, boolean showBotOverlay, boolean animateAvatar) {
this.setupWithStatus(status, listener, mediaPreviewEnabled, showBotOverlay, animateAvatar, null); this.setupWithStatus(status, listener, mediaPreviewEnabled, showBotOverlay, animateAvatar, null);
} }
@ -653,7 +621,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
setSpoilerAndContent(status.isExpanded(), status.getContent(), status.getSpoilerText(), status.getMentions(), status.getStatusEmojis(), listener); setSpoilerAndContent(status.isExpanded(), status.getContent(), status.getSpoilerText(), status.getMentions(), status.getStatusEmojis(), listener);
setContentDescription(status); setDescriptionForStatus(status);
setupPoll(status.getPoll(),status.getStatusEmojis(), listener); setupPoll(status.getPoll(),status.getStatusEmojis(), listener);
@ -674,17 +642,6 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} }
} }
private void setContentDescription(@Nullable StatusViewData.Concrete status) {
if (status == null) {
itemView.setContentDescription(
itemView.getContext().getString(R.string.load_more_placeholder_text));
} else {
setDescriptionForStatus(status);
}
}
private void setDescriptionForStatus(@NonNull StatusViewData.Concrete status) { private void setDescriptionForStatus(@NonNull StatusViewData.Concrete status) {
Context context = itemView.getContext(); Context context = itemView.getContext();
@ -706,21 +663,19 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
itemView.setContentDescription(description); itemView.setContentDescription(description);
} }
private CharSequence getReblogDescription(Context context, private static CharSequence getReblogDescription(Context context,
@NonNull StatusViewData.Concrete status) { @NonNull StatusViewData.Concrete status) {
CharSequence reblogDescriontion;
String rebloggedUsername = status.getRebloggedByUsername(); String rebloggedUsername = status.getRebloggedByUsername();
if (rebloggedUsername != null) { if (rebloggedUsername != null) {
reblogDescriontion = context return context
.getString(R.string.status_boosted_format, rebloggedUsername); .getString(R.string.status_boosted_format, rebloggedUsername);
} else { } else {
reblogDescriontion = ""; return "";
} }
return reblogDescriontion;
} }
private CharSequence getMediaDescription(Context context, private static CharSequence getMediaDescription(Context context,
@NonNull StatusViewData.Concrete status) { @NonNull StatusViewData.Concrete status) {
if (status.getAttachments().isEmpty()) { if (status.getAttachments().isEmpty()) {
return ""; return "";
} }
@ -740,8 +695,8 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
return context.getString(R.string.description_status_media, mediaDescriptions); return context.getString(R.string.description_status_media, mediaDescriptions);
} }
private CharSequence getContentWarningDescription(Context context, private static CharSequence getContentWarningDescription(Context context,
@NonNull StatusViewData.Concrete status) { @NonNull StatusViewData.Concrete status) {
if (!TextUtils.isEmpty(status.getSpoilerText())) { if (!TextUtils.isEmpty(status.getSpoilerText())) {
return context.getString(R.string.description_status_cw, status.getSpoilerText()); return context.getString(R.string.description_status_cw, status.getSpoilerText());
} else { } else {
@ -749,10 +704,8 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
} }
} }
private CharSequence getVisibilityDescription(Context context, Status.Visibility visibility) { private static CharSequence getVisibilityDescription(Context context, Status.Visibility visibility) {
if (visibility == null) {
return "";
}
int resource; int resource;
switch (visibility) { switch (visibility) {
case PUBLIC: case PUBLIC:
@ -878,7 +831,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
if (useAbsoluteTime) { if (useAbsoluteTime) {
pollDurationInfo = context.getString(R.string.poll_info_time_absolute, getAbsoluteTime(poll.getExpiresAt())); pollDurationInfo = context.getString(R.string.poll_info_time_absolute, getAbsoluteTime(poll.getExpiresAt()));
} else { } else {
String pollDuration = DateUtils.formatPollDuration(pollDescription.getContext(), poll.getExpiresAt().getTime(), timestamp); String pollDuration = TimestampUtils.formatPollDuration(pollDescription.getContext(), poll.getExpiresAt().getTime(), timestamp);
pollDurationInfo = context.getString(R.string.poll_info_time_relative, pollDuration); pollDurationInfo = context.getString(R.string.poll_info_time_relative, pollDuration);
} }
} }

View File

@ -29,6 +29,7 @@ import com.keylesspalace.tusky.viewdata.StatusViewData;
import java.text.DateFormat; import java.text.DateFormat;
import java.util.Date; import java.util.Date;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -66,13 +67,9 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
} }
@Override @Override
protected void setCreatedAt(@Nullable Date createdAt) { protected void setCreatedAt(@NonNull Date createdAt) {
if (createdAt != null) { DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT);
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT); timestampInfo.setText(dateFormat.format(createdAt));
timestampInfo.setText(dateFormat.format(createdAt));
} else {
timestampInfo.setText("");
}
} }
private void setReblogAndFavCount(int reblogCount, int favCount, StatusActionListener listener) { private void setReblogAndFavCount(int reblogCount, int favCount, StatusActionListener listener) {
@ -138,7 +135,6 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
setApplication(status.getApplication()); setApplication(status.getApplication());
View.OnLongClickListener longClickListener = view -> { View.OnLongClickListener longClickListener = view -> {
TextView textView = (TextView) view; TextView textView = (TextView) view;
ClipboardManager clipboard = (ClipboardManager) view.getContext().getSystemService(Context.CLIPBOARD_SERVICE); ClipboardManager clipboard = (ClipboardManager) view.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
@ -224,9 +220,6 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
} }
private void setStatusVisibility(Status.Visibility visibility) { private void setStatusVisibility(Status.Visibility visibility) {
if (visibility == null || this.timestampInfo == null) {
return;
}
int visibilityIcon; int visibilityIcon;
switch (visibility) { switch (visibility) {
@ -260,7 +253,7 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
size size
); );
visibilityDrawable.setTint(this.timestampInfo.getCurrentTextColor()); visibilityDrawable.setTint(this.timestampInfo.getCurrentTextColor());
this.timestampInfo.setCompoundDrawables( this.timestampInfo.setCompoundDrawablesWithIntrinsicBounds(
visibilityDrawable, visibilityDrawable,
null, null,
null, null,

View File

@ -17,6 +17,7 @@ package com.keylesspalace.tusky.adapter;
import android.content.Context; import android.content.Context;
import android.text.InputFilter; import android.text.InputFilter;
import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import android.widget.ToggleButton; import android.widget.ToggleButton;
@ -53,26 +54,21 @@ public class StatusViewHolder extends StatusBaseViewHolder {
protected void setupWithStatus(StatusViewData.Concrete status, final StatusActionListener listener, protected void setupWithStatus(StatusViewData.Concrete status, final StatusActionListener listener,
boolean mediaPreviewEnabled, boolean showBotOverlay, boolean animateAvatar, boolean mediaPreviewEnabled, boolean showBotOverlay, boolean animateAvatar,
@Nullable Object payloads) { @Nullable Object payloads) {
if (status == null || payloads == null) { if (payloads == null) {
if (status == null) {
showContent(false); setupCollapsedState(status, listener);
String rebloggedByDisplayName = status.getRebloggedByUsername();
if (rebloggedByDisplayName == null) {
hideStatusInfo();
} else { } else {
showContent(true); setRebloggedByDisplayName(rebloggedByDisplayName);
setupCollapsedState(status, listener); statusInfo.setOnClickListener(v -> listener.onOpenReblog(getAdapterPosition()));
super.setupWithStatus(status, listener, mediaPreviewEnabled, showBotOverlay, animateAvatar, null);
String rebloggedByDisplayName = status.getRebloggedByUsername();
if (rebloggedByDisplayName == null) {
hideStatusInfo();
} else {
setRebloggedByDisplayName(rebloggedByDisplayName);
statusInfo.setOnClickListener(v -> listener.onOpenReblog(getAdapterPosition()));
}
} }
} else {
super.setupWithStatus(status, listener, mediaPreviewEnabled, showBotOverlay, animateAvatar, payloads);
} }
super.setupWithStatus(status, listener, mediaPreviewEnabled, showBotOverlay, animateAvatar, payloads);
} }
private void setRebloggedByDisplayName(final String name) { private void setRebloggedByDisplayName(final String name) {
@ -92,15 +88,12 @@ public class StatusViewHolder extends StatusBaseViewHolder {
} }
void hideStatusInfo() { void hideStatusInfo() {
if (statusInfo == null) {
return;
}
statusInfo.setVisibility(View.GONE); statusInfo.setVisibility(View.GONE);
} }
private void setupCollapsedState(final StatusViewData.Concrete status, final StatusActionListener listener) { private void setupCollapsedState(final StatusViewData.Concrete status, final StatusActionListener listener) {
/* input filter for TextViews have to be set before text */ /* input filter for TextViews have to be set before text */
if (status.isCollapsible() && (status.isExpanded() || status.getSpoilerText() == null || status.getSpoilerText().isEmpty())) { if (status.isCollapsible() && (status.isExpanded() || TextUtils.isEmpty(status.getSpoilerText()))) {
contentCollapseButton.setOnCheckedChangeListener((buttonView, isChecked) -> { contentCollapseButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
int position = getAdapterPosition(); int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) if (position != RecyclerView.NO_POSITION)

View File

@ -26,7 +26,6 @@ import android.widget.ToggleButton;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.R;
import com.keylesspalace.tusky.adapter.StatusBaseViewHolder; import com.keylesspalace.tusky.adapter.StatusBaseViewHolder;
import com.keylesspalace.tusky.entity.Attachment; import com.keylesspalace.tusky.entity.Attachment;
@ -56,7 +55,11 @@ public class ConversationViewHolder extends StatusBaseViewHolder {
super(itemView, useAbsoluteTime); super(itemView, useAbsoluteTime);
conversationNameTextView = itemView.findViewById(R.id.conversation_name); conversationNameTextView = itemView.findViewById(R.id.conversation_name);
contentCollapseButton = itemView.findViewById(R.id.button_toggle_content); contentCollapseButton = itemView.findViewById(R.id.button_toggle_content);
avatars = new ImageView[]{avatar, itemView.findViewById(R.id.status_avatar_1), itemView.findViewById(R.id.status_avatar_2)}; avatars = new ImageView[]{
avatar,
itemView.findViewById(R.id.status_avatar_1),
itemView.findViewById(R.id.status_avatar_2)
};
this.listener = listener; this.listener = listener;
this.mediaPreviewEnabled = mediaPreviewEnabled; this.mediaPreviewEnabled = mediaPreviewEnabled;

View File

@ -130,7 +130,7 @@ class StatusViewHolder(itemView: View,
itemView.timestampInfo.text = if (createdAt != null) { itemView.timestampInfo.text = if (createdAt != null) {
val then = createdAt.time val then = createdAt.time
val now = System.currentTimeMillis() val now = System.currentTimeMillis()
DateUtils.getRelativeTimeSpanString(itemView.timestampInfo.context, then, now) TimestampUtils.getRelativeTimeSpanString(itemView.timestampInfo.context, then, now)
} else { } else {
// unknown minutes~ // unknown minutes~
"?m" "?m"

View File

@ -129,7 +129,6 @@ public class LinkHelper {
} }
view.setText(builder); view.setText(builder);
view.setLinksClickable(true);
view.setMovementMethod(LinkMovementMethod.getInstance()); view.setMovementMethod(LinkMovementMethod.getInstance());
} }
@ -177,7 +176,6 @@ public class LinkHelper {
start = end; start = end;
} }
view.setText(builder); view.setText(builder);
view.setLinksClickable(true);
view.setMovementMethod(LinkMovementMethod.getInstance()); view.setMovementMethod(LinkMovementMethod.getInstance());
} }
@ -210,7 +208,7 @@ public class LinkHelper {
try { try {
context.startActivity(intent); context.startActivity(intent);
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
Log.w("LinkHelper", "Actvity was not found for intent, " + intent.toString()); Log.w("LinkHelper", "Actvity was not found for intent, " + intent);
} }
} }
@ -231,7 +229,7 @@ public class LinkHelper {
try { try {
customTabsIntent.launchUrl(context, uri); customTabsIntent.launchUrl(context, uri);
} catch (ActivityNotFoundException e) { } catch (ActivityNotFoundException e) {
Log.w("LinkHelper", "Activity was not found for intent " + customTabsIntent.toString()); Log.w("LinkHelper", "Activity was not found for intent " + customTabsIntent);
openLinkInBrowser(uri, context); openLinkInBrowser(uri, context);
} }

View File

@ -267,7 +267,7 @@ class StatusViewHelper(private val itemView: View) {
if (useAbsoluteTime) { if (useAbsoluteTime) {
pollDurationInfo = context.getString(R.string.poll_info_time_absolute, getAbsoluteTime(poll.expiresAt)) pollDurationInfo = context.getString(R.string.poll_info_time_absolute, getAbsoluteTime(poll.expiresAt))
} else { } else {
val pollDuration = DateUtils.formatPollDuration(context, poll.expiresAt!!.time, timestamp) val pollDuration = TimestampUtils.formatPollDuration(context, poll.expiresAt!!.time, timestamp)
pollDurationInfo = context.getString(R.string.poll_info_time_relative, pollDuration) pollDurationInfo = context.getString(R.string.poll_info_time_relative, pollDuration)
} }
} }

View File

@ -19,7 +19,7 @@ import android.content.Context;
import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.R;
public class DateUtils { public class TimestampUtils {
private static final long SECOND_IN_MILLIS = 1000; private static final long SECOND_IN_MILLIS = 1000;
private static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60; private static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;

View File

@ -329,7 +329,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/status_media_label_1" android:id="@+id/status_media_label_0"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
@ -341,6 +341,19 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/status_media_label_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_0" />
<TextView <TextView
android:id="@+id/status_media_label_2" android:id="@+id/status_media_label_2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -367,19 +380,6 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_2" /> app:layout_constraintTop_toBottomOf="@id/status_media_label_2" />
<TextView
android:id="@+id/status_media_label_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_3" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -314,7 +314,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/status_media_label_1" android:id="@+id/status_media_label_0"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
@ -326,6 +326,19 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/status_media_label_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_0" />
<TextView <TextView
android:id="@+id/status_media_label_2" android:id="@+id/status_media_label_2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -352,19 +365,6 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_2" /> app:layout_constraintTop_toBottomOf="@id/status_media_label_2" />
<TextView
android:id="@+id/status_media_label_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_3" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView

View File

@ -328,7 +328,7 @@
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/status_media_label_1" android:id="@+id/status_media_label_0"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
@ -340,6 +340,19 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/status_media_label_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_0" />
<TextView <TextView
android:id="@+id/status_media_label_2" android:id="@+id/status_media_label_2"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -366,19 +379,6 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_2" /> app:layout_constraintTop_toBottomOf="@id/status_media_label_2" />
<TextView
android:id="@+id/status_media_label_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:drawablePadding="4dp"
android:gravity="center_vertical"
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_3" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>