diff --git a/app/src/main/java/app/fedilab/android/client/Entities/Account.java b/app/src/main/java/app/fedilab/android/client/Entities/Account.java index 08fbd6dae..bb57ea56a 100644 --- a/app/src/main/java/app/fedilab/android/client/Entities/Account.java +++ b/app/src/main/java/app/fedilab/android/client/Entities/Account.java @@ -1076,17 +1076,11 @@ public class Account implements Parcelable { for (final Emojis emoji : emojis) { try { Glide.with(context) - .asFile() + .asDrawable() .load(emoji.getUrl()) - .into(new SimpleTarget() { + .into(new SimpleTarget() { @Override - public void onResourceReady(@NonNull File resourceFile, @Nullable Transition transition) { - Drawable resource; - if( emoji.getUrl().endsWith(".gif")){ - resource = GifDrawable.fromFile(resourceFile.getAbsolutePath()); - }else{ - resource = APNGDrawable.fromFile(resourceFile.getAbsolutePath()); - } + public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { final String targetedEmoji = ":" + emoji.getShortcode() + ":"; if (displayNameSpan.toString().contains(targetedEmoji)) { //emojis can be used several times so we have to loop @@ -1119,6 +1113,7 @@ public class Account implements Parcelable { } } + }); }catch (Exception ignored){} diff --git a/app/src/main/java/app/fedilab/android/client/Entities/Notification.java b/app/src/main/java/app/fedilab/android/client/Entities/Notification.java index faa28761f..bf00fd425 100644 --- a/app/src/main/java/app/fedilab/android/client/Entities/Notification.java +++ b/app/src/main/java/app/fedilab/android/client/Entities/Notification.java @@ -28,6 +28,7 @@ import androidx.annotation.Nullable; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ImageSpan; +import android.util.Log; import com.bumptech.glide.Glide; import com.bumptech.glide.load.DataSource; @@ -43,6 +44,7 @@ import java.io.File; import java.util.Date; import java.util.List; +import app.fedilab.android.R; import app.fedilab.android.helper.Helper; import app.fedilab.android.interfaces.OnRetrieveEmojiInterface; @@ -156,15 +158,93 @@ public class Notification implements Parcelable { return; if( status.getReblog() == null && status.getAccount() == null) return; - final List emojisAccounts = status.getReblog() != null ?status.getReblog().getAccount().getEmojis():status.getAccount().getEmojis(); + final List emojisAccounts = status.getAccount().getEmojis(); - SpannableString displayNameSpan = status.getDisplayNameSpan(); + String typeString = ""; + switch (notification.getType()){ + case "mention": + if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0) + typeString = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),context.getString(R.string.notif_mention)); + else + typeString = String.format("@%s %s", notification.getAccount().getUsername(),context.getString(R.string.notif_mention)); + break; + case "poll": + typeString = context.getString(R.string.notif_poll);; + break; + case "reblog": + if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0) + typeString = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),context.getString(R.string.notif_reblog)); + else + typeString = String.format("@%s %s", notification.getAccount().getUsername(),context.getString(R.string.notif_reblog)); + break; + case "favourite": + if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0) + typeString = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),context.getString(R.string.notif_favourite)); + else + typeString = String.format("@%s %s", notification.getAccount().getUsername(),context.getString(R.string.notif_favourite)); + break; + case "follow": + if( notification.getAccount().getDisplay_name() != null && notification.getAccount().getDisplay_name().length() > 0) + typeString = String.format("%s %s", Helper.shortnameToUnicode(notification.getAccount().getDisplay_name(), true),context.getString(R.string.notif_follow)); + else + typeString = String.format("@%s %s", notification.getAccount().getUsername(),context.getString(R.string.notif_follow)); + break; + } + SpannableString displayNameSpan = new SpannableString(typeString); SpannableString contentSpan = status.getContentSpan(); SpannableString contentSpanCW = status.getContentSpanCW(); SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); boolean disableAnimatedEmoji = sharedpreferences.getBoolean(Helper.SET_DISABLE_ANIMATED_EMOJI, false); - if( emojisAccounts != null) - emojis.addAll(emojisAccounts); + + if( emojisAccounts != null && emojisAccounts.size() > 0 ) { + final int[] j = {0}; + for (final Emojis emoji : emojisAccounts) { + Glide.with(context) + .asDrawable() + .load(emoji.getUrl()) + .listener(new RequestListener() { + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + return false; + } + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + j[0]++; + if( j[0] == (emojisAccounts.size())) { + listener.onRetrieveEmoji(notification); + } + return false; + } + }) + .into(new SimpleTarget() { + @Override + public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { + final String targetedEmoji = ":" + emoji.getShortcode() + ":"; + if (displayNameSpan != null && displayNameSpan.toString().contains(targetedEmoji)) { + //emojis can be used several times so we have to loop + for (int startPosition = -1; (startPosition = displayNameSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) { + final int endPosition = startPosition + targetedEmoji.length(); + if(endPosition <= displayNameSpan.toString().length() && endPosition >= startPosition) { + resource.setBounds(0,0,(int) Helper.convertDpToPixel(20, context),(int) Helper.convertDpToPixel(20, context)); + resource.setVisible(true, true); + ImageSpan imageSpan = new ImageSpan(resource); + displayNameSpan.setSpan( + imageSpan, startPosition, + endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + } + } + } + j[0]++; + if( j[0] == (emojisAccounts.size())) { + notification.getAccount().setdisplayNameSpan(displayNameSpan); + Log.v(Helper.TAG,"displayNameSpan: " + displayNameSpan); + listener.onRetrieveEmoji(notification); + } + } + }); + } + } + if( emojis != null && emojis.size() > 0 ) { final int[] i = {0}; for (final Emojis emoji : emojis) { @@ -191,7 +271,6 @@ public class Notification implements Parcelable { Drawable resource; if( emoji.getUrl().endsWith(".gif")){ resource = GifDrawable.fromFile(resourceFile.getAbsolutePath()); - ((GifDrawable) resource).start(); }else{ resource = APNGDrawable.fromFile(resourceFile.getAbsolutePath()); } @@ -219,20 +298,6 @@ public class Notification implements Parcelable { } } } - if (displayNameSpan != null && displayNameSpan.toString().contains(targetedEmoji)) { - //emojis can be used several times so we have to loop - for (int startPosition = -1; (startPosition = displayNameSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) { - final int endPosition = startPosition + targetedEmoji.length(); - if(endPosition <= displayNameSpan.toString().length() && endPosition >= startPosition) { - resource.setBounds(0,0,(int) Helper.convertDpToPixel(20, context),(int) Helper.convertDpToPixel(20, context)); - resource.setVisible(true, true); - ImageSpan imageSpan = new ImageSpan(resource); - displayNameSpan.setSpan( - imageSpan, startPosition, - endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); - } - } - } if (contentSpanCW != null && contentSpanCW.toString().contains(targetedEmoji)) { //emojis can be used several times so we have to loop for (int startPosition = -1; (startPosition = contentSpanCW.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) { @@ -260,7 +325,6 @@ public class Notification implements Parcelable { if( i[0] == (emojis.size())) { status.setContentSpan(contentSpan); status.setContentSpanCW(contentSpanCW); - status.setDisplayNameSpan(displayNameSpan); status.setEmojiFound(true); listener.onRetrieveEmoji(notification); } diff --git a/app/src/main/java/app/fedilab/android/client/Entities/Status.java b/app/src/main/java/app/fedilab/android/client/Entities/Status.java index 9a8aaf0cf..30943d767 100644 --- a/app/src/main/java/app/fedilab/android/client/Entities/Status.java +++ b/app/src/main/java/app/fedilab/android/client/Entities/Status.java @@ -1080,15 +1080,74 @@ public class Status implements Parcelable{ final List emojis = status.getReblog() != null ? status.getReblog().getEmojis() : status.getEmojis(); final List emojisAccounts = status.getReblog() != null ?status.getReblog().getAccount().getEmojis():status.getAccount().getEmojis(); - //Account.makeAccountNameEmoji(context, null, status.getAccount()); + Account.makeAccountNameEmoji(context, null, status.getAccount()); SpannableString displayNameSpan = status.getDisplayNameSpan(); SpannableString contentSpan = status.getContentSpan(); SpannableString contentSpanCW = status.getContentSpanCW(); SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); boolean disableAnimatedEmoji = sharedpreferences.getBoolean(Helper.SET_DISABLE_ANIMATED_EMOJI, false); - if( emojisAccounts != null) - emojis.addAll(emojisAccounts); + + if( emojisAccounts != null && emojisAccounts.size() > 0 ) { + final int[] i = {0}; + for (final Emojis emoji : emojisAccounts) { + Glide.with(context) + .asDrawable() + .load(emoji.getUrl()) + .listener(new RequestListener() { + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + return false; + } + + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + i[0]++; + if( i[0] == (emojisAccounts.size())) { + listener.onRetrieveEmoji(status,false); + } + return false; + } + }) + .into(new SimpleTarget() { + @Override + public void onResourceReady(@NonNull Drawable resource, @Nullable Transition transition) { + final String targetedEmoji = ":" + emoji.getShortcode() + ":"; + if (displayNameSpan != null && displayNameSpan.toString().contains(targetedEmoji)) { + //emojis can be used several times so we have to loop + for (int startPosition = -1; (startPosition = displayNameSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) { + final int endPosition = startPosition + targetedEmoji.length(); + if(endPosition <= displayNameSpan.toString().length() && endPosition >= startPosition) { + + ImageSpan imageSpan; + if( !disableAnimatedEmoji) { + resource.setBounds(0,0,(int) Helper.convertDpToPixel(20, context),(int) Helper.convertDpToPixel(20, context)); + resource.setVisible(true, true); + imageSpan = new ImageSpan(resource); + }else{ + resource.setVisible(true, true); + Bitmap bitmap = drawableToBitmap(resource.getCurrent()); + imageSpan = new ImageSpan(context, + Bitmap.createScaledBitmap(bitmap, (int) Helper.convertDpToPixel(20, context), + (int) Helper.convertDpToPixel(20, context), false)); + } + displayNameSpan.setSpan( + imageSpan, startPosition, + endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + } + } + } + i[0]++; + if( i[0] == (emojisAccounts.size())) { + status.setDisplayNameSpan(displayNameSpan); + listener.onRetrieveEmoji(status, false); + } + } + }); + + } + + } if( emojis != null && emojis.size() > 0 ) { final int[] i = {0}; for (final Emojis emoji : emojis) { @@ -1144,30 +1203,6 @@ public class Status implements Parcelable{ } } } - if (displayNameSpan != null && displayNameSpan.toString().contains(targetedEmoji)) { - //emojis can be used several times so we have to loop - for (int startPosition = -1; (startPosition = displayNameSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) { - final int endPosition = startPosition + targetedEmoji.length(); - if(endPosition <= displayNameSpan.toString().length() && endPosition >= startPosition) { - - ImageSpan imageSpan; - if( !disableAnimatedEmoji) { - resource.setBounds(0,0,(int) Helper.convertDpToPixel(20, context),(int) Helper.convertDpToPixel(20, context)); - resource.setVisible(true, true); - imageSpan = new ImageSpan(resource); - }else{ - resource.setVisible(true, true); - Bitmap bitmap = drawableToBitmap(resource.getCurrent()); - imageSpan = new ImageSpan(context, - Bitmap.createScaledBitmap(bitmap, (int) Helper.convertDpToPixel(20, context), - (int) Helper.convertDpToPixel(20, context), false)); - } - displayNameSpan.setSpan( - imageSpan, startPosition, - endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); - } - } - } if (contentSpanCW != null && contentSpanCW.toString().contains(targetedEmoji)) { //emojis can be used several times so we have to loop for (int startPosition = -1; (startPosition = contentSpanCW.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) { @@ -1195,7 +1230,6 @@ public class Status implements Parcelable{ if( i[0] == (emojis.size())) { status.setContentSpan(contentSpan); status.setContentSpanCW(contentSpanCW); - status.setDisplayNameSpan(displayNameSpan); status.setEmojiFound(true); listener.onRetrieveEmoji(status, false); } diff --git a/app/src/main/java/app/fedilab/android/drawers/NotificationsListAdapter.java b/app/src/main/java/app/fedilab/android/drawers/NotificationsListAdapter.java index 3696f33d9..3b83bf839 100644 --- a/app/src/main/java/app/fedilab/android/drawers/NotificationsListAdapter.java +++ b/app/src/main/java/app/fedilab/android/drawers/NotificationsListAdapter.java @@ -38,6 +38,7 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.text.Html; import android.text.method.LinkMovementMethod; +import android.util.Log; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.MenuItem; @@ -353,14 +354,10 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On if( notification.getAccount().getdisplayNameSpan() == null) { holder.notification_type.setText(typeString); notification.getAccount().setStored_displayname(notification.getAccount().getDisplay_name()); - notification.getAccount().setDisplay_name(typeString); + // notification.getAccount().setDisplay_name(typeString); }else holder.notification_type.setText(notification.getAccount().getdisplayNameSpan(), TextView.BufferType.SPANNABLE); - if( !notification.isEmojiFound()) { - notification.setEmojiFound(true); - notification.getAccount().makeAccountNameEmoji(context, NotificationsListAdapter.this, notification.getAccount()); - } if( imgH != null) { holder.notification_type.setCompoundDrawablePadding((int)Helper.convertDpToPixel(5, context)); imgH.setBounds(0, 0, (int) (20 * iconSizePercent / 100 * scale + 0.5f), (int) (20 * iconSizePercent / 100 * scale + 0.5f)); @@ -442,8 +439,8 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On status.setClickable(true); Status.transform(context, status); } - if( !status.isEmojiFound()) { - status.setEmojiFound(true); + if( !notification.isEmojiFound()) { + notification.setEmojiFound(true); Notification.makeEmojis(context, NotificationsListAdapter.this, notification); } if( !status.isImageFound()) { @@ -1163,10 +1160,20 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On private void notifyNotificationChanged(Notification notification){ for (int i = 0; i < notificationsListAdapter.getItemCount(); i++) { - if (notificationsListAdapter.getItemAt(i) != null && notificationsListAdapter.getItemAt(i).getId().equals(notification.getId())) { + + if (notificationsListAdapter.getItemAt(i) != null && notificationsListAdapter.getItemAt(i).getId().trim().compareTo(notification.getId().trim()) == 0) { try { - notificationsListAdapter.notifyItemChanged(i); - } catch (Exception ignored) { } + if( mRecyclerView != null) { + int finalI = i; + mRecyclerView.post(new Runnable() { + @Override + public void run() { + notificationsListAdapter.notifyItemChanged(finalI); + } + }); + } + break; + } catch (Exception ignored) {} } } } @@ -1178,7 +1185,16 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On try { if( notifications.get(i).getStatus() != null){ notifications.get(i).setStatus(status); - notificationsListAdapter.notifyItemChanged(i); + notifyItemChanged(i); + if( mRecyclerView != null) { + int finalI = i; + mRecyclerView.post(new Runnable() { + @Override + public void run() { + notificationsListAdapter.notifyItemChanged(finalI); + } + }); + } break; } } catch (Exception ignored) {} @@ -1375,13 +1391,12 @@ public class NotificationsListAdapter extends RecyclerView.Adapter implements On @Override public void onRetrieveEmoji(Status status, boolean fromTranslation) { - + notifyNotificationWithActionChanged(status); } @Override public void onRetrieveEmoji(Notification notification) { if( notification != null && notification.getStatus() != null) { - notification.getStatus().setEmojiFound(true); notifyNotificationChanged(notification); } } diff --git a/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java b/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java index 87391e4c5..908a30bb1 100644 --- a/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java +++ b/app/src/main/java/app/fedilab/android/drawers/StatusListAdapter.java @@ -4225,9 +4225,19 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct //noinspection ConstantConditions if (statusListAdapter.getItemAt(i) != null && statusListAdapter.getItemAt(i).getId().equals(status.getId())) { try { - statusListAdapter.notifyItemChanged(i); + statuses.set(i, status); + if( mRecyclerView != null) { + int finalI = i; + mRecyclerView.post(new Runnable() { + @Override + public void run() { + statusListAdapter.notifyItemChanged(finalI); + } + }); + } } catch (Exception ignored) { } + break; } } } @@ -4240,9 +4250,18 @@ public class StatusListAdapter extends RecyclerView.Adapter implements OnPostAct if (statusListAdapter.getItemAt(i) != null && statusListAdapter.getItemAt(i).getId().equals(status.getId())) { try { statuses.set(i, status); - statusListAdapter.notifyItemChanged(i); + if( mRecyclerView != null) { + int finalI = i; + mRecyclerView.post(new Runnable() { + @Override + public void run() { + statusListAdapter.notifyItemChanged(finalI); + } + }); + } } catch (Exception ignored) { } + break; } } }