1717import android .graphics .Color ;
1818import android .graphics .PorterDuff ;
1919import android .graphics .drawable .Drawable ;
20- import android .net .Uri ;
2120import android .os .Handler ;
2221import android .os .Looper ;
2322import android .text .Spannable ;
24- import android .text .SpannableString ;
2523import android .text .SpannableStringBuilder ;
2624import android .text .Spanned ;
2725import android .text .TextPaint ;
2826import android .text .TextUtils ;
2927import android .text .format .DateFormat ;
3028import android .text .format .DateUtils ;
29+ import android .text .method .LinkMovementMethod ;
3130import android .text .style .ClickableSpan ;
3231import android .text .style .ForegroundColorSpan ;
3332import android .text .style .StyleSpan ;
3837import android .widget .LinearLayout ;
3938import android .widget .TextView ;
4039
41- import com .bumptech .glide .GenericRequestBuilder ;
42- import com .bumptech .glide .Glide ;
43- import com .bumptech .glide .load .engine .DiskCacheStrategy ;
44- import com .bumptech .glide .load .model .StreamEncoder ;
45- import com .bumptech .glide .load .resource .file .FileToStreamDecoder ;
46- import com .caverock .androidsvg .SVG ;
4740import com .google .android .material .chip .ChipDrawable ;
4841import com .nextcloud .client .account .CurrentAccountProvider ;
4942import com .nextcloud .client .network .ClientFactory ;
5043import com .nextcloud .common .NextcloudClient ;
51- import com .nextcloud .utils .text .Spans ;
5244import com .nextcloud .utils .GlideHelper ;
45+ import com .nextcloud .utils .text .Spans ;
5346import com .owncloud .android .MainApp ;
5447import com .owncloud .android .R ;
5548import com .owncloud .android .databinding .ActivityListItemBinding ;
6861import java .util .ArrayList ;
6962import java .util .List ;
7063import java .util .Locale ;
71- import java .util .regex .Matcher ;
72- import java .util .regex .Pattern ;
7364import java .util .Optional ;
7465
7566import androidx .annotation .NonNull ;
76- import androidx .annotation .XmlRes ;
7767import androidx .recyclerview .widget .RecyclerView ;
7868import third_parties .fresco .BetterImageSpan ;
7969
8070/**
8171 * Adapter for the activity view.
8272 */
83- public class ActivityListAdapter extends RecyclerView .Adapter <RecyclerView .ViewHolder > implements StickyHeaderAdapter {
73+ public class ActivityListAdapter extends RecyclerView .Adapter <RecyclerView .ViewHolder > implements StickyHeaderAdapter ,
74+ DisplayUtils .AvatarGenerationListener {
8475
8576 static final int HEADER_TYPE = 100 ;
8677 static final int ACTIVITY_TYPE = 101 ;
@@ -162,16 +153,17 @@ public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int positi
162153
163154 if (!TextUtils .isEmpty (activity .getRichSubjectElement ().getRichSubject ())) {
164155 activityViewHolder .binding .subject .setVisibility (View .VISIBLE );
165- // activityViewHolder.binding.subject.setMovementMethod(LinkMovementMethod.getInstance());
166- // activityViewHolder.binding.subject.setText(addClickablePart(activity.getRichSubjectElement()),
167- // TextView.BufferType.SPANNABLE);
168-
169- activityViewHolder .binding .subject .setText (searchAndReplaceWithMentionSpan ("actor" ,
170- activity .getRichSubjectElement ().getRichSubject (),
171- "1" ,
172- "label" ,
173- R .xml .chip_others ));
156+
157+
158+
159+
160+ activityViewHolder .binding .subject .setMovementMethod (LinkMovementMethod .getInstance ());
161+ // activityViewHolder.binding.subject.setText(addClickablePart(activity.getRichSubjectElement()), TextView.BufferType.SPANNABLE);
162+
163+ Spanned old = addClickablePart (activity .getRichSubjectElement ());
174164
165+ activityViewHolder .binding .subject .setText (old );
166+
175167 activityViewHolder .binding .subject .setVisibility (View .VISIBLE );
176168 } else if (!TextUtils .isEmpty (activity .getSubject ())) {
177169 activityViewHolder .binding .subject .setVisibility (View .VISIBLE );
@@ -296,88 +288,31 @@ private ImageView createThumbnailNew(PreviewObject previewObject, List<RichObjec
296288
297289 return imageView ;
298290 }
299-
300- private void downloadIcon (Activity activity , ImageView itemViewType ) {
301- GenericRequestBuilder <Uri , InputStream , SVG , Bitmap > requestBuilder = Glide .with (context )
302- .using (Glide .buildStreamModelLoader (Uri .class , context ), InputStream .class )
303- .from (Uri .class )
304- .as (SVG .class )
305- .transcode (new SvgBitmapTranscoder (128 , 128 ), Bitmap .class )
306- .sourceEncoder (new StreamEncoder ())
307- .cacheDecoder (new FileToStreamDecoder <>(new SvgDecoder ()))
308- .decoder (new SvgDecoder ())
309- .placeholder (R .drawable .ic_activity )
310- .error (R .drawable .ic_activity )
311- .animate (android .R .anim .fade_in );
312-
313- Uri uri = Uri .parse (activity .getIcon ());
314- requestBuilder
315- .diskCacheStrategy (DiskCacheStrategy .SOURCE )
316- .load (uri )
317- .into (itemViewType );
318- }
319-
320- /**
321- * c&p from Talk: DisplayUtils:227
322- *
323- * @return Spannable
324- */
325- private Spanned searchAndReplaceWithMentionSpan (
326- String key ,
327- String text ,
328- String id ,
329- String label ,
330- @ XmlRes int chipXmlRes ) {
331- Spannable spannableString = new SpannableString (text );
332- String stringText = text .toString ();
333- String keyWithBrackets = "{" + key + "}" ;
334- Matcher m = Pattern .compile (keyWithBrackets , Pattern .CASE_INSENSITIVE | Pattern .LITERAL | Pattern .MULTILINE )
335- .matcher (spannableString );
336- ClickableSpan clickableSpan = new ClickableSpan () {
337- @ Override
338- public void onClick (@ NonNull View view ) {
339- //EventBus.getDefault().post(new UserMentionClickEvent(id));
340- }
341- };
342-
343- int lastStartIndex = 0 ;
344- Spans .MentionChipSpan mentionChipSpan ;
345-
346- while (m .find ()) {
347- int start = stringText .indexOf (m .group (), lastStartIndex );
348- int end = start + m .group ().length ();
349- lastStartIndex = end ;
350- Drawable drawableForChip = getDrawableForMentionChipSpan (
351- chipXmlRes ,
352- label
353- );
354-
355-
356- mentionChipSpan = new Spans .MentionChipSpan (
357- drawableForChip ,
358- BetterImageSpan .ALIGN_CENTER ,
359- id ,
360- label
361- );
362- spannableString .setSpan (mentionChipSpan , start , end , Spannable .SPAN_EXCLUSIVE_EXCLUSIVE );
363- // if (chipXmlRes == R.xml.chip_you) {
364- // spannableString.setSpan(
365- // viewThemeUtils.talk.themeForegroundColorSpan(context),
366- // start,
367- // end,
368- // Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
369- // );
370- // }
371- // if ("user" == type && conversationUser.userId != id && !isFederated) {
372- // spannableString.setSpan(clickableSpan, start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
373- // }
374- }
375- return spannableString ;
376- }
377-
378- private Drawable getDrawableForMentionChipSpan (int chipResource , String text ) {
291+ //
292+ // private void downloadIcon(Activity activity, ImageView itemViewType) {
293+ // GenericRequestBuilder<Uri, InputStream, SVG, Bitmap> requestBuilder = Glide.with(context)
294+ // .using(Glide.buildStreamModelLoader(Uri.class, context), InputStream.class)
295+ // .from(Uri.class)
296+ // .as(SVG.class)
297+ // .transcode(new SvgBitmapTranscoder(128, 128), Bitmap.class)
298+ // .sourceEncoder(new StreamEncoder())
299+ // .cacheDecoder(new FileToStreamDecoder<>(new SvgDecoder()))
300+ // .decoder(new SvgDecoder())
301+ // .placeholder(R.drawable.ic_activity)
302+ // .error(R.drawable.ic_activity)
303+ // .animate(android.R.anim.fade_in);
304+ //
305+ // Uri uri = Uri.parse(activity.getIcon());
306+ // requestBuilder
307+ // .diskCacheStrategy(DiskCacheStrategy.SOURCE)
308+ // .load(uri)
309+ // .into(itemViewType);
310+ // }
311+
312+ private ChipDrawable getDrawableForMentionChipSpan (int chipResource , String text ) {
379313 ChipDrawable chip = ChipDrawable .createFromResource (context , chipResource );
380314 chip .setEllipsize (TextUtils .TruncateAt .MIDDLE );
315+ chip .setLayoutDirection (context .getResources ().getConfiguration ().getLayoutDirection ());
381316 chip .setText (text );
382317 chip .setChipIconResource (R .drawable .accent_circle );
383318 chip .setBounds (0 , 0 , chip .getIntrinsicWidth (), chip .getIntrinsicHeight ());
@@ -396,28 +331,65 @@ private SpannableStringBuilder addClickablePart(RichElement richElement) {
396331 final String clickString = text .substring (idx1 + 1 , idx2 - 1 );
397332 final RichObject richObject = searchObjectByName (richElement .getRichObjectList (), clickString );
398333 if (richObject != null ) {
399- String name = richObject .getName ();
400- ssb .replace (idx1 , idx2 , name );
401- text = ssb .toString ();
402- idx2 = idx1 + name .length ();
403- ssb .setSpan (new ClickableSpan () {
404- @ Override
405- public void onClick (@ NonNull View widget ) {
406- activityListInterface .onActivityClicked (richObject );
407- }
334+ if ("user" .equals (richObject .getType ())) {
335+ String name = richObject .getName ();
336+
337+ ChipDrawable drawableForChip = getDrawableForMentionChipSpan (R .xml .chip_others , name );
338+
339+ Spans .MentionChipSpan mentionChipSpan = new Spans .MentionChipSpan (drawableForChip ,
340+ BetterImageSpan .ALIGN_CENTER ,
341+ richObject .getId (),
342+ name
343+ );
344+
345+ DisplayUtils .setAvatar (
346+ currentAccountProvider .getUser (),
347+ richObject .getId (),
348+ name ,
349+ this ,
350+ context .getResources ().getDimension (R .dimen .standard_padding ),
351+ context .getResources (),
352+ drawableForChip ,
353+ context
354+ );
355+
356+ ssb .setSpan (mentionChipSpan , idx1 , idx2 , Spannable .SPAN_INCLUSIVE_EXCLUSIVE );
408357
409- @ Override
410- public void updateDrawState (@ NonNull TextPaint ds ) {
411- ds .setUnderlineText (false );
412- }
413- }, idx1 , idx2 , 0 );
414- ssb .setSpan (new StyleSpan (android .graphics .Typeface .BOLD ), idx1 , idx2 , 0 );
415- ssb .setSpan (
416- new ForegroundColorSpan (context .getResources ().getColor (R .color .text_color )),
417- idx1 ,
418- idx2 ,
419- Spannable .SPAN_EXCLUSIVE_EXCLUSIVE
420- );
358+ // if (chipXmlRes == R.xml.chip_you) {
359+ // spannableString.setSpan(
360+ // viewThemeUtils.talk.themeForegroundColorSpan(context),
361+ // start,
362+ // end,
363+ // Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
364+ // );
365+ // }
366+ // if ("user" == type && conversationUser.userId != id && !isFederated) {
367+ // spannableString.setSpan(clickableSpan, start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
368+ // }
369+ } else {
370+ String name = richObject .getName ();
371+ ssb .replace (idx1 , idx2 , name );
372+ text = ssb .toString ();
373+ idx2 = idx1 + name .length ();
374+ ssb .setSpan (new ClickableSpan () {
375+ @ Override
376+ public void onClick (@ NonNull View widget ) {
377+ activityListInterface .onActivityClicked (richObject );
378+ }
379+
380+ @ Override
381+ public void updateDrawState (@ NonNull TextPaint ds ) {
382+ ds .setUnderlineText (false );
383+ }
384+ }, idx1 , idx2 , 0 );
385+ ssb .setSpan (new StyleSpan (android .graphics .Typeface .BOLD ), idx1 , idx2 , 0 );
386+ ssb .setSpan (
387+ new ForegroundColorSpan (context .getResources ().getColor (R .color .log_level_error )),
388+ idx1 ,
389+ idx2 ,
390+ Spannable .SPAN_EXCLUSIVE_EXCLUSIVE
391+ );
392+ }
421393 }
422394 idx1 = text .indexOf ('{' , idx2 );
423395 }
@@ -506,6 +478,16 @@ public boolean isHeader(int itemPosition) {
506478 return this .getItemViewType (itemPosition ) == HEADER_TYPE ;
507479 }
508480
481+ @ Override
482+ public void avatarGenerated (Drawable avatarDrawable , Object callContext ) {
483+ ((ChipDrawable ) callContext ).setChipIcon (avatarDrawable );
484+ }
485+
486+ @ Override
487+ public boolean shouldCallGeneratedCallback (String tag , Object callContext ) {
488+ return true ;
489+ }
490+
509491 protected class ActivityViewHolder extends RecyclerView .ViewHolder {
510492
511493 ActivityListItemBinding binding ;
0 commit comments