From 24677ea239786ea53fe1c824d53f3dd182195ab6 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Wed, 1 Nov 2023 19:23:09 +0100 Subject: [PATCH 1/4] feat(status): translate media attachments --- .../fragments/BaseStatusListFragment.java | 11 ++++++++ .../android/model/Translation.java | 6 +++++ .../MediaGridStatusDisplayItem.java | 27 +++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java index a73d7d722..2964b4522 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java @@ -858,6 +858,10 @@ public abstract class BaseStatusListFragment exten return; status.translation=result; status.translationState=Status.TranslationState.SHOWN; + MediaGridStatusDisplayItem.Holder media=findHolderOfType(itemID, MediaGridStatusDisplayItem.Holder.class); + if (media!=null) { + media.rebind(); + } TextStatusDisplayItem.Holder text=findHolderOfType(itemID, TextStatusDisplayItem.Holder.class); if(text!=null){ text.updateTranslation(true); @@ -896,8 +900,15 @@ public abstract class BaseStatusListFragment exten }else{ notifyItemChanged(itemID, TextStatusDisplayItem.class); } + + MediaGridStatusDisplayItem.Holder media=findHolderOfType(itemID, MediaGridStatusDisplayItem.Holder.class); + if (media!=null) { + media.rebind(); + } } + private void updateTranslation() {} + public void rebuildAllDisplayItems(){ displayItems.clear(); for(T item:data){ diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java b/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java index 68487451d..54216c873 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java @@ -7,4 +7,10 @@ public class Translation extends BaseModel{ public String content; public String detectedSourceLanguage; public String provider; + public MediaAttachment[] mediaAttachments; + + public static class MediaAttachment { + public String id; + public String description; + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/MediaGridStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/MediaGridStatusDisplayItem.java index 0d066fdf3..c43ff02f6 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/MediaGridStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/MediaGridStatusDisplayItem.java @@ -12,6 +12,7 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.text.TextUtils; +import android.util.Pair; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -26,6 +27,7 @@ import org.joinmastodon.android.R; import org.joinmastodon.android.fragments.BaseStatusListFragment; import org.joinmastodon.android.model.Attachment; import org.joinmastodon.android.model.Status; +import org.joinmastodon.android.model.Translation; import org.joinmastodon.android.ui.OutlineProviders; import org.joinmastodon.android.ui.PhotoLayoutHelper; import org.joinmastodon.android.ui.drawables.SpoilerStripesDrawable; @@ -38,7 +40,12 @@ import org.joinmastodon.android.ui.views.MediaGridLayout; import org.joinmastodon.android.utils.TypedObjectPool; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; import me.grishka.appkit.imageloader.ImageLoaderViewHolder; import me.grishka.appkit.imageloader.requests.ImageLoaderRequest; @@ -52,6 +59,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{ private PhotoLayoutHelper.TiledLayoutResult tiledLayout; private final TypedObjectPool viewPool; private final List attachments; + private final Map> translatedAttachments = new HashMap<>(); private final ArrayList requests=new ArrayList<>(); public final Status status; public String sensitiveTitle; @@ -189,6 +197,25 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{ c.btnsWrap.setAlpha(1f); } controllers.add(c); + + if (item.status.translation != null){ + if(item.status.translationState==Status.TranslationState.SHOWN){ + if(!item.translatedAttachments.containsKey(att.id)){ + Optional translatedAttachment=Arrays.stream(item.status.translation.mediaAttachments).filter(mediaAttachment->mediaAttachment.id.equals(att.id)).findFirst(); + translatedAttachment.ifPresent(mediaAttachment->{ + item.translatedAttachments.put(mediaAttachment.id, new Pair<>(att.description, mediaAttachment.description)); + att.description=mediaAttachment.description; + }); + }else{ + //SAFETY: must be non-null, as we check if the map contains the attachment before + att.description=Objects.requireNonNull(item.translatedAttachments.get(att.id)).second; + } + }else{ + if (item.translatedAttachments.containsKey(att.id)) { + att.description=Objects.requireNonNull(item.translatedAttachments.get(att.id)).first; + } + } + } c.bind(att, item.status); i++; } From 6c9db5ce0d0eea3b5b8e3f8d77d9b07ff78c6345 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Wed, 1 Nov 2023 19:52:45 +0100 Subject: [PATCH 2/4] feat(status): translate poll options --- .../fragments/BaseStatusListFragment.java | 33 ++++++++----------- .../android/model/Translation.java | 10 ++++++ .../PollOptionStatusDisplayItem.java | 16 +++++++-- .../ui/displayitems/StatusDisplayItem.java | 6 ++-- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java index 2964b4522..2585f4ca6 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java @@ -493,7 +493,7 @@ public abstract class BaseStatusListFragment exten spoilerFooterIndex=spoilerItem.contentItems.indexOf(pollItems.get(pollItems.size()-1)); } pollItems.clear(); - StatusDisplayItem.buildPollItems(itemID, this, poll, pollItems); + StatusDisplayItem.buildPollItems(itemID, this, poll, status, pollItems); if(spoilerItem!=null){ spoilerItem.contentItems.subList(spoilerFirstOptionIndex, spoilerFooterIndex+1).clear(); spoilerItem.contentItems.addAll(spoilerFirstOptionIndex, pollItems); @@ -858,17 +858,7 @@ public abstract class BaseStatusListFragment exten return; status.translation=result; status.translationState=Status.TranslationState.SHOWN; - MediaGridStatusDisplayItem.Holder media=findHolderOfType(itemID, MediaGridStatusDisplayItem.Holder.class); - if (media!=null) { - media.rebind(); - } - TextStatusDisplayItem.Holder text=findHolderOfType(itemID, TextStatusDisplayItem.Holder.class); - if(text!=null){ - text.updateTranslation(true); - imgLoader.bindViewHolder((ImageLoaderRecyclerAdapter) list.getAdapter(), text, text.getAbsoluteAdapterPosition()); - }else{ - notifyItemChanged(itemID, TextStatusDisplayItem.class); - } + updateTranslation(itemID); } @Override @@ -876,12 +866,7 @@ public abstract class BaseStatusListFragment exten if(getActivity()==null) return; status.translationState=Status.TranslationState.HIDDEN; - TextStatusDisplayItem.Holder text=findHolderOfType(itemID, TextStatusDisplayItem.Holder.class); - if(text!=null){ - text.updateTranslation(true); - }else{ - notifyItemChanged(itemID, TextStatusDisplayItem.class); - } + updateTranslation(itemID); new M3AlertDialogBuilder(getActivity()) .setTitle(R.string.error) .setMessage(R.string.translation_failed) @@ -893,6 +878,10 @@ public abstract class BaseStatusListFragment exten } } } + updateTranslation(itemID); + } + + private void updateTranslation(String itemID) { TextStatusDisplayItem.Holder text=findHolderOfType(itemID, TextStatusDisplayItem.Holder.class); if(text!=null){ text.updateTranslation(true); @@ -905,9 +894,13 @@ public abstract class BaseStatusListFragment exten if (media!=null) { media.rebind(); } - } - private void updateTranslation() {} + for(int i=0;i items){ + public static void buildPollItems(String parentID, BaseStatusListFragment fragment, Poll poll, Status status, List items){ int i=0; for(Poll.Option opt:poll.options){ - items.add(new PollOptionStatusDisplayItem(parentID, poll, i, fragment)); + items.add(new PollOptionStatusDisplayItem(parentID, poll, i, fragment, status)); i++; } items.add(new PollFooterStatusDisplayItem(parentID, fragment, poll)); From be2b2903008309c4beab9c2f2ee9bc5624e43445 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Wed, 1 Nov 2023 19:56:59 +0100 Subject: [PATCH 3/4] fix(status/translation): do not require all fields --- .../java/org/joinmastodon/android/model/Translation.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java b/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java index 5a86153b4..fc4d97105 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java @@ -1,11 +1,14 @@ package org.joinmastodon.android.model; -import org.joinmastodon.android.api.AllFieldsAreRequired; -@AllFieldsAreRequired +import org.joinmastodon.android.api.RequiredField; + public class Translation extends BaseModel{ + @RequiredField public String content; + @RequiredField public String detectedSourceLanguage; + @RequiredField public String provider; public MediaAttachment[] mediaAttachments; public PollTranslation poll; From 47549fa88ca43e82527de99bcd9842eb7495bacb Mon Sep 17 00:00:00 2001 From: FineFindus Date: Wed, 1 Nov 2023 20:44:24 +0100 Subject: [PATCH 4/4] feat(status/translation): support translating spoiler --- .../android/fragments/BaseStatusListFragment.java | 5 +++++ .../org/joinmastodon/android/model/Translation.java | 1 + .../ui/displayitems/SpoilerStatusDisplayItem.java | 10 +++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java index 2585f4ca6..d7d3c111e 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java @@ -890,6 +890,11 @@ public abstract class BaseStatusListFragment exten notifyItemChanged(itemID, TextStatusDisplayItem.class); } + SpoilerStatusDisplayItem.Holder spoiler=findHolderOfType(itemID, SpoilerStatusDisplayItem.Holder.class); + if(spoiler!=null){ + spoiler.rebind(); + } + MediaGridStatusDisplayItem.Holder media=findHolderOfType(itemID, MediaGridStatusDisplayItem.Holder.class); if (media!=null) { media.rebind(); diff --git a/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java b/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java index fc4d97105..0bbe596ce 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java +++ b/mastodon/src/main/java/org/joinmastodon/android/model/Translation.java @@ -10,6 +10,7 @@ public class Translation extends BaseModel{ public String detectedSourceLanguage; @RequiredField public String provider; + public String spoilerText; public MediaAttachment[] mediaAttachments; public PollTranslation poll; diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/SpoilerStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/SpoilerStatusDisplayItem.java index 722bd5c49..e8feadaae 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/SpoilerStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/SpoilerStatusDisplayItem.java @@ -27,6 +27,7 @@ public class SpoilerStatusDisplayItem extends StatusDisplayItem{ public final Status status; public final ArrayList contentItems=new ArrayList<>(); private final CharSequence parsedTitle; + private CharSequence translatedTitle; private final CustomEmojiHelper emojiHelper; private final Type type; private final int attachmentCount; @@ -90,7 +91,14 @@ public class SpoilerStatusDisplayItem extends StatusDisplayItem{ @Override public void onBind(SpoilerStatusDisplayItem item){ - title.setText(item.parsedTitle); + if(item.status.translationState==Status.TranslationState.SHOWN){ + if(item.translatedTitle==null){ + item.translatedTitle=item.status.translation.spoilerText; + } + title.setText(item.translatedTitle); + }else{ + title.setText(item.parsedTitle); + } action.setText(item.status.spoilerRevealed ? R.string.spoiler_hide : R.string.sk_spoiler_show); itemView.setPadding( itemView.getPaddingLeft(),