From b085643555e595d7c2a768016c6ef8ad124a5ca5 Mon Sep 17 00:00:00 2001 From: steckbrief Date: Tue, 11 Aug 2015 22:19:48 +0200 Subject: Fixes FS#20: Limitation of end conversation swipe to left side --- .../conversations/ui/ConversationActivity.java | 117 +++++++++++---------- 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java index 0504ff34..bf261dba 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationActivity.java @@ -188,65 +188,66 @@ public class ConversationActivity extends XmppActivity listView.setDismissCallback(new EnhancedListView.OnDismissCallback() { - @Override - public EnhancedListView.Undoable onDismiss(final EnhancedListView enhancedListView, final int position) { - - final int index = listView.getFirstVisiblePosition(); - View v = listView.getChildAt(0); - final int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop()); - - swipedConversation = listAdapter.getItem(position); - listAdapter.remove(swipedConversation); - swipedConversation.markRead(); - xmppConnectionService.getNotificationService().clear(swipedConversation); - - final boolean formerlySelected = (getSelectedConversation() == swipedConversation); - if (position == 0 && listAdapter.getCount() == 0) { - endConversation(swipedConversation, false, true); - return null; - } else if (formerlySelected) { - setSelectedConversation(listAdapter.getItem(0)); - ConversationActivity.this.mConversationFragment - .reInit(getSelectedConversation()); - } - - return new EnhancedListView.Undoable() { - - @Override - public void undo() { - listAdapter.insert(swipedConversation, position); - if (formerlySelected) { - setSelectedConversation(swipedConversation); - ConversationActivity.this.mConversationFragment - .reInit(getSelectedConversation()); - } - swipedConversation = null; - listView.setSelectionFromTop(index + (listView.getChildCount() < position ? 1 : 0), top); - } - - @Override - public void discard() { - if (!swipedConversation.isRead() - && swipedConversation.getMode() == Conversation.MODE_SINGLE) { - swipedConversation = null; - return; - } - endConversation(swipedConversation, false, false); - swipedConversation = null; - } - - @Override - public String getTitle() { - if (swipedConversation.getMode() == Conversation.MODE_MULTI) { - return getResources().getString(R.string.title_undo_swipe_out_muc); - } else { - return getResources().getString(R.string.title_undo_swipe_out_conversation); - } - } - }; - } - }); + @Override + public EnhancedListView.Undoable onDismiss(final EnhancedListView enhancedListView, final int position) { + + final int index = listView.getFirstVisiblePosition(); + View v = listView.getChildAt(0); + final int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop()); + + swipedConversation = listAdapter.getItem(position); + listAdapter.remove(swipedConversation); + swipedConversation.markRead(); + xmppConnectionService.getNotificationService().clear(swipedConversation); + + final boolean formerlySelected = (getSelectedConversation() == swipedConversation); + if (position == 0 && listAdapter.getCount() == 0) { + endConversation(swipedConversation, false, true); + return null; + } else if (formerlySelected) { + setSelectedConversation(listAdapter.getItem(0)); + ConversationActivity.this.mConversationFragment + .reInit(getSelectedConversation()); + } + + return new EnhancedListView.Undoable() { + + @Override + public void undo() { + listAdapter.insert(swipedConversation, position); + if (formerlySelected) { + setSelectedConversation(swipedConversation); + ConversationActivity.this.mConversationFragment + .reInit(getSelectedConversation()); + } + swipedConversation = null; + listView.setSelectionFromTop(index + (listView.getChildCount() < position ? 1 : 0), top); + } + + @Override + public void discard() { + if (!swipedConversation.isRead() + && swipedConversation.getMode() == Conversation.MODE_SINGLE) { + swipedConversation = null; + return; + } + endConversation(swipedConversation, false, false); + swipedConversation = null; + } + + @Override + public String getTitle() { + if (swipedConversation.getMode() == Conversation.MODE_MULTI) { + return getResources().getString(R.string.title_undo_swipe_out_muc); + } else { + return getResources().getString(R.string.title_undo_swipe_out_conversation); + } + } + }; + } + }); listView.enableSwipeToDismiss(); + listView.setSwipeDirection(EnhancedListView.SwipeDirection.START); listView.setSwipingLayout(R.id.swipeable_item); listView.setUndoStyle(EnhancedListView.UndoStyle.SINGLE_POPUP); listView.setUndoHideDelay(5000); -- cgit v1.2.3 From 473f0353550f81bb95cb576caa47089a6e62671e Mon Sep 17 00:00:00 2001 From: lookshe Date: Wed, 12 Aug 2015 18:28:56 +0200 Subject: Fixes FS#33 - Get back the comment --- src/main/java/eu/siacs/conversations/entities/Message.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index 9a904cab..eaa15de4 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -506,6 +506,11 @@ public class Message extends AbstractEntity { } public Decision treatAsDownloadable() { + /** + * there are a few cases where spaces result in an unwanted behavior, e.g. + * "http://example.com/image.jpg" text that will not be shown /abc.png" + * or more than one image link in one message. + */ if (body.trim().contains(" ")) { return Decision.NEVER; } -- cgit v1.2.3 From 0ee1992da2014d51e42c008b2ae39a6e1e033d0b Mon Sep 17 00:00:00 2001 From: lookshe Date: Wed, 12 Aug 2015 19:07:25 +0200 Subject: Fixes FS#38 - Issues with URLs with multiple dots in file name --- .../eu/siacs/conversations/entities/Message.java | 25 ++++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index eaa15de4..e3fb7944 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -473,17 +473,28 @@ public class Message extends AbstractEntity { private static String extractRelevantExtension(URL url) { String path = url.getPath(); + return extractRelevantExtension(path); + } + + private static String extractRelevantExtension(String path) { if (path == null || path.isEmpty()) { return null; } + String filename = path.substring(path.lastIndexOf('/') + 1).toLowerCase(); - String[] extensionParts = filename.split("\\."); - if (extensionParts.length == 2) { - return extensionParts[extensionParts.length - 1]; - } else if (extensionParts.length == 3 && Arrays - .asList(Transferable.VALID_CRYPTO_EXTENSIONS) - .contains(extensionParts[extensionParts.length - 1])) { - return extensionParts[extensionParts.length -2]; + + int dotPosition = filename.lastIndexOf("."); + + if (dotPosition != -1) + { + String extension = filename.substring(dotPosition + 1); + + // we want the real file extension, not the crypto one + if (Arrays.asList(Transferable.VALID_CRYPTO_EXTENSIONS).contains(extension)) { + return extractRelevantExtension(path.substring(0,dotPosition)); + } else { + return extension; + } } return null; } -- cgit v1.2.3 From 79c585144d0967a2e5d4b1cfb6c486332d0b0cfb Mon Sep 17 00:00:00 2001 From: steckbrief Date: Wed, 12 Aug 2015 23:01:37 +0200 Subject: - Introduction of SwipeRefreshLayout for conversation view - OnScrollListener for ListView of messages removed and replaced with swipe refresh - Loading of messages now possible even if no message is present in conversation --- .../services/XmppConnectionService.java | 75 ++++---- .../conversations/ui/ConversationFragment.java | 191 ++++++--------------- .../ConversationMoreMessagesLoadedListener.java | 118 +++++++++++++ .../ConversationSwipeRefreshListener.java | 48 ++++++ src/main/res/layout/fragment_conversation.xml | 8 + 5 files changed, 271 insertions(+), 169 deletions(-) create mode 100644 src/main/java/eu/siacs/conversations/ui/listeners/ConversationMoreMessagesLoadedListener.java create mode 100644 src/main/java/eu/siacs/conversations/ui/listeners/ConversationSwipeRefreshListener.java diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 27bc502a..f50b9fa6 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -382,21 +382,21 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } else { mFileAddingExecutor.execute(new Runnable() { - @Override - public void run() { - try { - getFileBackend().copyFileToPrivateStorage(message, uri); - getFileBackend().updateFileParams(message); - if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { - getPgpEngine().encrypt(message, callback); - } else { - callback.success(message); - } - } catch (FileBackend.FileCopyException e) { - callback.error(e.getResId(), message); - } - } - }); + @Override + public void run() { + try { + getFileBackend().copyFileToPrivateStorage(message, uri); + getFileBackend().updateFileParams(message); + if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { + getPgpEngine().encrypt(message, callback); + } else { + callback.success(message); + } + } catch (FileBackend.FileCopyException e) { + callback.error(e.getResId(), message); + } + } + }); } } @@ -851,7 +851,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": fetching roster"); } iqPacket.query(Xmlns.ROSTER).setAttribute("ver",account.getRosterVersion()); - sendIqPacket(account,iqPacket,mIqParser); + sendIqPacket(account, iqPacket, mIqParser); } public void fetchBookmarks(final Account account) { @@ -1029,24 +1029,25 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa } } Collections.sort(list, new Comparator() { - @Override - public int compare(Conversation lhs, Conversation rhs) { - Message left = lhs.getLatestMessage(); - Message right = rhs.getLatestMessage(); - if (left.getTimeSent() > right.getTimeSent()) { - return -1; - } else if (left.getTimeSent() < right.getTimeSent()) { - return 1; - } else { - return 0; - } - } - }); + @Override + public int compare(Conversation lhs, Conversation rhs) { + Message left = lhs.getLatestMessage(); + Message right = rhs.getLatestMessage(); + if (left.getTimeSent() > right.getTimeSent()) { + return -1; + } else if (left.getTimeSent() < right.getTimeSent()) { + return 1; + } else { + return 0; + } + } + }); } public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) { Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp)); if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation,callback)) { + Log.d("mam", "Query in progress"); return; } Runnable runnable = new Runnable() { @@ -1054,19 +1055,26 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void run() { final Account account = conversation.getAccount(); List messages = databaseBackend.getMessages(conversation, 50,timestamp); + Log.d("mam", "runnable load more messages"); if (messages.size() > 0) { + Log.d("mam", "At least one message"); conversation.addAll(0, messages); checkDeletedFiles(conversation); callback.onMoreMessagesLoaded(messages.size(), conversation); } else if (conversation.hasMessagesLeftOnServer() && account.isOnlineAndConnected() && account.getXmppConnection().getFeatures().mam()) { + Log.d("mam", "mam activate, account online and connected and messages left on server"); MessageArchiveService.Query query = getMessageArchiveService().query(conversation,0,timestamp - 1); if (query != null) { query.setCallback(callback); } callback.informUser(R.string.fetching_history_from_server); - } + } else { + Log.d("mam", ((!conversation.hasMessagesLeftOnServer()) ? "no" : "") + " more messages left on server, mam " + ((account.getXmppConnection().getFeatures().mam()) ? "" : "not") + " activated, account is " + ((account.isOnlineAndConnected()) ? "" : "not") + " online or connected)"); + callback.onMoreMessagesLoaded(0, conversation); + callback.informUser(R.string.no_more_history_on_server); + } } }; mDatabaseExecutor.execute(runnable); @@ -2496,7 +2504,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa public void clearConversationHistory(final Conversation conversation) { conversation.clearMessages(); - conversation.setHasMessagesLeftOnServer(false); //avoid messages getting loaded through mam + /* + * In case the history was loaded completely before. + * The flag "hasMessagesLeftOnServer" is set to false and no messages will be loaded anymore + * Therefore set this flag to true and try to get messages from server + */ + conversation.setHasMessagesLeftOnServer(true); new Thread(new Runnable() { @Override public void run() { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 5a672520..dc472360 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -10,7 +10,9 @@ import android.content.Intent; import android.content.IntentSender; import android.content.IntentSender.SendIntentException; import android.os.Bundle; +import android.support.v4.widget.SwipeRefreshLayout; import android.text.InputType; +import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Gravity; @@ -22,8 +24,6 @@ import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; -import android.widget.AbsListView; -import android.widget.AbsListView.OnScrollListener; import android.widget.AdapterView; import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.ImageButton; @@ -42,7 +42,6 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.ConcurrentLinkedQueue; -import de.tzur.conversations.Settings; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.crypto.PgpEngine; @@ -61,11 +60,11 @@ import eu.siacs.conversations.ui.XmppActivity.OnValueEdited; import eu.siacs.conversations.ui.adapter.MessageAdapter; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureClicked; import eu.siacs.conversations.ui.adapter.MessageAdapter.OnContactPictureLongClicked; +import eu.siacs.conversations.ui.listeners.ConversationSwipeRefreshListener; import eu.siacs.conversations.utils.GeoHelper; import eu.siacs.conversations.utils.UIHelper; import eu.siacs.conversations.xmpp.chatstate.ChatState; import eu.siacs.conversations.xmpp.jid.Jid; -import github.ankushsachdeva.emojicon.EmojiconEditText; import github.ankushsachdeva.emojicon.EmojiconGridView; import github.ankushsachdeva.emojicon.EmojiconsPopup; import github.ankushsachdeva.emojicon.emoji.Emojicon; @@ -107,7 +106,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa } }; protected ListView messagesView; - final protected List messageList = new ArrayList<>(); + protected SwipeRefreshLayout swipeLayout; + final protected List messageList = new ArrayList<>(); protected MessageAdapter messageListAdapter; private EditMessage mEditMessage; private ImageButton mSendButton; @@ -117,96 +117,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa private RelativeLayout snackbar; private TextView snackbarMessage; private TextView snackbarAction; - private boolean messagesLoaded = true; - private Toast messageLoaderToast; - - private OnScrollListener mOnScrollListener = new OnScrollListener() { - - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - // TODO Auto-generated method stub - - } - - private int getIndexOf(String uuid, List messages) { - if (uuid == null) { - return 0; - } - for(int i = 0; i < messages.size(); ++i) { - if (uuid.equals(messages.get(i).getUuid())) { - return i; - } else { - Message next = messages.get(i); - while(next != null && next.wasMergedIntoPrevious()) { - if (uuid.equals(next.getUuid())) { - return i; - } - next = next.next(); - } - - } - } - return 0; - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, - int visibleItemCount, int totalItemCount) { - synchronized (ConversationFragment.this.messageList) { - if (firstVisibleItem < 5 && messagesLoaded && messageList.size() > 0) { - long timestamp = ConversationFragment.this.messageList.get(0).getTimeSent(); - messagesLoaded = false; - activity.xmppConnectionService.loadMoreMessages(conversation, timestamp, new XmppConnectionService.OnMoreMessagesLoaded() { - @Override - public void onMoreMessagesLoaded(final int c, Conversation conversation) { - if (ConversationFragment.this.conversation != conversation) { - return; - } - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - final int oldPosition = messagesView.getFirstVisiblePosition(); - Message message = messageList.get(oldPosition); - String uuid = message != null ? message.getUuid() : null; - View v = messagesView.getChildAt(0); - final int pxOffset = (v == null) ? 0 : v.getTop(); - ConversationFragment.this.conversation.populateWithMessages(ConversationFragment.this.messageList); - updateStatusMessages(); - messageListAdapter.notifyDataSetChanged(); - int pos = getIndexOf(uuid,messageList); - messagesView.setSelectionFromTop(pos, pxOffset); - messagesLoaded = true; - if (messageLoaderToast != null) { - messageLoaderToast.cancel(); - } - } - }); - } - - @Override - public void informUser(final int resId) { - - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - if (messageLoaderToast != null) { - messageLoaderToast.cancel(); - } - if (ConversationFragment.this.conversation != conversation) { - return; - } - messageLoaderToast = Toast.makeText(activity, resId, Toast.LENGTH_LONG); - messageLoaderToast.show(); - } - }); - - } - }); - - } - } - } - }; private IntentSender askForPassphraseIntent = null; protected OnClickListener clickToDecryptListener = new OnClickListener() { @@ -322,8 +232,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (conversation.getMode() == Conversation.MODE_MULTI && conversation.getNextCounterpart() != null) { this.mEditMessage.setHint(getString( - R.string.send_private_message_to, - conversation.getNextCounterpart().getResourcepart())); + R.string.send_private_message_to, + conversation.getNextCounterpart().getResourcepart())); } else { switch (conversation.getNextEncryption(activity.forceEncryption())) { case Message.ENCRYPTION_NONE: @@ -382,66 +292,66 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa //Set on emojicon click listener mEmojPopup.setOnEmojiconClickedListener(new EmojiconGridView.OnEmojiconClickedListener() { - @Override - public void onEmojiconClicked(Emojicon emojicon) { - mEditMessage.append(emojicon.getEmoji()); - } - }); + @Override + public void onEmojiconClicked(Emojicon emojicon) { + mEditMessage.append(emojicon.getEmoji()); + } + }); //Set on backspace click listener mEmojPopup.setOnEmojiconBackspaceClickedListener(new EmojiconsPopup.OnEmojiconBackspaceClickedListener() { - @Override - public void onEmojiconBackspaceClicked(View v) { - KeyEvent event = new KeyEvent( - 0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL); - mEditMessage.dispatchKeyEvent(event); - } - }); + @Override + public void onEmojiconBackspaceClicked(View v) { + KeyEvent event = new KeyEvent( + 0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL); + mEditMessage.dispatchKeyEvent(event); + } + }); //If the emoji popup is dismissed, change emojiButton to smiley icon mEmojPopup.setOnDismissListener(new PopupWindow.OnDismissListener() { - @Override - public void onDismiss() { - changeEmojiKeyboardIcon(mEmojButton, R.drawable.smiley); - } - }); + @Override + public void onDismiss() { + changeEmojiKeyboardIcon(mEmojButton, R.drawable.smiley); + } + }); //If the text keyboard closes, also dismiss the emoji popup mEmojPopup.setOnSoftKeyboardOpenCloseListener(new EmojiconsPopup.OnSoftKeyboardOpenCloseListener() { - @Override - public void onKeyboardOpen(int keyBoardHeight) { + @Override + public void onKeyboardOpen(int keyBoardHeight) { - } + } - @Override - public void onKeyboardClose() { - if (mEmojPopup.isShowing()) - mEmojPopup.dismiss(); - } - }); + @Override + public void onKeyboardClose() { + if (mEmojPopup.isShowing()) + mEmojPopup.dismiss(); + } + }); //On emoji clicked, add it to edittext mEmojPopup.setOnEmojiconClickedListener(new EmojiconGridView.OnEmojiconClickedListener() { - @Override - public void onEmojiconClicked(Emojicon emojicon) { - mEditMessage.append(emojicon.getEmoji()); - } - }); + @Override + public void onEmojiconClicked(Emojicon emojicon) { + mEditMessage.append(emojicon.getEmoji()); + } + }); //On backspace clicked, emulate the KEYCODE_DEL key event mEmojPopup.setOnEmojiconBackspaceClickedListener(new EmojiconsPopup.OnEmojiconBackspaceClickedListener() { - @Override - public void onEmojiconBackspaceClicked(View v) { - KeyEvent event = new KeyEvent( - 0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL); - mEditMessage.dispatchKeyEvent(event); - } - }); + @Override + public void onEmojiconBackspaceClicked(View v) { + KeyEvent event = new KeyEvent( + 0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL); + mEditMessage.dispatchKeyEvent(event); + } + }); // To toggle between text keyboard and emoji keyboard keyboard(Popup) mEmojButton.setOnClickListener(new OnClickListener() { @@ -486,7 +396,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa snackbarAction = (TextView) view.findViewById(R.id.snackbar_action); messagesView = (ListView) view.findViewById(R.id.messages_view); - messagesView.setOnScrollListener(mOnScrollListener); messagesView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL); messageListAdapter = new MessageAdapter((ConversationActivity) getActivity(), this.messageList); messageListAdapter.setOnContactPictureClicked(new OnContactPictureClicked() { @@ -533,6 +442,12 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa registerForContextMenu(messagesView); + // Start of swipe refresh + // New Swipe refresh + swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh_container); + swipeLayout.setOnRefreshListener(new ConversationSwipeRefreshListener(messageList, swipeLayout, this, messagesView, messageListAdapter)); + // End of swipe refresh + return view; } @@ -763,11 +678,11 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa this.mEditMessage.setKeyboardListener(this); this.messagesView.setAdapter(messageListAdapter); updateMessages(); - this.messagesLoaded = true; int size = this.messageList.size(); if (size > 0) { messagesView.setSelection(size - 1); } + swipeLayout.setRefreshing(false); } private OnClickListener mUnblockClickListener = new OnClickListener() { @@ -1094,7 +1009,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa this.mSendButton.setImageResource(getSendButtonImageResource(action, status)); } - protected void updateStatusMessages() { + public void updateStatusMessages() { synchronized (this.messageList) { if (conversation.getMode() == Conversation.MODE_SINGLE) { ChatState state = conversation.getIncomingChatState(); diff --git a/src/main/java/eu/siacs/conversations/ui/listeners/ConversationMoreMessagesLoadedListener.java b/src/main/java/eu/siacs/conversations/ui/listeners/ConversationMoreMessagesLoadedListener.java new file mode 100644 index 00000000..2154f8d8 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/listeners/ConversationMoreMessagesLoadedListener.java @@ -0,0 +1,118 @@ +package eu.siacs.conversations.ui.listeners; + +import android.support.v4.widget.SwipeRefreshLayout; +import android.view.View; +import android.widget.ListView; +import android.widget.Toast; + +import java.util.List; + +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.ui.ConversationActivity; +import eu.siacs.conversations.ui.ConversationFragment; +import eu.siacs.conversations.ui.adapter.MessageAdapter; + +/** + * This listener updates the UI when messages are loaded from the server. + */ +public class ConversationMoreMessagesLoadedListener implements XmppConnectionService.OnMoreMessagesLoaded { + private SwipeRefreshLayout swipeLayout; + private List messageList; + private ConversationFragment fragment; + private ListView messagesView; + private MessageAdapter messageListAdapter; + private Toast messageLoaderToast; + + public ConversationMoreMessagesLoadedListener(SwipeRefreshLayout swipeLayout, List messageList, ConversationFragment fragment, ListView messagesView, MessageAdapter messageListAdapter) { + this.swipeLayout = swipeLayout; + this.messageList = messageList; + this.fragment = fragment; + this.messagesView = messagesView; + this.messageListAdapter = messageListAdapter; + } + + @Override + public void onMoreMessagesLoaded(final int c, final Conversation conversation) { + ConversationActivity activity = (ConversationActivity) fragment.getActivity(); + if (activity.getSelectedConversation() != conversation) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + swipeLayout.setRefreshing(false); + } + }); + return; + } + if (0 == c) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + swipeLayout.setRefreshing(false); + } + }); + } + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + final int oldPosition = messagesView.getFirstVisiblePosition(); + int pos = 0; + View v = messagesView.getChildAt(0); + final int pxOffset = (v == null) ? 0 : v.getTop(); + if (-1 < oldPosition && messageList.size() > oldPosition) { + Message message = messageList.get(oldPosition); + String uuid = message != null ? message.getUuid() : null; + pos = getIndexOf(uuid, messageList); + } + conversation.populateWithMessages(messageList); + fragment.updateStatusMessages(); + messageListAdapter.notifyDataSetChanged(); + messagesView.setSelectionFromTop(pos, pxOffset); + + if (messageLoaderToast != null) { + messageLoaderToast.cancel(); + } + swipeLayout.setRefreshing(false); + } + }); + } + + @Override + public void informUser(final int resId) { + final ConversationActivity activity = (ConversationActivity) fragment.getActivity(); + + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + if (messageLoaderToast != null) { + messageLoaderToast.cancel(); + } + messageLoaderToast = Toast.makeText(activity, resId, Toast.LENGTH_LONG); + messageLoaderToast.show(); + } + }); + + } + + private int getIndexOf(String uuid, List messages) { + if (uuid == null) { + return 0; + } + for(int i = 0; i < messages.size(); ++i) { + if (uuid.equals(messages.get(i).getUuid())) { + return i; + } else { + Message next = messages.get(i); + while(next != null && next.wasMergedIntoPrevious()) { + if (uuid.equals(next.getUuid())) { + return i; + } + next = next.next(); + } + + } + } + return 0; + } +} diff --git a/src/main/java/eu/siacs/conversations/ui/listeners/ConversationSwipeRefreshListener.java b/src/main/java/eu/siacs/conversations/ui/listeners/ConversationSwipeRefreshListener.java new file mode 100644 index 00000000..09a8d730 --- /dev/null +++ b/src/main/java/eu/siacs/conversations/ui/listeners/ConversationSwipeRefreshListener.java @@ -0,0 +1,48 @@ +package eu.siacs.conversations.ui.listeners; + +import android.support.v4.widget.SwipeRefreshLayout; +import android.util.Log; +import android.view.View; +import android.widget.ListView; +import android.widget.Toast; + +import java.util.List; + +import eu.siacs.conversations.Config; +import eu.siacs.conversations.entities.Conversation; +import eu.siacs.conversations.entities.Message; +import eu.siacs.conversations.services.XmppConnectionService; +import eu.siacs.conversations.ui.ConversationActivity; +import eu.siacs.conversations.ui.ConversationFragment; +import eu.siacs.conversations.ui.adapter.MessageAdapter; + +/** + * This listener starts loading messages from the server. + */ +public class ConversationSwipeRefreshListener implements SwipeRefreshLayout.OnRefreshListener { + private List messageList; + private ConversationFragment fragment; + private ConversationMoreMessagesLoadedListener listener; + + public ConversationSwipeRefreshListener(List messageList, SwipeRefreshLayout swipeLayout, ConversationFragment fragment, ListView messagesView, MessageAdapter messageListAdapter) { + this.messageList = messageList; + this.fragment = fragment; + this.listener = new ConversationMoreMessagesLoadedListener(swipeLayout, messageList, fragment, messagesView, messageListAdapter); + } + + @Override + public void onRefresh() { + Log.d(Config.LOGTAG, "Refresh swipe container"); + synchronized (this.messageList) { + long timestamp; + if (messageList.isEmpty()) { + timestamp = System.currentTimeMillis(); + } else { + timestamp = this.messageList.get(0).getTimeSent(); + } + ConversationActivity activity = (ConversationActivity) fragment.getActivity(); + activity.xmppConnectionService.loadMoreMessages(activity.getSelectedConversation(), timestamp, this.listener); + } + Log.d(Config.LOGTAG, "End Refresh swipe container"); + } +} diff --git a/src/main/res/layout/fragment_conversation.xml b/src/main/res/layout/fragment_conversation.xml index 3fd80aa2..321055e9 100644 --- a/src/main/res/layout/fragment_conversation.xml +++ b/src/main/res/layout/fragment_conversation.xml @@ -5,6 +5,13 @@ android:layout_height="match_parent" android:background="@color/grey200" > + + Date: Sat, 15 Aug 2015 23:45:43 +0200 Subject: Merged https://github.com/ankushsachdeva/emojicon/pull/16 --- .../ankushsachdeva/emojicon/EmojiconsPopup.java | 28 ++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconsPopup.java b/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconsPopup.java index 12bc16e0..b5d26047 100644 --- a/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconsPopup.java +++ b/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconsPopup.java @@ -29,16 +29,21 @@ import java.util.List; import android.app.Activity; import android.content.Context; +import android.content.res.Resources; import android.graphics.Rect; +import android.os.Build; import android.os.Handler; import android.os.SystemClock; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.Gravity; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; +import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.WindowManager.LayoutParams; @@ -155,13 +160,28 @@ public class EmojiconsPopup extends PopupWindow implements ViewPager.OnPageChang .getHeight(); int heightDifference = screenHeight - (r.bottom - r.top); - int resourceId = mContext.getResources() + Resources resources = mContext.getResources(); + int statusBarId = resources .getIdentifier("status_bar_height", "dimen", "android"); - if (resourceId > 0) { - heightDifference -= mContext.getResources() - .getDimensionPixelSize(resourceId); + if (statusBarId > 0) { + heightDifference -= resources + .getDimensionPixelSize(statusBarId); } + + //Resolved using http://stackoverflow.com/a/16608481/2853322 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + int navBarId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); + boolean hasMenuKey; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + hasMenuKey = ViewConfiguration.get(mContext).hasPermanentMenuKey(); + } else hasMenuKey = true; //Skip has menu key below ICS + boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK); + if (navBarId > 0 && !hasMenuKey && !hasBackKey) { + heightDifference -= resources.getDimensionPixelSize(navBarId); + } + } + if (heightDifference > 100) { keyBoardHeight = heightDifference; setSize(LayoutParams.MATCH_PARENT, keyBoardHeight); -- cgit v1.2.3 From fe3a3c24711538e1d866cf107481df6f69152494 Mon Sep 17 00:00:00 2001 From: lookshe Date: Sun, 16 Aug 2015 00:02:14 +0200 Subject: Fixes FS#37 - Remove special treatment of unicode hearts Fixes FS#34 - review all calls for String.trim() --- .../eu/siacs/conversations/crypto/PgpEngine.java | 4 +-- .../eu/siacs/conversations/entities/Contact.java | 2 +- .../eu/siacs/conversations/entities/Message.java | 32 +++++++++------------- .../conversations/generator/AbstractGenerator.java | 2 +- .../conversations/ui/ConversationFragment.java | 2 +- .../conversations/ui/adapter/MessageAdapter.java | 2 -- .../eu/siacs/conversations/utils/UIHelper.java | 6 ++-- 7 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java index 4a4d3f03..f393264c 100644 --- a/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java +++ b/src/main/java/eu/siacs/conversations/crypto/PgpEngine.java @@ -244,7 +244,7 @@ public class PgpEngine { pgpSig.append("-----BEGIN PGP SIGNATURE-----"); pgpSig.append('\n'); pgpSig.append('\n'); - pgpSig.append(signature.replace("\n", "").trim()); + pgpSig.append(signature.replace("\n", "")); pgpSig.append('\n'); pgpSig.append("-----END PGP SIGNATURE-----"); Intent params = new Intent(); @@ -297,7 +297,7 @@ public class PgpEngine { sig = false; } else { if (!line.contains("Version")) { - signatureBuilder.append(line.trim()); + signatureBuilder.append(line); } } } diff --git a/src/main/java/eu/siacs/conversations/entities/Contact.java b/src/main/java/eu/siacs/conversations/entities/Contact.java index a215874f..81f6568b 100644 --- a/src/main/java/eu/siacs/conversations/entities/Contact.java +++ b/src/main/java/eu/siacs/conversations/entities/Contact.java @@ -162,7 +162,7 @@ public class Contact implements ListItem, Blockable { if (needle == null || needle.isEmpty()) { return true; } - needle = needle.toLowerCase(Locale.US).trim(); + needle = needle.toLowerCase(Locale.US); String[] parts = needle.split("\\s+"); if (parts.length > 1) { for(int i = 0; i < parts.length; ++i) { diff --git a/src/main/java/eu/siacs/conversations/entities/Message.java b/src/main/java/eu/siacs/conversations/entities/Message.java index e3fb7944..d04dff87 100644 --- a/src/main/java/eu/siacs/conversations/entities/Message.java +++ b/src/main/java/eu/siacs/conversations/entities/Message.java @@ -59,7 +59,7 @@ public class Message extends AbstractEntity { protected String conversationUuid; protected Jid counterpart; protected Jid trueCounterpart; - protected String body; + private String body; protected String encryptedBody; protected long timeSent; protected int encryption; @@ -319,16 +319,16 @@ public class Message extends AbstractEntity { public boolean equals(Message message) { if (this.serverMsgId != null && message.getServerMsgId() != null) { return this.serverMsgId.equals(message.getServerMsgId()); - } else if (this.body == null || this.counterpart == null) { + } else if (this.getBody() == null || this.counterpart == null) { return false; } else { String body, otherBody; if (this.hasFileOnRemoteHost()) { body = getFileParams().url.toString(); - otherBody = message.body == null ? null : message.body.trim(); + otherBody = message.getBody() == null ? null : message.getBody(); } else { - body = this.body; - otherBody = message.body; + body = this.getBody(); + otherBody = message.getBody(); } if (message.getRemoteMsgId() != null) { return (message.getRemoteMsgId().equals(this.remoteMsgId) || message.getRemoteMsgId().equals(this.uuid)) @@ -385,13 +385,11 @@ public class Message extends AbstractEntity { this.getCounterpart().equals(message.getCounterpart()) && (message.getTimeSent() - this.getTimeSent()) <= (Config.MESSAGE_MERGE_WINDOW * 1000) && !GeoHelper.isGeoUri(message.getBody()) && - !GeoHelper.isGeoUri(this.body) && + !GeoHelper.isGeoUri(this.getBody()) && message.treatAsDownloadable() == Decision.NEVER && this.treatAsDownloadable() == Decision.NEVER && !message.getBody().startsWith(ME_COMMAND) && - !this.getBody().startsWith(ME_COMMAND) && - !this.bodyIsHeart() && - !message.bodyIsHeart() + !this.getBody().startsWith(ME_COMMAND) ); } @@ -509,7 +507,7 @@ public class Message extends AbstractEntity { } } else { try { - return MimeUtils.guessMimeTypeFromExtension(extractRelevantExtension(new URL(body.trim()))); + return MimeUtils.guessMimeTypeFromExtension(extractRelevantExtension(new URL(this.getBody()))); } catch (MalformedURLException e) { return null; } @@ -522,7 +520,7 @@ public class Message extends AbstractEntity { * "http://example.com/image.jpg" text that will not be shown /abc.png" * or more than one image link in one message. */ - if (body.trim().contains(" ")) { + if (getBody().contains(" ")) { return Decision.NEVER; } try { @@ -555,10 +553,6 @@ public class Message extends AbstractEntity { } } - public boolean bodyIsHeart() { - return body != null && UIHelper.HEARTS.contains(body.trim()); - } - public FileParams getFileParams() { FileParams params = getLegacyFileParams(); if (params != null) { @@ -568,10 +562,10 @@ public class Message extends AbstractEntity { if (this.transferable != null) { params.size = this.transferable.getFileSize(); } - if (body == null) { + if (this.getBody() == null) { return params; } - String parts[] = body.split("\\|"); + String parts[] = this.getBody().split("\\|"); switch (parts.length) { case 1: try { @@ -630,10 +624,10 @@ public class Message extends AbstractEntity { public FileParams getLegacyFileParams() { FileParams params = new FileParams(); - if (body == null) { + if (this.getBody() == null) { return params; } - String parts[] = body.split(","); + String parts[] = this.getBody().split(","); if (parts.length == 3) { try { params.size = Long.parseLong(parts[0]); diff --git a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java index 186b4b98..16984910 100644 --- a/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/AbstractGenerator.java @@ -71,7 +71,7 @@ public abstract class AbstractGenerator { s.append(feature + "<"); } byte[] sha1 = md.digest(s.toString().getBytes()); - return new String(Base64.encode(sha1, Base64.DEFAULT)).trim(); + return new String(Base64.encode(sha1, Base64.DEFAULT)); } public static String getTimestamp(long time) { diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index dc472360..67eafefb 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -586,7 +586,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa resId = R.string.file_url; url = message.getFileParams().url.toString(); } else { - url = message.getBody().trim(); + url = message.getBody(); resId = R.string.file_url; } if (activity.copyTextToClipboard(url, resId)) { diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index b7ac3092..9699f7d4 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -529,8 +529,6 @@ public class MessageAdapter extends ArrayAdapter { } else { if (GeoHelper.isGeoUri(message.getBody())) { displayLocationMessage(viewHolder,message); - } else if (message.bodyIsHeart()) { - displayHeartMessage(viewHolder, message.getBody().trim()); } else if (message.treatAsDownloadable() == Message.Decision.MUST) { displayDownloadableMessage(viewHolder, message, activity.getString(R.string.check_x_filesize, UIHelper.getFileDescriptionString(activity, message))); } else { diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index de669ea6..1e3d1caf 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -400,9 +400,9 @@ public class UIHelper { if (counterpart==null) { return ""; } else if (!counterpart.isBareJid()) { - return counterpart.getResourcepart().trim(); + return counterpart.getResourcepart(); } else { - return counterpart.toString().trim(); + return counterpart.toString(); } } @@ -412,7 +412,7 @@ public class UIHelper { || message.getType() != Message.TYPE_TEXT) { return false; } - String body = message.getBody() == null ? null : message.getBody().trim().toLowerCase(Locale.getDefault()); + String body = message.getBody() == null ? null : message.getBody().toLowerCase(Locale.getDefault()); body = body.replace("?","").replace("¿",""); return LOCATION_QUESTIONS.contains(body); } -- cgit v1.2.3 From b67060989302daf9850e84e2d4d4320e99bdfb83 Mon Sep 17 00:00:00 2001 From: lookshe Date: Sun, 16 Aug 2015 00:32:12 +0200 Subject: Fixes FS#15 - Adding smiley only possible at the end Removed unnecessary ClickedListeners --- .../conversations/ui/ConversationFragment.java | 34 +++++++++------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java index 67eafefb..eb2688fd 100644 --- a/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/ConversationFragment.java @@ -289,26 +289,6 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa //Will automatically set size according to the soft keyboard size mEmojPopup.setSizeForSoftKeyboard(); - //Set on emojicon click listener - mEmojPopup.setOnEmojiconClickedListener(new EmojiconGridView.OnEmojiconClickedListener() { - - @Override - public void onEmojiconClicked(Emojicon emojicon) { - mEditMessage.append(emojicon.getEmoji()); - } - }); - - //Set on backspace click listener - mEmojPopup.setOnEmojiconBackspaceClickedListener(new EmojiconsPopup.OnEmojiconBackspaceClickedListener() { - - @Override - public void onEmojiconBackspaceClicked(View v) { - KeyEvent event = new KeyEvent( - 0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL); - mEditMessage.dispatchKeyEvent(event); - } - }); - //If the emoji popup is dismissed, change emojiButton to smiley icon mEmojPopup.setOnDismissListener(new PopupWindow.OnDismissListener() { @@ -338,7 +318,19 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa @Override public void onEmojiconClicked(Emojicon emojicon) { - mEditMessage.append(emojicon.getEmoji()); + if (mEditMessage == null || emojicon == null) { + return; + } + + int start = mEditMessage.getSelectionStart(); + int end = mEditMessage.getSelectionEnd(); + if (start < 0) { + mEditMessage.append(emojicon.getEmoji()); + } else { + mEditMessage.getText().replace(Math.min(start, end), + Math.max(start, end), emojicon.getEmoji(), 0, + emojicon.getEmoji().length()); + } } }); -- cgit v1.2.3 From ea1debd8f72903bfbcc631713d803c27be433f20 Mon Sep 17 00:00:00 2001 From: lookshe Date: Sun, 16 Aug 2015 17:30:06 +0200 Subject: Fixes FS#12 - Move smiley replacement from UIHelper to Emojicon module --- .../ankushsachdeva/emojicon/EmojiconHandler.java | 101 ++++++++++++++++ .../ankushsachdeva/emojicon/EmojiconImageSpan.java | 14 +++ .../src/main/res/drawable/emo_im_angel.png | Bin 0 -> 3592 bytes .../emojicon/src/main/res/drawable/emo_im_cool.png | Bin 0 -> 3466 bytes .../src/main/res/drawable/emo_im_crying.png | Bin 0 -> 3558 bytes .../src/main/res/drawable/emo_im_embarrassed.png | Bin 0 -> 3619 bytes .../src/main/res/drawable/emo_im_foot_in_mouth.png | Bin 0 -> 3603 bytes .../src/main/res/drawable/emo_im_happy.png | Bin 0 -> 3591 bytes .../src/main/res/drawable/emo_im_heart.png | Bin 0 -> 684 bytes .../src/main/res/drawable/emo_im_kissing.png | Bin 0 -> 3492 bytes .../src/main/res/drawable/emo_im_laughing.png | Bin 0 -> 3624 bytes .../main/res/drawable/emo_im_lips_are_sealed.png | Bin 0 -> 3670 bytes .../src/main/res/drawable/emo_im_money_mouth.png | Bin 0 -> 3649 bytes libs/emojicon/src/main/res/drawable/emo_im_sad.png | Bin 0 -> 3572 bytes .../src/main/res/drawable/emo_im_surprised.png | Bin 0 -> 3490 bytes .../res/drawable/emo_im_tongue_sticking_out.png | Bin 0 -> 3653 bytes .../src/main/res/drawable/emo_im_undecided.png | Bin 0 -> 3552 bytes .../src/main/res/drawable/emo_im_winking.png | Bin 0 -> 3568 bytes libs/emojicon/src/main/res/drawable/emo_im_wtf.png | Bin 0 -> 3591 bytes .../src/main/res/drawable/emo_im_yelling.png | Bin 0 -> 3575 bytes .../siacs/conversations/ui/SettingsActivity.java | 8 +- .../ui/adapter/ConversationAdapter.java | 3 +- .../conversations/ui/adapter/MessageAdapter.java | 5 +- .../eu/siacs/conversations/utils/UIHelper.java | 129 --------------------- src/main/res/drawable/emo_im_angel.png | Bin 3592 -> 0 bytes src/main/res/drawable/emo_im_cool.png | Bin 3466 -> 0 bytes src/main/res/drawable/emo_im_crying.png | Bin 3558 -> 0 bytes src/main/res/drawable/emo_im_embarrassed.png | Bin 3619 -> 0 bytes src/main/res/drawable/emo_im_foot_in_mouth.png | Bin 3603 -> 0 bytes src/main/res/drawable/emo_im_happy.png | Bin 3591 -> 0 bytes src/main/res/drawable/emo_im_heart.png | Bin 684 -> 0 bytes src/main/res/drawable/emo_im_kissing.png | Bin 3492 -> 0 bytes src/main/res/drawable/emo_im_laughing.png | Bin 3624 -> 0 bytes src/main/res/drawable/emo_im_lips_are_sealed.png | Bin 3670 -> 0 bytes src/main/res/drawable/emo_im_money_mouth.png | Bin 3649 -> 0 bytes src/main/res/drawable/emo_im_sad.png | Bin 3572 -> 0 bytes src/main/res/drawable/emo_im_surprised.png | Bin 3490 -> 0 bytes .../res/drawable/emo_im_tongue_sticking_out.png | Bin 3653 -> 0 bytes src/main/res/drawable/emo_im_undecided.png | Bin 3552 -> 0 bytes src/main/res/drawable/emo_im_winking.png | Bin 3568 -> 0 bytes src/main/res/drawable/emo_im_wtf.png | Bin 3591 -> 0 bytes src/main/res/drawable/emo_im_yelling.png | Bin 3575 -> 0 bytes 42 files changed, 123 insertions(+), 137 deletions(-) create mode 100644 libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconImageSpan.java create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_angel.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_cool.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_crying.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_embarrassed.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_foot_in_mouth.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_happy.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_heart.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_kissing.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_laughing.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_lips_are_sealed.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_money_mouth.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_sad.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_surprised.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_tongue_sticking_out.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_undecided.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_winking.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_wtf.png create mode 100644 libs/emojicon/src/main/res/drawable/emo_im_yelling.png delete mode 100644 src/main/res/drawable/emo_im_angel.png delete mode 100644 src/main/res/drawable/emo_im_cool.png delete mode 100644 src/main/res/drawable/emo_im_crying.png delete mode 100644 src/main/res/drawable/emo_im_embarrassed.png delete mode 100644 src/main/res/drawable/emo_im_foot_in_mouth.png delete mode 100644 src/main/res/drawable/emo_im_happy.png delete mode 100644 src/main/res/drawable/emo_im_heart.png delete mode 100644 src/main/res/drawable/emo_im_kissing.png delete mode 100644 src/main/res/drawable/emo_im_laughing.png delete mode 100644 src/main/res/drawable/emo_im_lips_are_sealed.png delete mode 100644 src/main/res/drawable/emo_im_money_mouth.png delete mode 100644 src/main/res/drawable/emo_im_sad.png delete mode 100644 src/main/res/drawable/emo_im_surprised.png delete mode 100644 src/main/res/drawable/emo_im_tongue_sticking_out.png delete mode 100644 src/main/res/drawable/emo_im_undecided.png delete mode 100644 src/main/res/drawable/emo_im_winking.png delete mode 100644 src/main/res/drawable/emo_im_wtf.png delete mode 100644 src/main/res/drawable/emo_im_yelling.png diff --git a/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconHandler.java b/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconHandler.java index c84bebb8..0df62b57 100644 --- a/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconHandler.java +++ b/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconHandler.java @@ -19,8 +19,14 @@ import github.ankushsachdeva.emojicon.R; import android.content.Context; import android.text.Spannable; +import android.text.style.ImageSpan; import android.util.SparseIntArray; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * @author Hieu Rocker (rockerhieu@gmail.com) */ @@ -28,6 +34,16 @@ public final class EmojiconHandler { private EmojiconHandler() { } + public static boolean isParseEmoticons() { + return bParseEmoticons; + } + + public static void setParseEmoticons(boolean bParseEmoticons) { + EmojiconHandler.bParseEmoticons = bParseEmoticons; + } + + private static boolean bParseEmoticons = true; + private static final SparseIntArray sEmojisMap = new SparseIntArray(846); private static final SparseIntArray sSoftbanksMap = new SparseIntArray(471); @@ -1384,6 +1400,88 @@ public final class EmojiconHandler { addEmojis(context, text, emojiSize, 0, -1); } + public static final Map ANDROID_EMOTICONS = new HashMap(); + + private static final Spannable.Factory spannableFactory = Spannable.Factory + .getInstance(); + + static { + addPattern(ANDROID_EMOTICONS, ":)", R.drawable.emo_im_happy); + addPattern(ANDROID_EMOTICONS, ":-)", R.drawable.emo_im_happy); + addPattern(ANDROID_EMOTICONS, ":(", R.drawable.emo_im_sad); + addPattern(ANDROID_EMOTICONS, ":-(", R.drawable.emo_im_sad); + addPattern(ANDROID_EMOTICONS, ";)", R.drawable.emo_im_winking); + addPattern(ANDROID_EMOTICONS, ";-)", R.drawable.emo_im_winking); + addPattern(ANDROID_EMOTICONS, ":P", + R.drawable.emo_im_tongue_sticking_out); + addPattern(ANDROID_EMOTICONS, ":-P", + R.drawable.emo_im_tongue_sticking_out); + addPattern(ANDROID_EMOTICONS, "=-O", R.drawable.emo_im_surprised); + addPattern(ANDROID_EMOTICONS, ":*", R.drawable.emo_im_kissing); + addPattern(ANDROID_EMOTICONS, ":-*", R.drawable.emo_im_kissing); + addPattern(ANDROID_EMOTICONS, ":O", R.drawable.emo_im_wtf); + addPattern(ANDROID_EMOTICONS, ":-O", R.drawable.emo_im_wtf); + addPattern(ANDROID_EMOTICONS, "B)", R.drawable.emo_im_cool); + addPattern(ANDROID_EMOTICONS, "B-)", R.drawable.emo_im_cool); + addPattern(ANDROID_EMOTICONS, "8)", R.drawable.emo_im_cool); + addPattern(ANDROID_EMOTICONS, "8-)", R.drawable.emo_im_cool); + addPattern(ANDROID_EMOTICONS, ":$", R.drawable.emo_im_money_mouth); + addPattern(ANDROID_EMOTICONS, ":-$", R.drawable.emo_im_money_mouth); + addPattern(ANDROID_EMOTICONS, ":-!", R.drawable.emo_im_foot_in_mouth); + addPattern(ANDROID_EMOTICONS, ":-[", R.drawable.emo_im_embarrassed); + addPattern(ANDROID_EMOTICONS, "O:)", R.drawable.emo_im_angel); + addPattern(ANDROID_EMOTICONS, "O:-)", R.drawable.emo_im_angel); + addPattern(ANDROID_EMOTICONS, ":\\", R.drawable.emo_im_undecided); + addPattern(ANDROID_EMOTICONS, ":-\\", R.drawable.emo_im_undecided); + addPattern(ANDROID_EMOTICONS, ":'(", R.drawable.emo_im_crying); + addPattern(ANDROID_EMOTICONS, ":D", R.drawable.emo_im_laughing); + addPattern(ANDROID_EMOTICONS, ":-D", R.drawable.emo_im_laughing); + addPattern(ANDROID_EMOTICONS, "O_o", R.drawable.emo_im_wtf); + addPattern(ANDROID_EMOTICONS, "o_O", R.drawable.emo_im_wtf); + addPattern(ANDROID_EMOTICONS, ">:O", R.drawable.emo_im_yelling); + addPattern(ANDROID_EMOTICONS, ">:0", R.drawable.emo_im_yelling); + addPattern(ANDROID_EMOTICONS, ":S", R.drawable.emo_im_lips_are_sealed); + addPattern(ANDROID_EMOTICONS, ":-S", R.drawable.emo_im_lips_are_sealed); + addPattern(ANDROID_EMOTICONS, "<3", R.drawable.emo_im_heart); + } + + private static void addPattern(Map map, String smile, + int resource) { + map.put(Pattern.compile(Pattern.quote(smile)), resource); + } + + private static boolean getSmiledText(Context context, Spannable spannable) { + // remove spans throughout all text + ImageSpan[] oldSpans = spannable.getSpans(0, spannable.length(), EmojiconImageSpan.class); + for (int i = 0; i < oldSpans.length; i++) { + spannable.removeSpan(oldSpans[i]); + } + boolean hasChanges = false; + Map emoticons = ANDROID_EMOTICONS; + for (Map.Entry entry : emoticons.entrySet()) { + Matcher matcher = entry.getKey().matcher(spannable); + while (matcher.find()) { + boolean set = true; + for (EmojiconImageSpan span : spannable.getSpans(matcher.start(), + matcher.end(), EmojiconImageSpan.class)) + if (spannable.getSpanStart(span) >= matcher.start() + && spannable.getSpanEnd(span) <= matcher.end()) + spannable.removeSpan(span); + else { + set = false; + break; + } + if (set) { + spannable.setSpan(new EmojiconImageSpan(context, entry.getValue()), + matcher.start(), matcher.end(), + Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + hasChanges = true; + } + } + } + return hasChanges; + } + /** * Convert emoji characters of the given Spannable to the according emojicon. * @@ -1394,6 +1492,9 @@ public final class EmojiconHandler { * @param length */ public static void addEmojis(Context context, Spannable text, int emojiSize, int index, int length) { + if (isParseEmoticons()) { + getSmiledText(context, text); + } int textLength = text.length(); int textLengthToProcessMax = textLength - index; int textLengthToProcess = length < 0 || length >= textLengthToProcessMax ? textLength : (length+index); diff --git a/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconImageSpan.java b/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconImageSpan.java new file mode 100644 index 00000000..8ad8fbb5 --- /dev/null +++ b/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconImageSpan.java @@ -0,0 +1,14 @@ +package github.ankushsachdeva.emojicon; + +import android.content.Context; +import android.text.style.ImageSpan; + +/** + * Created by lookshe on 16.08.2015. + */ +public class EmojiconImageSpan extends ImageSpan { + + EmojiconImageSpan(Context context, int resourceId) { + super(context, resourceId); + } +} diff --git a/libs/emojicon/src/main/res/drawable/emo_im_angel.png b/libs/emojicon/src/main/res/drawable/emo_im_angel.png new file mode 100644 index 00000000..c34dfa69 Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_angel.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_cool.png b/libs/emojicon/src/main/res/drawable/emo_im_cool.png new file mode 100644 index 00000000..d8eeb34e Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_cool.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_crying.png b/libs/emojicon/src/main/res/drawable/emo_im_crying.png new file mode 100644 index 00000000..1cafdb32 Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_crying.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_embarrassed.png b/libs/emojicon/src/main/res/drawable/emo_im_embarrassed.png new file mode 100644 index 00000000..e4db9634 Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_embarrassed.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_foot_in_mouth.png b/libs/emojicon/src/main/res/drawable/emo_im_foot_in_mouth.png new file mode 100644 index 00000000..09d1fba6 Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_foot_in_mouth.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_happy.png b/libs/emojicon/src/main/res/drawable/emo_im_happy.png new file mode 100644 index 00000000..b86602ae Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_happy.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_heart.png b/libs/emojicon/src/main/res/drawable/emo_im_heart.png new file mode 100644 index 00000000..d88bcccd Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_heart.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_kissing.png b/libs/emojicon/src/main/res/drawable/emo_im_kissing.png new file mode 100644 index 00000000..56378f6a Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_kissing.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_laughing.png b/libs/emojicon/src/main/res/drawable/emo_im_laughing.png new file mode 100644 index 00000000..980bf281 Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_laughing.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_lips_are_sealed.png b/libs/emojicon/src/main/res/drawable/emo_im_lips_are_sealed.png new file mode 100644 index 00000000..f2de993b Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_lips_are_sealed.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_money_mouth.png b/libs/emojicon/src/main/res/drawable/emo_im_money_mouth.png new file mode 100644 index 00000000..08c53fd6 Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_money_mouth.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_sad.png b/libs/emojicon/src/main/res/drawable/emo_im_sad.png new file mode 100644 index 00000000..31c08d06 Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_sad.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_surprised.png b/libs/emojicon/src/main/res/drawable/emo_im_surprised.png new file mode 100644 index 00000000..abe8c7ad Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_surprised.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_tongue_sticking_out.png b/libs/emojicon/src/main/res/drawable/emo_im_tongue_sticking_out.png new file mode 100644 index 00000000..6f0f47b0 Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_tongue_sticking_out.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_undecided.png b/libs/emojicon/src/main/res/drawable/emo_im_undecided.png new file mode 100644 index 00000000..eb4f8c5b Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_undecided.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_winking.png b/libs/emojicon/src/main/res/drawable/emo_im_winking.png new file mode 100644 index 00000000..568562ad Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_winking.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_wtf.png b/libs/emojicon/src/main/res/drawable/emo_im_wtf.png new file mode 100644 index 00000000..41dd47fc Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_wtf.png differ diff --git a/libs/emojicon/src/main/res/drawable/emo_im_yelling.png b/libs/emojicon/src/main/res/drawable/emo_im_yelling.png new file mode 100644 index 00000000..c3c8612b Binary files /dev/null and b/libs/emojicon/src/main/res/drawable/emo_im_yelling.png differ diff --git a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java index f3d5d8bd..df2933c9 100644 --- a/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java +++ b/src/main/java/eu/siacs/conversations/ui/SettingsActivity.java @@ -12,6 +12,7 @@ import de.duenndns.ssl.MemorizingTrustManager; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.xmpp.XmppConnection; +import github.ankushsachdeva.emojicon.EmojiconHandler; import android.app.AlertDialog; import android.app.Fragment; @@ -165,8 +166,11 @@ public class SettingsActivity extends XmppActivity implements } break; case "dont_trust_system_cas": - xmppConnectionService.updateMemorizingTrustmanager(); - reconnectAccounts(); + xmppConnectionService.updateMemorizingTrustmanager(); + reconnectAccounts(); + break; + case "parse_emoticons": + EmojiconHandler.setParseEmoticons(Settings.PARSE_EMOTICONS); break; } } diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java index c42dd305..7443c0cb 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/ConversationAdapter.java @@ -119,8 +119,7 @@ public class ConversationAdapter extends ArrayAdapter { Pair preview = UIHelper.getMessagePreview(activity,message); mLastMessage.setVisibility(View.VISIBLE); imagePreview.setVisibility(View.GONE); - boolean parseEmoticons = Settings.PARSE_EMOTICONS; - CharSequence msgText = parseEmoticons ? UIHelper.transformAsciiEmoticons(getContext(), preview.first) : preview.first; + CharSequence msgText = preview.first; mLastMessage.setText(msgText); if (preview.second) { if (conversation.isRead()) { diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index 9699f7d4..b6979cc6 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -252,10 +252,7 @@ public class MessageAdapter extends ArrayAdapter { Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); viewHolder.messageBody.setText(span); } else { - boolean parseEmoticons = Settings.PARSE_EMOTICONS; - viewHolder.messageBody.setText(parseEmoticons ? UIHelper - .transformAsciiEmoticons(getContext(), message.getMergedBody()) - : formattedBody); + viewHolder.messageBody.setText(formattedBody); } } else { String privateMarker; diff --git a/src/main/java/eu/siacs/conversations/utils/UIHelper.java b/src/main/java/eu/siacs/conversations/utils/UIHelper.java index 1e3d1caf..76f48037 100644 --- a/src/main/java/eu/siacs/conversations/utils/UIHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/UIHelper.java @@ -142,135 +142,6 @@ public class UIHelper { } } - public static final Map ANDROID_EMOTICONS = new HashMap(); - - private static final Factory spannableFactory = Spannable.Factory - .getInstance(); - - static { - addPattern(ANDROID_EMOTICONS, ":)", R.drawable.emo_im_happy); - addPattern(ANDROID_EMOTICONS, ":-)", R.drawable.emo_im_happy); - addPattern(ANDROID_EMOTICONS, ":(", R.drawable.emo_im_sad); - addPattern(ANDROID_EMOTICONS, ":-(", R.drawable.emo_im_sad); - addPattern(ANDROID_EMOTICONS, ";)", R.drawable.emo_im_winking); - addPattern(ANDROID_EMOTICONS, ";-)", R.drawable.emo_im_winking); - addPattern(ANDROID_EMOTICONS, ":P", - R.drawable.emo_im_tongue_sticking_out); - addPattern(ANDROID_EMOTICONS, ":-P", - R.drawable.emo_im_tongue_sticking_out); - addPattern(ANDROID_EMOTICONS, "=-O", R.drawable.emo_im_surprised); - addPattern(ANDROID_EMOTICONS, ":*", R.drawable.emo_im_kissing); - addPattern(ANDROID_EMOTICONS, ":-*", R.drawable.emo_im_kissing); - addPattern(ANDROID_EMOTICONS, ":O", R.drawable.emo_im_wtf); - addPattern(ANDROID_EMOTICONS, ":-O", R.drawable.emo_im_wtf); - addPattern(ANDROID_EMOTICONS, "B)", R.drawable.emo_im_cool); - addPattern(ANDROID_EMOTICONS, "B-)", R.drawable.emo_im_cool); - addPattern(ANDROID_EMOTICONS, "8)", R.drawable.emo_im_cool); - addPattern(ANDROID_EMOTICONS, "8-)", R.drawable.emo_im_cool); - addPattern(ANDROID_EMOTICONS, ":$", R.drawable.emo_im_money_mouth); - addPattern(ANDROID_EMOTICONS, ":-$", R.drawable.emo_im_money_mouth); - addPattern(ANDROID_EMOTICONS, ":-!", R.drawable.emo_im_foot_in_mouth); - addPattern(ANDROID_EMOTICONS, ":-[", R.drawable.emo_im_embarrassed); - addPattern(ANDROID_EMOTICONS, "O:)", R.drawable.emo_im_angel); - addPattern(ANDROID_EMOTICONS, "O:-)", R.drawable.emo_im_angel); - addPattern(ANDROID_EMOTICONS, ":\\", R.drawable.emo_im_undecided); - addPattern(ANDROID_EMOTICONS, ":-\\", R.drawable.emo_im_undecided); - addPattern(ANDROID_EMOTICONS, ":'(", R.drawable.emo_im_crying); - addPattern(ANDROID_EMOTICONS, ":D", R.drawable.emo_im_laughing); - addPattern(ANDROID_EMOTICONS, ":-D", R.drawable.emo_im_laughing); - addPattern(ANDROID_EMOTICONS, "O_o", R.drawable.emo_im_wtf); - addPattern(ANDROID_EMOTICONS, "o_O", R.drawable.emo_im_wtf); - addPattern(ANDROID_EMOTICONS, ">:O", R.drawable.emo_im_yelling); - addPattern(ANDROID_EMOTICONS, ">:0", R.drawable.emo_im_yelling); - addPattern(ANDROID_EMOTICONS, ":S", R.drawable.emo_im_lips_are_sealed); - addPattern(ANDROID_EMOTICONS, ":-S", R.drawable.emo_im_lips_are_sealed); - addPattern(ANDROID_EMOTICONS, "<3", R.drawable.emo_im_heart); - } - - private static void addPattern(Map map, String smile, - int resource) { - map.put(Pattern.compile(Pattern.quote(smile)), resource); - } - - private static boolean getSmiledText(Context context, Spannable spannable) { - boolean hasChanges = false; - Map emoticons = ANDROID_EMOTICONS; - for (Entry entry : emoticons.entrySet()) { - Matcher matcher = entry.getKey().matcher(spannable); - while (matcher.find()) { - boolean set = true; - for (ImageSpan span : spannable.getSpans(matcher.start(), - matcher.end(), ImageSpan.class)) - if (spannable.getSpanStart(span) >= matcher.start() - && spannable.getSpanEnd(span) <= matcher.end()) - spannable.removeSpan(span); - else { - set = false; - break; - } - if (set) { - spannable.setSpan(new ImageSpan(context, entry.getValue()), - matcher.start(), matcher.end(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - hasChanges = true; - } - } - } - return hasChanges; - } - - private final static class EmoticonPattern { - Pattern pattern; - String replacement; - - EmoticonPattern(String ascii, int unicode) { - this.pattern = Pattern.compile("(?<=(^|\\s))" + ascii - + "(?=(\\s|$))"); - this.replacement = new String(new int[] { unicode, }, 0, 1); - } - - String replaceAll(String body) { - return pattern.matcher(body).replaceAll(replacement); - } - } - - private static final EmoticonPattern[] patterns = new EmoticonPattern[] { - new EmoticonPattern(":-?D", 0x1f600), - new EmoticonPattern("\\^\\^", 0x1f601), - new EmoticonPattern(":'D", 0x1f602), - new EmoticonPattern("\\]-?D", 0x1f608), - new EmoticonPattern(";-?\\)", 0x1f609), - new EmoticonPattern(":-?\\)", 0x1f60a), - new EmoticonPattern("[B8]-?\\)", 0x1f60e), - new EmoticonPattern(":-?\\|", 0x1f610), - new EmoticonPattern(":-?[/\\\\]", 0x1f615), - new EmoticonPattern(":-?\\*", 0x1f617), - new EmoticonPattern(":-?[Ppb]", 0x1f61b), - new EmoticonPattern(":-?\\(", 0x1f61e), - new EmoticonPattern(":-?[0Oo]", 0x1f62e), - new EmoticonPattern("\\\\o/", 0x1F631), }; - - public static String transformAsciiEmoticonsToUtf8(String body) { - if (body != null) { - for (EmoticonPattern p : patterns) { - body = p.replaceAll(body); - } - } - return body; - } - - public static Spannable transformAsciiEmoticons(Context context, String body) { - Spannable spannable; - if (Config.UTF8_EMOTICONS) { - spannable = spannableFactory.newSpannable(transformAsciiEmoticonsToUtf8(body)); - } - else { - spannable = spannableFactory.newSpannable(body); - getSmiledText(context, spannable); - } - return spannable; - } - public static int getColorForName(String name) { if (name.isEmpty()) { return 0xFF202020; diff --git a/src/main/res/drawable/emo_im_angel.png b/src/main/res/drawable/emo_im_angel.png deleted file mode 100644 index c34dfa69..00000000 Binary files a/src/main/res/drawable/emo_im_angel.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_cool.png b/src/main/res/drawable/emo_im_cool.png deleted file mode 100644 index d8eeb34e..00000000 Binary files a/src/main/res/drawable/emo_im_cool.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_crying.png b/src/main/res/drawable/emo_im_crying.png deleted file mode 100644 index 1cafdb32..00000000 Binary files a/src/main/res/drawable/emo_im_crying.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_embarrassed.png b/src/main/res/drawable/emo_im_embarrassed.png deleted file mode 100644 index e4db9634..00000000 Binary files a/src/main/res/drawable/emo_im_embarrassed.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_foot_in_mouth.png b/src/main/res/drawable/emo_im_foot_in_mouth.png deleted file mode 100644 index 09d1fba6..00000000 Binary files a/src/main/res/drawable/emo_im_foot_in_mouth.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_happy.png b/src/main/res/drawable/emo_im_happy.png deleted file mode 100644 index b86602ae..00000000 Binary files a/src/main/res/drawable/emo_im_happy.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_heart.png b/src/main/res/drawable/emo_im_heart.png deleted file mode 100644 index d88bcccd..00000000 Binary files a/src/main/res/drawable/emo_im_heart.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_kissing.png b/src/main/res/drawable/emo_im_kissing.png deleted file mode 100644 index 56378f6a..00000000 Binary files a/src/main/res/drawable/emo_im_kissing.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_laughing.png b/src/main/res/drawable/emo_im_laughing.png deleted file mode 100644 index 980bf281..00000000 Binary files a/src/main/res/drawable/emo_im_laughing.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_lips_are_sealed.png b/src/main/res/drawable/emo_im_lips_are_sealed.png deleted file mode 100644 index f2de993b..00000000 Binary files a/src/main/res/drawable/emo_im_lips_are_sealed.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_money_mouth.png b/src/main/res/drawable/emo_im_money_mouth.png deleted file mode 100644 index 08c53fd6..00000000 Binary files a/src/main/res/drawable/emo_im_money_mouth.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_sad.png b/src/main/res/drawable/emo_im_sad.png deleted file mode 100644 index 31c08d06..00000000 Binary files a/src/main/res/drawable/emo_im_sad.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_surprised.png b/src/main/res/drawable/emo_im_surprised.png deleted file mode 100644 index abe8c7ad..00000000 Binary files a/src/main/res/drawable/emo_im_surprised.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_tongue_sticking_out.png b/src/main/res/drawable/emo_im_tongue_sticking_out.png deleted file mode 100644 index 6f0f47b0..00000000 Binary files a/src/main/res/drawable/emo_im_tongue_sticking_out.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_undecided.png b/src/main/res/drawable/emo_im_undecided.png deleted file mode 100644 index eb4f8c5b..00000000 Binary files a/src/main/res/drawable/emo_im_undecided.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_winking.png b/src/main/res/drawable/emo_im_winking.png deleted file mode 100644 index 568562ad..00000000 Binary files a/src/main/res/drawable/emo_im_winking.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_wtf.png b/src/main/res/drawable/emo_im_wtf.png deleted file mode 100644 index 41dd47fc..00000000 Binary files a/src/main/res/drawable/emo_im_wtf.png and /dev/null differ diff --git a/src/main/res/drawable/emo_im_yelling.png b/src/main/res/drawable/emo_im_yelling.png deleted file mode 100644 index c3c8612b..00000000 Binary files a/src/main/res/drawable/emo_im_yelling.png and /dev/null differ -- cgit v1.2.3 From 3be4dbf66ae360e16e07a8a5da01c35f67e6ddfe Mon Sep 17 00:00:00 2001 From: lookshe Date: Sun, 16 Aug 2015 17:56:46 +0200 Subject: fixes FS#13 - Change smiley replacement patterns to be case insensitive --- .../ankushsachdeva/emojicon/EmojiconHandler.java | 52 ++++++++-------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconHandler.java b/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconHandler.java index 0df62b57..3e032c42 100644 --- a/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconHandler.java +++ b/libs/emojicon/src/main/java/github/ankushsachdeva/emojicon/EmojiconHandler.java @@ -1406,48 +1406,32 @@ public final class EmojiconHandler { .getInstance(); static { - addPattern(ANDROID_EMOTICONS, ":)", R.drawable.emo_im_happy); - addPattern(ANDROID_EMOTICONS, ":-)", R.drawable.emo_im_happy); - addPattern(ANDROID_EMOTICONS, ":(", R.drawable.emo_im_sad); - addPattern(ANDROID_EMOTICONS, ":-(", R.drawable.emo_im_sad); - addPattern(ANDROID_EMOTICONS, ";)", R.drawable.emo_im_winking); - addPattern(ANDROID_EMOTICONS, ";-)", R.drawable.emo_im_winking); - addPattern(ANDROID_EMOTICONS, ":P", + addPattern(ANDROID_EMOTICONS, ":-?\\)", R.drawable.emo_im_happy); + addPattern(ANDROID_EMOTICONS, ":-?\\(", R.drawable.emo_im_sad); + addPattern(ANDROID_EMOTICONS, ";-?\\)", R.drawable.emo_im_winking); + addPattern(ANDROID_EMOTICONS, ":-?[pP]", R.drawable.emo_im_tongue_sticking_out); - addPattern(ANDROID_EMOTICONS, ":-P", - R.drawable.emo_im_tongue_sticking_out); - addPattern(ANDROID_EMOTICONS, "=-O", R.drawable.emo_im_surprised); - addPattern(ANDROID_EMOTICONS, ":*", R.drawable.emo_im_kissing); - addPattern(ANDROID_EMOTICONS, ":-*", R.drawable.emo_im_kissing); - addPattern(ANDROID_EMOTICONS, ":O", R.drawable.emo_im_wtf); - addPattern(ANDROID_EMOTICONS, ":-O", R.drawable.emo_im_wtf); - addPattern(ANDROID_EMOTICONS, "B)", R.drawable.emo_im_cool); - addPattern(ANDROID_EMOTICONS, "B-)", R.drawable.emo_im_cool); - addPattern(ANDROID_EMOTICONS, "8)", R.drawable.emo_im_cool); - addPattern(ANDROID_EMOTICONS, "8-)", R.drawable.emo_im_cool); - addPattern(ANDROID_EMOTICONS, ":$", R.drawable.emo_im_money_mouth); - addPattern(ANDROID_EMOTICONS, ":-$", R.drawable.emo_im_money_mouth); - addPattern(ANDROID_EMOTICONS, ":-!", R.drawable.emo_im_foot_in_mouth); - addPattern(ANDROID_EMOTICONS, ":-[", R.drawable.emo_im_embarrassed); - addPattern(ANDROID_EMOTICONS, "O:)", R.drawable.emo_im_angel); - addPattern(ANDROID_EMOTICONS, "O:-)", R.drawable.emo_im_angel); - addPattern(ANDROID_EMOTICONS, ":\\", R.drawable.emo_im_undecided); - addPattern(ANDROID_EMOTICONS, ":-\\", R.drawable.emo_im_undecided); - addPattern(ANDROID_EMOTICONS, ":'(", R.drawable.emo_im_crying); - addPattern(ANDROID_EMOTICONS, ":D", R.drawable.emo_im_laughing); - addPattern(ANDROID_EMOTICONS, ":-D", R.drawable.emo_im_laughing); + addPattern(ANDROID_EMOTICONS, "=-[oO0]", R.drawable.emo_im_surprised); + addPattern(ANDROID_EMOTICONS, ":-?\\*", R.drawable.emo_im_kissing); + addPattern(ANDROID_EMOTICONS, ":-?[oO0]", R.drawable.emo_im_wtf); + addPattern(ANDROID_EMOTICONS, "[8B]-?\\)", R.drawable.emo_im_cool); + addPattern(ANDROID_EMOTICONS, ":-?\\$", R.drawable.emo_im_money_mouth); + addPattern(ANDROID_EMOTICONS, ":-?!", R.drawable.emo_im_foot_in_mouth); + addPattern(ANDROID_EMOTICONS, ":-?\\[", R.drawable.emo_im_embarrassed); + addPattern(ANDROID_EMOTICONS, "[oO0]:-?\\)", R.drawable.emo_im_angel); + addPattern(ANDROID_EMOTICONS, ":-?[\\\\/]", R.drawable.emo_im_undecided); + addPattern(ANDROID_EMOTICONS, ":'-?\\(", R.drawable.emo_im_crying); + addPattern(ANDROID_EMOTICONS, ":-?D", R.drawable.emo_im_laughing); addPattern(ANDROID_EMOTICONS, "O_o", R.drawable.emo_im_wtf); addPattern(ANDROID_EMOTICONS, "o_O", R.drawable.emo_im_wtf); - addPattern(ANDROID_EMOTICONS, ">:O", R.drawable.emo_im_yelling); - addPattern(ANDROID_EMOTICONS, ">:0", R.drawable.emo_im_yelling); - addPattern(ANDROID_EMOTICONS, ":S", R.drawable.emo_im_lips_are_sealed); - addPattern(ANDROID_EMOTICONS, ":-S", R.drawable.emo_im_lips_are_sealed); + addPattern(ANDROID_EMOTICONS, ">:[oO0]", R.drawable.emo_im_yelling); + addPattern(ANDROID_EMOTICONS, ":-?[sS]", R.drawable.emo_im_lips_are_sealed); addPattern(ANDROID_EMOTICONS, "<3", R.drawable.emo_im_heart); } private static void addPattern(Map map, String smile, int resource) { - map.put(Pattern.compile(Pattern.quote(smile)), resource); + map.put(Pattern.compile(smile), resource); } private static boolean getSmiledText(Context context, Spannable spannable) { -- cgit v1.2.3 From 0321ebb7a6785b4673376f9e6458e41dd96b2230 Mon Sep 17 00:00:00 2001 From: lookshe Date: Sun, 16 Aug 2015 18:33:10 +0200 Subject: fixes FS#35 - Shortcut Badger compatible to setting always_notify_in_conference --- src/main/java/eu/siacs/conversations/entities/Account.java | 6 ++++++ .../java/eu/siacs/conversations/entities/Conversation.java | 10 ++++++++-- .../eu/siacs/conversations/services/NotificationService.java | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Account.java b/src/main/java/eu/siacs/conversations/entities/Account.java index f472361f..90c10199 100644 --- a/src/main/java/eu/siacs/conversations/entities/Account.java +++ b/src/main/java/eu/siacs/conversations/entities/Account.java @@ -128,6 +128,7 @@ public class Account extends AbstractEntity { private final Roster roster = new Roster(this); private List bookmarks = new CopyOnWriteArrayList<>(); private final Collection blocklist = new CopyOnWriteArraySet<>(); + private XmppConnectionService mXmppConnectionService; public Account() { this.uuid = "0"; @@ -278,6 +279,7 @@ public class Account extends AbstractEntity { } public void initAccountServices(final XmppConnectionService context) { + this.mXmppConnectionService = context; this.mOtrService = new OtrService(context, this); } @@ -418,4 +420,8 @@ public class Account extends AbstractEntity { public boolean isOnlineAndConnected() { return this.getStatus() == State.ONLINE && this.getXmppConnection() != null; } + + public XmppConnectionService getXmppConnectionService() { + return mXmppConnectionService; + } } diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 289ed4ea..6ff0e270 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -759,10 +759,16 @@ public class Conversation extends AbstractEntity implements Blockable { synchronized (this.messages) { int count = 0; for(int i = this.messages.size() - 1; i >= 0; --i) { - if (this.messages.get(i).isRead()) { + Message message = this.messages.get(i); + if (message.isRead()) { return count; } - ++count; + if (getMode() == Conversation.MODE_SINGLE + || account.getXmppConnectionService().getNotificationService().conferenceNotificationsEnabled() + || account.getXmppConnectionService().getNotificationService().wasHighlightedOrPrivate(message) + ) { + ++count; + } } return count; } diff --git a/src/main/java/eu/siacs/conversations/services/NotificationService.java b/src/main/java/eu/siacs/conversations/services/NotificationService.java index 09d223b3..683fcb04 100644 --- a/src/main/java/eu/siacs/conversations/services/NotificationService.java +++ b/src/main/java/eu/siacs/conversations/services/NotificationService.java @@ -442,7 +442,7 @@ public class NotificationService { return PendingIntent.getService(mXmppConnectionService,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); } - private boolean wasHighlightedOrPrivate(final Message message) { + public boolean wasHighlightedOrPrivate(final Message message) { final String nick = message.getConversation().getMucOptions().getActualNick(); final Pattern highlight = generateNickHighlightPattern(nick); if (message.getBody() == null || nick == null) { -- cgit v1.2.3