show status edits (#3049)
* show status edits part 1 * show status edits part 2 - load status edits * fix code formatting * add dialog to show status edits * small improvements * use ALIGN_CENTER to position status visibility icon when possible * rename status_timestamp_info view to status_meta_info * make dateFormat static * remove commented-out code * move edits to dedicated fragment
This commit is contained in:
parent
8c0f02cf33
commit
61a45ae376
26 changed files with 731 additions and 75 deletions
|
|
@ -2,13 +2,18 @@ package com.keylesspalace.tusky.adapter;
|
|||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextUtils;
|
||||
import android.os.Build;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.text.style.DynamicDrawableSpan;
|
||||
import android.text.style.ImageSpan;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.keylesspalace.tusky.R;
|
||||
|
|
@ -16,19 +21,20 @@ import com.keylesspalace.tusky.entity.Status;
|
|||
import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
||||
import com.keylesspalace.tusky.util.CardViewMode;
|
||||
import com.keylesspalace.tusky.util.LinkHelper;
|
||||
import com.keylesspalace.tusky.util.NoUnderlineURLSpan;
|
||||
import com.keylesspalace.tusky.util.StatusDisplayOptions;
|
||||
import com.keylesspalace.tusky.viewdata.StatusViewData;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
||||
private final TextView reblogs;
|
||||
private final TextView favourites;
|
||||
private final View infoDivider;
|
||||
|
||||
private static final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT);
|
||||
|
||||
public StatusDetailedViewHolder(View view) {
|
||||
super(view);
|
||||
reblogs = view.findViewById(R.id.status_reblogs);
|
||||
|
|
@ -37,17 +43,74 @@ public class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void setCreatedAt(Date createdAt, Date editedAt, StatusDisplayOptions statusDisplayOptions) {
|
||||
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT);
|
||||
Context context = timestampInfo.getContext();
|
||||
List<String> list = new ArrayList<>();
|
||||
protected void setMetaData(StatusViewData.Concrete statusViewData, StatusDisplayOptions statusDisplayOptions, StatusActionListener listener) {
|
||||
|
||||
Status status = statusViewData.getActionable();
|
||||
|
||||
Status.Visibility visibility = status.getVisibility();
|
||||
Context context = metaInfo.getContext();
|
||||
|
||||
Drawable visibilityIcon = getVisibilityIcon(visibility);
|
||||
CharSequence visibilityString = getVisibilityDescription(context, visibility);
|
||||
|
||||
SpannableStringBuilder sb = new SpannableStringBuilder(visibilityString);
|
||||
|
||||
if (visibilityIcon != null) {
|
||||
ImageSpan visibilityIconSpan = new ImageSpan(
|
||||
visibilityIcon,
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ? DynamicDrawableSpan.ALIGN_CENTER : DynamicDrawableSpan.ALIGN_BASELINE
|
||||
);
|
||||
sb.setSpan(visibilityIconSpan, 0, visibilityString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
String metadataJoiner = context.getString(R.string.metadata_joiner);
|
||||
|
||||
Date createdAt = status.getCreatedAt();
|
||||
if (createdAt != null) {
|
||||
list.add(dateFormat.format(createdAt));
|
||||
|
||||
sb.append(" ");
|
||||
sb.append(dateFormat.format(createdAt));
|
||||
}
|
||||
|
||||
Date editedAt = status.getEditedAt();
|
||||
|
||||
if (editedAt != null) {
|
||||
list.add(context.getString(R.string.post_edited, dateFormat.format(editedAt)));
|
||||
String editedAtString = context.getString(R.string.post_edited, dateFormat.format(editedAt));
|
||||
|
||||
sb.append(metadataJoiner);
|
||||
int spanStart = sb.length();
|
||||
int spanEnd = spanStart + editedAtString.length();
|
||||
|
||||
sb.append(editedAtString);
|
||||
|
||||
if (statusViewData.getStatus().getEditedAt() != null) {
|
||||
NoUnderlineURLSpan editedClickSpan = new NoUnderlineURLSpan("") {
|
||||
@Override
|
||||
public void onClick(@NonNull View view) {
|
||||
listener.onShowEdits(getBindingAdapterPosition());
|
||||
}
|
||||
};
|
||||
|
||||
sb.setSpan(editedClickSpan, spanStart, spanEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
timestampInfo.setText(TextUtils.join(context.getString(R.string.timestamp_joiner), list));
|
||||
|
||||
Status.Application app = status.getApplication();
|
||||
|
||||
if (app != null) {
|
||||
|
||||
sb.append(metadataJoiner);
|
||||
|
||||
if (app.getWebsite() != null) {
|
||||
CharSequence text = LinkHelper.createClickableText(app.getName(), app.getWebsite());
|
||||
sb.append(text);
|
||||
} else {
|
||||
sb.append(app.getName());
|
||||
}
|
||||
}
|
||||
|
||||
metaInfo.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
metaInfo.setText(sb);
|
||||
}
|
||||
|
||||
private void setReblogAndFavCount(int reblogCount, int favCount, StatusActionListener listener) {
|
||||
|
|
@ -85,21 +148,6 @@ public class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
|||
});
|
||||
}
|
||||
|
||||
private void setApplication(@Nullable Status.Application app) {
|
||||
if (app != null) {
|
||||
|
||||
timestampInfo.append(" • ");
|
||||
|
||||
if (app.getWebsite() != null) {
|
||||
CharSequence text = LinkHelper.createClickableText(app.getName(), app.getWebsite());
|
||||
timestampInfo.append(text);
|
||||
timestampInfo.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
} else {
|
||||
timestampInfo.append(app.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupWithStatus(@NonNull final StatusViewData.Concrete status,
|
||||
@NonNull final StatusActionListener listener,
|
||||
|
|
@ -107,8 +155,8 @@ public class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
|||
@Nullable Object payloads) {
|
||||
// We never collapse statuses in the detail view
|
||||
StatusViewData.Concrete uncollapsedStatus = (status.isCollapsible() && status.isCollapsed()) ?
|
||||
status.copyWithCollapsed(false) :
|
||||
status;
|
||||
status.copyWithCollapsed(false) :
|
||||
status;
|
||||
|
||||
super.setupWithStatus(uncollapsedStatus, listener, statusDisplayOptions, payloads);
|
||||
setupCard(uncollapsedStatus, CardViewMode.FULL_WIDTH, statusDisplayOptions, listener); // Always show card for detailed status
|
||||
|
|
@ -121,17 +169,13 @@ public class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
|||
} else {
|
||||
hideQuantitativeStats();
|
||||
}
|
||||
|
||||
setApplication(actionable.getApplication());
|
||||
|
||||
setStatusVisibility(actionable.getVisibility());
|
||||
}
|
||||
}
|
||||
|
||||
private void setStatusVisibility(Status.Visibility visibility) {
|
||||
private @Nullable Drawable getVisibilityIcon(@Nullable Status.Visibility visibility) {
|
||||
|
||||
if (visibility == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
int visibilityIcon;
|
||||
|
|
@ -149,29 +193,26 @@ public class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
|||
visibilityIcon = R.drawable.ic_email_24dp;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
final Drawable visibilityDrawable = this.timestampInfo.getContext()
|
||||
.getDrawable(visibilityIcon);
|
||||
final Drawable visibilityDrawable = AppCompatResources.getDrawable(
|
||||
this.metaInfo.getContext(), visibilityIcon
|
||||
);
|
||||
if (visibilityDrawable == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
final int size = (int) this.timestampInfo.getTextSize();
|
||||
final int size = (int) this.metaInfo.getTextSize();
|
||||
visibilityDrawable.setBounds(
|
||||
0,
|
||||
0,
|
||||
size,
|
||||
size
|
||||
);
|
||||
visibilityDrawable.setTint(this.timestampInfo.getCurrentTextColor());
|
||||
this.timestampInfo.setCompoundDrawables(
|
||||
visibilityDrawable,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
visibilityDrawable.setTint(this.metaInfo.getCurrentTextColor());
|
||||
|
||||
return visibilityDrawable;
|
||||
}
|
||||
|
||||
private void hideQuantitativeStats() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue