diff options
Diffstat (limited to 'src/main/java/de/pixart/messenger/ui/adapter')
5 files changed, 1237 insertions, 1237 deletions
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java index 812c41ace..f8eb6f4f0 100644 --- a/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java +++ b/src/main/java/de/pixart/messenger/ui/adapter/AccountAdapter.java @@ -17,43 +17,43 @@ import de.pixart.messenger.ui.XmppActivity; public class AccountAdapter extends ArrayAdapter<Account> { - private XmppActivity activity; + private XmppActivity activity; - public AccountAdapter(XmppActivity activity, List<Account> objects) { - super(activity, 0, objects); - this.activity = activity; - } + public AccountAdapter(XmppActivity activity, List<Account> objects) { + super(activity, 0, objects); + this.activity = activity; + } - @Override - public View getView(int position, View view, ViewGroup parent) { - final Account account = getItem(position); - if (view == null) { - LayoutInflater inflater = (LayoutInflater) getContext() - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = inflater.inflate(R.layout.account_row, parent, false); - } - TextView jid = (TextView) view.findViewById(R.id.account_jid); - if (Config.DOMAIN_LOCK != null) { - jid.setText(account.getJid().getLocalpart()); - } else { - jid.setText(account.getJid().toBareJid().toString()); - } - TextView statusView = (TextView) view.findViewById(R.id.account_status); - ImageView imageView = (ImageView) view.findViewById(R.id.account_image); - imageView.setImageBitmap(activity.avatarService().get(account, activity.getPixel(56))); - statusView.setText(getContext().getString(account.getStatus().getReadableId())); - switch (account.getStatus()) { - case ONLINE: - statusView.setTextColor(activity.getOnlineColor()); - break; - case DISABLED: - case CONNECTING: - statusView.setTextColor(activity.getSecondaryTextColor()); - break; - default: - statusView.setTextColor(activity.getWarningTextColor()); - break; - } - return view; - } + @Override + public View getView(int position, View view, ViewGroup parent) { + final Account account = getItem(position); + if (view == null) { + LayoutInflater inflater = (LayoutInflater) getContext() + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + view = inflater.inflate(R.layout.account_row, parent, false); + } + TextView jid = (TextView) view.findViewById(R.id.account_jid); + if (Config.DOMAIN_LOCK != null) { + jid.setText(account.getJid().getLocalpart()); + } else { + jid.setText(account.getJid().toBareJid().toString()); + } + TextView statusView = (TextView) view.findViewById(R.id.account_status); + ImageView imageView = (ImageView) view.findViewById(R.id.account_image); + imageView.setImageBitmap(activity.avatarService().get(account, activity.getPixel(56))); + statusView.setText(getContext().getString(account.getStatus().getReadableId())); + switch (account.getStatus()) { + case ONLINE: + statusView.setTextColor(activity.getOnlineColor()); + break; + case DISABLED: + case CONNECTING: + statusView.setTextColor(activity.getSecondaryTextColor()); + break; + default: + statusView.setTextColor(activity.getWarningTextColor()); + break; + } + return view; + } } diff --git a/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java index f19dfa43b..d78c82cb2 100644 --- a/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java +++ b/src/main/java/de/pixart/messenger/ui/adapter/ConversationAdapter.java @@ -29,13 +29,13 @@ import de.pixart.messenger.xmpp.chatstate.ChatState; public class ConversationAdapter extends ArrayAdapter<Conversation> { - private XmppActivity activity; + private XmppActivity activity; - public ConversationAdapter(XmppActivity activity, - List<Conversation> conversations) { - super(activity, 0, conversations); - this.activity = activity; - } + public ConversationAdapter(XmppActivity activity, + List<Conversation> conversations) { + super(activity, 0, conversations); + this.activity = activity; + } public static boolean cancelPotentialWork(Conversation conversation, ImageView imageView) { final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); @@ -62,8 +62,8 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> { return null; } - @Override - public View getView(int position, View view, ViewGroup parent) { + @Override + public View getView(int position, View view, ViewGroup parent) { if (view == null) { LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.conversation_list_row, parent, false); @@ -126,23 +126,23 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> { } } } else {*/ - Pair<String, Boolean> preview = UIHelper.getMessagePreview(activity, message); - mLastMessage.setVisibility(View.VISIBLE); - imagePreview.setVisibility(View.GONE); - mLastMessage.setText(preview.first); - if (preview.second) { - if (conversation.isRead()) { - mLastMessage.setTypeface(null, Typeface.ITALIC); - } else { - mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC); - } + Pair<String, Boolean> preview = UIHelper.getMessagePreview(activity, message); + mLastMessage.setVisibility(View.VISIBLE); + imagePreview.setVisibility(View.GONE); + mLastMessage.setText(preview.first); + if (preview.second) { + if (conversation.isRead()) { + mLastMessage.setTypeface(null, Typeface.ITALIC); } else { - if (conversation.isRead()) { - mLastMessage.setTypeface(null, Typeface.NORMAL); - } else { - mLastMessage.setTypeface(null, Typeface.BOLD); - } + mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC); } + } else { + if (conversation.isRead()) { + mLastMessage.setTypeface(null, Typeface.NORMAL); + } else { + mLastMessage.setTypeface(null, Typeface.BOLD); + } + } //} long muted_till = conversation.getLongAttribute(Conversation.ATTRIBUTE_MUTED_TILL, 0); @@ -168,41 +168,41 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> { mLastMessage.setTypeface(null, Typeface.BOLD_ITALIC); } return view; - } - - public void loadAvatar(Conversation conversation, ImageView imageView) { - if (cancelPotentialWork(conversation, imageView)) { - final Bitmap bm = activity.avatarService().get(conversation, activity.getPixel(56), true); - if (bm != null) { - cancelPotentialWork(conversation, imageView); - imageView.setImageBitmap(bm); - imageView.setBackgroundColor(0x00000000); - } else { - imageView.setBackgroundColor(UIHelper.getColorForName(conversation.getName())); - imageView.setImageDrawable(null); - final BitmapWorkerTask task = new BitmapWorkerTask(imageView); - final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); - imageView.setImageDrawable(asyncDrawable); - try { - task.execute(conversation); - } catch (final RejectedExecutionException ignored) { - } - } - } - } - - static class AsyncDrawable extends BitmapDrawable { - private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; - - public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { - super(res, bitmap); - bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); - } - - public BitmapWorkerTask getBitmapWorkerTask() { - return bitmapWorkerTaskReference.get(); - } - } + } + + public void loadAvatar(Conversation conversation, ImageView imageView) { + if (cancelPotentialWork(conversation, imageView)) { + final Bitmap bm = activity.avatarService().get(conversation, activity.getPixel(56), true); + if (bm != null) { + cancelPotentialWork(conversation, imageView); + imageView.setImageBitmap(bm); + imageView.setBackgroundColor(0x00000000); + } else { + imageView.setBackgroundColor(UIHelper.getColorForName(conversation.getName())); + imageView.setImageDrawable(null); + final BitmapWorkerTask task = new BitmapWorkerTask(imageView); + final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); + imageView.setImageDrawable(asyncDrawable); + try { + task.execute(conversation); + } catch (final RejectedExecutionException ignored) { + } + } + } + } + + static class AsyncDrawable extends BitmapDrawable { + private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; + + public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { + super(res, bitmap); + bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); + } + + public BitmapWorkerTask getBitmapWorkerTask() { + return bitmapWorkerTaskReference.get(); + } + } class BitmapWorkerTask extends AsyncTask<Conversation, Void, Bitmap> { private final WeakReference<ImageView> imageViewReference; diff --git a/src/main/java/de/pixart/messenger/ui/adapter/KnownHostsAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/KnownHostsAdapter.java index 2906f16ba..6096a7196 100644 --- a/src/main/java/de/pixart/messenger/ui/adapter/KnownHostsAdapter.java +++ b/src/main/java/de/pixart/messenger/ui/adapter/KnownHostsAdapter.java @@ -9,62 +9,62 @@ import java.util.List; import java.util.Locale; public class KnownHostsAdapter extends ArrayAdapter<String> { - private ArrayList<String> domains; - private Filter domainFilter = new Filter() { + private ArrayList<String> domains; + private Filter domainFilter = new Filter() { - @Override - protected FilterResults performFiltering(CharSequence constraint) { - if (constraint != null) { - ArrayList<String> suggestions = new ArrayList<>(); - final String[] split = constraint.toString().split("@"); - if (split.length == 1) { - for (String domain : domains) { - suggestions.add(split[0].toLowerCase(Locale - .getDefault()) + "@" + domain); - } - } else if (split.length == 2) { - for (String domain : domains) { - if (domain.contentEquals(split[1])) { - suggestions.clear(); - break; - } else if (domain.contains(split[1])) { - suggestions.add(split[0].toLowerCase(Locale - .getDefault()) + "@" + domain); - } - } - } else { - return new FilterResults(); - } - FilterResults filterResults = new FilterResults(); - filterResults.values = suggestions; - filterResults.count = suggestions.size(); - return filterResults; - } else { - return new FilterResults(); - } - } + @Override + protected FilterResults performFiltering(CharSequence constraint) { + if (constraint != null) { + ArrayList<String> suggestions = new ArrayList<>(); + final String[] split = constraint.toString().split("@"); + if (split.length == 1) { + for (String domain : domains) { + suggestions.add(split[0].toLowerCase(Locale + .getDefault()) + "@" + domain); + } + } else if (split.length == 2) { + for (String domain : domains) { + if (domain.contentEquals(split[1])) { + suggestions.clear(); + break; + } else if (domain.contains(split[1])) { + suggestions.add(split[0].toLowerCase(Locale + .getDefault()) + "@" + domain); + } + } + } else { + return new FilterResults(); + } + FilterResults filterResults = new FilterResults(); + filterResults.values = suggestions; + filterResults.count = suggestions.size(); + return filterResults; + } else { + return new FilterResults(); + } + } - @Override - protected void publishResults(CharSequence constraint, - FilterResults results) { - ArrayList filteredList = (ArrayList) results.values; - if (results != null && results.count > 0) { - clear(); - for (Object c : filteredList) { - add((String) c); - } - notifyDataSetChanged(); - } - } - }; + @Override + protected void publishResults(CharSequence constraint, + FilterResults results) { + ArrayList filteredList = (ArrayList) results.values; + if (results != null && results.count > 0) { + clear(); + for (Object c : filteredList) { + add((String) c); + } + notifyDataSetChanged(); + } + } + }; - public KnownHostsAdapter(Context context, int viewResourceId, List<String> mKnownHosts) { - super(context, viewResourceId, new ArrayList<String>()); - domains = new ArrayList<>(mKnownHosts); - } + public KnownHostsAdapter(Context context, int viewResourceId, List<String> mKnownHosts) { + super(context, viewResourceId, new ArrayList<String>()); + domains = new ArrayList<>(mKnownHosts); + } - @Override - public Filter getFilter() { - return domainFilter; - } + @Override + public Filter getFilter() { + return domainFilter; + } } diff --git a/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java index 691b901db..1502b187d 100644 --- a/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java +++ b/src/main/java/de/pixart/messenger/ui/adapter/ListItemAdapter.java @@ -28,156 +28,156 @@ import de.pixart.messenger.utils.UIHelper; public class ListItemAdapter extends ArrayAdapter<ListItem> { - protected XmppActivity activity; - protected boolean showDynamicTags = false; - private View.OnClickListener onTagTvClick = new View.OnClickListener() { - @Override - public void onClick(View view) { - if (view instanceof TextView && mOnTagClickedListener != null) { - TextView tv = (TextView) view; - final String tag = tv.getText().toString(); - mOnTagClickedListener.onTagClicked(tag); - } - } - }; - private OnTagClickedListener mOnTagClickedListener = null; - - public ListItemAdapter(XmppActivity activity, List<ListItem> objects) { - super(activity, 0, objects); - this.activity = activity; - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); - this.showDynamicTags = preferences.getBoolean("show_dynamic_tags",false); - } - - @Override - public View getView(int position, View view, ViewGroup parent) { - LayoutInflater inflater = (LayoutInflater) getContext() - .getSystemService(Context.LAYOUT_INFLATER_SERVICE); - ListItem item = getItem(position); - if (view == null) { - view = inflater.inflate(R.layout.contact, parent, false); - } - TextView tvName = (TextView) view.findViewById(R.id.contact_display_name); - TextView tvJid = (TextView) view.findViewById(R.id.contact_jid); - ImageView picture = (ImageView) view.findViewById(R.id.contact_photo); - FlowLayout tagLayout = (FlowLayout) view.findViewById(R.id.tags); - - List<ListItem.Tag> tags = item.getTags(activity); - if (tags.size() == 0 || !this.showDynamicTags) { - tagLayout.setVisibility(View.GONE); - } else { - tagLayout.setVisibility(View.VISIBLE); - tagLayout.removeAllViewsInLayout(); - for(ListItem.Tag tag : tags) { - TextView tv = (TextView) inflater.inflate(R.layout.list_item_tag,tagLayout,false); - tv.setText(tag.getName()); - tv.setBackgroundColor(tag.getColor()); - tv.setOnClickListener(this.onTagTvClick); - tagLayout.addView(tv); - } - } - final String jid = item.getDisplayJid(); - if (jid != null) { - tvJid.setVisibility(View.VISIBLE); - tvJid.setText(jid); - } else { - tvJid.setVisibility(View.GONE); - } - tvName.setText(item.getDisplayName()); - loadAvatar(item,picture); - return view; - } - - public void setOnTagClickedListener(OnTagClickedListener listener) { - this.mOnTagClickedListener = listener; - } - - public interface OnTagClickedListener { - void onTagClicked(String tag); - } - - class BitmapWorkerTask extends AsyncTask<ListItem, Void, Bitmap> { - private final WeakReference<ImageView> imageViewReference; - private ListItem item = null; - - public BitmapWorkerTask(ImageView imageView) { - imageViewReference = new WeakReference<>(imageView); - } - - @Override - protected Bitmap doInBackground(ListItem... params) { - return activity.avatarService().get(params[0], activity.getPixel(48), isCancelled()); - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - if (bitmap != null && !isCancelled()) { - final ImageView imageView = imageViewReference.get(); - if (imageView != null) { - imageView.setImageBitmap(bitmap); - imageView.setBackgroundColor(0x00000000); - } - } - } - } - - public void loadAvatar(ListItem item, ImageView imageView) { - if (cancelPotentialWork(item, imageView)) { - final Bitmap bm = activity.avatarService().get(item,activity.getPixel(48),true); - if (bm != null) { - cancelPotentialWork(item, imageView); - imageView.setImageBitmap(bm); - imageView.setBackgroundColor(0x00000000); - } else { - imageView.setBackgroundColor(UIHelper.getColorForName(item.getDisplayName())); - imageView.setImageDrawable(null); - final BitmapWorkerTask task = new BitmapWorkerTask(imageView); - final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); - imageView.setImageDrawable(asyncDrawable); - try { - task.execute(item); - } catch (final RejectedExecutionException ignored) { - } - } - } - } - - public static boolean cancelPotentialWork(ListItem item, ImageView imageView) { - final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - - if (bitmapWorkerTask != null) { - final ListItem oldItem = bitmapWorkerTask.item; - if (oldItem == null || item != oldItem) { - bitmapWorkerTask.cancel(true); - } else { - return false; - } - } - return true; - } - - private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { - if (imageView != null) { - final Drawable drawable = imageView.getDrawable(); - if (drawable instanceof AsyncDrawable) { - final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; - return asyncDrawable.getBitmapWorkerTask(); - } - } - return null; - } - - static class AsyncDrawable extends BitmapDrawable { - private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; - - public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { - super(res, bitmap); - bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); - } - - public BitmapWorkerTask getBitmapWorkerTask() { - return bitmapWorkerTaskReference.get(); - } - } + protected XmppActivity activity; + protected boolean showDynamicTags = false; + private View.OnClickListener onTagTvClick = new View.OnClickListener() { + @Override + public void onClick(View view) { + if (view instanceof TextView && mOnTagClickedListener != null) { + TextView tv = (TextView) view; + final String tag = tv.getText().toString(); + mOnTagClickedListener.onTagClicked(tag); + } + } + }; + private OnTagClickedListener mOnTagClickedListener = null; + + public ListItemAdapter(XmppActivity activity, List<ListItem> objects) { + super(activity, 0, objects); + this.activity = activity; + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity); + this.showDynamicTags = preferences.getBoolean("show_dynamic_tags", false); + } + + @Override + public View getView(int position, View view, ViewGroup parent) { + LayoutInflater inflater = (LayoutInflater) getContext() + .getSystemService(Context.LAYOUT_INFLATER_SERVICE); + ListItem item = getItem(position); + if (view == null) { + view = inflater.inflate(R.layout.contact, parent, false); + } + TextView tvName = (TextView) view.findViewById(R.id.contact_display_name); + TextView tvJid = (TextView) view.findViewById(R.id.contact_jid); + ImageView picture = (ImageView) view.findViewById(R.id.contact_photo); + FlowLayout tagLayout = (FlowLayout) view.findViewById(R.id.tags); + + List<ListItem.Tag> tags = item.getTags(activity); + if (tags.size() == 0 || !this.showDynamicTags) { + tagLayout.setVisibility(View.GONE); + } else { + tagLayout.setVisibility(View.VISIBLE); + tagLayout.removeAllViewsInLayout(); + for (ListItem.Tag tag : tags) { + TextView tv = (TextView) inflater.inflate(R.layout.list_item_tag, tagLayout, false); + tv.setText(tag.getName()); + tv.setBackgroundColor(tag.getColor()); + tv.setOnClickListener(this.onTagTvClick); + tagLayout.addView(tv); + } + } + final String jid = item.getDisplayJid(); + if (jid != null) { + tvJid.setVisibility(View.VISIBLE); + tvJid.setText(jid); + } else { + tvJid.setVisibility(View.GONE); + } + tvName.setText(item.getDisplayName()); + loadAvatar(item, picture); + return view; + } + + public void setOnTagClickedListener(OnTagClickedListener listener) { + this.mOnTagClickedListener = listener; + } + + public interface OnTagClickedListener { + void onTagClicked(String tag); + } + + class BitmapWorkerTask extends AsyncTask<ListItem, Void, Bitmap> { + private final WeakReference<ImageView> imageViewReference; + private ListItem item = null; + + public BitmapWorkerTask(ImageView imageView) { + imageViewReference = new WeakReference<>(imageView); + } + + @Override + protected Bitmap doInBackground(ListItem... params) { + return activity.avatarService().get(params[0], activity.getPixel(48), isCancelled()); + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (bitmap != null && !isCancelled()) { + final ImageView imageView = imageViewReference.get(); + if (imageView != null) { + imageView.setImageBitmap(bitmap); + imageView.setBackgroundColor(0x00000000); + } + } + } + } + + public void loadAvatar(ListItem item, ImageView imageView) { + if (cancelPotentialWork(item, imageView)) { + final Bitmap bm = activity.avatarService().get(item, activity.getPixel(48), true); + if (bm != null) { + cancelPotentialWork(item, imageView); + imageView.setImageBitmap(bm); + imageView.setBackgroundColor(0x00000000); + } else { + imageView.setBackgroundColor(UIHelper.getColorForName(item.getDisplayName())); + imageView.setImageDrawable(null); + final BitmapWorkerTask task = new BitmapWorkerTask(imageView); + final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); + imageView.setImageDrawable(asyncDrawable); + try { + task.execute(item); + } catch (final RejectedExecutionException ignored) { + } + } + } + } + + public static boolean cancelPotentialWork(ListItem item, ImageView imageView) { + final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); + + if (bitmapWorkerTask != null) { + final ListItem oldItem = bitmapWorkerTask.item; + if (oldItem == null || item != oldItem) { + bitmapWorkerTask.cancel(true); + } else { + return false; + } + } + return true; + } + + private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { + if (imageView != null) { + final Drawable drawable = imageView.getDrawable(); + if (drawable instanceof AsyncDrawable) { + final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; + return asyncDrawable.getBitmapWorkerTask(); + } + } + return null; + } + + static class AsyncDrawable extends BitmapDrawable { + private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; + + public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { + super(res, bitmap); + bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); + } + + public BitmapWorkerTask getBitmapWorkerTask() { + return bitmapWorkerTaskReference.get(); + } + } } diff --git a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java index 02cbbdfd0..6cf16fdd5 100644 --- a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java +++ b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java @@ -74,941 +74,941 @@ import nl.changer.audiowife.AudioWife; public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextView.CopyHandler { - private static final int SENT = 0; - private static final int RECEIVED = 1; - private static final int STATUS = 2; - private static final Pattern XMPP_PATTERN = Pattern - .compile("xmpp\\:(?:(?:[" - + Patterns.GOOD_IRI_CHAR - + "\\;\\/\\?\\@\\&\\=\\#\\~\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])" - + "|(?:\\%[a-fA-F0-9]{2}))+"); - - private ConversationActivity activity; - - private DisplayMetrics metrics; - - private AudioWife audioWife; - - private OnContactPictureClicked mOnContactPictureClickedListener; - private OnContactPictureLongClicked mOnContactPictureLongClickedListener; - - private boolean mIndicateReceived = false; - private final ListSelectionManager listSelectionManager = new ListSelectionManager(); - private HashMap<Integer, AudioWife> audioPlayer; - private boolean mUseWhiteBackground = false; - - public MessageAdapter(ConversationActivity activity, List<Message> messages) { - super(activity, 0, messages); - this.activity = activity; - metrics = getContext().getResources().getDisplayMetrics(); - updatePreferences(); - } - - public void setOnContactPictureClicked(OnContactPictureClicked listener) { - this.mOnContactPictureClickedListener = listener; - } - - public void setOnContactPictureLongClicked( - OnContactPictureLongClicked listener) { - this.mOnContactPictureLongClickedListener = listener; - } - - @Override - public int getViewTypeCount() { - return 3; - } - - public int getItemViewType(Message message) { - if (message.getType() == Message.TYPE_STATUS) { - return STATUS; - } else if (message.getStatus() <= Message.STATUS_RECEIVED) { - return RECEIVED; - } - - return SENT; - } - - @Override - public int getItemViewType(int position) { - return getItemViewType(getItem(position)); - } - - private int getMessageTextColor(boolean onDark, boolean primary) { - if (onDark) { - return activity.getResources().getColor(primary ? R.color.dark : R.color.primary); - } else { - return activity.getResources().getColor(primary ? R.color.dark : R.color.primary); - } - } - - private void displayStatus(ViewHolder viewHolder, Message message, int type, boolean darkBackground) { - String filesize = null; - String info = null; - boolean error = false; - if (viewHolder.indicatorReceived != null) { - viewHolder.indicatorReceived.setVisibility(View.GONE); - viewHolder.indicatorRead.setVisibility(View.GONE); - } - - if (viewHolder.edit_indicator != null) { - if (message.edited()) { - viewHolder.edit_indicator.setVisibility(View.VISIBLE); - } else { - viewHolder.edit_indicator.setVisibility(View.GONE); - } - } - boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI - && message.getMergedStatus() <= Message.STATUS_RECEIVED; - if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getTransferable() != null) { - FileParams params = message.getFileParams(); - if (params.size > (1 * 1024 * 1024)) { - filesize = params.size / (1024 * 1024) + " MiB"; - } else if (params.size > (1 * 1024)) { - filesize = params.size / 1024 + " KiB"; - } else if (params.size > 0) { - filesize = "1 KiB"; - } - if (message.getTransferable() != null && message.getTransferable().getStatus() == Transferable.STATUS_FAILED) { - error = true; - } - } - switch (message.getMergedStatus()) { - case Message.STATUS_WAITING: - info = getContext().getString(R.string.waiting); - break; - case Message.STATUS_UNSEND: - Transferable d = message.getTransferable(); - if (d != null) { - info = getContext().getString(R.string.sending_file, d.getProgress()); - } else { - info = getContext().getString(R.string.sending); - } - break; - case Message.STATUS_OFFERED: - info = getContext().getString(R.string.offering); - break; - case Message.STATUS_SEND_RECEIVED: - if (mIndicateReceived) { - viewHolder.indicatorReceived.setVisibility(View.VISIBLE); - } - break; - case Message.STATUS_SEND_DISPLAYED: - if (mIndicateReceived) { - viewHolder.indicatorReceived.setVisibility(View.VISIBLE); - viewHolder.indicatorRead.setVisibility(View.VISIBLE); - } - break; - case Message.STATUS_SEND_FAILED: - info = getContext().getString(R.string.send_failed); - error = true; - break; - default: - if (multiReceived) { - info = UIHelper.getMessageDisplayName(message); - } - break; - } - if (error && type == SENT) { - viewHolder.time.setTextColor(activity.getWarningTextColor()); - } else if (!message.isValidInSession() && type == RECEIVED) { - viewHolder.time.setTextColor(activity.getUnencryptedTextColor()); - } else { - viewHolder.time.setTextColor(this.getMessageTextColor(darkBackground,false)); - } - if (message.getEncryption() == Message.ENCRYPTION_NONE) { - viewHolder.indicator.setVisibility(View.GONE); - } else { - viewHolder.indicator.setVisibility(View.VISIBLE); - if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { - FingerprintStatus status = message.getConversation() - .getAccount().getAxolotlService().getFingerprintTrust( - message.getFingerprint()); - - if(status == null || (!status.isTrustedAndActive())) { - viewHolder.indicator.setColorFilter(activity.getWarningTextColor()); - viewHolder.indicator.setAlpha(1.0f); - } else { - viewHolder.indicator.clearColorFilter(); - if (darkBackground) { - viewHolder.indicator.setAlpha(0.7f); - } else { - viewHolder.indicator.setAlpha(0.57f); - } - } - } else { - viewHolder.indicator.clearColorFilter(); - if (darkBackground) { - viewHolder.indicator.setAlpha(0.7f); - } else { - viewHolder.indicator.setAlpha(0.57f); - } - } - } - - String formatedTime = UIHelper.readableTimeDifferenceFull(getContext(), - message.getMergedTimeSent()); - if (message.getStatus() <= Message.STATUS_RECEIVED) { - if ((filesize != null) && (info != null)) { - viewHolder.time.setText(formatedTime + " \u00B7 " + filesize +" \u00B7 " + info); - } else if ((filesize == null) && (info != null)) { - viewHolder.time.setText(formatedTime + " \u00B7 " + info); - } else if ((filesize != null) && (info == null)) { - viewHolder.time.setText(formatedTime + " \u00B7 " + filesize); - } else { - viewHolder.time.setText(formatedTime); - } - } else { - if ((filesize != null) && (info != null)) { - viewHolder.time.setText(filesize + " \u00B7 " + info); - } else if ((filesize == null) && (info != null)) { - if (error) { - viewHolder.time.setText(info + " \u00B7 " + formatedTime); - } else { - viewHolder.time.setText(info); - } - } else if ((filesize != null) && (info == null)) { - viewHolder.time.setText(filesize + " \u00B7 " + formatedTime); - } else { - viewHolder.time.setText(formatedTime); - } - } - } - - private void displayInfoMessage(ViewHolder viewHolder, String text, boolean darkBackground) { - viewHolder.aw_player.setVisibility(View.GONE); - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.VISIBLE); - viewHolder.messageBody.setText(text); - viewHolder.messageBody.setTextColor(getMessageTextColor(darkBackground, false)); - viewHolder.messageBody.setTypeface(null, Typeface.ITALIC); - viewHolder.messageBody.setTextIsSelectable(false); - } - - private void displayDecryptionFailed(ViewHolder viewHolder, boolean darkBackground) { - viewHolder.aw_player.setVisibility(View.GONE); - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.VISIBLE); - viewHolder.messageBody.setText(getContext().getString( - R.string.decryption_failed)); - viewHolder.messageBody.setTextColor(getMessageTextColor(darkBackground, false)); - viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); - viewHolder.messageBody.setTextIsSelectable(false); - } - - private void displayHeartMessage(final ViewHolder viewHolder, final String body) { - viewHolder.aw_player.setVisibility(View.GONE); - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.VISIBLE); - viewHolder.messageBody.setIncludeFontPadding(false); - Spannable span = new SpannableString(body); - span.setSpan(new RelativeSizeSpan(4.0f), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()), 0, body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - viewHolder.messageBody.setText(span); - } - - private void displayXmppMessage(final ViewHolder viewHolder, final String body) { - String contact = body.toLowerCase(); - contact = contact.split(":")[1]; - contact = contact.split("\\?")[0]; - String add_contact = activity.getString(R.string.add_to_contact_list) + " (" + contact + ")"; - viewHolder.aw_player.setVisibility(View.GONE); - viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setText(add_contact); - viewHolder.download_button.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(body)); - activity.startActivity(intent); - } - }); - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); - - } - - private void displayTextMessage(final ViewHolder viewHolder, final Message message, boolean darkBackground) { - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.VISIBLE); - viewHolder.messageBody.setIncludeFontPadding(true); - if (message.getBody() != null) { - final String nick = UIHelper.getMessageDisplayName(message); - SpannableStringBuilder body = message.getMergedBody(); - boolean hasMeCommand = message.hasMeCommand(); - if (hasMeCommand) { - body = body.replace(0, Message.ME_COMMAND.length(), nick + " "); - } - if (body.length() > Config.MAX_DISPLAY_MESSAGE_CHARS) { - body = new SpannableStringBuilder(body, 0, Config.MAX_DISPLAY_MESSAGE_CHARS); - body.append("\u2026"); - } - Message.MergeSeparator[] mergeSeparators = body.getSpans(0, body.length(), Message.MergeSeparator.class); - for (Message.MergeSeparator mergeSeparator : mergeSeparators) { - int start = body.getSpanStart(mergeSeparator); - int end = body.getSpanEnd(mergeSeparator); - body.setSpan(new RelativeSizeSpan(0.3f), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - if (message.getType() != Message.TYPE_PRIVATE) { - if (hasMeCommand) { - body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - } else { - String privateMarker; - if (message.getStatus() <= Message.STATUS_RECEIVED) { - privateMarker = activity - .getString(R.string.private_message); - } else { - final String to; - if (message.getCounterpart() != null) { - to = message.getCounterpart().getResourcepart(); - } else { - to = ""; - } - privateMarker = activity.getString(R.string.private_message_to, to); - } - body.insert(0, privateMarker); - int privateMarkerIndex = privateMarker.length(); - body.insert(privateMarkerIndex, " "); - body.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground, false)), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - body.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - if (hasMeCommand) { - body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarkerIndex + 1, privateMarkerIndex + 1 + nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - } - Linkify.addLinks(body, Linkify.WEB_URLS); - Linkify.addLinks(body, XMPP_PATTERN, "xmpp"); - Linkify.addLinks(body, GeoHelper.GEO_URI, "geo"); - viewHolder.messageBody.setAutoLinkMask(0); - viewHolder.messageBody.setText(body); - viewHolder.messageBody.setTextIsSelectable(true); - viewHolder.messageBody.setMovementMethod(ClickableMovementMethod.getInstance()); - listSelectionManager.onUpdate(viewHolder.messageBody, message); - - } else { - viewHolder.messageBody.setText(""); - viewHolder.messageBody.setTextIsSelectable(false); - } - viewHolder.messageBody.setTextColor(this.getMessageTextColor(darkBackground, true)); - viewHolder.messageBody.setLinkTextColor(this.getMessageTextColor(darkBackground, true)); - viewHolder.messageBody.setHighlightColor(activity.getResources().getColor(darkBackground ? R.color.grey800 : R.color.grey500)); - viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); - } - - private void displayDownloadableMessage(ViewHolder viewHolder, final Message message, String text) { - viewHolder.aw_player.setVisibility(View.GONE); - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); - viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setText(text); - viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_download_grey600_48dp,0,0,0); - viewHolder.download_button.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - activity.startDownloadable(message); - } - }); - } - - private void displayAudioMessage(ViewHolder viewHolder, final Message message, int position) { - if (audioPlayer == null) audioPlayer = new HashMap<>(); - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - viewHolder.aw_player.setVisibility(View.VISIBLE); - Uri audioFile = Uri.fromFile(activity.xmppConnectionService.getFileBackend().getFile(message)); - - audioWife = audioPlayer.get(position); - if (audioWife == null) { - audioWife = new AudioWife(); - audioWife.init(getContext(), audioFile); - audioPlayer.put(position, audioWife); - RelativeLayout vg = new RelativeLayout(activity); - LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - audioWife.useDefaultUi(vg, layoutInflater); - viewHolder.aw_player.addView(audioWife.getPlayerUi()); - } else { - audioWife.cleanPlayerUi(); - viewHolder.aw_player.addView(audioWife.getPlayerUi()); - } - } - - private void displayOpenableMessage(ViewHolder viewHolder,final Message message) { - viewHolder.aw_player.setVisibility(View.GONE); - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); - viewHolder.download_button.setVisibility(View.VISIBLE); - String mimeType = message.getMimeType(); - String fullName = ""; - if (mimeType != null) { - if (message.getMimeType().contains("pdf")) { - viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_file_pdf_grey600_48dp,0,0,0); - } else if (message.getMimeType().contains("vcard")) { - File file = new File(activity.xmppConnectionService.getFileBackend().getFile(message).toString()); - VCard vcard = null; - String name = null; - String version = null; - try { - vcard = Ezvcard.parse(file).first(); - } catch (IOException e) { - e.printStackTrace(); - } - if (vcard != null) { - version = vcard.getVersion().toString(); - Log.d(Config.LOGTAG, "VCard version: " + version); - name = vcard.getFormattedName().getValue(); - fullName = " (" + name + ")"; - } - viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_account_card_details_grey600_48dp,0,0,0); - } else if (message.getMimeType().contains("calendar")) { - viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_calendar_grey600_48dp,0,0,0); - } else { - viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_file_grey600_48dp,0,0,0); - } - } - viewHolder.download_button.setText(activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity, message) + fullName)); - viewHolder.download_button.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - openDownloadable(message); - } - }); - } - - private void displayLocationMessage(ViewHolder viewHolder, final Message message) { - viewHolder.aw_player.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); - String url = GeoHelper.MapPreviewUri(message); - viewHolder.image.setVisibility(View.VISIBLE); - viewHolder.image.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - showLocation(message); - } - }); - Glide - .with(activity) - .load(Uri.parse(url)) - .asBitmap() - .diskCacheStrategy(DiskCacheStrategy.ALL) - .fitCenter() - .placeholder(R.drawable.ic_map_marker_grey600_48dp) - .error(R.drawable.ic_map_marker_grey600_48dp) - .into(viewHolder.image); - viewHolder.image.setMaxWidth(500); - viewHolder.image.setAdjustViewBounds(true); - viewHolder.download_button.setVisibility(View.GONE); - viewHolder.download_button.setText(R.string.show_location); - viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_map_marker_grey600_48dp, 0, 0, 0); - viewHolder.download_button.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - showLocation(message); - } - }); - - } - - private void displayImageMessage(ViewHolder viewHolder, - final Message message) { - viewHolder.aw_player.setVisibility(View.GONE); - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - viewHolder.messageBody.setVisibility(View.GONE); - viewHolder.image.setVisibility(View.VISIBLE); - FileParams params = message.getFileParams(); - double target = metrics.density * 200; - int scaledW; - int scaledH; - if (Math.max(params.height, params.width) * metrics.density <= target) { - scaledW = (int) (params.width * metrics.density); - scaledH = (int) (params.height * metrics.density); - } else if (Math.max(params.height,params.width) <= target) { - scaledW = params.width; - scaledH = params.height; - } else if (params.width <= params.height) { - scaledW = (int) (params.width / ((double) params.height / target)); - scaledH = (int) target; - } else { - scaledW = (int) target; - scaledH = (int) (params.height / ((double) params.width / target)); - } - LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(scaledW, scaledH); - layoutParams.setMargins(0, (int) (metrics.density * 4), 0, (int) (metrics.density * 4)); - viewHolder.image.setLayoutParams(layoutParams); - activity.loadBitmap(message, viewHolder.image); - viewHolder.image.setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - openDownloadable(message); - } - }); - } - - private void loadMoreMessages(Conversation conversation) { - conversation.setLastClearHistory(0); - activity.xmppConnectionService.updateConversation(conversation); - conversation.setHasMessagesLeftOnServer(true); - conversation.setFirstMamReference(null); - long timestamp = conversation.getLastMessageTransmitted(); - if (timestamp == 0) { - timestamp = System.currentTimeMillis(); - } - activity.setMessagesLoaded(); - activity.xmppConnectionService.getMessageArchiveService().query(conversation, 0, timestamp); - Toast.makeText(activity, R.string.fetching_history_from_server,Toast.LENGTH_LONG).show(); - } - - @Override - public View getView(int position, View unused, ViewGroup parent) { - final Message message = getItem(position); - final boolean isInValidSession = message.isValidInSession(); - final Conversation conversation = message.getConversation(); - final Account account = conversation.getAccount(); - final int type = getItemViewType(position); - ViewHolder viewHolder; - View view; - viewHolder = new ViewHolder(); - switch (type) { - case SENT: - view = activity.getLayoutInflater().inflate( - R.layout.message_sent, parent, false); - viewHolder.message_box = (LinearLayout) view - .findViewById(R.id.message_box); - viewHolder.contact_picture = (ImageView) view - .findViewById(R.id.message_photo); - viewHolder.aw_player = (ViewGroup) view.findViewById(R.id.aw_player); - viewHolder.download_button = (Button) view - .findViewById(R.id.download_button); - viewHolder.indicator = (ImageView) view - .findViewById(R.id.security_indicator); - viewHolder.edit_indicator = (ImageView) view.findViewById(R.id.edit_indicator); - viewHolder.image = (ImageView) view - .findViewById(R.id.message_image); - viewHolder.messageBody = (CopyTextView) view - .findViewById(R.id.message_body); - viewHolder.time = (TextView) view - .findViewById(R.id.message_time); - viewHolder.indicatorReceived = (ImageView) view - .findViewById(R.id.indicator_received); - viewHolder.indicatorRead = (ImageView) view - .findViewById(R.id.indicator_read); - break; - case RECEIVED: - view = activity.getLayoutInflater().inflate( - R.layout.message_received, parent, false); - viewHolder.message_box = (LinearLayout) view - .findViewById(R.id.message_box); - viewHolder.contact_picture = (ImageView) view - .findViewById(R.id.message_photo); - viewHolder.aw_player = (ViewGroup) view.findViewById(R.id.aw_player); - viewHolder.download_button = (Button) view - .findViewById(R.id.download_button); - viewHolder.indicator = (ImageView) view - .findViewById(R.id.security_indicator); - viewHolder.edit_indicator = (ImageView) view.findViewById(R.id.edit_indicator); - viewHolder.image = (ImageView) view - .findViewById(R.id.message_image); - viewHolder.messageBody = (CopyTextView) view - .findViewById(R.id.message_body); - viewHolder.time = (TextView) view - .findViewById(R.id.message_time); - viewHolder.indicatorReceived = (ImageView) view - .findViewById(R.id.indicator_received); - viewHolder.encryption = (TextView) view.findViewById(R.id.message_encryption); - break; - case STATUS: - view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false); - viewHolder.contact_picture = (ImageView) view.findViewById(R.id.message_photo); - viewHolder.status_message = (TextView) view.findViewById(R.id.status_message); - viewHolder.load_more_messages = (Button) view.findViewById(R.id.load_more_messages); - break; - default: - view = new View(getContext()); - viewHolder = null; - break; - } - if (viewHolder.messageBody != null) { - listSelectionManager.onCreate(viewHolder.messageBody); - viewHolder.messageBody.setCopyHandler(this); - } - view.setTag(viewHolder); - if (viewHolder == null) { - return view; - } - - - boolean darkBackground = (type == SENT && (!isInValidSession || !mUseWhiteBackground)); - - if (type == STATUS) { - if ("LOAD_MORE".equals(message.getBody())) { - viewHolder.status_message.setVisibility(View.GONE); - viewHolder.contact_picture.setVisibility(View.GONE); - viewHolder.load_more_messages.setVisibility(View.VISIBLE); - viewHolder.load_more_messages.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - loadMoreMessages(message.getConversation()); - } - }); - } else { - viewHolder.status_message.setVisibility(View.VISIBLE); - viewHolder.contact_picture.setVisibility(View.VISIBLE); - viewHolder.load_more_messages.setVisibility(View.GONE); - if (conversation.getMode() == Conversation.MODE_SINGLE) { - viewHolder.contact_picture.setImageBitmap(activity - .avatarService().get(conversation.getContact(), - activity.getPixel(32))); - viewHolder.contact_picture.setAlpha(0.5f); - } - viewHolder.status_message.setText(message.getBody()); - } - return view; - } else { - loadAvatar(message, viewHolder.contact_picture); - } - - viewHolder.contact_picture - .setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - if (MessageAdapter.this.mOnContactPictureClickedListener != null) { - MessageAdapter.this.mOnContactPictureClickedListener - .onContactPictureClicked(message); - } - - } - }); - viewHolder.contact_picture - .setOnLongClickListener(new OnLongClickListener() { - - @Override - public boolean onLongClick(View v) { - if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) { - MessageAdapter.this.mOnContactPictureLongClickedListener - .onContactPictureLongClicked(message); - return true; - } else { - return false; - } - } - }); - - final Transferable transferable = message.getTransferable(); - String mimeType = message.getMimeType(); - if (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING) { - if (transferable.getStatus() == Transferable.STATUS_OFFER) { - displayDownloadableMessage(viewHolder,message,activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message))); - } else if (transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) { - displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message))); - } else { - displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first,darkBackground); - } - } else if (message.getType() == Message.TYPE_IMAGE && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) { - displayImageMessage(viewHolder, message); - } else if (message.getType() == Message.TYPE_FILE && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) { - if (message.getFileParams().width > 0) { - displayImageMessage(viewHolder,message); - } else { - if (mimeType != null) { - if (message.getMimeType().startsWith("audio/")) { - displayAudioMessage(viewHolder, message, position); - } else displayOpenableMessage(viewHolder, message); - } else displayOpenableMessage(viewHolder, message); - } - } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { - if (account.isPgpDecryptionServiceConnected()) { - if (!account.hasPendingPgpIntent(conversation)) { - displayInfoMessage(viewHolder, activity.getString(R.string.message_decrypting), darkBackground); - } else { - displayInfoMessage(viewHolder, activity.getString(R.string.pgp_message), darkBackground); - } - } else { - displayInfoMessage(viewHolder,activity.getString(R.string.install_openkeychain),darkBackground); - if (viewHolder != null) { - viewHolder.message_box - .setOnClickListener(new OnClickListener() { - - @Override - public void onClick(View v) { - activity.showInstallPgpDialog(); - } - }); - } - } - } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { - displayDecryptionFailed(viewHolder,darkBackground); - } else { - if (GeoHelper.isGeoUri(message.getBody())) { - displayLocationMessage(viewHolder,message); - } else if (message.bodyIsHeart()) { - displayHeartMessage(viewHolder, message.getBody().trim()); - } else if (message.bodyIsXmpp()) { - displayXmppMessage(viewHolder, message.getBody().trim()); - } else if (message.treatAsDownloadable() == Message.Decision.MUST || - message.treatAsDownloadable() == Message.Decision.SHOULD) { - try { - URL url = new URL(message.getBody()); - displayDownloadableMessage(viewHolder, - message, - activity.getString(R.string.check_x_filesize_on_host, - UIHelper.getFileDescriptionString(activity, message), - url.getHost())); - } catch (Exception e) { - displayDownloadableMessage(viewHolder, - message, - activity.getString(R.string.check_x_filesize, - UIHelper.getFileDescriptionString(activity, message))); - } - } else { - displayTextMessage(viewHolder, message, darkBackground); - } - } - - if (type == RECEIVED) { - if(isInValidSession) { - viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received); - viewHolder.encryption.setVisibility(View.GONE); - } else { - viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_warning); - viewHolder.encryption.setVisibility(View.VISIBLE); - viewHolder.encryption.setText(CryptoHelper.encryptionTypeToText(message.getEncryption())); - } - } - - if (type == SENT) { - if (mUseWhiteBackground) { - viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_sent_white); - } else { - viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_sent); - } - } - - displayStatus(viewHolder, message, type, darkBackground); - - return view; - } - - @Override - public void notifyDataSetChanged() { - listSelectionManager.onBeforeNotifyDataSetChanged(); - super.notifyDataSetChanged(); - listSelectionManager.onAfterNotifyDataSetChanged(); - } - - @Override - public String transformTextForCopy(CharSequence text, int start, int end) { - return text.toString().substring(start, end); - } - - public void openDownloadable(Message message) { - DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); - if (!file.exists()) { - Toast.makeText(activity, R.string.file_deleted, Toast.LENGTH_SHORT).show(); - return; - } - String mime = file.getMimeType(); - if (mime.startsWith("image/")) { - Intent intent = new Intent(getContext(), ShowFullscreenMessageActivity.class); - intent.putExtra("image", Uri.fromFile(file)); - try { - activity.startActivity(intent); - return; - } catch (ActivityNotFoundException e) { - //ignored - } - } else if (mime.startsWith("video/")) { - Intent intent = new Intent(getContext(), ShowFullscreenMessageActivity.class); - intent.putExtra("video", Uri.fromFile(file)); - try { - activity.startActivity(intent); - return; - } catch (ActivityNotFoundException e) { - //ignored - } - } - Intent openIntent = new Intent(Intent.ACTION_VIEW); - if (mime == null) { - mime = "*/*"; - } - Uri uri; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - try { - uri = FileProvider.getUriForFile(activity, FileBackend.CONVERSATIONS_FILE_PROVIDER, file); - } catch (IllegalArgumentException e) { - Toast.makeText(activity,activity.getString(R.string.no_permission_to_access_x,file.getAbsolutePath()), Toast.LENGTH_SHORT).show(); - return; - } - openIntent.setDataAndType(uri, mime); - openIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - } else { - uri = Uri.fromFile(file); - } - openIntent.setDataAndType(uri, mime); - PackageManager manager = activity.getPackageManager(); - List<ResolveInfo> info = manager.queryIntentActivities(openIntent, 0); - if (info.size() == 0) { - openIntent.setDataAndType(Uri.fromFile(file),"*/*"); - } - try { - getContext().startActivity(openIntent); - } catch (ActivityNotFoundException e) { - Toast.makeText(activity,R.string.no_application_found_to_open_file,Toast.LENGTH_SHORT).show(); - } - } - - public void showLocation(Message message) { - for(Intent intent : GeoHelper.createGeoIntentsFromMessage(message)) { - if (intent.resolveActivity(getContext().getPackageManager()) != null) { - getContext().startActivity(intent); - return; - } - } - Toast.makeText(activity,R.string.no_application_found_to_display_location,Toast.LENGTH_SHORT).show(); - } - - public void updatePreferences() { - this.mIndicateReceived = activity.indicateReceived(); - this.mUseWhiteBackground = activity.useWhiteBackground(); - } - - public TextView getMessageBody(View view) { - final Object tag = view.getTag(); - if (tag instanceof ViewHolder) { - final ViewHolder viewHolder = (ViewHolder) tag; - return viewHolder.messageBody; - } - return null; - } - - public interface OnContactPictureClicked { - void onContactPictureClicked(Message message); - } - - public interface OnContactPictureLongClicked { - void onContactPictureLongClicked(Message message); - } - - private static class ViewHolder { - - protected LinearLayout message_box; - protected Button download_button; - protected ViewGroup aw_player; - protected ImageView image; - protected ImageView indicator; - protected ImageView indicatorReceived; - protected ImageView indicatorRead; - protected TextView time; - protected CopyTextView messageBody; - protected ImageView contact_picture; - protected TextView status_message; - protected TextView encryption; - public Button load_more_messages; - public ImageView edit_indicator; - } - - class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> { - private final WeakReference<ImageView> imageViewReference; - private Message message = null; - - public BitmapWorkerTask(ImageView imageView) { - imageViewReference = new WeakReference<>(imageView); - } - - @Override - protected Bitmap doInBackground(Message... params) { - return activity.avatarService().get(params[0], activity.getPixel(48), isCancelled()); - } - - @Override - protected void onPostExecute(Bitmap bitmap) { - if (bitmap != null && !isCancelled()) { - final ImageView imageView = imageViewReference.get(); - if (imageView != null) { - imageView.setImageBitmap(bitmap); - imageView.setBackgroundColor(0x00000000); - } - } - } - } - - public void loadAvatar(Message message, ImageView imageView) { - if (cancelPotentialWork(message, imageView)) { - final Bitmap bm = activity.avatarService().get(message, activity.getPixel(48), true); - if (bm != null) { - cancelPotentialWork(message, imageView); - imageView.setImageBitmap(bm); - imageView.setBackgroundColor(0x00000000); - } else { - imageView.setBackgroundColor(UIHelper.getColorForName(UIHelper.getMessageDisplayName(message))); - imageView.setImageDrawable(null); - final BitmapWorkerTask task = new BitmapWorkerTask(imageView); - final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); - imageView.setImageDrawable(asyncDrawable); - try { - task.execute(message); - } catch (final RejectedExecutionException ignored) { - } - } - } - } - - public static boolean cancelPotentialWork(Message message, ImageView imageView) { - final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); - - if (bitmapWorkerTask != null) { - final Message oldMessage = bitmapWorkerTask.message; - if (oldMessage == null || message != oldMessage) { - bitmapWorkerTask.cancel(true); - } else { - return false; - } - } - return true; - } - - private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { - if (imageView != null) { - final Drawable drawable = imageView.getDrawable(); - if (drawable instanceof AsyncDrawable) { - final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; - return asyncDrawable.getBitmapWorkerTask(); - } - } - return null; - } - - static class AsyncDrawable extends BitmapDrawable { - private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; - - public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { - super(res, bitmap); - bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); - } - - public BitmapWorkerTask getBitmapWorkerTask() { - return bitmapWorkerTaskReference.get(); - } - } + private static final int SENT = 0; + private static final int RECEIVED = 1; + private static final int STATUS = 2; + private static final Pattern XMPP_PATTERN = Pattern + .compile("xmpp\\:(?:(?:[" + + Patterns.GOOD_IRI_CHAR + + "\\;\\/\\?\\@\\&\\=\\#\\~\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])" + + "|(?:\\%[a-fA-F0-9]{2}))+"); + + private ConversationActivity activity; + + private DisplayMetrics metrics; + + private AudioWife audioWife; + + private OnContactPictureClicked mOnContactPictureClickedListener; + private OnContactPictureLongClicked mOnContactPictureLongClickedListener; + + private boolean mIndicateReceived = false; + private final ListSelectionManager listSelectionManager = new ListSelectionManager(); + private HashMap<Integer, AudioWife> audioPlayer; + private boolean mUseWhiteBackground = false; + + public MessageAdapter(ConversationActivity activity, List<Message> messages) { + super(activity, 0, messages); + this.activity = activity; + metrics = getContext().getResources().getDisplayMetrics(); + updatePreferences(); + } + + public void setOnContactPictureClicked(OnContactPictureClicked listener) { + this.mOnContactPictureClickedListener = listener; + } + + public void setOnContactPictureLongClicked( + OnContactPictureLongClicked listener) { + this.mOnContactPictureLongClickedListener = listener; + } + + @Override + public int getViewTypeCount() { + return 3; + } + + public int getItemViewType(Message message) { + if (message.getType() == Message.TYPE_STATUS) { + return STATUS; + } else if (message.getStatus() <= Message.STATUS_RECEIVED) { + return RECEIVED; + } + + return SENT; + } + + @Override + public int getItemViewType(int position) { + return getItemViewType(getItem(position)); + } + + private int getMessageTextColor(boolean onDark, boolean primary) { + if (onDark) { + return activity.getResources().getColor(primary ? R.color.dark : R.color.primary); + } else { + return activity.getResources().getColor(primary ? R.color.dark : R.color.primary); + } + } + + private void displayStatus(ViewHolder viewHolder, Message message, int type, boolean darkBackground) { + String filesize = null; + String info = null; + boolean error = false; + if (viewHolder.indicatorReceived != null) { + viewHolder.indicatorReceived.setVisibility(View.GONE); + viewHolder.indicatorRead.setVisibility(View.GONE); + } + + if (viewHolder.edit_indicator != null) { + if (message.edited()) { + viewHolder.edit_indicator.setVisibility(View.VISIBLE); + } else { + viewHolder.edit_indicator.setVisibility(View.GONE); + } + } + boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI + && message.getMergedStatus() <= Message.STATUS_RECEIVED; + if (message.getType() == Message.TYPE_IMAGE || message.getType() == Message.TYPE_FILE || message.getTransferable() != null) { + FileParams params = message.getFileParams(); + if (params.size > (1 * 1024 * 1024)) { + filesize = params.size / (1024 * 1024) + " MiB"; + } else if (params.size > (1 * 1024)) { + filesize = params.size / 1024 + " KiB"; + } else if (params.size > 0) { + filesize = "1 KiB"; + } + if (message.getTransferable() != null && message.getTransferable().getStatus() == Transferable.STATUS_FAILED) { + error = true; + } + } + switch (message.getMergedStatus()) { + case Message.STATUS_WAITING: + info = getContext().getString(R.string.waiting); + break; + case Message.STATUS_UNSEND: + Transferable d = message.getTransferable(); + if (d != null) { + info = getContext().getString(R.string.sending_file, d.getProgress()); + } else { + info = getContext().getString(R.string.sending); + } + break; + case Message.STATUS_OFFERED: + info = getContext().getString(R.string.offering); + break; + case Message.STATUS_SEND_RECEIVED: + if (mIndicateReceived) { + viewHolder.indicatorReceived.setVisibility(View.VISIBLE); + } + break; + case Message.STATUS_SEND_DISPLAYED: + if (mIndicateReceived) { + viewHolder.indicatorReceived.setVisibility(View.VISIBLE); + viewHolder.indicatorRead.setVisibility(View.VISIBLE); + } + break; + case Message.STATUS_SEND_FAILED: + info = getContext().getString(R.string.send_failed); + error = true; + break; + default: + if (multiReceived) { + info = UIHelper.getMessageDisplayName(message); + } + break; + } + if (error && type == SENT) { + viewHolder.time.setTextColor(activity.getWarningTextColor()); + } else if (!message.isValidInSession() && type == RECEIVED) { + viewHolder.time.setTextColor(activity.getUnencryptedTextColor()); + } else { + viewHolder.time.setTextColor(this.getMessageTextColor(darkBackground, false)); + } + if (message.getEncryption() == Message.ENCRYPTION_NONE) { + viewHolder.indicator.setVisibility(View.GONE); + } else { + viewHolder.indicator.setVisibility(View.VISIBLE); + if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL) { + FingerprintStatus status = message.getConversation() + .getAccount().getAxolotlService().getFingerprintTrust( + message.getFingerprint()); + + if (status == null || (!status.isTrustedAndActive())) { + viewHolder.indicator.setColorFilter(activity.getWarningTextColor()); + viewHolder.indicator.setAlpha(1.0f); + } else { + viewHolder.indicator.clearColorFilter(); + if (darkBackground) { + viewHolder.indicator.setAlpha(0.7f); + } else { + viewHolder.indicator.setAlpha(0.57f); + } + } + } else { + viewHolder.indicator.clearColorFilter(); + if (darkBackground) { + viewHolder.indicator.setAlpha(0.7f); + } else { + viewHolder.indicator.setAlpha(0.57f); + } + } + } + + String formatedTime = UIHelper.readableTimeDifferenceFull(getContext(), + message.getMergedTimeSent()); + if (message.getStatus() <= Message.STATUS_RECEIVED) { + if ((filesize != null) && (info != null)) { + viewHolder.time.setText(formatedTime + " \u00B7 " + filesize + " \u00B7 " + info); + } else if ((filesize == null) && (info != null)) { + viewHolder.time.setText(formatedTime + " \u00B7 " + info); + } else if ((filesize != null) && (info == null)) { + viewHolder.time.setText(formatedTime + " \u00B7 " + filesize); + } else { + viewHolder.time.setText(formatedTime); + } + } else { + if ((filesize != null) && (info != null)) { + viewHolder.time.setText(filesize + " \u00B7 " + info); + } else if ((filesize == null) && (info != null)) { + if (error) { + viewHolder.time.setText(info + " \u00B7 " + formatedTime); + } else { + viewHolder.time.setText(info); + } + } else if ((filesize != null) && (info == null)) { + viewHolder.time.setText(filesize + " \u00B7 " + formatedTime); + } else { + viewHolder.time.setText(formatedTime); + } + } + } + + private void displayInfoMessage(ViewHolder viewHolder, String text, boolean darkBackground) { + viewHolder.aw_player.setVisibility(View.GONE); + if (viewHolder.download_button != null) { + viewHolder.download_button.setVisibility(View.GONE); + } + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setText(text); + viewHolder.messageBody.setTextColor(getMessageTextColor(darkBackground, false)); + viewHolder.messageBody.setTypeface(null, Typeface.ITALIC); + viewHolder.messageBody.setTextIsSelectable(false); + } + + private void displayDecryptionFailed(ViewHolder viewHolder, boolean darkBackground) { + viewHolder.aw_player.setVisibility(View.GONE); + if (viewHolder.download_button != null) { + viewHolder.download_button.setVisibility(View.GONE); + } + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setText(getContext().getString( + R.string.decryption_failed)); + viewHolder.messageBody.setTextColor(getMessageTextColor(darkBackground, false)); + viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); + viewHolder.messageBody.setTextIsSelectable(false); + } + + private void displayHeartMessage(final ViewHolder viewHolder, final String body) { + viewHolder.aw_player.setVisibility(View.GONE); + if (viewHolder.download_button != null) { + viewHolder.download_button.setVisibility(View.GONE); + } + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setIncludeFontPadding(false); + Spannable span = new SpannableString(body); + span.setSpan(new RelativeSizeSpan(4.0f), 0, body.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + span.setSpan(new ForegroundColorSpan(activity.getWarningTextColor()), 0, body.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + viewHolder.messageBody.setText(span); + } + + private void displayXmppMessage(final ViewHolder viewHolder, final String body) { + String contact = body.toLowerCase(); + contact = contact.split(":")[1]; + contact = contact.split("\\?")[0]; + String add_contact = activity.getString(R.string.add_to_contact_list) + " (" + contact + ")"; + viewHolder.aw_player.setVisibility(View.GONE); + viewHolder.download_button.setVisibility(View.VISIBLE); + viewHolder.download_button.setText(add_contact); + viewHolder.download_button.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(body)); + activity.startActivity(intent); + } + }); + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.GONE); + + } + + private void displayTextMessage(final ViewHolder viewHolder, final Message message, boolean darkBackground) { + if (viewHolder.download_button != null) { + viewHolder.download_button.setVisibility(View.GONE); + } + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.VISIBLE); + viewHolder.messageBody.setIncludeFontPadding(true); + if (message.getBody() != null) { + final String nick = UIHelper.getMessageDisplayName(message); + SpannableStringBuilder body = message.getMergedBody(); + boolean hasMeCommand = message.hasMeCommand(); + if (hasMeCommand) { + body = body.replace(0, Message.ME_COMMAND.length(), nick + " "); + } + if (body.length() > Config.MAX_DISPLAY_MESSAGE_CHARS) { + body = new SpannableStringBuilder(body, 0, Config.MAX_DISPLAY_MESSAGE_CHARS); + body.append("\u2026"); + } + Message.MergeSeparator[] mergeSeparators = body.getSpans(0, body.length(), Message.MergeSeparator.class); + for (Message.MergeSeparator mergeSeparator : mergeSeparators) { + int start = body.getSpanStart(mergeSeparator); + int end = body.getSpanEnd(mergeSeparator); + body.setSpan(new RelativeSizeSpan(0.3f), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + if (message.getType() != Message.TYPE_PRIVATE) { + if (hasMeCommand) { + body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), 0, nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } else { + String privateMarker; + if (message.getStatus() <= Message.STATUS_RECEIVED) { + privateMarker = activity + .getString(R.string.private_message); + } else { + final String to; + if (message.getCounterpart() != null) { + to = message.getCounterpart().getResourcepart(); + } else { + to = ""; + } + privateMarker = activity.getString(R.string.private_message_to, to); + } + body.insert(0, privateMarker); + int privateMarkerIndex = privateMarker.length(); + body.insert(privateMarkerIndex, " "); + body.setSpan(new ForegroundColorSpan(getMessageTextColor(darkBackground, false)), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + body.setSpan(new StyleSpan(Typeface.BOLD), 0, privateMarkerIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + if (hasMeCommand) { + body.setSpan(new StyleSpan(Typeface.BOLD_ITALIC), privateMarkerIndex + 1, privateMarkerIndex + 1 + nick.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + Linkify.addLinks(body, Linkify.WEB_URLS); + Linkify.addLinks(body, XMPP_PATTERN, "xmpp"); + Linkify.addLinks(body, GeoHelper.GEO_URI, "geo"); + viewHolder.messageBody.setAutoLinkMask(0); + viewHolder.messageBody.setText(body); + viewHolder.messageBody.setTextIsSelectable(true); + viewHolder.messageBody.setMovementMethod(ClickableMovementMethod.getInstance()); + listSelectionManager.onUpdate(viewHolder.messageBody, message); + + } else { + viewHolder.messageBody.setText(""); + viewHolder.messageBody.setTextIsSelectable(false); + } + viewHolder.messageBody.setTextColor(this.getMessageTextColor(darkBackground, true)); + viewHolder.messageBody.setLinkTextColor(this.getMessageTextColor(darkBackground, true)); + viewHolder.messageBody.setHighlightColor(activity.getResources().getColor(darkBackground ? R.color.grey800 : R.color.grey500)); + viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); + } + + private void displayDownloadableMessage(ViewHolder viewHolder, final Message message, String text) { + viewHolder.aw_player.setVisibility(View.GONE); + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.GONE); + viewHolder.download_button.setVisibility(View.VISIBLE); + viewHolder.download_button.setText(text); + viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_download_grey600_48dp, 0, 0, 0); + viewHolder.download_button.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + activity.startDownloadable(message); + } + }); + } + + private void displayAudioMessage(ViewHolder viewHolder, final Message message, int position) { + if (audioPlayer == null) audioPlayer = new HashMap<>(); + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.GONE); + if (viewHolder.download_button != null) { + viewHolder.download_button.setVisibility(View.GONE); + } + viewHolder.aw_player.setVisibility(View.VISIBLE); + Uri audioFile = Uri.fromFile(activity.xmppConnectionService.getFileBackend().getFile(message)); + + audioWife = audioPlayer.get(position); + if (audioWife == null) { + audioWife = new AudioWife(); + audioWife.init(getContext(), audioFile); + audioPlayer.put(position, audioWife); + RelativeLayout vg = new RelativeLayout(activity); + LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); + audioWife.useDefaultUi(vg, layoutInflater); + viewHolder.aw_player.addView(audioWife.getPlayerUi()); + } else { + audioWife.cleanPlayerUi(); + viewHolder.aw_player.addView(audioWife.getPlayerUi()); + } + } + + private void displayOpenableMessage(ViewHolder viewHolder, final Message message) { + viewHolder.aw_player.setVisibility(View.GONE); + viewHolder.image.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.GONE); + viewHolder.download_button.setVisibility(View.VISIBLE); + String mimeType = message.getMimeType(); + String fullName = ""; + if (mimeType != null) { + if (message.getMimeType().contains("pdf")) { + viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_file_pdf_grey600_48dp, 0, 0, 0); + } else if (message.getMimeType().contains("vcard")) { + File file = new File(activity.xmppConnectionService.getFileBackend().getFile(message).toString()); + VCard vcard = null; + String name = null; + String version = null; + try { + vcard = Ezvcard.parse(file).first(); + } catch (IOException e) { + e.printStackTrace(); + } + if (vcard != null) { + version = vcard.getVersion().toString(); + Log.d(Config.LOGTAG, "VCard version: " + version); + name = vcard.getFormattedName().getValue(); + fullName = " (" + name + ")"; + } + viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_account_card_details_grey600_48dp, 0, 0, 0); + } else if (message.getMimeType().contains("calendar")) { + viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_calendar_grey600_48dp, 0, 0, 0); + } else { + viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_file_grey600_48dp, 0, 0, 0); + } + } + viewHolder.download_button.setText(activity.getString(R.string.open_x_file, UIHelper.getFileDescriptionString(activity, message) + fullName)); + viewHolder.download_button.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + openDownloadable(message); + } + }); + } + + private void displayLocationMessage(ViewHolder viewHolder, final Message message) { + viewHolder.aw_player.setVisibility(View.GONE); + viewHolder.messageBody.setVisibility(View.GONE); + String url = GeoHelper.MapPreviewUri(message); + viewHolder.image.setVisibility(View.VISIBLE); + viewHolder.image.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + showLocation(message); + } + }); + Glide + .with(activity) + .load(Uri.parse(url)) + .asBitmap() + .diskCacheStrategy(DiskCacheStrategy.ALL) + .fitCenter() + .placeholder(R.drawable.ic_map_marker_grey600_48dp) + .error(R.drawable.ic_map_marker_grey600_48dp) + .into(viewHolder.image); + viewHolder.image.setMaxWidth(500); + viewHolder.image.setAdjustViewBounds(true); + viewHolder.download_button.setVisibility(View.GONE); + viewHolder.download_button.setText(R.string.show_location); + viewHolder.download_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_map_marker_grey600_48dp, 0, 0, 0); + viewHolder.download_button.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + showLocation(message); + } + }); + + } + + private void displayImageMessage(ViewHolder viewHolder, + final Message message) { + viewHolder.aw_player.setVisibility(View.GONE); + if (viewHolder.download_button != null) { + viewHolder.download_button.setVisibility(View.GONE); + } + viewHolder.messageBody.setVisibility(View.GONE); + viewHolder.image.setVisibility(View.VISIBLE); + FileParams params = message.getFileParams(); + double target = metrics.density * 200; + int scaledW; + int scaledH; + if (Math.max(params.height, params.width) * metrics.density <= target) { + scaledW = (int) (params.width * metrics.density); + scaledH = (int) (params.height * metrics.density); + } else if (Math.max(params.height, params.width) <= target) { + scaledW = params.width; + scaledH = params.height; + } else if (params.width <= params.height) { + scaledW = (int) (params.width / ((double) params.height / target)); + scaledH = (int) target; + } else { + scaledW = (int) target; + scaledH = (int) (params.height / ((double) params.width / target)); + } + LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(scaledW, scaledH); + layoutParams.setMargins(0, (int) (metrics.density * 4), 0, (int) (metrics.density * 4)); + viewHolder.image.setLayoutParams(layoutParams); + activity.loadBitmap(message, viewHolder.image); + viewHolder.image.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + openDownloadable(message); + } + }); + } + + private void loadMoreMessages(Conversation conversation) { + conversation.setLastClearHistory(0); + activity.xmppConnectionService.updateConversation(conversation); + conversation.setHasMessagesLeftOnServer(true); + conversation.setFirstMamReference(null); + long timestamp = conversation.getLastMessageTransmitted(); + if (timestamp == 0) { + timestamp = System.currentTimeMillis(); + } + activity.setMessagesLoaded(); + activity.xmppConnectionService.getMessageArchiveService().query(conversation, 0, timestamp); + Toast.makeText(activity, R.string.fetching_history_from_server, Toast.LENGTH_LONG).show(); + } + + @Override + public View getView(int position, View unused, ViewGroup parent) { + final Message message = getItem(position); + final boolean isInValidSession = message.isValidInSession(); + final Conversation conversation = message.getConversation(); + final Account account = conversation.getAccount(); + final int type = getItemViewType(position); + ViewHolder viewHolder; + View view; + viewHolder = new ViewHolder(); + switch (type) { + case SENT: + view = activity.getLayoutInflater().inflate( + R.layout.message_sent, parent, false); + viewHolder.message_box = (LinearLayout) view + .findViewById(R.id.message_box); + viewHolder.contact_picture = (ImageView) view + .findViewById(R.id.message_photo); + viewHolder.aw_player = (ViewGroup) view.findViewById(R.id.aw_player); + viewHolder.download_button = (Button) view + .findViewById(R.id.download_button); + viewHolder.indicator = (ImageView) view + .findViewById(R.id.security_indicator); + viewHolder.edit_indicator = (ImageView) view.findViewById(R.id.edit_indicator); + viewHolder.image = (ImageView) view + .findViewById(R.id.message_image); + viewHolder.messageBody = (CopyTextView) view + .findViewById(R.id.message_body); + viewHolder.time = (TextView) view + .findViewById(R.id.message_time); + viewHolder.indicatorReceived = (ImageView) view + .findViewById(R.id.indicator_received); + viewHolder.indicatorRead = (ImageView) view + .findViewById(R.id.indicator_read); + break; + case RECEIVED: + view = activity.getLayoutInflater().inflate( + R.layout.message_received, parent, false); + viewHolder.message_box = (LinearLayout) view + .findViewById(R.id.message_box); + viewHolder.contact_picture = (ImageView) view + .findViewById(R.id.message_photo); + viewHolder.aw_player = (ViewGroup) view.findViewById(R.id.aw_player); + viewHolder.download_button = (Button) view + .findViewById(R.id.download_button); + viewHolder.indicator = (ImageView) view + .findViewById(R.id.security_indicator); + viewHolder.edit_indicator = (ImageView) view.findViewById(R.id.edit_indicator); + viewHolder.image = (ImageView) view + .findViewById(R.id.message_image); + viewHolder.messageBody = (CopyTextView) view + .findViewById(R.id.message_body); + viewHolder.time = (TextView) view + .findViewById(R.id.message_time); + viewHolder.indicatorReceived = (ImageView) view + .findViewById(R.id.indicator_received); + viewHolder.encryption = (TextView) view.findViewById(R.id.message_encryption); + break; + case STATUS: + view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false); + viewHolder.contact_picture = (ImageView) view.findViewById(R.id.message_photo); + viewHolder.status_message = (TextView) view.findViewById(R.id.status_message); + viewHolder.load_more_messages = (Button) view.findViewById(R.id.load_more_messages); + break; + default: + view = new View(getContext()); + viewHolder = null; + break; + } + if (viewHolder.messageBody != null) { + listSelectionManager.onCreate(viewHolder.messageBody); + viewHolder.messageBody.setCopyHandler(this); + } + view.setTag(viewHolder); + if (viewHolder == null) { + return view; + } + + + boolean darkBackground = (type == SENT && (!isInValidSession || !mUseWhiteBackground)); + + if (type == STATUS) { + if ("LOAD_MORE".equals(message.getBody())) { + viewHolder.status_message.setVisibility(View.GONE); + viewHolder.contact_picture.setVisibility(View.GONE); + viewHolder.load_more_messages.setVisibility(View.VISIBLE); + viewHolder.load_more_messages.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + loadMoreMessages(message.getConversation()); + } + }); + } else { + viewHolder.status_message.setVisibility(View.VISIBLE); + viewHolder.contact_picture.setVisibility(View.VISIBLE); + viewHolder.load_more_messages.setVisibility(View.GONE); + if (conversation.getMode() == Conversation.MODE_SINGLE) { + viewHolder.contact_picture.setImageBitmap(activity + .avatarService().get(conversation.getContact(), + activity.getPixel(32))); + viewHolder.contact_picture.setAlpha(0.5f); + } + viewHolder.status_message.setText(message.getBody()); + } + return view; + } else { + loadAvatar(message, viewHolder.contact_picture); + } + + viewHolder.contact_picture + .setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + if (MessageAdapter.this.mOnContactPictureClickedListener != null) { + MessageAdapter.this.mOnContactPictureClickedListener + .onContactPictureClicked(message); + } + + } + }); + viewHolder.contact_picture + .setOnLongClickListener(new OnLongClickListener() { + + @Override + public boolean onLongClick(View v) { + if (MessageAdapter.this.mOnContactPictureLongClickedListener != null) { + MessageAdapter.this.mOnContactPictureLongClickedListener + .onContactPictureLongClicked(message); + return true; + } else { + return false; + } + } + }); + + final Transferable transferable = message.getTransferable(); + String mimeType = message.getMimeType(); + if (transferable != null && transferable.getStatus() != Transferable.STATUS_UPLOADING) { + if (transferable.getStatus() == Transferable.STATUS_OFFER) { + displayDownloadableMessage(viewHolder, message, activity.getString(R.string.download_x_file, UIHelper.getFileDescriptionString(activity, message))); + } else if (transferable.getStatus() == Transferable.STATUS_OFFER_CHECK_FILESIZE) { + displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message))); + } else { + displayInfoMessage(viewHolder, UIHelper.getMessagePreview(activity, message).first, darkBackground); + } + } else if (message.getType() == Message.TYPE_IMAGE && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) { + displayImageMessage(viewHolder, message); + } else if (message.getType() == Message.TYPE_FILE && message.getEncryption() != Message.ENCRYPTION_PGP && message.getEncryption() != Message.ENCRYPTION_DECRYPTION_FAILED) { + if (message.getFileParams().width > 0) { + displayImageMessage(viewHolder, message); + } else { + if (mimeType != null) { + if (message.getMimeType().startsWith("audio/")) { + displayAudioMessage(viewHolder, message, position); + } else displayOpenableMessage(viewHolder, message); + } else displayOpenableMessage(viewHolder, message); + } + } else if (message.getEncryption() == Message.ENCRYPTION_PGP) { + if (account.isPgpDecryptionServiceConnected()) { + if (!account.hasPendingPgpIntent(conversation)) { + displayInfoMessage(viewHolder, activity.getString(R.string.message_decrypting), darkBackground); + } else { + displayInfoMessage(viewHolder, activity.getString(R.string.pgp_message), darkBackground); + } + } else { + displayInfoMessage(viewHolder, activity.getString(R.string.install_openkeychain), darkBackground); + if (viewHolder != null) { + viewHolder.message_box + .setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + activity.showInstallPgpDialog(); + } + }); + } + } + } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { + displayDecryptionFailed(viewHolder, darkBackground); + } else { + if (GeoHelper.isGeoUri(message.getBody())) { + displayLocationMessage(viewHolder, message); + } else if (message.bodyIsHeart()) { + displayHeartMessage(viewHolder, message.getBody().trim()); + } else if (message.bodyIsXmpp()) { + displayXmppMessage(viewHolder, message.getBody().trim()); + } else if (message.treatAsDownloadable() == Message.Decision.MUST || + message.treatAsDownloadable() == Message.Decision.SHOULD) { + try { + URL url = new URL(message.getBody()); + displayDownloadableMessage(viewHolder, + message, + activity.getString(R.string.check_x_filesize_on_host, + UIHelper.getFileDescriptionString(activity, message), + url.getHost())); + } catch (Exception e) { + displayDownloadableMessage(viewHolder, + message, + activity.getString(R.string.check_x_filesize, + UIHelper.getFileDescriptionString(activity, message))); + } + } else { + displayTextMessage(viewHolder, message, darkBackground); + } + } + + if (type == RECEIVED) { + if (isInValidSession) { + viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received); + viewHolder.encryption.setVisibility(View.GONE); + } else { + viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_warning); + viewHolder.encryption.setVisibility(View.VISIBLE); + viewHolder.encryption.setText(CryptoHelper.encryptionTypeToText(message.getEncryption())); + } + } + + if (type == SENT) { + if (mUseWhiteBackground) { + viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_sent_white); + } else { + viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_sent); + } + } + + displayStatus(viewHolder, message, type, darkBackground); + + return view; + } + + @Override + public void notifyDataSetChanged() { + listSelectionManager.onBeforeNotifyDataSetChanged(); + super.notifyDataSetChanged(); + listSelectionManager.onAfterNotifyDataSetChanged(); + } + + @Override + public String transformTextForCopy(CharSequence text, int start, int end) { + return text.toString().substring(start, end); + } + + public void openDownloadable(Message message) { + DownloadableFile file = activity.xmppConnectionService.getFileBackend().getFile(message); + if (!file.exists()) { + Toast.makeText(activity, R.string.file_deleted, Toast.LENGTH_SHORT).show(); + return; + } + String mime = file.getMimeType(); + if (mime.startsWith("image/")) { + Intent intent = new Intent(getContext(), ShowFullscreenMessageActivity.class); + intent.putExtra("image", Uri.fromFile(file)); + try { + activity.startActivity(intent); + return; + } catch (ActivityNotFoundException e) { + //ignored + } + } else if (mime.startsWith("video/")) { + Intent intent = new Intent(getContext(), ShowFullscreenMessageActivity.class); + intent.putExtra("video", Uri.fromFile(file)); + try { + activity.startActivity(intent); + return; + } catch (ActivityNotFoundException e) { + //ignored + } + } + Intent openIntent = new Intent(Intent.ACTION_VIEW); + if (mime == null) { + mime = "*/*"; + } + Uri uri; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + try { + uri = FileProvider.getUriForFile(activity, FileBackend.CONVERSATIONS_FILE_PROVIDER, file); + } catch (IllegalArgumentException e) { + Toast.makeText(activity, activity.getString(R.string.no_permission_to_access_x, file.getAbsolutePath()), Toast.LENGTH_SHORT).show(); + return; + } + openIntent.setDataAndType(uri, mime); + openIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + uri = Uri.fromFile(file); + } + openIntent.setDataAndType(uri, mime); + PackageManager manager = activity.getPackageManager(); + List<ResolveInfo> info = manager.queryIntentActivities(openIntent, 0); + if (info.size() == 0) { + openIntent.setDataAndType(Uri.fromFile(file), "*/*"); + } + try { + getContext().startActivity(openIntent); + } catch (ActivityNotFoundException e) { + Toast.makeText(activity, R.string.no_application_found_to_open_file, Toast.LENGTH_SHORT).show(); + } + } + + public void showLocation(Message message) { + for (Intent intent : GeoHelper.createGeoIntentsFromMessage(message)) { + if (intent.resolveActivity(getContext().getPackageManager()) != null) { + getContext().startActivity(intent); + return; + } + } + Toast.makeText(activity, R.string.no_application_found_to_display_location, Toast.LENGTH_SHORT).show(); + } + + public void updatePreferences() { + this.mIndicateReceived = activity.indicateReceived(); + this.mUseWhiteBackground = activity.useWhiteBackground(); + } + + public TextView getMessageBody(View view) { + final Object tag = view.getTag(); + if (tag instanceof ViewHolder) { + final ViewHolder viewHolder = (ViewHolder) tag; + return viewHolder.messageBody; + } + return null; + } + + public interface OnContactPictureClicked { + void onContactPictureClicked(Message message); + } + + public interface OnContactPictureLongClicked { + void onContactPictureLongClicked(Message message); + } + + private static class ViewHolder { + + protected LinearLayout message_box; + protected Button download_button; + protected ViewGroup aw_player; + protected ImageView image; + protected ImageView indicator; + protected ImageView indicatorReceived; + protected ImageView indicatorRead; + protected TextView time; + protected CopyTextView messageBody; + protected ImageView contact_picture; + protected TextView status_message; + protected TextView encryption; + public Button load_more_messages; + public ImageView edit_indicator; + } + + class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> { + private final WeakReference<ImageView> imageViewReference; + private Message message = null; + + public BitmapWorkerTask(ImageView imageView) { + imageViewReference = new WeakReference<>(imageView); + } + + @Override + protected Bitmap doInBackground(Message... params) { + return activity.avatarService().get(params[0], activity.getPixel(48), isCancelled()); + } + + @Override + protected void onPostExecute(Bitmap bitmap) { + if (bitmap != null && !isCancelled()) { + final ImageView imageView = imageViewReference.get(); + if (imageView != null) { + imageView.setImageBitmap(bitmap); + imageView.setBackgroundColor(0x00000000); + } + } + } + } + + public void loadAvatar(Message message, ImageView imageView) { + if (cancelPotentialWork(message, imageView)) { + final Bitmap bm = activity.avatarService().get(message, activity.getPixel(48), true); + if (bm != null) { + cancelPotentialWork(message, imageView); + imageView.setImageBitmap(bm); + imageView.setBackgroundColor(0x00000000); + } else { + imageView.setBackgroundColor(UIHelper.getColorForName(UIHelper.getMessageDisplayName(message))); + imageView.setImageDrawable(null); + final BitmapWorkerTask task = new BitmapWorkerTask(imageView); + final AsyncDrawable asyncDrawable = new AsyncDrawable(activity.getResources(), null, task); + imageView.setImageDrawable(asyncDrawable); + try { + task.execute(message); + } catch (final RejectedExecutionException ignored) { + } + } + } + } + + public static boolean cancelPotentialWork(Message message, ImageView imageView) { + final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); + + if (bitmapWorkerTask != null) { + final Message oldMessage = bitmapWorkerTask.message; + if (oldMessage == null || message != oldMessage) { + bitmapWorkerTask.cancel(true); + } else { + return false; + } + } + return true; + } + + private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { + if (imageView != null) { + final Drawable drawable = imageView.getDrawable(); + if (drawable instanceof AsyncDrawable) { + final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; + return asyncDrawable.getBitmapWorkerTask(); + } + } + return null; + } + + static class AsyncDrawable extends BitmapDrawable { + private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference; + + public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { + super(res, bitmap); + bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); + } + + public BitmapWorkerTask getBitmapWorkerTask() { + return bitmapWorkerTaskReference.get(); + } + } } |