megalodon/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/TextStatusDisplayItem.java

231 lines
9.7 KiB
Java
Raw Normal View History

2022-01-17 11:27:34 +01:00
package org.joinmastodon.android.ui.displayitems;
import android.app.Activity;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
2022-02-16 22:31:01 +01:00
import android.text.TextUtils;
import android.view.View;
2022-01-17 11:27:34 +01:00
import android.view.ViewGroup;
import android.widget.LinearLayout;
2022-12-09 02:37:38 +01:00
import android.widget.Button;
2022-02-16 22:31:01 +01:00
import android.widget.TextView;
import android.widget.Toast;
import com.github.bottomSoftwareFoundation.bottom.Bottom;
import com.github.bottomSoftwareFoundation.bottom.TranslationError;
2022-01-17 11:27:34 +01:00
2022-12-21 16:35:47 +01:00
import org.joinmastodon.android.GlobalUserPreferences;
2022-01-17 11:27:34 +01:00
import org.joinmastodon.android.R;
2022-12-09 02:37:38 +01:00
import org.joinmastodon.android.api.requests.statuses.TranslateStatus;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
2022-02-08 11:25:17 +01:00
import org.joinmastodon.android.fragments.BaseStatusListFragment;
2022-12-09 02:37:38 +01:00
import org.joinmastodon.android.model.Instance;
2022-02-16 22:31:01 +01:00
import org.joinmastodon.android.model.Status;
2022-12-09 02:37:38 +01:00
import org.joinmastodon.android.model.StatusPrivacy;
import org.joinmastodon.android.model.TranslatedStatus;
2022-05-13 18:10:27 +02:00
import org.joinmastodon.android.ui.text.HtmlParser;
2022-03-02 10:38:14 +01:00
import org.joinmastodon.android.ui.utils.CustomEmojiHelper;
2022-12-21 19:46:24 +01:00
import org.joinmastodon.android.ui.utils.UiUtils;
2022-01-17 11:27:34 +01:00
import org.joinmastodon.android.ui.views.LinkedTextView;
import org.joinmastodon.android.utils.StringEncoder;
import java.util.regex.Pattern;
2022-01-17 11:27:34 +01:00
2022-12-09 02:37:38 +01:00
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
2022-01-17 11:27:34 +01:00
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
import me.grishka.appkit.imageloader.MovieDrawable;
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
2022-12-21 16:19:08 +01:00
import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
2022-01-17 11:27:34 +01:00
2022-02-09 15:53:27 +01:00
public class TextStatusDisplayItem extends StatusDisplayItem{
2022-01-17 11:27:34 +01:00
private CharSequence text;
2022-05-13 18:10:27 +02:00
private CustomEmojiHelper emojiHelper=new CustomEmojiHelper(), spoilerEmojiHelper;
private CharSequence parsedSpoilerText;
2022-04-07 17:33:39 +02:00
public boolean textSelectable;
2022-02-16 22:31:01 +01:00
public final Status status;
public boolean disableTranslate;
2022-12-09 02:37:38 +01:00
public boolean translated = false;
public TranslatedStatus translation = null;
private AccountSession session;
public static final Pattern BOTTOM_TEXT_PATTERN = Pattern.compile("(?:[\uD83E\uDEC2\uD83D\uDC96✨\uD83E\uDD7A,]+|❤️)(?:\uD83D\uDC49\uD83D\uDC48(?:[\uD83E\uDEC2\uD83D\uDC96✨\uD83E\uDD7A,]+|❤️))*\uD83D\uDC49\uD83D\uDC48");
2022-02-16 22:31:01 +01:00
public TextStatusDisplayItem(String parentID, CharSequence text, BaseStatusListFragment parentFragment, Status status, boolean disableTranslate){
2022-02-08 11:25:17 +01:00
super(parentID, parentFragment);
2022-01-17 11:27:34 +01:00
this.text=text;
2022-02-16 22:31:01 +01:00
this.status=status;
this.disableTranslate=disableTranslate;
emojiHelper.setText(text);
2022-05-13 18:10:27 +02:00
if(!TextUtils.isEmpty(status.spoilerText)){
parsedSpoilerText=HtmlParser.parseCustomEmoji(status.spoilerText, status.emojis);
spoilerEmojiHelper=new CustomEmojiHelper();
spoilerEmojiHelper.setText(parsedSpoilerText);
}
2022-12-09 02:37:38 +01:00
session = AccountSessionManager.getInstance().getAccount(parentFragment.getAccountID());
2022-01-17 11:27:34 +01:00
}
@Override
public Type getType(){
return Type.TEXT;
}
@Override
public int getImageCount(){
2022-05-13 18:10:27 +02:00
if(spoilerEmojiHelper!=null && !status.spoilerRevealed)
return spoilerEmojiHelper.getImageCount();
return emojiHelper.getImageCount();
2022-01-17 11:27:34 +01:00
}
@Override
public ImageLoaderRequest getImageRequest(int index){
2022-05-13 18:10:27 +02:00
if(spoilerEmojiHelper!=null && !status.spoilerRevealed)
return spoilerEmojiHelper.getImageRequest(index);
return emojiHelper.getImageRequest(index);
2022-01-17 11:27:34 +01:00
}
2022-02-08 17:49:45 +01:00
public static class Holder extends StatusDisplayItem.Holder<TextStatusDisplayItem> implements ImageLoaderViewHolder{
2022-01-17 11:27:34 +01:00
private final LinkedTextView text;
private final LinearLayout spoilerHeader;
private final TextView spoilerTitle, spoilerTitleInline, translateInfo;
private final View spoilerOverlay, borderTop, borderBottom, textWrap, translateWrap, translateProgress;
2022-12-21 19:46:24 +01:00
private final int backgroundColor, borderColor;
2022-12-09 02:37:38 +01:00
private final Button translateButton;
2022-01-17 11:27:34 +01:00
public Holder(Activity activity, ViewGroup parent){
super(activity, R.layout.display_item_text, parent);
text=findViewById(R.id.text);
2022-02-16 22:31:01 +01:00
spoilerTitle=findViewById(R.id.spoiler_title);
2022-11-17 00:43:37 +01:00
spoilerTitleInline=findViewById(R.id.spoiler_title_inline);
spoilerHeader=findViewById(R.id.spoiler_header);
2022-02-16 22:31:01 +01:00
spoilerOverlay=findViewById(R.id.spoiler_overlay);
borderTop=findViewById(R.id.border_top);
borderBottom=findViewById(R.id.border_bottom);
2022-12-09 02:37:38 +01:00
textWrap=findViewById(R.id.text_wrap);
translateWrap=findViewById(R.id.translate_wrap);
translateButton=findViewById(R.id.translate_btn);
translateInfo=findViewById(R.id.translate_info);
2022-12-09 03:05:17 +01:00
translateProgress=findViewById(R.id.translate_progress);
2022-02-16 22:31:01 +01:00
itemView.setOnClickListener(v->item.parentFragment.onRevealSpoilerClick(this));
2022-12-21 19:46:24 +01:00
backgroundColor=UiUtils.getThemeColor(activity, R.attr.colorBackgroundLight);
borderColor=UiUtils.getThemeColor(activity, R.attr.colorPollVoted);
2022-01-17 11:27:34 +01:00
}
@Override
public void onBind(TextStatusDisplayItem item){
2022-12-09 02:37:38 +01:00
text.setText(item.translated
? HtmlParser.parse(item.translation.content, item.status.emojis, item.status.mentions, item.status.tags, item.parentFragment.getAccountID())
: item.text);
2022-04-07 17:33:39 +02:00
text.setTextIsSelectable(item.textSelectable);
2022-11-17 20:46:39 +01:00
spoilerTitleInline.setTextIsSelectable(item.textSelectable);
2022-01-17 11:27:34 +01:00
text.setInvalidateOnEveryFrame(false);
2022-12-21 19:46:24 +01:00
spoilerTitleInline.setBackgroundColor(item.inset ? 0 : backgroundColor);
spoilerTitleInline.setPadding(spoilerTitleInline.getPaddingLeft(), item.inset ? 0 : V.dp(14), spoilerTitleInline.getPaddingRight(), item.inset ? 0 : V.dp(14));
2022-12-21 19:46:24 +01:00
borderTop.setBackgroundColor(item.inset ? 0 : borderColor);
borderBottom.setBackgroundColor(item.inset ? 0 : borderColor);
2022-02-16 22:31:01 +01:00
if(!TextUtils.isEmpty(item.status.spoilerText)){
2022-05-13 18:10:27 +02:00
spoilerTitle.setText(item.parsedSpoilerText);
2022-11-17 00:43:37 +01:00
spoilerTitleInline.setText(item.parsedSpoilerText);
2022-02-16 22:31:01 +01:00
if(item.status.spoilerRevealed){
spoilerOverlay.setVisibility(View.GONE);
2022-11-17 00:43:37 +01:00
spoilerHeader.setVisibility(View.VISIBLE);
2022-12-09 02:37:38 +01:00
textWrap.setVisibility(View.VISIBLE);
2022-02-16 22:31:01 +01:00
itemView.setClickable(false);
}else{
spoilerOverlay.setVisibility(View.VISIBLE);
spoilerHeader.setVisibility(View.GONE);
textWrap.setVisibility(View.GONE);
2022-02-16 22:31:01 +01:00
itemView.setClickable(true);
}
}else{
spoilerOverlay.setVisibility(View.GONE);
2022-11-17 00:43:37 +01:00
spoilerHeader.setVisibility(View.GONE);
2022-12-09 02:37:38 +01:00
textWrap.setVisibility(View.VISIBLE);
2022-02-16 22:31:01 +01:00
itemView.setClickable(false);
}
2022-12-09 02:37:38 +01:00
Instance instanceInfo = AccountSessionManager.getInstance().getInstanceInfo(item.session.domain);
2023-01-24 02:17:15 +01:00
boolean translateEnabled = !item.disableTranslate && instanceInfo != null &&
instanceInfo.v2 != null && instanceInfo.v2.configuration.translation != null &&
instanceInfo.v2.configuration.translation.enabled;
boolean isBottomText = BOTTOM_TEXT_PATTERN.matcher(item.status.getStrippedText()).find();
translateWrap.setVisibility((isBottomText || (
2022-12-21 16:35:47 +01:00
translateEnabled &&
2022-12-09 02:37:38 +01:00
!item.status.visibility.isLessVisibleThan(StatusPrivacy.UNLISTED) &&
item.status.language != null &&
(item.session.preferences == null || !item.status.language.equalsIgnoreCase(item.session.preferences.postingDefaultLanguage))))
&& (!GlobalUserPreferences.translateButtonOpenedOnly || item.textSelectable)
? View.VISIBLE : View.GONE
);
translateButton.setText(item.translated ? R.string.sk_translate_show_original : R.string.sk_translate_post);
translateInfo.setText(item.translated ? itemView.getResources().getString(R.string.sk_translated_using, isBottomText ? "bottom-java" : item.translation.provider) : "");
2022-12-09 02:37:38 +01:00
translateButton.setOnClickListener(v->{
if (item.translation == null) {
if (isBottomText) {
try {
item.translation = new TranslatedStatus();
item.translation.content = new StringEncoder(Bottom::decode).decode(item.status.getStrippedText(), BOTTOM_TEXT_PATTERN);
item.translated = true;
} catch (TranslationError err) {
item.translation = null;
Toast.makeText(itemView.getContext(), err.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
rebind();
return;
}
2022-12-09 03:05:17 +01:00
translateProgress.setVisibility(View.VISIBLE);
translateButton.setClickable(false);
2022-12-21 16:19:08 +01:00
translateButton.animate().alpha(0.5f).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(150).start();
2022-12-09 02:37:38 +01:00
new TranslateStatus(item.status.id).setCallback(new Callback<>() {
@Override
public void onSuccess(TranslatedStatus translatedStatus) {
item.translation = translatedStatus;
item.translated = true;
2023-01-25 23:23:43 +01:00
if (item.parentFragment.getActivity() == null) return;
2022-12-09 03:05:17 +01:00
translateProgress.setVisibility(View.GONE);
translateButton.setClickable(true);
2022-12-21 16:19:08 +01:00
translateButton.animate().alpha(1).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(50).start();
2022-12-09 02:37:38 +01:00
rebind();
}
@Override
public void onError(ErrorResponse error) {
2022-12-09 03:05:17 +01:00
translateProgress.setVisibility(View.GONE);
translateButton.setClickable(true);
2022-12-21 16:19:08 +01:00
translateButton.animate().alpha(1).setInterpolator(CubicBezierInterpolator.DEFAULT).setDuration(50).start();
2022-12-09 02:37:38 +01:00
error.showToast(itemView.getContext());
}
}).exec(item.parentFragment.getAccountID());
} else {
item.translated = !item.translated;
rebind();
}
});
2022-01-17 11:27:34 +01:00
}
@Override
public void setImage(int index, Drawable image){
2022-05-13 18:10:27 +02:00
getEmojiHelper().setImageDrawable(index, image);
2022-01-17 11:27:34 +01:00
text.invalidate();
2022-05-13 18:10:27 +02:00
spoilerTitle.invalidate();
2022-01-17 11:27:34 +01:00
if(image instanceof Animatable){
((Animatable) image).start();
if(image instanceof MovieDrawable)
text.setInvalidateOnEveryFrame(true);
}
}
@Override
public void clearImage(int index){
2022-05-13 18:10:27 +02:00
getEmojiHelper().setImageDrawable(index, null);
2022-01-17 11:27:34 +01:00
text.invalidate();
}
2022-05-13 18:10:27 +02:00
private CustomEmojiHelper getEmojiHelper(){
return item.spoilerEmojiHelper!=null && !item.status.spoilerRevealed ? item.spoilerEmojiHelper : item.emojiHelper;
}
2022-01-17 11:27:34 +01:00
}
}