1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package it.niedermann.nextcloud.deck.ui.card.comments;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ImageSpan;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.TooltipCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import java.text.DateFormat;
import java.util.List;
import it.niedermann.nextcloud.deck.R;
import it.niedermann.nextcloud.deck.databinding.ItemCommentBinding;
import it.niedermann.nextcloud.deck.model.Account;
import it.niedermann.nextcloud.deck.model.ocs.comment.DeckComment;
import it.niedermann.nextcloud.deck.model.ocs.comment.Mention;
import it.niedermann.nextcloud.deck.util.DateUtil;
import it.niedermann.nextcloud.deck.util.ViewUtil;
import static it.niedermann.nextcloud.deck.util.DimensionUtil.getAvatarDimension;
public class CardCommentsAdapter extends RecyclerView.Adapter<CardCommentsAdapter.ItemCommentViewHolder> {
private final Context context;
private final List<DeckComment> comments;
private final Account account;
CardCommentsAdapter(@NonNull Context context, @NonNull List<DeckComment> comments, @NonNull Account account) {
this.context = context;
this.comments = comments;
this.account = account;
setHasStableIds(true);
}
@Override
public long getItemId(int position) {
return comments.get(position).getLocalId();
}
@NonNull
@Override
public ItemCommentViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int position) {
return new ItemCommentViewHolder(ItemCommentBinding.inflate(LayoutInflater.from(viewGroup.getContext()), viewGroup, false));
}
@Override
public void onBindViewHolder(@NonNull ItemCommentViewHolder viewHolder, int position) {
DeckComment comment = comments.get(position);
ViewUtil.addAvatar(context, viewHolder.binding.avatar, account.getUrl(), account.getUserName(), getAvatarDimension(context, R.dimen.icon_size_details), R.drawable.ic_person_grey600_24dp);
viewHolder.binding.message.setText(comment.getMessage());
viewHolder.binding.actorDisplayName.setText(comment.getActorDisplayName());
viewHolder.binding.creationDateTime.setText(DateUtil.getRelativeDateTimeString(context, comment.getCreationDateTime().getTime()));
TooltipCompat.setTooltipText(viewHolder.binding.creationDateTime, DateFormat.getDateTimeInstance().format(comment.getCreationDateTime()));
setupMentions(comment.getMentions(), viewHolder.binding.message);
}
private void setupMentions(List<Mention> mentions, TextView tv) {
SpannableStringBuilder messageBuilder = new SpannableStringBuilder(tv.getText());
// Step 1
// Add avatar icons and display names
for (Mention m : mentions) {
final String mentionId = "@" + m.getMentionId();
final String mentionDisplayName = " " + m.getMentionDisplayName();
int index = messageBuilder.toString().lastIndexOf(mentionId);
while (index >= 0) {
messageBuilder.setSpan(new ImageSpan(context, R.drawable.ic_person_grey600_24dp), index, index + mentionId.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
messageBuilder.insert(index + mentionId.length(), mentionDisplayName);
index = messageBuilder.toString().substring(0, index).lastIndexOf(mentionId);
}
}
tv.setText(messageBuilder);
// Step 2
// Replace avatar icons with real avatars
final ImageSpan[] list = messageBuilder.getSpans(0, messageBuilder.length(), ImageSpan.class);
for (ImageSpan span : list) {
final int spanStart = messageBuilder.getSpanStart(span);
final int spanEnd = messageBuilder.getSpanEnd(span);
Glide.with(context)
.asBitmap()
.placeholder(R.drawable.ic_person_grey600_24dp)
.load(account.getUrl() + "/index.php/avatar/" + messageBuilder.subSequence(spanStart + 1, spanEnd).toString() + "/" + getAvatarDimension(context, R.dimen.icon_size_details))
.apply(RequestOptions.circleCropTransform())
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
messageBuilder.removeSpan(span);
messageBuilder.setSpan(new ImageSpan(context, resource), spanStart, spanEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
// silence is gold
}
});
}
tv.setText(messageBuilder);
}
@Override
public int getItemCount() {
return comments == null ? 0 : comments.size();
}
static class ItemCommentViewHolder extends RecyclerView.ViewHolder {
private ItemCommentBinding binding;
private ItemCommentViewHolder(ItemCommentBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
}
|