2017-08-03 23:26:26 +02:00
|
|
|
package com.keylesspalace.tusky.adapter;
|
|
|
|
|
2022-12-03 12:15:54 +01:00
|
|
|
import android.content.Context;
|
2018-11-28 19:46:10 +01:00
|
|
|
import android.graphics.drawable.Drawable;
|
2023-01-02 14:09:18 +01:00
|
|
|
import android.os.Build;
|
|
|
|
import android.text.SpannableStringBuilder;
|
|
|
|
import android.text.Spanned;
|
2017-08-03 23:26:26 +02:00
|
|
|
import android.text.method.LinkMovementMethod;
|
2023-01-02 14:09:18 +01:00
|
|
|
import android.text.style.DynamicDrawableSpan;
|
|
|
|
import android.text.style.ImageSpan;
|
2017-08-03 23:26:26 +02:00
|
|
|
import android.view.View;
|
|
|
|
import android.widget.TextView;
|
|
|
|
|
2022-04-21 18:46:55 +02:00
|
|
|
import androidx.annotation.NonNull;
|
2019-12-30 21:37:20 +01:00
|
|
|
import androidx.annotation.Nullable;
|
2023-01-02 14:09:18 +01:00
|
|
|
import androidx.appcompat.content.res.AppCompatResources;
|
2019-12-30 21:37:20 +01:00
|
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
|
2017-08-03 23:26:26 +02:00
|
|
|
import com.keylesspalace.tusky.R;
|
|
|
|
import com.keylesspalace.tusky.entity.Status;
|
|
|
|
import com.keylesspalace.tusky.interfaces.StatusActionListener;
|
2020-03-02 19:34:31 +01:00
|
|
|
import com.keylesspalace.tusky.util.CardViewMode;
|
2017-10-27 13:20:17 +02:00
|
|
|
import com.keylesspalace.tusky.util.LinkHelper;
|
2023-01-02 14:09:18 +01:00
|
|
|
import com.keylesspalace.tusky.util.NoUnderlineURLSpan;
|
2019-12-30 21:37:20 +01:00
|
|
|
import com.keylesspalace.tusky.util.StatusDisplayOptions;
|
2017-08-03 23:26:26 +02:00
|
|
|
import com.keylesspalace.tusky.viewdata.StatusViewData;
|
|
|
|
|
|
|
|
import java.text.DateFormat;
|
|
|
|
import java.util.Date;
|
|
|
|
|
2022-08-15 11:00:18 +02:00
|
|
|
public class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
|
|
|
private final TextView reblogs;
|
|
|
|
private final TextView favourites;
|
|
|
|
private final View infoDivider;
|
2018-12-27 09:48:24 +01:00
|
|
|
|
2023-01-02 14:09:18 +01:00
|
|
|
private static final DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT);
|
|
|
|
|
2022-08-15 11:00:18 +02:00
|
|
|
public StatusDetailedViewHolder(View view) {
|
2019-12-30 21:37:20 +01:00
|
|
|
super(view);
|
2017-10-18 00:20:26 +02:00
|
|
|
reblogs = view.findViewById(R.id.status_reblogs);
|
|
|
|
favourites = view.findViewById(R.id.status_favourites);
|
2018-12-27 09:48:24 +01:00
|
|
|
infoDivider = view.findViewById(R.id.status_info_divider);
|
2017-08-03 23:26:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2023-01-02 14:09:18 +01:00
|
|
|
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();
|
2022-12-03 12:15:54 +01:00
|
|
|
if (createdAt != null) {
|
2023-01-02 14:09:18 +01:00
|
|
|
|
|
|
|
sb.append(" ");
|
|
|
|
sb.append(dateFormat.format(createdAt));
|
2022-12-03 12:15:54 +01:00
|
|
|
}
|
2023-01-02 14:09:18 +01:00
|
|
|
|
|
|
|
Date editedAt = status.getEditedAt();
|
|
|
|
|
2022-12-03 12:15:54 +01:00
|
|
|
if (editedAt != null) {
|
2023-01-02 14:09:18 +01:00
|
|
|
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);
|
|
|
|
}
|
2019-09-15 09:10:07 +02:00
|
|
|
}
|
2023-01-02 14:09:18 +01:00
|
|
|
|
|
|
|
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);
|
2017-08-03 23:26:26 +02:00
|
|
|
}
|
|
|
|
|
2019-03-04 19:24:27 +01:00
|
|
|
private void setReblogAndFavCount(int reblogCount, int favCount, StatusActionListener listener) {
|
2018-12-27 09:48:24 +01:00
|
|
|
|
2019-03-04 19:24:27 +01:00
|
|
|
if (reblogCount > 0) {
|
|
|
|
reblogs.setText(getReblogsText(reblogs.getContext(), reblogCount));
|
2018-12-27 09:48:24 +01:00
|
|
|
reblogs.setVisibility(View.VISIBLE);
|
|
|
|
} else {
|
|
|
|
reblogs.setVisibility(View.GONE);
|
|
|
|
}
|
2019-03-04 19:24:27 +01:00
|
|
|
if (favCount > 0) {
|
|
|
|
favourites.setText(getFavsText(favourites.getContext(), favCount));
|
2018-12-27 09:48:24 +01:00
|
|
|
favourites.setVisibility(View.VISIBLE);
|
|
|
|
} else {
|
|
|
|
favourites.setVisibility(View.GONE);
|
|
|
|
}
|
|
|
|
|
2019-03-04 19:24:27 +01:00
|
|
|
if (reblogs.getVisibility() == View.GONE && favourites.getVisibility() == View.GONE) {
|
2018-12-27 09:48:24 +01:00
|
|
|
infoDivider.setVisibility(View.GONE);
|
|
|
|
} else {
|
|
|
|
infoDivider.setVisibility(View.VISIBLE);
|
|
|
|
}
|
|
|
|
|
2019-03-04 19:24:27 +01:00
|
|
|
reblogs.setOnClickListener(v -> {
|
2021-04-10 20:30:44 +02:00
|
|
|
int position = getBindingAdapterPosition();
|
2018-12-27 09:48:24 +01:00
|
|
|
if (position != RecyclerView.NO_POSITION) {
|
|
|
|
listener.onShowReblogs(position);
|
|
|
|
}
|
|
|
|
});
|
2019-03-04 19:24:27 +01:00
|
|
|
favourites.setOnClickListener(v -> {
|
2021-04-10 20:30:44 +02:00
|
|
|
int position = getBindingAdapterPosition();
|
2018-12-27 09:48:24 +01:00
|
|
|
if (position != RecyclerView.NO_POSITION) {
|
|
|
|
listener.onShowFavs(position);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-08-03 23:26:26 +02:00
|
|
|
@Override
|
2022-04-21 18:46:55 +02:00
|
|
|
public void setupWithStatus(@NonNull final StatusViewData.Concrete status,
|
|
|
|
@NonNull final StatusActionListener listener,
|
|
|
|
@NonNull StatusDisplayOptions statusDisplayOptions,
|
|
|
|
@Nullable Object payloads) {
|
2022-06-24 21:47:49 +02:00
|
|
|
// We never collapse statuses in the detail view
|
|
|
|
StatusViewData.Concrete uncollapsedStatus = (status.isCollapsible() && status.isCollapsed()) ?
|
2023-01-02 14:09:18 +01:00
|
|
|
status.copyWithCollapsed(false) :
|
|
|
|
status;
|
2022-06-24 21:47:49 +02:00
|
|
|
|
|
|
|
super.setupWithStatus(uncollapsedStatus, listener, statusDisplayOptions, payloads);
|
2023-03-01 20:00:56 +01:00
|
|
|
setupCard(uncollapsedStatus, status.isExpanded(), CardViewMode.FULL_WIDTH, statusDisplayOptions, listener); // Always show card for detailed status
|
2019-04-25 19:29:15 +02:00
|
|
|
if (payloads == null) {
|
2022-06-24 21:47:49 +02:00
|
|
|
Status actionable = uncollapsedStatus.getActionable();
|
2020-12-23 19:13:37 +01:00
|
|
|
|
|
|
|
if (!statusDisplayOptions.hideStats()) {
|
2022-06-24 21:47:49 +02:00
|
|
|
setReblogAndFavCount(actionable.getReblogsCount(),
|
|
|
|
actionable.getFavouritesCount(), listener);
|
2020-12-23 19:13:37 +01:00
|
|
|
} else {
|
|
|
|
hideQuantitativeStats();
|
|
|
|
}
|
2017-10-27 13:20:17 +02:00
|
|
|
}
|
2018-11-28 19:46:10 +01:00
|
|
|
}
|
|
|
|
|
2023-01-02 14:09:18 +01:00
|
|
|
private @Nullable Drawable getVisibilityIcon(@Nullable Status.Visibility visibility) {
|
2018-11-28 19:46:10 +01:00
|
|
|
|
2020-01-03 20:22:02 +01:00
|
|
|
if (visibility == null) {
|
2023-01-02 14:09:18 +01:00
|
|
|
return null;
|
2019-09-12 20:03:07 +02:00
|
|
|
}
|
|
|
|
|
2018-11-28 19:46:10 +01:00
|
|
|
int visibilityIcon;
|
|
|
|
switch (visibility) {
|
|
|
|
case PUBLIC:
|
|
|
|
visibilityIcon = R.drawable.ic_public_24dp;
|
|
|
|
break;
|
|
|
|
case UNLISTED:
|
|
|
|
visibilityIcon = R.drawable.ic_lock_open_24dp;
|
|
|
|
break;
|
|
|
|
case PRIVATE:
|
2018-12-20 18:25:36 +01:00
|
|
|
visibilityIcon = R.drawable.ic_lock_outline_24dp;
|
2018-11-28 19:46:10 +01:00
|
|
|
break;
|
|
|
|
case DIRECT:
|
|
|
|
visibilityIcon = R.drawable.ic_email_24dp;
|
|
|
|
break;
|
|
|
|
default:
|
2023-01-02 14:09:18 +01:00
|
|
|
return null;
|
2018-11-28 19:46:10 +01:00
|
|
|
}
|
|
|
|
|
2023-01-02 14:09:18 +01:00
|
|
|
final Drawable visibilityDrawable = AppCompatResources.getDrawable(
|
|
|
|
this.metaInfo.getContext(), visibilityIcon
|
|
|
|
);
|
2018-11-28 19:46:10 +01:00
|
|
|
if (visibilityDrawable == null) {
|
2023-01-02 14:09:18 +01:00
|
|
|
return null;
|
2018-11-28 19:46:10 +01:00
|
|
|
}
|
2017-10-27 13:20:17 +02:00
|
|
|
|
2023-01-02 14:09:18 +01:00
|
|
|
final int size = (int) this.metaInfo.getTextSize();
|
2018-11-28 19:46:10 +01:00
|
|
|
visibilityDrawable.setBounds(
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
size,
|
|
|
|
size
|
|
|
|
);
|
2023-01-02 14:09:18 +01:00
|
|
|
visibilityDrawable.setTint(this.metaInfo.getCurrentTextColor());
|
|
|
|
|
|
|
|
return visibilityDrawable;
|
2017-08-03 23:26:26 +02:00
|
|
|
}
|
2020-12-23 19:13:37 +01:00
|
|
|
|
|
|
|
private void hideQuantitativeStats() {
|
|
|
|
reblogs.setVisibility(View.GONE);
|
|
|
|
favourites.setVisibility(View.GONE);
|
|
|
|
infoDivider.setVisibility(View.GONE);
|
|
|
|
}
|
2017-08-03 23:26:26 +02:00
|
|
|
}
|