Java tutorial
/* * Copyright 2018 GIG Technology NV * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @@license_version:1.4@@ */ package com.mobicage.rogerthat.plugins.messaging; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Resources; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.Typeface; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.v4.content.ContextCompat; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView.RecyclerListener; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CursorAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.SectionIndexer; import android.widget.TextView; import com.mikepenz.fontawesome_typeface_library.FontAwesome; import com.mikepenz.iconics.IconicsDrawable; import com.mobicage.rogerth.at.R; import com.mobicage.rogerthat.App; import com.mobicage.rogerthat.HomeActivity; import com.mobicage.rogerthat.IdentityStore; import com.mobicage.rogerthat.MainActivity; import com.mobicage.rogerthat.SendMessageContactActivity; import com.mobicage.rogerthat.ServiceBoundActivity; import com.mobicage.rogerthat.ServiceBoundCursorListActivity; import com.mobicage.rogerthat.plugins.friends.FriendsPlugin; import com.mobicage.rogerthat.plugins.messaging.MessageStore.CursorSet; import com.mobicage.rogerthat.plugins.scan.ProcessScanActivity; import com.mobicage.rogerthat.plugins.security.PinLockMgr; import com.mobicage.rogerthat.util.ActivityUtils; import com.mobicage.rogerthat.util.RegexPatterns; import com.mobicage.rogerthat.util.TextUtils; import com.mobicage.rogerthat.util.logging.L; import com.mobicage.rogerthat.util.system.SafeBroadcastReceiver; import com.mobicage.rogerthat.util.system.SafeRunnable; import com.mobicage.rogerthat.util.system.SafeViewOnClickListener; import com.mobicage.rogerthat.util.system.SystemUtils; import com.mobicage.rogerthat.util.system.T; import com.mobicage.rogerthat.util.time.TimeUtils; import com.mobicage.rogerthat.util.ui.UIUtils; import com.mobicage.rpc.config.AppConstants; import com.mobicage.rpc.config.LookAndFeelConstants; import com.mobicage.to.messaging.MemberStatusTO; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class MessagingActivity extends ServiceBoundCursorListActivity { private static final long sGMTOffsetMillis = TimeUtils.getGMTOffsetMillis(); // Owned by UI thread private BroadcastReceiver mBroadcastReceiver; private FloatingActionButton mFloatingActionButton; private MessagingPlugin mMessagingPlugin; private FriendsPlugin mFriendsPlugin; private String mMemberFilter; private String mMyEmail; private Resources mResources; private boolean mEditing = false; private Set<String> mToBeDeleted; private CursorSet mCursorSet = null; private Map<View, SafeRunnable> mCellsToUpdate = new HashMap<View, SafeRunnable>(); private Intent mPendingIntent; @Override public boolean onPrepareOptionsMenu(Menu menu) { for (int i = 0; i < menu.size(); i++) { MenuItem item = menu.getItem(i); switch (item.getItemId()) { case R.id.select_all: case R.id.deselect_all: item.setVisible(mEditing); break; case R.id.delete_messages: item.setEnabled(((CursorAdapter) getListAdapter()).getCursor().getCount() > 0); //$FALL-THROUGH$ default: item.setVisible(!mEditing); break; } } return super.onPrepareOptionsMenu(menu); } @Override public boolean onCreateOptionsMenu(Menu menu) { T.UI(); super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.messaging_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { T.UI(); switch (item.getItemId()) { case R.id.delete_messages: setEditing(true); return true; case R.id.select_all: mToBeDeleted.clear(); Cursor c = ((CursorAdapter) getListAdapter()).getCursor(); if (!c.moveToFirst()) { L.e("Could not move cursor to first position"); return false; } do { String key = MessageStore.getKeyFromMessageCursor(c); String parentKey = MessageStore.getParentKeyFromMessageCursor(c); long flags = MessageStore.getFlagsFromMessageCursor(c); if (!SystemUtils.isFlagEnabled(flags, MessagingPlugin.FLAG_NOT_REMOVABLE)) mToBeDeleted.add(parentKey == null ? key : parentKey); } while (c.moveToNext()); ((CursorAdapter) getListAdapter()).notifyDataSetChanged(); return true; case R.id.deselect_all: mToBeDeleted.clear(); ((CursorAdapter) getListAdapter()).notifyDataSetChanged(); return true; } return super.onOptionsItemSelected(item); } @Override protected void onResume() { super.onResume(); T.UI(); if (mMessagingPlugin != null && mMemberFilter == null) mMessagingPlugin.inboxOpened(); if (getWasPaused() && mCursorSet != null) { startManagingCursor(mCursorSet.cursor); startManagingCursor(mCursorSet.indexer); ((CursorAdapter) getListAdapter()).notifyDataSetChanged(); } } @Override protected void onPause() { super.onPause(); if (mCursorSet != null) { stopManagingCursor(mCursorSet.cursor); stopManagingCursor(mCursorSet.indexer); } } @Override protected void onDestroy() { if (mService != null) { for (SafeRunnable sr : mCellsToUpdate.values()) { mService.removeFromUIHandler(sr); } } mCellsToUpdate.clear(); super.onDestroy(); } @Override protected void onCreate(Bundle savedInstanceState) { T.UI(); super.onCreate(savedInstanceState); mResources = getResources(); mBroadcastReceiver = new SafeBroadcastReceiver() { @Override public String[] onSafeReceive(Context context, Intent intent) { if (PinLockMgr.PIN_ENTERED_INTENT.equals(intent.getAction())) { if (mPendingIntent != null) { processMessageUpdatesIntent(mPendingIntent); mPendingIntent = null; } return new String[] { intent.getAction() }; } return null; }; }; } private void processMessageUpdatesIntent(final Intent intent) { final String url = intent.getDataString(); if (intent.getBooleanExtra(HomeActivity.INTENT_PROCESSED, false)) return; if (url != null) { ActivityUtils.goToMessagingActivity(this, false, null); processUrl(url); } else if (intent.hasExtra(HomeActivity.INTENT_KEY_LAUNCHINFO)) { String value = intent.getStringExtra(HomeActivity.INTENT_KEY_LAUNCHINFO); if (HomeActivity.INTENT_VALUE_SHOW_FRIENDS.equals(value)) { // goToUserFriendsActivity(); } else if (HomeActivity.INTENT_VALUE_SHOW_MESSAGES.equals(value)) { ActivityUtils.goToMessagingActivity(this, false, null); } else if (HomeActivity.INTENT_VALUE_SHOW_NEW_MESSAGES.equals(value) || HomeActivity.INTENT_VALUE_SHOW_UPDATED_MESSAGES.equals(value)) { if (intent.hasExtra(HomeActivity.INTENT_KEY_MESSAGE)) { if (!App.getContext().getPinLockMgr().canContinueToActivity()) { mPendingIntent = intent; return; } String messageKey = intent.getStringExtra(HomeActivity.INTENT_KEY_MESSAGE); goToMessageDetail(messageKey); } else { ActivityUtils.goToMessagingActivity(this, false, null); } } else if (HomeActivity.INTENT_VALUE_SHOW_SCANTAB.equals(value)) { ActivityUtils.goToScanActivity(this, false, null); } else { L.bug("Unexpected (key, value) for HomeActivity intent: (" + HomeActivity.INTENT_KEY_LAUNCHINFO + ", " + value + ")"); } } intent.putExtra(HomeActivity.INTENT_PROCESSED, true); } private void processUrl(final String url) { T.UI(); if (RegexPatterns.OPEN_HOME_URL.matcher(url).matches()) return; if (RegexPatterns.FRIEND_INVITE_URL.matcher(url).matches() || RegexPatterns.SERVICE_INTERACT_URL.matcher(url).matches()) { final Intent launchIntent = new Intent(this, ProcessScanActivity.class); launchIntent.putExtra(ProcessScanActivity.URL, url); launchIntent.putExtra(ProcessScanActivity.SCAN_RESULT, false); startActivity(launchIntent); } } private void goToMessageDetail(final String messageKey) { Message message = mMessagingPlugin.getStore().getPartialMessageByKey(messageKey); if (message == null) { UIUtils.showLongToast(this, getString(R.string.message_not_found)); } else { mMessagingPlugin.showMessage(this, message, null); } } @Override protected String[] getAllReceivingIntents() { return new String[] { MessagingPlugin.NEW_MESSAGE_RECEIVED_INTENT, MessagingPlugin.MESSAGE_MEMBER_STATUS_UPDATE_RECEIVED_INTENT, MessagingPlugin.MESSAGE_DIRTY_CLEANED_INTENT, MessagingPlugin.MESSAGE_LOCKED_INTENT, MessagingPlugin.MESSAGE_PROCESSED_INTENT, MessagingPlugin.MESSAGE_FAILURE, MessagingPlugin.MESSAGE_THREAD_VISIBILITY_CHANGED_INTENT, MessagingPlugin.THREAD_DELETED_INTENT, MessagingPlugin.THREAD_RECOVERED_INTENT, MessagingPlugin.THREAD_MODIFIED_INTENT, FriendsPlugin.FRIEND_AVATAR_CHANGED_INTENT, IdentityStore.IDENTITY_CHANGED_INTENT, FriendsPlugin.FRIENDS_LIST_REFRESHED }; } private void processIntent(Intent intent, Boolean start) { if (intent != null) { final String intentAction = intent.getAction(); if (MainActivity.ACTION_NOTIFICATION_MESSAGE_RECEIVED.equals(intentAction)) { processMessageUpdatesIntent(intent); } else { final String url = intent.getDataString(); if (url != null) { processUrl(url); } if (start) { Bundle extras = intent.getExtras(); if (extras != null) { mMemberFilter = extras.getString(MessagingPlugin.MEMBER_FILTER); } } } } } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); if (mService != null) { processIntent(intent, false); } } @Override protected void onServiceBound() { T.UI(); mMessagingPlugin = mService.getPlugin(MessagingPlugin.class); mFriendsPlugin = mService.getPlugin(FriendsPlugin.class); mMyEmail = mService.getIdentityStore().getIdentity().getEmail(); processIntent(getIntent(), true); if (mMemberFilter == null) { mMessagingPlugin.inboxOpened(); setContentView(R.layout.messaging); setActivityName("messages"); } else { setContentView(R.layout.messaging); setActivityName("messages_filter"); } setListView((ListView) findViewById(R.id.message_list)); findViewById(R.id.delete_done_button).setOnClickListener(new SafeViewOnClickListener() { @Override public void safeOnClick(View v) { for (String threadKey : mToBeDeleted) { mMessagingPlugin.deleteConversation(threadKey); } changeCursor(); setEditing(false); } }); findViewById(R.id.delete_cancel_button).setOnClickListener(new SafeViewOnClickListener() { @Override public void safeOnClick(View v) { setEditing(false); } }); mFloatingActionButton = ((FloatingActionButton) findViewById(R.id.add)); mFloatingActionButton.setImageDrawable( new IconicsDrawable(this, FontAwesome.Icon.faw_plus).color(Color.WHITE).sizeDp(24)); mFloatingActionButton.setOnClickListener(new SafeViewOnClickListener() { @Override public void safeOnClick(View v) { showSendMessageActivity(); } }); if (!AppConstants.FRIENDS_ENABLED || mMemberFilter != null) { mFloatingActionButton.hide(); } if (mMemberFilter == null) { setTitle(R.string.tab_messaging); } else { setTitle(R.string.message_history); } createCursorSet(); startManagingCursor(mCursorSet.cursor); startManagingCursor(mCursorSet.indexer); final MessageListAdapter messageListAdapter = new MessageListAdapter(this, mCursorSet, mMessagingPlugin.getStore(), mFriendsPlugin); setListAdapter(messageListAdapter); final IntentFilter filter = new IntentFilter(); for (String action : getAllReceivingIntents()) filter.addAction(action); registerReceiver(getDefaultBroadcastReceiver(), filter); registerReceiver(mBroadcastReceiver, new IntentFilter(PinLockMgr.PIN_ENTERED_INTENT)); } @Override protected void onServiceUnbound() { unregisterReceiver(getDefaultBroadcastReceiver()); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { T.UI(); final Object tag = v.getTag(); if (tag != null) { final ViewInfoHolder holder = (ViewInfoHolder) tag; final Message message = holder.message; mMessagingPlugin.showMessage(this, message, mMemberFilter); } } @Override protected boolean onListItemLongClick(ListView l, View v, int position, long id) { final Object tag = v.getTag(); if (tag != null) { final ViewInfoHolder holder = (ViewInfoHolder) tag; if (SystemUtils.isFlagEnabled(holder.message.flags, MessagingPlugin.FLAG_NOT_REMOVABLE)) return false; mMessagingPlugin.removeConversationFromList(this, holder.message.getThreadKey()); } return true; } private void createCursorSet() { if (mCursorSet != null) { stopManagingCursor(mCursorSet.cursor); stopManagingCursor(mCursorSet.indexer); } mCursorSet = mMessagingPlugin.getStore().getMessagesCursor(mMemberFilter); } @Override protected void changeCursor() { if (mServiceIsBound) { createCursorSet(); MessageListAdapter mla = (MessageListAdapter) getListAdapter(); mla.mCursor = mCursorSet.cursor; mla.mIndexerCursor = mCursorSet.indexer; mla.mQuery = mCursorSet.query; mla.changeCursor(mCursorSet.cursor); mla.buildSectionIndex(); } } private void showSendMessageActivity() { long currentTime = System.currentTimeMillis(); if (getLastTimeClicked() != 0 && (currentTime < (getLastTimeClicked() + ServiceBoundActivity.DOUBLE_CLICK_TIMESPAN))) { L.d("ignoring click on send message"); return; } setLastTimeClicked(currentTime); Intent intent = new Intent(this, SendMessageContactActivity.class); startActivity(intent); } private void setEditing(boolean editing) { mEditing = editing; if (AppConstants.FRIENDS_ENABLED && mMemberFilter == null) { if (editing) { mFloatingActionButton.hide(); } else { mFloatingActionButton.show(); } } supportInvalidateOptionsMenu(); mToBeDeleted = mEditing ? new HashSet<String>() : null; findViewById(R.id.delete_messages).setVisibility(mEditing ? View.VISIBLE : View.GONE); ((CursorAdapter) getListAdapter()).notifyDataSetChanged(); } // Object put in view tag. Contains fast references to message and subviews private class ViewInfoHolder { Message message; TextView recipientsView; TextView timestampView; TextView messageView; TextView messageCountView; ImageView avatarView; CheckBox checkBox; ImageView statusView; } private class MessageListAdapter extends CursorAdapter implements SectionIndexer { private class Section { int day; int start; @Override public String toString() { // e.g. beginning of day 10 (start with day 0) is 10 * 86400 seconds in UTC // however, in Belgium summer time we need to subtract 7200 seconds return TimeUtils.getDayStrOrToday(MessagingActivity.this, day * 86400L * 1000L - sGMTOffsetMillis); } } private final MessageStore mStore; private final FriendsPlugin mFriendsPlugin; private final LayoutInflater mLayoutInflater; private Section[] mSections; private Cursor mCursor; private Cursor mIndexerCursor; private int mQuery; public MessageListAdapter(Context context, CursorSet cursorSet, MessageStore store, FriendsPlugin friendsPlugin) { super(context, cursorSet.cursor, false); mCursor = cursorSet.cursor; mStore = store; mFriendsPlugin = friendsPlugin; mLayoutInflater = getLayoutInflater(); mIndexerCursor = cursorSet.indexer; mQuery = cursorSet.query; buildSectionIndex(); } private void buildSectionIndex() { mSections = new Section[mIndexerCursor.getCount()]; int pos = 0; int index = 0; if (mIndexerCursor.moveToFirst()) { while (true) { Section section = new Section(); section.start = pos; section.day = mIndexerCursor.getInt(0); mSections[index++] = section; pos += mIndexerCursor.getInt(1); if (!mIndexerCursor.moveToNext()) { break; } } } getListView().setRecyclerListener(new RecyclerListener() { @Override public void onMovedToScrapHeap(View view) { SafeRunnable sr = mCellsToUpdate.get(view); if (sr != null) { mService.removeFromUIHandler(sr); mCellsToUpdate.remove(view); } } }); } @Override public int getCount() { int c = super.getCount(); return c; } @Override public boolean areAllItemsEnabled() { return true; } @Override public boolean isEnabled(int position) { return true; } @Override public View getView(int position, View convertView, ViewGroup parent) { T.UI(); if (!mCursor.moveToPosition(position)) { throw new IllegalStateException("couldn't move cursor to position " + position); } View view; Message message = mStore.getCurrentMessage(mCursor, mQuery); if (!message.threadShowInList) { message.threadShowInList = true; mMessagingPlugin.setMessageThreadVisibility(message.getThreadKey(), true); } ViewInfoHolder holder = null; if (convertView == null || convertView.getTag() == null) { view = mLayoutInflater.inflate(R.layout.message, parent, false); } else { view = convertView; holder = (ViewInfoHolder) convertView.getTag(); } if (holder == null) { holder = new ViewInfoHolder(); holder.avatarView = (ImageView) view.findViewById(R.id.avatar); holder.recipientsView = (TextView) view.findViewById(R.id.recipients); holder.timestampView = (TextView) view.findViewById(R.id.timestamp); holder.messageView = (TextView) view.findViewById(R.id.message); holder.messageCountView = (TextView) view.findViewById(R.id.message_count); holder.checkBox = (CheckBox) view.findViewById(R.id.message_checkbox); holder.statusView = (ImageView) view.findViewById(R.id.message_status); view.setTag(holder); } holder.message = message; int primaryColor = LookAndFeelConstants.getPrimaryColor(mService); UIUtils.setBackgroundColor(holder.messageCountView, primaryColor); final boolean dynamicChat = SystemUtils.isFlagEnabled(message.flags, MessagingPlugin.FLAG_DYNAMIC_CHAT); setMessageOnView(view, holder, dynamicChat); return view; } private void setMessageOnView(final View view, ViewInfoHolder holder, boolean dynamicChat) { final Message message = holder.message; final ImageView avatarView = holder.avatarView; boolean shouldShowStatusIcon = true; final Bitmap threadAvatar; if (message.thread_avatar_hash != null && (threadAvatar = mMessagingPlugin.getStore() .getThreadAvatar(message.thread_avatar_hash)) != null) { avatarView.setImageBitmap(threadAvatar); } else if (dynamicChat) { avatarView.setImageResource(R.drawable.group_60); } else if (FriendsPlugin.SYSTEM_FRIEND.equals(message.sender) || mFriendsPlugin.getStore() .getFriendType(message.sender) == FriendsPlugin.FRIEND_TYPE_SERVICE) { shouldShowStatusIcon = false; avatarView.setImageBitmap(mFriendsPlugin.getAvatarBitmap(message.sender)); } else if (message.members.length == 2) { String otherOne = null; for (MemberStatusTO member : message.members) { if (!mMyEmail.equals(member.member)) { otherOne = member.member; break; } } if (otherOne == null) otherOne = message.sender; avatarView.setImageBitmap(mFriendsPlugin.getAvatarBitmap(otherOne)); } else { avatarView.setImageResource(R.drawable.group_60); } String recipients; String messageText; if (message.parent_key == null && dynamicChat) { try { JSONObject json = (JSONObject) JSONValue.parse(message.message); recipients = (String) json.get("t"); messageText = (String) json.get("d"); } catch (Throwable t) { recipients = message.recipients; messageText = message.message; } } else if (message.parent_key != null && dynamicChat) { try { JSONObject json = (JSONObject) JSONValue .parse(mMessagingPlugin.getStore().getMessageMessage(message.parent_key)); recipients = (String) json.get("t"); messageText = message.message; } catch (Throwable t) { recipients = message.recipients; messageText = message.message; } } else { recipients = message.recipients; messageText = message.message; } if (TextUtils.isEmptyOrWhitespace(messageText)) { messageText = mMessagingPlugin.getMessageTextFromButtonsOrAttachments(message); } if (message.members.length > 2) { if (mMyEmail.equals(message.sender)) { messageText = message.message; } else { messageText = mFriendsPlugin.getName(message.sender) + ": " + message.message; } } // this can happen when the name of the service wasn't available yet when fetching the messages during re-registration. if (TextUtils.isEmptyOrWhitespace(recipients)) { recipients = mFriendsPlugin.getName(message.sender); mMessagingPlugin.getStore().updateMessageRecipients( message.parent_key != null ? message.parent_key : message.key, recipients); } int tmpThreadTextColor = Integer.MAX_VALUE; int tmpThreadBackgroundColor = Integer.MAX_VALUE; final long priority = message.priority; if (priority == Message.PRIORITY_HIGH) { tmpThreadTextColor = ContextCompat.getColor(mService, R.color.mc_priority_high_text); tmpThreadBackgroundColor = ContextCompat.getColor(mService, R.color.mc_priority_high_background); } else if (priority == Message.PRIORITY_URGENT || priority == Message.PRIORITY_URGENT_WITH_ALARM) { tmpThreadTextColor = ContextCompat.getColor(mService, R.color.mc_priority_urgent_text); tmpThreadBackgroundColor = ContextCompat.getColor(mService, R.color.mc_priority_urgent_background); } final int threadTextColor = message.thread_text_color != null ? Color.parseColor("#" + message.thread_text_color) : tmpThreadTextColor; final int threadBackgroundColor = message.thread_background_color != null ? Color.parseColor("#" + message.thread_background_color) : tmpThreadBackgroundColor; final TextView recipientsView = holder.recipientsView; recipientsView.setText(recipients); if (threadTextColor != Integer.MAX_VALUE) { recipientsView.setTextColor(threadTextColor); } else { recipientsView.setTextColor(mResources.getColorStateList(android.R.color.primary_text_light)); } final TextView messageCountView = holder.messageCountView; long replyCount = message.replyCount; if (dynamicChat) replyCount--; long messageUnreadCount = message.unreadCount; if (dynamicChat && replyCount < messageUnreadCount) { messageUnreadCount--; } if (messageUnreadCount >= 1) { Typeface boldFont = TextUtils.getFont(MessagingActivity.this); holder.recipientsView.setTypeface(boldFont); holder.messageView.setTypeface(boldFont); messageCountView.setVisibility(View.VISIBLE); } else { Typeface normalFont = TextUtils.getFont(MessagingActivity.this, "regular"); holder.recipientsView.setTypeface(normalFont); holder.messageView.setTypeface(normalFont); messageCountView.setVisibility(View.GONE); } if (messageCountView.getVisibility() == View.VISIBLE) { long count = 0; if (messageUnreadCount >= 1) { count = messageUnreadCount; } else { count = replyCount; } if (count < 10) { messageCountView.setText(String.valueOf(count)); } else { messageCountView.setText("9+"); } } final TextView timestamp = holder.timestampView; if (timestamp != null) { long startRunnableIn = TimeUtils.startRunnableToUpdateTimeIn(MessagingActivity.this, message.timestamp * 1000); if (startRunnableIn > 0) { SafeRunnable sr = new SafeRunnable() { @Override protected void safeRun() throws Exception { timestamp.setText( TimeUtils.getHumanTime(MessagingActivity.this, message.timestamp * 1000, true)); long startRunnableIn = TimeUtils.startRunnableToUpdateTimeIn(MessagingActivity.this, message.timestamp * 1000); if (startRunnableIn > 0) { mService.postDelayedOnUIHandler(this, startRunnableIn); } else { mCellsToUpdate.remove(view); } } }; mCellsToUpdate.put(view, sr); mService.postDelayedOnUIHandler(sr, startRunnableIn); } timestamp.setText(TimeUtils.getHumanTime(MessagingActivity.this, message.timestamp * 1000, true)); if (threadTextColor != Integer.MAX_VALUE) { timestamp.setTextColor(threadTextColor); } else { timestamp.setTextColor(mResources.getColorStateList(android.R.color.secondary_text_light)); } } final TextView messageView = holder.messageView; messageView.setText(messageText); if (threadTextColor != Integer.MAX_VALUE) { messageView.setTextColor(threadTextColor); } if (threadBackgroundColor != Integer.MAX_VALUE) view.setBackgroundColor(threadBackgroundColor); holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (mToBeDeleted != null) { if (isChecked) { mToBeDeleted.add(message.getThreadKey()); } else { mToBeDeleted.remove(message.getThreadKey()); } } } }); holder.checkBox.setChecked(mToBeDeleted != null && mToBeDeleted.contains(message.getThreadKey())); holder.checkBox.setVisibility( mEditing && !SystemUtils.isFlagEnabled(message.flags, MessagingPlugin.FLAG_NOT_REMOVABLE) ? View.VISIBLE : View.GONE); boolean showMessageStatus = messageUnreadCount == 0; if (showMessageStatus) { showMessageStatus = shouldShowStatusIcon && setStatusIcon(MessagingActivity.this, message, holder.statusView, dynamicChat); } holder.statusView.setVisibility(showMessageStatus ? View.VISIBLE : View.GONE); } private boolean setStatusIcon(Context context, Message message, ImageView statusView, boolean dynamicChat) { if (dynamicChat) { if (message.priority == Message.PRIORITY_URGENT_WITH_ALARM) { int primaryColor = ContextCompat.getColor(mService, R.color.mc_gray_11); statusView.setImageDrawable( new IconicsDrawable(context, FontAwesome.Icon.faw_bell).color(primaryColor).sizeDp(15)); return true; } else { return false; } } else { if (!mMyEmail.equals(message.sender)) return false; if (message.recipients_status == MessageMemberStatusSummaryEncoding.ERROR) { int errorColor = ContextCompat.getColor(mService, R.color.mc_error); statusView.setImageDrawable(new IconicsDrawable(context, FontAwesome.Icon.faw_exclamation) .color(errorColor).sizeDp(15)); } else if (message.alert_flags >= AlertManager.ALERT_FLAG_RING_5 && !mMessagingPlugin.isMessageAckedByMe(message)) { int rogerthatColor = ContextCompat.getColor(mService, R.color.mc_green); statusView.setImageDrawable(new IconicsDrawable(context, FontAwesome.Icon.faw_bell) .color(rogerthatColor).sizeDp(15)); } else if (message.numAcked() != 0) { int rogerthatColor = ContextCompat.getColor(mService, R.color.mc_green); statusView.setImageDrawable(new IconicsDrawable(context, FontAwesome.Icon.faw_check) .color(rogerthatColor).sizeDp(15)); } else if (message.numReceived() != 0) { int grayColor = ContextCompat.getColor(mService, R.color.mc_gray_11); statusView.setImageDrawable( new IconicsDrawable(context, FontAwesome.Icon.faw_check).color(grayColor).sizeDp(15)); } else { int grayColor = ContextCompat.getColor(mService, R.color.mc_gray_11); statusView.setImageDrawable(new IconicsDrawable(context, FontAwesome.Icon.faw_paper_plane) .color(grayColor).sizeDp(15)); } return true; } } @Override public void bindView(View view, Context context, Cursor cursor) { L.bug("unused?"); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { L.bug("unused?"); return null; } @Override public int getPositionForSection(int sectionIndex) { return mSections[sectionIndex].start; } @Override public int getSectionForPosition(int position) { for (int i = 0; i < mSections.length; i++) { if (mSections[i].start > position) { if (i > 0) return i - 1; return 0; } } return 0; } @Override public Object[] getSections() { return mSections; } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && mEditing) { setEditing(false); return true; } return super.onKeyDown(keyCode, event); } }