aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/crypto/PgpEngine.java4
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/entities/Account.java6
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/entities/Contact.java2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java10
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/entities/Message.java62
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/generator/AbstractGenerator.java2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java2
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java75
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java117
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java198
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java8
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java3
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java7
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java135
14 files changed, 222 insertions, 409 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/crypto/PgpEngine.java b/src/main/java/de/thedevstack/conversationsplus/crypto/PgpEngine.java
index 4b8e339c..49c8db54 100644
--- a/src/main/java/de/thedevstack/conversationsplus/crypto/PgpEngine.java
+++ b/src/main/java/de/thedevstack/conversationsplus/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/de/thedevstack/conversationsplus/entities/Account.java b/src/main/java/de/thedevstack/conversationsplus/entities/Account.java
index b620887e..8d879fa0 100644
--- a/src/main/java/de/thedevstack/conversationsplus/entities/Account.java
+++ b/src/main/java/de/thedevstack/conversationsplus/entities/Account.java
@@ -128,6 +128,7 @@ public class Account extends AbstractEntity {
private final Roster roster = new Roster(this);
private List<Bookmark> bookmarks = new CopyOnWriteArrayList<>();
private final Collection<Jid> 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/de/thedevstack/conversationsplus/entities/Contact.java b/src/main/java/de/thedevstack/conversationsplus/entities/Contact.java
index d72a1197..ca734403 100644
--- a/src/main/java/de/thedevstack/conversationsplus/entities/Contact.java
+++ b/src/main/java/de/thedevstack/conversationsplus/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/de/thedevstack/conversationsplus/entities/Conversation.java b/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java
index 81c2eb4b..8d4b3c27 100644
--- a/src/main/java/de/thedevstack/conversationsplus/entities/Conversation.java
+++ b/src/main/java/de/thedevstack/conversationsplus/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/de/thedevstack/conversationsplus/entities/Message.java b/src/main/java/de/thedevstack/conversationsplus/entities/Message.java
index 68b47578..a5d06f46 100644
--- a/src/main/java/de/thedevstack/conversationsplus/entities/Message.java
+++ b/src/main/java/de/thedevstack/conversationsplus/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)
);
}
@@ -473,17 +471,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;
}
@@ -498,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;
}
@@ -506,7 +515,12 @@ public class Message extends AbstractEntity {
}
public Decision treatAsDownloadable() {
- if (body.trim().contains(" ")) {
+ /**
+ * 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 (getBody().contains(" ")) {
return Decision.NEVER;
}
try {
@@ -539,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) {
@@ -552,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 {
@@ -614,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/de/thedevstack/conversationsplus/generator/AbstractGenerator.java b/src/main/java/de/thedevstack/conversationsplus/generator/AbstractGenerator.java
index cb56228d..859a8a6c 100644
--- a/src/main/java/de/thedevstack/conversationsplus/generator/AbstractGenerator.java
+++ b/src/main/java/de/thedevstack/conversationsplus/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/de/thedevstack/conversationsplus/services/NotificationService.java b/src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java
index 52d7e2a2..563a7d67 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/NotificationService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/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) {
diff --git a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
index e5125f29..8ff5f0d2 100644
--- a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java
+++ b/src/main/java/de/thedevstack/conversationsplus/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<Conversation>() {
- @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<Message> 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/de/thedevstack/conversationsplus/ui/ConversationActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java
index f5de4ae8..cff681a9 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationActivity.java
+++ b/src/main/java/de/thedevstack/conversationsplus/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);
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java
index a30b3483..26e2b3c1 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java
+++ b/src/main/java/de/thedevstack/conversationsplus/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;
@@ -107,7 +107,8 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
}
};
protected ListView messagesView;
- final protected List<Message> messageList = new ArrayList<>();
+ protected SwipeRefreshLayout swipeLayout;
+ final protected List<Message> messageList = new ArrayList<>();
protected MessageAdapter messageListAdapter;
private EditMessage mEditMessage;
private ImageButton mSendButton;
@@ -117,96 +118,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<Message> 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 +233,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:
@@ -379,69 +290,61 @@ 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() {
- @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) {
+ 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());
+ }
+ }
+ });
//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 +389,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 +435,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;
}
@@ -671,7 +579,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)) {
@@ -763,11 +671,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 +1002,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/de/thedevstack/conversationsplus/ui/SettingsActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java
index 36e2cca0..46a68f65 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/SettingsActivity.java
@@ -12,6 +12,7 @@ import de.duenndns.ssl.MemorizingTrustManager;
import de.thedevstack.conversationsplus.R;
import de.thedevstack.conversationsplus.entities.Account;
import de.thedevstack.conversationsplus.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/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java
index c9698114..2da7bea3 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java
@@ -107,8 +107,7 @@ public class ConversationAdapter extends ArrayAdapter<Conversation> {
Pair<String,Boolean> 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/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java
index 67391136..48debdaf 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java
@@ -251,10 +251,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
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;
@@ -528,8 +525,6 @@ public class MessageAdapter extends ArrayAdapter<Message> {
} 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/de/thedevstack/conversationsplus/utils/UIHelper.java b/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java
index a66b1bf8..0ef07808 100644
--- a/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java
+++ b/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java
@@ -141,135 +141,6 @@ public class UIHelper {
}
}
- public static final Map<Pattern, Integer> ANDROID_EMOTICONS = new HashMap<Pattern, Integer>();
-
- 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<Pattern, Integer> 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<Pattern, Integer> emoticons = ANDROID_EMOTICONS;
- for (Entry<Pattern, Integer> 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;
@@ -399,9 +270,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();
}
}
@@ -411,7 +282,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);
}