From 0cd0d37eff6c676781f78cf40506f3d2bb6c8321 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Wed, 1 Nov 2023 19:23:09 +0100 Subject: [PATCH 1/6] feat(status): translate media attachments --- .../fragments/BaseStatusListFragment.java | 11 ++++++++ .../android/model/Translation.java | 6 ++++ .../MediaGridStatusDisplayItem.java | 28 +++++++++++++++++++ 3 files changed, 45 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 be1ea71f40..8655ac0e1a 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java @@ -586,6 +586,10 @@ public void onSuccess(Translation result){ 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); @@ -618,8 +622,15 @@ public void onError(ErrorResponse error){ text.updateTranslation(true); imgLoader.bindViewHolder((ImageLoaderRecyclerAdapter) list.getAdapter(), text, text.getAbsoluteAdapterPosition()); } + + 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 68487451d7..54216c8739 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 12980d1a82..c610bba5b1 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 @@ -9,6 +9,7 @@ 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; @@ -21,6 +22,8 @@ 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; import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost; @@ -31,7 +34,12 @@ 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; @@ -45,6 +53,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{ private final 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 boolean sensitiveRevealed; @@ -181,6 +190,25 @@ public void onBind(MediaGridStatusDisplayItem item){ c.altButton.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 d5d12a7ce50d04888a0f4ae52de7a4c70afbc5e7 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Wed, 1 Nov 2023 19:56:59 +0100 Subject: [PATCH 2/6] 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 54216c8739..36211edede 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; From be5f3b18af13e8d2d0f73f603dfbf335a93a0b2a Mon Sep 17 00:00:00 2001 From: FineFindus Date: Wed, 1 Nov 2023 19:52:45 +0100 Subject: [PATCH 3/6] feat(status): translate poll options --- .../fragments/BaseStatusListFragment.java | 29 +++++++++---------- .../android/model/Translation.java | 10 +++++++ .../PollOptionStatusDisplayItem.java | 16 ++++++++-- .../ui/displayitems/StatusDisplayItem.java | 6 ++-- 4 files changed, 40 insertions(+), 21 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 8655ac0e1a..e7da46ba77 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java @@ -357,7 +357,7 @@ protected void updatePoll(String itemID, Status status, Poll poll){ List pollItems=displayItems.subList(firstOptionIndex, footerIndex+1); int prevSize=pollItems.size(); pollItems.clear(); - StatusDisplayItem.buildPollItems(itemID, this, poll, pollItems); + StatusDisplayItem.buildPollItems(itemID, this, poll, pollItems, status); if(prevSize!=pollItems.size()){ adapter.notifyItemRangeRemoved(firstOptionIndex, prevSize); adapter.notifyItemRangeInserted(firstOptionIndex, pollItems.size()); @@ -586,15 +586,7 @@ public void onSuccess(Translation result){ 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()); - } + updateTranslation(itemID); } @Override @@ -602,10 +594,7 @@ public void onError(ErrorResponse error){ if(getActivity()==null) return; status.translationState=Status.TranslationState.HIDDEN; - TextStatusDisplayItem.Holder text=findHolderOfType(itemID, TextStatusDisplayItem.Holder.class); - if(text!=null){ - text.updateTranslation(true); - } + updateTranslation(itemID); new M3AlertDialogBuilder(getActivity()) .setTitle(R.string.error) .setMessage(R.string.translation_failed) @@ -617,6 +606,10 @@ public void onError(ErrorResponse error){ } } } + updateTranslation(itemID); + } + + private void updateTranslation(String itemID) { TextStatusDisplayItem.Holder text=findHolderOfType(itemID, TextStatusDisplayItem.Holder.class); if(text!=null){ text.updateTranslation(true); @@ -627,9 +620,13 @@ public void onError(ErrorResponse error){ 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 77b9efa7d165144e850afa945a788af36248cc8b Mon Sep 17 00:00:00 2001 From: FineFindus Date: Wed, 1 Nov 2023 20:44:24 +0100 Subject: [PATCH 4/6] feat(status/translation): support translating spoiler --- .../android/fragments/BaseStatusListFragment.java | 5 +++++ 1 file changed, 5 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 e7da46ba77..19edbf121b 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java @@ -616,6 +616,11 @@ private void updateTranslation(String itemID) { imgLoader.bindViewHolder((ImageLoaderRecyclerAdapter) list.getAdapter(), text, text.getAbsoluteAdapterPosition()); } + 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(); From 47b13384a8278be90ea8ba5bb062505fa15464cf Mon Sep 17 00:00:00 2001 From: FineFindus Date: Wed, 1 Nov 2023 20:44:24 +0100 Subject: [PATCH 5/6] feat(status/translation): support translating spoiler --- .../org/joinmastodon/android/model/Translation.java | 1 + .../ui/displayitems/SpoilerStatusDisplayItem.java | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) 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 fc4d971055..0bbe596cea 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 3516df08dd..bda5501b5e 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 @@ -26,6 +26,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; @@ -85,7 +86,14 @@ public Holder(Context context, ViewGroup parent, Type type){ @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.spoiler_show); } From 75e1a17a2cb7cfed087a454ad06a26f9d9f3b0d7 Mon Sep 17 00:00:00 2001 From: FineFindus Date: Fri, 10 Nov 2023 22:05:21 +0100 Subject: [PATCH 6/6] fix: add args in correct order --- .../joinmastodon/android/fragments/BaseStatusListFragment.java | 2 +- 1 file changed, 1 insertion(+), 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 19edbf121b..261f2c7863 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/BaseStatusListFragment.java @@ -357,7 +357,7 @@ protected void updatePoll(String itemID, Status status, Poll poll){ List pollItems=displayItems.subList(firstOptionIndex, footerIndex+1); int prevSize=pollItems.size(); pollItems.clear(); - StatusDisplayItem.buildPollItems(itemID, this, poll, pollItems, status); + StatusDisplayItem.buildPollItems(itemID, this, poll, status, pollItems); if(prevSize!=pollItems.size()){ adapter.notifyItemRangeRemoved(firstOptionIndex, prevSize); adapter.notifyItemRangeInserted(firstOptionIndex, pollItems.size());