1616import android .content .res .Resources ;
1717import android .graphics .Color ;
1818import android .graphics .PorterDuff ;
19+ import android .graphics .drawable .Drawable ;
1920import android .os .Handler ;
2021import android .os .Looper ;
2122import android .text .Spannable ;
2425import android .text .TextUtils ;
2526import android .text .format .DateFormat ;
2627import android .text .format .DateUtils ;
27- import android .text .method .LinkMovementMethod ;
2828import android .text .style .ClickableSpan ;
2929import android .text .style .ForegroundColorSpan ;
3030import android .text .style .StyleSpan ;
3535import android .widget .LinearLayout ;
3636import android .widget .TextView ;
3737
38+ import com .google .android .material .chip .ChipDrawable ;
3839import com .nextcloud .client .account .CurrentAccountProvider ;
3940import com .nextcloud .client .network .ClientFactory ;
4041import com .nextcloud .common .NextcloudClient ;
4142import com .nextcloud .utils .GlideHelper ;
43+ import com .nextcloud .utils .text .Spans ;
4244import com .owncloud .android .MainApp ;
4345import com .owncloud .android .R ;
4446import com .owncloud .android .databinding .ActivityListItemBinding ;
6163
6264import androidx .annotation .NonNull ;
6365import androidx .recyclerview .widget .RecyclerView ;
66+ import thirdparties .fresco .BetterImageSpan ;
6467
6568/**
6669 * Adapter for the activity view.
6770 */
68- public class ActivityListAdapter extends RecyclerView .Adapter <RecyclerView .ViewHolder > implements StickyHeaderAdapter {
71+ public class ActivityListAdapter extends RecyclerView .Adapter <RecyclerView .ViewHolder > implements StickyHeaderAdapter ,
72+ DisplayUtils .AvatarGenerationListener {
6973
7074 static final int HEADER_TYPE = 100 ;
7175 static final int ACTIVITY_TYPE = 101 ;
@@ -147,9 +151,8 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int positi
147151
148152 if (!TextUtils .isEmpty (activity .getRichSubjectElement ().getRichSubject ())) {
149153 activityViewHolder .binding .subject .setVisibility (View .VISIBLE );
150- activityViewHolder .binding .subject .setMovementMethod (LinkMovementMethod .getInstance ());
151- activityViewHolder .binding .subject .setText (addClickablePart (activity .getRichSubjectElement ()),
152- TextView .BufferType .SPANNABLE );
154+ activityViewHolder .binding .subject .setText (addClickablePart (activity .getRichSubjectElement ()));
155+
153156 activityViewHolder .binding .subject .setVisibility (View .VISIBLE );
154157 } else if (!TextUtils .isEmpty (activity .getSubject ())) {
155158 activityViewHolder .binding .subject .setVisibility (View .VISIBLE );
@@ -275,6 +278,17 @@ private ImageView createThumbnailNew(PreviewObject previewObject, List<RichObjec
275278 return imageView ;
276279 }
277280
281+ private ChipDrawable getDrawableForMentionChipSpan (int chipResource , String text ) {
282+ ChipDrawable chip = ChipDrawable .createFromResource (context , chipResource );
283+ chip .setEllipsize (TextUtils .TruncateAt .MIDDLE );
284+ chip .setLayoutDirection (context .getResources ().getConfiguration ().getLayoutDirection ());
285+ chip .setText (text );
286+ chip .setChipIconResource (R .drawable .accent_circle );
287+ chip .setBounds (0 , 0 , chip .getIntrinsicWidth (), chip .getIntrinsicHeight ());
288+
289+ return chip ;
290+ }
291+
278292 private SpannableStringBuilder addClickablePart (RichElement richElement ) {
279293 String text = richElement .getRichSubject ();
280294 SpannableStringBuilder ssb = new SpannableStringBuilder (text );
@@ -286,28 +300,53 @@ private SpannableStringBuilder addClickablePart(RichElement richElement) {
286300 final String clickString = text .substring (idx1 + 1 , idx2 - 1 );
287301 final RichObject richObject = searchObjectByName (richElement .getRichObjectList (), clickString );
288302 if (richObject != null ) {
289- String name = richObject .getName ();
290- ssb .replace (idx1 , idx2 , name );
291- text = ssb .toString ();
292- idx2 = idx1 + name .length ();
293- ssb .setSpan (new ClickableSpan () {
294- @ Override
295- public void onClick (@ NonNull View widget ) {
296- activityListInterface .onActivityClicked (richObject );
297- }
298-
299- @ Override
300- public void updateDrawState (@ NonNull TextPaint ds ) {
301- ds .setUnderlineText (false );
302- }
303- }, idx1 , idx2 , 0 );
304- ssb .setSpan (new StyleSpan (android .graphics .Typeface .BOLD ), idx1 , idx2 , 0 );
305- ssb .setSpan (
306- new ForegroundColorSpan (context .getResources ().getColor (R .color .text_color )),
307- idx1 ,
308- idx2 ,
309- Spannable .SPAN_EXCLUSIVE_EXCLUSIVE
310- );
303+ if ("user" .equals (richObject .getType ())) {
304+ String name = richObject .getName ();
305+
306+ ChipDrawable drawableForChip = getDrawableForMentionChipSpan (R .xml .chip_others , name );
307+
308+ Spans .MentionChipSpan mentionChipSpan = new Spans .MentionChipSpan (drawableForChip ,
309+ BetterImageSpan .ALIGN_CENTER ,
310+ richObject .getId (),
311+ name
312+ );
313+
314+ DisplayUtils .setAvatar (
315+ currentAccountProvider .getUser (),
316+ richObject .getId (),
317+ name ,
318+ this ,
319+ context .getResources ().getDimension (R .dimen .avatar_icon_radius ),
320+ context .getResources (),
321+ drawableForChip ,
322+ context
323+ );
324+
325+ ssb .setSpan (mentionChipSpan , idx1 , idx2 , Spannable .SPAN_INCLUSIVE_EXCLUSIVE );
326+ } else {
327+ String name = richObject .getName ();
328+ ssb .replace (idx1 , idx2 , name );
329+ text = ssb .toString ();
330+ idx2 = idx1 + name .length ();
331+ ssb .setSpan (new ClickableSpan () {
332+ @ Override
333+ public void onClick (@ NonNull View widget ) {
334+ activityListInterface .onActivityClicked (richObject );
335+ }
336+
337+ @ Override
338+ public void updateDrawState (@ NonNull TextPaint ds ) {
339+ ds .setUnderlineText (false );
340+ }
341+ }, idx1 , idx2 , 0 );
342+ ssb .setSpan (new StyleSpan (android .graphics .Typeface .BOLD ), idx1 , idx2 , 0 );
343+ ssb .setSpan (
344+ new ForegroundColorSpan (context .getResources ().getColor (R .color .text_color )),
345+ idx1 ,
346+ idx2 ,
347+ Spannable .SPAN_EXCLUSIVE_EXCLUSIVE
348+ );
349+ }
311350 }
312351 idx1 = text .indexOf ('{' , idx2 );
313352 }
@@ -396,6 +435,16 @@ public boolean isHeader(int itemPosition) {
396435 return this .getItemViewType (itemPosition ) == HEADER_TYPE ;
397436 }
398437
438+ @ Override
439+ public void avatarGenerated (Drawable avatarDrawable , Object callContext ) {
440+ ((ChipDrawable ) callContext ).setChipIcon (avatarDrawable );
441+ }
442+
443+ @ Override
444+ public boolean shouldCallGeneratedCallback (String tag , Object callContext ) {
445+ return true ;
446+ }
447+
399448 protected class ActivityViewHolder extends RecyclerView .ViewHolder {
400449
401450 ActivityListItemBinding binding ;
0 commit comments