finalized Emoji support (Mastodon), bug fix

This commit is contained in:
nuclearfog 2023-03-25 18:18:55 +01:00
parent af381a8feb
commit fc675a4e6f
No known key found for this signature in database
GPG Key ID: 03488A185C476379
13 changed files with 166 additions and 103 deletions

View File

@ -74,11 +74,12 @@ public class ImageCache {
if (imageFolder != null && !files.containsKey(key)) {
try {
File file = new File(imageFolder, key);
file.createNewFile();
FileOutputStream output = new FileOutputStream(file);
image.compress(Bitmap.CompressFormat.PNG, 1, output);
files.put(key, file);
} catch (IOException e) {
if (file.createNewFile()) {
FileOutputStream output = new FileOutputStream(file);
image.compress(Bitmap.CompressFormat.PNG, 1, output);
files.put(key, file);
}
} catch (IOException|SecurityException e) {
e.printStackTrace();
}
}

View File

@ -0,0 +1,53 @@
package org.nuclearfog.twidda.backend.utils;
import android.graphics.Bitmap;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ImageSpan;
import android.widget.TextView;
import java.util.Map;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* This class provides method to replace tags (e.g. :tagname:) from a TextView with bitmap drawables
*
* @author nuclearfog
*/
public class TextWithEmoji {
private static final Pattern EMOJI_PATTERN = Pattern.compile(":\\w+:");
private TextWithEmoji() {}
/**
* replace tags with emojis
*
* @param textView textview containing text with emoji tags (e.g. :tagname:)
* @param emojis a map of emoji tags & bitmap. every emoji bitmap has its own tag
*/
public static void addEmojis(TextView textView, Map<String, Bitmap> emojis) {
if (textView.length() > 0) {
SpannableStringBuilder builder = new SpannableStringBuilder(textView.getText());
Matcher matcher = EMOJI_PATTERN.matcher(textView.getText());
Stack<Integer> indexes = new Stack<>();
while (matcher.find()) {
indexes.push(matcher.start());
indexes.push(matcher.end());
}
while (!indexes.isEmpty()) {
int end = indexes.pop();
int start = indexes.pop();
String tag = builder.subSequence(start + 1, end - 1).toString();
Bitmap emoji = emojis.get(tag);
if (emoji != null) {
ImageSpan imgSpan = new ImageSpan(textView.getContext(), emoji);
builder.setSpan(imgSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
textView.setText(builder);
}
}
}

View File

@ -1453,7 +1453,16 @@ public class AppDatabase {
} else {
flags &= ~MASK_USER_DEFAULT_IMAGE;
}
ContentValues column = new ContentValues(13);
ContentValues column = new ContentValues(14);
if (user.getEmojis().length > 0) {
StringBuilder buf = new StringBuilder();
saveEmojis(user.getEmojis(), db);
for (Emoji emoji : user.getEmojis()) {
buf.append(emoji.getCode()).append(';');
}
String emojiKeys = buf.deleteCharAt(buf.length() - 1).toString();
column.put(UserTable.EMOJI, emojiKeys);
}
column.put(UserTable.ID, user.getId());
column.put(UserTable.USERNAME, user.getUsername());
column.put(UserTable.SCREENNAME, user.getScreenname());

View File

@ -16,7 +16,7 @@ public class DatabasePoll implements Poll {
private static final long serialVersionUID = 3534663789678017084L;
private static final Pattern SPLIT = Pattern.compile(";");
private static final Pattern SEPARATOR = Pattern.compile(";");
public static final String[] PROJECTION = {
PollTable.ID,
@ -39,7 +39,7 @@ public class DatabasePoll implements Poll {
expired = cursor.getLong(2);
String optionStr = cursor.getString(3);
if (optionStr != null && !optionStr.isEmpty()) {
String[] optArray = SPLIT.split(optionStr);
String[] optArray = SEPARATOR.split(optionStr);
options = new DatabasePollOption[optArray.length];
for (int i = 0; i < optArray.length; i++) {
options[i] = new DatabasePollOption(optArray[i]);

View File

@ -38,38 +38,24 @@ public class DatabaseStatus implements Status {
private static final Pattern KEY_SEPARATOR = Pattern.compile(";");
private long id;
private long time;
private long embeddedId;
private long replyID;
private long replyUserId;
private long myRepostId;
private long locationId;
private long pollId;
private long id, time, embeddedId, replyID, replyUserId, myRepostId, locationId, pollId;
private int repostCount, favoriteCount, replyCount;
private boolean reposted, favorited, bookmarked, sensitive, spoiler, isHidden;
private Status embedded;
private Poll poll;
private User author;
private Location location;
private String[] mediaKeys = {};
private String[] emojiKeys = {};
private Media[] medias = {};
private Emoji[] emojis = {};
private Card[] cards = {};
private Poll poll;
private User author;
private Location location;
private int repostCount;
private int favoriteCount;
private int replyCount;
private String replyName = "";
private String text = "";
private String source = "";
private String userMentions = "";
private String statusUrl = "";
private String language = "";
private boolean reposted;
private boolean favorited;
private boolean bookmarked;
private boolean sensitive;
private boolean spoiler;
private boolean isHidden;
/**
* @param cursor database cursor

View File

@ -29,17 +29,9 @@ public class DatabaseUser implements User {
private static final Pattern KEY_SEPARATOR = Pattern.compile(";");
private long id;
private long createdAt;
private int following;
private int follower;
private int statusCount;
private int favorCount;
private boolean isCurrentUser;
private boolean isVerified;
private boolean isLocked;
private boolean followReqSent;
private boolean defaultImage;
private long id, createdAt;
private int following, follower, statusCount, favorCount;
private boolean isCurrentUser, isVerified, isLocked, followReqSent, defaultImage;
private String username = "";
private String screen_name = "";
private String bio = "";
@ -94,8 +86,6 @@ public class DatabaseUser implements User {
this.profileBannerOrig = profileBannerOrig;
if (emojiKeys != null && !emojiKeys.isEmpty())
this.emojiKeys = KEY_SEPARATOR.split(emojiKeys);
if (emojiKeys != null && !emojiKeys.isEmpty())
this.emojiKeys = KEY_SEPARATOR.split(emojiKeys);
switch (account.getConfiguration()) {
case TWITTER1:

View File

@ -21,14 +21,10 @@ import static org.nuclearfog.twidda.ui.activities.UsersActivity.USERS_REQUESTS;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ImageSpan;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@ -78,6 +74,7 @@ import org.nuclearfog.twidda.backend.utils.AppStyles;
import org.nuclearfog.twidda.backend.utils.ErrorHandler;
import org.nuclearfog.twidda.backend.utils.PicassoBuilder;
import org.nuclearfog.twidda.backend.utils.StringTools;
import org.nuclearfog.twidda.backend.utils.TextWithEmoji;
import org.nuclearfog.twidda.config.Configuration;
import org.nuclearfog.twidda.config.GlobalSettings;
import org.nuclearfog.twidda.database.impl.DatabaseUser;
@ -89,7 +86,6 @@ import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog.OnConfirmListener;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation;
@ -157,7 +153,7 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult
private ConstraintLayout header;
private ViewGroup body;
private TextView[] tabIndicator;
private TextView user_location, user_createdAt, user_website, user_bio, follow_back, username, screenName;
private TextView user_location, user_createdAt, user_website, description, follow_back, username, screenName;
private ImageView profileImage, bannerImage, toolbarBackground;
private Button following, follower;
private ViewPager tabPages;
@ -185,7 +181,7 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult
body = findViewById(R.id.page_profile_body);
root = findViewById(R.id.user_view);
toolbar = findViewById(R.id.profile_toolbar);
user_bio = findViewById(R.id.bio);
description = findViewById(R.id.bio);
following = findViewById(R.id.following);
follower = findViewById(R.id.follower);
user_website = findViewById(R.id.links);
@ -220,8 +216,8 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult
toolbar.setBackgroundColor(settings.getBackgroundColor() & TOOLBAR_TRANSPARENCY);
username.setBackgroundColor(settings.getBackgroundColor() & TEXT_TRANSPARENCY);
follow_back.setBackgroundColor(settings.getBackgroundColor() & TEXT_TRANSPARENCY);
user_bio.setMovementMethod(LinkAndScrollMovement.getInstance());
user_bio.setLinkTextColor(settings.getHighlightColor());
description.setMovementMethod(LinkAndScrollMovement.getInstance());
description.setLinkTextColor(settings.getHighlightColor());
AppStyles.setTheme(root);
user_website.setTextColor(settings.getHighlightColor());
tabLayout.setBackgroundColor(Color.TRANSPARENT);
@ -775,10 +771,10 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult
user_location.setVisibility(GONE);
}
if (!user.getDescription().isEmpty()) {
user_bio.setVisibility(VISIBLE);
user_bio.setText(bio);
description.setVisibility(VISIBLE);
description.setText(bio);
} else {
user_bio.setVisibility(GONE);
description.setVisibility(GONE);
}
if (!user.getProfileUrl().isEmpty()) {
String link = user.getProfileUrl();
@ -819,20 +815,8 @@ public class ProfileActivity extends AppCompatActivity implements ActivityResult
*/
private void onEmojiResult(EmojiLoader.EmojiResult result) {
if (settings.getLogin().getConfiguration() == Configuration.MASTODON && result.images != null) {
TextView[] textViews = {username, user_bio};
for (TextView textView: textViews) {
if (textView.length() > 0) {
SpannableStringBuilder builder = new SpannableStringBuilder(textView.getText());
for (Map.Entry<String, Bitmap> item : result.images.entrySet()) {
int idx = TextUtils.indexOf(builder, ':' + item.getKey() + ':');
if (idx >= 0) {
ImageSpan imgSpan = new ImageSpan(getApplicationContext(), item.getValue());
builder.setSpan(imgSpan, idx, idx + item.getKey().length() + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
textView.setText(builder);
}
}
TextWithEmoji.addEmojis(username, result.images);
TextWithEmoji.addEmojis(description, result.images);
}
}
}

View File

@ -17,15 +17,10 @@ import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.net.Uri;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ImageSpan;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
@ -74,6 +69,7 @@ import org.nuclearfog.twidda.backend.utils.AppStyles;
import org.nuclearfog.twidda.backend.utils.ErrorHandler;
import org.nuclearfog.twidda.backend.utils.PicassoBuilder;
import org.nuclearfog.twidda.backend.utils.StringTools;
import org.nuclearfog.twidda.backend.utils.TextWithEmoji;
import org.nuclearfog.twidda.config.Configuration;
import org.nuclearfog.twidda.config.GlobalSettings;
import org.nuclearfog.twidda.database.impl.DatabaseNotification;
@ -97,7 +93,6 @@ import org.nuclearfog.twidda.ui.fragments.StatusFragment;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
import jp.wasabeef.picasso.transformations.RoundedCornersTransformation;
@ -218,7 +213,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
private NestedScrollView container;
private ViewGroup root, body;
private TextView statusApi, createdAt, statusText, screenName, userName, locationName, sensitive, spoiler, spoilerHint, translateText;
private TextView statusApi, createdAt, statusText, screenName, username, locationName, sensitive, spoiler, spoilerHint, translateText;
private Button replyButton, repostButton, likeButton, replyName, repostNameButton;
private ImageView profileImage;
private RecyclerView cardList;
@ -250,7 +245,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
replyButton = findViewById(R.id.page_status_reply);
repostButton = findViewById(R.id.page_status_repost);
likeButton = findViewById(R.id.page_status_favorite);
userName = findViewById(R.id.page_status_username);
username = findViewById(R.id.page_status_username);
screenName = findViewById(R.id.page_status_screenname);
profileImage = findViewById(R.id.page_status_profile);
replyName = findViewById(R.id.page_status_reply_reference);
@ -831,10 +826,10 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
AppStyles.setDrawableColor(likeButton, settings.getIconColor());
}
if (author.isVerified()) {
userName.setCompoundDrawablesWithIntrinsicBounds(R.drawable.verify, 0, 0, 0);
AppStyles.setDrawableColor(userName, settings.getIconColor());
username.setCompoundDrawablesWithIntrinsicBounds(R.drawable.verify, 0, 0, 0);
AppStyles.setDrawableColor(username, settings.getIconColor());
} else {
userName.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
username.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
if (author.isProtected()) {
screenName.setCompoundDrawablesWithIntrinsicBounds(R.drawable.lock, 0, 0, 0);
@ -846,7 +841,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
translateText.setVisibility(View.VISIBLE);
translateText.setTextColor(settings.getHighlightColor());
}
userName.setText(author.getUsername());
username.setText(author.getUsername());
screenName.setText(author.getScreenname());
createdAt.setText(SimpleDateFormat.getDateTimeInstance().format(status.getTimestamp()));
replyButton.setText(StringTools.NUMBER_FORMAT.format(status.getReplyCount()));
@ -1152,20 +1147,8 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
*/
private void onEmojiResult(EmojiResult result) {
if (settings.getLogin().getConfiguration() == Configuration.MASTODON && result.images != null) {
TextView[] textViews = {statusText, userName};
for (TextView textView : textViews) {
if (textView.length() > 0) {
SpannableStringBuilder builder = new SpannableStringBuilder(textView.getText());
for (Map.Entry<String, Bitmap> item : result.images.entrySet()) {
int idx = TextUtils.indexOf(builder, ':' + item.getKey() + ':');
if (idx >= 0) {
ImageSpan imgSpan = new ImageSpan(getApplicationContext(), item.getValue());
builder.setSpan(imgSpan, idx, idx + item.getKey().length() + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
textView.setText(builder);
}
}
TextWithEmoji.addEmojis(statusText, result.images);
TextWithEmoji.addEmojis(username, result.images);
}
}
}

View File

@ -10,6 +10,7 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.squareup.picasso.Picasso;
import org.nuclearfog.twidda.backend.async.EmojiLoader;
import org.nuclearfog.twidda.backend.utils.PicassoBuilder;
import org.nuclearfog.twidda.config.GlobalSettings;
import org.nuclearfog.twidda.model.Notification;
@ -54,6 +55,7 @@ public class NotificationAdapter extends Adapter<ViewHolder> implements OnHolder
private Picasso picasso;
private GlobalSettings settings;
private OnNotificationClickListener listener;
private EmojiLoader emojiLoader;
private List<Notification> items;
private int loadingIndex;
@ -62,6 +64,7 @@ public class NotificationAdapter extends Adapter<ViewHolder> implements OnHolder
public NotificationAdapter(Context context, OnNotificationClickListener listener) {
settings = GlobalSettings.getInstance(context);
picasso = PicassoBuilder.get(context);
emojiLoader = new EmojiLoader(context);
items = new LinkedList<>();
loadingIndex = NO_LOADING;
this.listener = listener;
@ -72,9 +75,9 @@ public class NotificationAdapter extends Adapter<ViewHolder> implements OnHolder
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == TYPE_STATUS) {
return new StatusHolder(parent, settings, picasso, this);
return new StatusHolder(parent, settings, picasso, emojiLoader, this);
} else if (viewType == TYPE_USER) {
return new UserHolder(parent, settings, picasso, this, false);
return new UserHolder(parent, settings, picasso, emojiLoader, this, false);
} else {
return new PlaceHolder(parent, settings, false, this);
}

View File

@ -11,6 +11,7 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.squareup.picasso.Picasso;
import org.nuclearfog.twidda.backend.async.EmojiLoader;
import org.nuclearfog.twidda.backend.utils.PicassoBuilder;
import org.nuclearfog.twidda.config.GlobalSettings;
import org.nuclearfog.twidda.model.Status;
@ -50,6 +51,7 @@ public class StatusAdapter extends Adapter<ViewHolder> implements OnHolderClickL
*/
private static final int MIN_COUNT = 2;
private EmojiLoader emojiLoader;
private StatusSelectListener listener;
private GlobalSettings settings;
private Picasso picasso;
@ -63,6 +65,7 @@ public class StatusAdapter extends Adapter<ViewHolder> implements OnHolderClickL
public StatusAdapter(Context context, StatusSelectListener itemClickListener) {
settings = GlobalSettings.getInstance(context);
picasso = PicassoBuilder.get(context);
emojiLoader = new EmojiLoader(context);
loadingIndex = NO_LOADING;
items = new LinkedList<>();
this.listener = itemClickListener;
@ -96,7 +99,7 @@ public class StatusAdapter extends Adapter<ViewHolder> implements OnHolderClickL
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_STATUS) {
return new StatusHolder(parent, settings, picasso, this);
return new StatusHolder(parent, settings, picasso, emojiLoader, this);
} else {
return new PlaceHolder(parent, settings, false, this);
}
@ -108,7 +111,8 @@ public class StatusAdapter extends Adapter<ViewHolder> implements OnHolderClickL
if (holder instanceof StatusHolder) {
Status status = items.get(index);
if (status != null) {
((StatusHolder) holder).setContent(status);
StatusHolder statusHolder = ((StatusHolder) holder);
statusHolder.setContent(status);
}
} else if (holder instanceof PlaceHolder) {
PlaceHolder placeHolder = (PlaceHolder) holder;

View File

@ -11,6 +11,7 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.squareup.picasso.Picasso;
import org.nuclearfog.twidda.backend.async.EmojiLoader;
import org.nuclearfog.twidda.backend.helper.Users;
import org.nuclearfog.twidda.backend.utils.PicassoBuilder;
import org.nuclearfog.twidda.config.GlobalSettings;
@ -44,6 +45,7 @@ public class UserAdapter extends Adapter<ViewHolder> implements OnHolderClickLis
private GlobalSettings settings;
private Picasso picasso;
private EmojiLoader emojiLoader;
private UserClickListener listener;
private boolean enableDelete;
@ -58,6 +60,7 @@ public class UserAdapter extends Adapter<ViewHolder> implements OnHolderClickLis
public UserAdapter(Context context, UserClickListener listener, boolean enableDelete) {
settings = GlobalSettings.getInstance(context);
picasso = PicassoBuilder.get(context);
emojiLoader = new EmojiLoader(context);
users = new Users(0L, 0L);
loadingIndex = NO_LOADING;
this.enableDelete = enableDelete;
@ -92,7 +95,7 @@ public class UserAdapter extends Adapter<ViewHolder> implements OnHolderClickLis
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == ITEM_USER) {
return new UserHolder(parent, settings, picasso, this, enableDelete);
return new UserHolder(parent, settings, picasso, emojiLoader, this, enableDelete);
} else {
return new PlaceHolder(parent, settings, false, this);
}

View File

@ -24,9 +24,16 @@ import com.squareup.picasso.Transformation;
import org.nuclearfog.tag.Tagger;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.async.AsyncExecutor.AsyncCallback;
import org.nuclearfog.twidda.backend.async.EmojiLoader;
import org.nuclearfog.twidda.backend.async.EmojiLoader.EmojiParam;
import org.nuclearfog.twidda.backend.async.EmojiLoader.EmojiResult;
import org.nuclearfog.twidda.backend.utils.AppStyles;
import org.nuclearfog.twidda.backend.utils.StringTools;
import org.nuclearfog.twidda.backend.utils.TextWithEmoji;
import org.nuclearfog.twidda.config.Configuration;
import org.nuclearfog.twidda.config.GlobalSettings;
import org.nuclearfog.twidda.model.Emoji;
import org.nuclearfog.twidda.model.Notification;
import org.nuclearfog.twidda.model.Status;
import org.nuclearfog.twidda.model.User;
@ -41,7 +48,7 @@ import jp.wasabeef.picasso.transformations.RoundedCornersTransformation;
* @author nuclearfog
* @see StatusAdapter
*/
public class StatusHolder extends ViewHolder implements OnClickListener {
public class StatusHolder extends ViewHolder implements OnClickListener, AsyncCallback<EmojiResult> {
private ImageView profile, repostUserIcon, verifiedIcon, lockedIcon, repostIcon, favoriteIcon, replyStatus;
private TextView username, screenname, text, repost, favorite, reply, reposter, created, replyname, label;
@ -50,15 +57,17 @@ public class StatusHolder extends ViewHolder implements OnClickListener {
private GlobalSettings settings;
private Picasso picasso;
private EmojiLoader emojiLoader;
private IconAdapter adapter;
private OnHolderClickListener listener;
public StatusHolder(ViewGroup parent, GlobalSettings settings, Picasso picasso, OnHolderClickListener listener) {
public StatusHolder(ViewGroup parent, GlobalSettings settings, Picasso picasso, EmojiLoader emojiLoader, OnHolderClickListener listener) {
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_status, parent, false));
this.settings = settings;
this.picasso = picasso;
this.listener = listener;
this.emojiLoader = emojiLoader;
CardView cardLayout = (CardView) itemView;
ViewGroup container = itemView.findViewById(R.id.item_status_container);
@ -114,6 +123,15 @@ public class StatusHolder extends ViewHolder implements OnClickListener {
}
}
@Override
public void onResult(EmojiResult result) {
if (settings.getLogin().getConfiguration() == Configuration.MASTODON && result.images != null) {
TextWithEmoji.addEmojis(text, result.images);
TextWithEmoji.addEmojis(username, result.images);
}
}
/**
* set view content
*
@ -202,6 +220,16 @@ public class StatusHolder extends ViewHolder implements OnClickListener {
} else {
iconList.setVisibility(View.GONE);
}
if (status.getEmojis().length > 0 || status.getAuthor().getEmojis().length > 0) {
int index = 0;
Emoji[] emojis = new Emoji[status.getEmojis().length + status.getAuthor().getEmojis().length];
for (Emoji emoji : status.getEmojis())
emojis[index++] = emoji;
for (Emoji emoji : status.getAuthor().getEmojis())
emojis[index++] = emoji;
EmojiParam param = new EmojiParam(emojis, text.getLineHeight());
emojiLoader.execute(param, this);
}
}
/**

View File

@ -21,8 +21,14 @@ import com.squareup.picasso.Picasso;
import com.squareup.picasso.Transformation;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.async.AsyncExecutor.AsyncCallback;
import org.nuclearfog.twidda.backend.async.EmojiLoader;
import org.nuclearfog.twidda.backend.async.EmojiLoader.EmojiParam;
import org.nuclearfog.twidda.backend.async.EmojiLoader.EmojiResult;
import org.nuclearfog.twidda.backend.utils.AppStyles;
import org.nuclearfog.twidda.backend.utils.StringTools;
import org.nuclearfog.twidda.backend.utils.TextWithEmoji;
import org.nuclearfog.twidda.config.Configuration;
import org.nuclearfog.twidda.config.GlobalSettings;
import org.nuclearfog.twidda.model.Notification;
import org.nuclearfog.twidda.model.User;
@ -35,7 +41,7 @@ import jp.wasabeef.picasso.transformations.RoundedCornersTransformation;
* @author nuclearfog
* @see org.nuclearfog.twidda.ui.adapter.UserAdapter
*/
public class UserHolder extends ViewHolder implements OnClickListener {
public class UserHolder extends ViewHolder implements OnClickListener, AsyncCallback<EmojiResult> {
private TextView username, screenname, followingCount, followerCount, label;
private ImageView profileImg, verifyIcon, lockedIcon;
@ -43,16 +49,18 @@ public class UserHolder extends ViewHolder implements OnClickListener {
private View notificationDismiss;
private GlobalSettings settings;
private EmojiLoader emojiLoader;
private Picasso picasso;
private OnHolderClickListener listener;
public UserHolder(ViewGroup parent, GlobalSettings settings, Picasso picasso, OnHolderClickListener listener, boolean enableDelete) {
public UserHolder(ViewGroup parent, GlobalSettings settings, Picasso picasso, EmojiLoader emojiLoader, OnHolderClickListener listener, boolean enableDelete) {
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user, parent, false));
this.settings = settings;
this.picasso = picasso;
this.listener = listener;
this.emojiLoader = emojiLoader;
CardView background = (CardView) itemView;
ViewGroup container = itemView.findViewById(R.id.item_user_container);
@ -74,7 +82,6 @@ public class UserHolder extends ViewHolder implements OnClickListener {
} else {
delete.setVisibility(GONE);
}
itemView.setOnClickListener(this);
notificationDismiss.setOnClickListener(this);
delete.setOnClickListener(this);
@ -95,6 +102,14 @@ public class UserHolder extends ViewHolder implements OnClickListener {
}
}
@Override
public void onResult(EmojiResult result) {
if (settings.getLogin().getConfiguration() == Configuration.MASTODON && result.images != null) {
TextWithEmoji.addEmojis(username, result.images);
}
}
/**
* set user information
*
@ -122,6 +137,10 @@ public class UserHolder extends ViewHolder implements OnClickListener {
} else {
profileImg.setImageResource(0);
}
if (user.getEmojis().length > 0) {
EmojiParam param = new EmojiParam(user.getEmojis(), username.getLineHeight());
emojiLoader.execute(param, this);
}
}
/**