aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/ui/listeners
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/ui/listeners')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationMoreMessagesLoadedListener.java143
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationSwipeRefreshListener.java103
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/listeners/DeleteFileCallback.java9
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java22
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShareWithResizePictureUserDecisionListener.java6
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShowResourcesListDialogListener.java4
6 files changed, 266 insertions, 21 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationMoreMessagesLoadedListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationMoreMessagesLoadedListener.java
new file mode 100644
index 00000000..8e2909ad
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationMoreMessagesLoadedListener.java
@@ -0,0 +1,143 @@
+package de.thedevstack.conversationsplus.ui.listeners;
+
+import android.view.View;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import com.orangegangsters.github.swipyrefreshlayout.library.SwipyRefreshLayout;
+
+import java.util.List;
+
+import de.thedevstack.conversationsplus.entities.Conversation;
+import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.services.XmppConnectionService;
+import de.thedevstack.conversationsplus.ui.ConversationActivity;
+import de.thedevstack.conversationsplus.ui.ConversationFragment;
+import de.thedevstack.conversationsplus.ui.adapter.MessageAdapter;
+
+/**
+ * This listener updates the UI when messages are loaded from the server.
+ */
+public class ConversationMoreMessagesLoadedListener implements XmppConnectionService.OnMoreMessagesLoaded {
+ private SwipyRefreshLayout swipeLayout;
+ private List<Message> messageList;
+ private ConversationFragment fragment;
+ private ListView messagesView;
+ private MessageAdapter messageListAdapter;
+ private Toast messageLoaderToast;
+ /*
+ The current loading status
+ */
+ private boolean loadingMessages = false;
+ /**
+ * Whether the user is loading only history messages or not.
+ * History messages are messages which are older than the oldest in the database.
+ */
+ private boolean loadHistory = true;
+
+ public ConversationMoreMessagesLoadedListener(SwipyRefreshLayout swipeLayout, List<Message> messageList, ConversationFragment fragment, ListView messagesView, MessageAdapter messageListAdapter) {
+ this.swipeLayout = swipeLayout;
+ this.messageList = messageList;
+ this.fragment = fragment;
+ this.messagesView = messagesView;
+ this.messageListAdapter = messageListAdapter;
+ }
+
+ public void setLoadHistory(boolean value) {
+ this.loadHistory = value;
+ }
+
+ public void setLoadingInProgress() {
+ this.loadingMessages = true;
+ }
+
+ public boolean isLoadingInProgress() {
+ return this.loadingMessages;
+ }
+
+ @Override
+ public void onMoreMessagesLoaded(final int c, final Conversation conversation) {
+ ConversationActivity activity = (ConversationActivity) fragment.getActivity();
+ // Current selected conversation is not the same the messages are loaded - skip updating message view and hide loading graphic
+ if (activity.getSelectedConversation() != conversation) {
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ swipeLayout.setRefreshing(false);
+ }
+ });
+ return;
+ }
+ // No new messages are loaded
+ if (0 == c) {
+ if (this.loadHistory) {
+ conversation.setHasMessagesLeftOnServer(false);
+ }
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ swipeLayout.setRefreshing(false);
+ }
+ });
+ }
+ activity.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ final int oldPosition = messagesView.getFirstVisiblePosition(); // Always 0 - because loading starts always when hitting the top
+ String uuid = null;
+ boolean oldMessageListWasEmpty = messageList.isEmpty();
+ if (-1 < oldPosition && messageList.size() > oldPosition) {
+ Message message = messageList.get(oldPosition);
+ uuid = message != null ? message.getUuid() : null;
+ }
+ View v = messagesView.getChildAt(0);
+ final int pxOffset = (v == null) ? 0 : v.getTop();
+
+ conversation.populateWithMessages(messageList); // This overrides the old message list
+ fragment.updateStatusMessages(); // This adds "messages" to the list for the status
+ messageListAdapter.notifyDataSetChanged();
+ loadingMessages = false; // Loading of messages is finished - next query can be loaded
+
+ int pos = getIndexOf(uuid, messageList);
+
+ if (!oldMessageListWasEmpty) {
+ 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<Message> messages) {
+ if (uuid == null) {
+ return 0;
+ }
+ for (int i = 0; i < messages.size(); ++i) {
+ if (uuid.equals(messages.get(i).getUuid())) {
+ return i;
+ }
+ }
+ return 0;
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationSwipeRefreshListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationSwipeRefreshListener.java
new file mode 100644
index 00000000..6dc9f4a4
--- /dev/null
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationSwipeRefreshListener.java
@@ -0,0 +1,103 @@
+package de.thedevstack.conversationsplus.ui.listeners;
+
+import android.widget.ListView;
+
+import com.orangegangsters.github.swipyrefreshlayout.library.SwipyRefreshLayout;
+import com.orangegangsters.github.swipyrefreshlayout.library.SwipyRefreshLayoutDirection;
+
+import java.util.List;
+
+import de.thedevstack.android.logcat.Logging;
+import de.thedevstack.conversationsplus.Config;
+import de.thedevstack.conversationsplus.R;
+import de.thedevstack.conversationsplus.entities.Account;
+import de.thedevstack.conversationsplus.entities.Conversation;
+import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.services.MessageArchiveService;
+import de.thedevstack.conversationsplus.ui.ConversationActivity;
+import de.thedevstack.conversationsplus.ui.ConversationFragment;
+import de.thedevstack.conversationsplus.ui.adapter.MessageAdapter;
+
+/**
+ * This listener starts loading messages from the server.
+ */
+public class ConversationSwipeRefreshListener implements SwipyRefreshLayout.OnRefreshListener {
+ private List<Message> messageList;
+ private ConversationFragment fragment;
+ private ConversationMoreMessagesLoadedListener listener;
+ private SwipyRefreshLayout swipeLayout;
+
+ public ConversationSwipeRefreshListener(List<Message> messageList, SwipyRefreshLayout swipeLayout, ConversationFragment fragment, ListView messagesView, MessageAdapter messageListAdapter) {
+ this.messageList = messageList;
+ this.fragment = fragment;
+ this.swipeLayout = swipeLayout;
+ this.listener = new ConversationMoreMessagesLoadedListener(swipeLayout, messageList, fragment, messagesView, messageListAdapter);
+ }
+
+ @Override
+ public void onRefresh(SwipyRefreshLayoutDirection direction) {
+ Logging.d(Config.LOGTAG, "Refresh swipe container");
+ Logging.d(Config.LOGTAG, "Refresh direction " + direction);
+ final ConversationActivity activity = (ConversationActivity) fragment.getActivity();
+ if (activity.getSelectedConversation().getAccount().getStatus() != Account.State.DISABLED) {
+ synchronized (this.messageList) {
+ long timestamp;
+ if (SwipyRefreshLayoutDirection.TOP == direction) { // Load history -> messages sent/received before first message in database
+ if (messageList.isEmpty()) {
+ timestamp = System.currentTimeMillis();
+ } else {
+ timestamp = this.messageList.get(0).getTimeSent(); // works only because of the ordering (last msg = first msg in list)
+ }
+ this.listener.setLoadHistory(true);
+ activity.xmppConnectionService.loadMoreMessages(activity.getSelectedConversation(), timestamp, this.listener);
+ } else if (SwipyRefreshLayoutDirection.BOTTOM == direction) { // load messages sent/received between last received or last session establishment and now
+ if (activity.getSelectedConversation().getAccount().isOnlineAndConnected()) {
+ Logging.d("mam", "loading missing messages from mam (last session establishing or last received message)");
+ long lastSessionEstablished = this.getTimestampOfLastSessionEstablished(activity.getSelectedConversation());
+ long lastReceivedMessage = this.getTimestampOfLastReceivedOrTransmittedMessage();
+ long startTimestamp = Math.min(lastSessionEstablished, lastReceivedMessage);
+ MessageArchiveService.Query query = activity.xmppConnectionService.getMessageArchiveService().query(activity.getSelectedConversation(), startTimestamp, System.currentTimeMillis(), this.listener);
+ if (query != null) {
+ this.listener.setLoadHistory(false);
+ } else {
+ Logging.d("mam", "no query built - no messages loaded");
+ this.listener.onMoreMessagesLoaded(0, activity.getSelectedConversation());
+ this.listener.informUser(R.string.no_more_history_on_server);
+ }
+ this.listener.informUser(R.string.fetching_history_from_server);
+ } else {
+ this.listener.informUser(R.string.not_connected_try_again);
+ swipeLayout.setRefreshing(false);
+ }
+ }
+ }
+ } else {
+ this.listener.informUser(R.string.this_account_is_disabled);
+ swipeLayout.setRefreshing(false);
+ }
+ Logging.d(Config.LOGTAG, "End Refresh swipe container");
+ }
+
+ private long getTimestampOfLastReceivedOrTransmittedMessage() {
+ long lastReceivedOrTransmittedMessage = Long.MAX_VALUE;
+ if (null != this.messageList
+ && !this.messageList.isEmpty()) {
+ int lastMessageIndex = this.messageList.size() - 1;
+ if (0 <= lastMessageIndex && this.messageList.size() > lastMessageIndex) {
+ lastReceivedOrTransmittedMessage = this.messageList.get(lastMessageIndex).getTimeSent();
+ }
+ }
+
+ return lastReceivedOrTransmittedMessage;
+ }
+
+ private long getTimestampOfLastSessionEstablished(Conversation conversation) {
+ long lastSessionEstablished = Long.MAX_VALUE;
+ if (null != conversation
+ && null != conversation.getAccount()
+ && null != conversation.getAccount().getXmppConnection()) {
+ lastSessionEstablished = conversation.getAccount().getXmppConnection().getLastSessionEstablished();
+ }
+ return lastSessionEstablished;
+ }
+}
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/DeleteFileCallback.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/DeleteFileCallback.java
index 222e473b..f855a90d 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/DeleteFileCallback.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/DeleteFileCallback.java
@@ -1,12 +1,11 @@
package de.thedevstack.conversationsplus.ui.listeners;
+import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.entities.Transferable;
+import de.thedevstack.conversationsplus.entities.TransferablePlaceholder;
+import de.thedevstack.conversationsplus.persistance.FileBackend;
import de.thedevstack.conversationsplus.utils.UiUpdateHelper;
-import eu.siacs.conversations.entities.Message;
-import eu.siacs.conversations.entities.Transferable;
-import eu.siacs.conversations.entities.TransferablePlaceholder;
-import eu.siacs.conversations.persistance.FileBackend;
-
/**
* Callback for the user decision if a file should be deleted or not.
*/
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java
index dec6b885..1574bb85 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java
@@ -13,25 +13,25 @@ import java.io.InputStream;
import de.thedevstack.android.logcat.Logging;
import de.thedevstack.conversationsplus.ConversationsPlusApplication;
import de.thedevstack.conversationsplus.ConversationsPlusPreferences;
+import de.thedevstack.conversationsplus.crypto.PgpEngine;
import de.thedevstack.conversationsplus.entities.FileParams;
import de.thedevstack.conversationsplus.enums.FileStatus;
import de.thedevstack.conversationsplus.enums.UserDecision;
import de.thedevstack.conversationsplus.exceptions.UiException;
+import de.thedevstack.conversationsplus.utils.FileUtils;
import de.thedevstack.conversationsplus.utils.ImageUtil;
import de.thedevstack.conversationsplus.utils.MessageUtil;
+import de.thedevstack.conversationsplus.R;
+import de.thedevstack.conversationsplus.entities.Conversation;
+import de.thedevstack.conversationsplus.entities.DownloadableFile;
+import de.thedevstack.conversationsplus.entities.Message;
+import de.thedevstack.conversationsplus.persistance.FileBackend;
+import de.thedevstack.conversationsplus.services.XmppConnectionService;
+import de.thedevstack.conversationsplus.ui.UiCallback;
+import de.thedevstack.conversationsplus.ui.XmppActivity;
+import de.thedevstack.conversationsplus.utils.MimeUtils;
import de.thedevstack.conversationsplus.utils.StreamUtil;
-import eu.siacs.conversations.R;
-import eu.siacs.conversations.crypto.PgpEngine;
-import eu.siacs.conversations.entities.Conversation;
-import eu.siacs.conversations.entities.DownloadableFile;
-import eu.siacs.conversations.entities.Message;
-import eu.siacs.conversations.persistance.FileBackend;
-import eu.siacs.conversations.services.XmppConnectionService;
-import eu.siacs.conversations.ui.UiCallback;
-import eu.siacs.conversations.ui.XmppActivity;
-import eu.siacs.conversations.utils.FileUtils;
-
/**
* Listener to let the user decide whether to resize a picture before sending or not.
*/
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShareWithResizePictureUserDecisionListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShareWithResizePictureUserDecisionListener.java
index 7455cf97..e2678ef7 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShareWithResizePictureUserDecisionListener.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShareWithResizePictureUserDecisionListener.java
@@ -4,9 +4,9 @@ import android.net.Uri;
import java.util.List;
-import eu.siacs.conversations.entities.Conversation;
-import eu.siacs.conversations.services.XmppConnectionService;
-import eu.siacs.conversations.ui.XmppActivity;
+import de.thedevstack.conversationsplus.entities.Conversation;
+import de.thedevstack.conversationsplus.services.XmppConnectionService;
+import de.thedevstack.conversationsplus.ui.XmppActivity;
/**
* Created by tzur on 03.11.2015.
diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShowResourcesListDialogListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShowResourcesListDialogListener.java
index 1c16095c..791b31a7 100644
--- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShowResourcesListDialogListener.java
+++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ShowResourcesListDialogListener.java
@@ -5,8 +5,8 @@ import android.view.View;
import de.thedevstack.conversationsplus.ui.adapter.PresencesArrayAdapter;
import de.thedevstack.conversationsplus.ui.dialogs.AbstractAlertDialog;
-import eu.siacs.conversations.R;
-import eu.siacs.conversations.entities.Contact;
+import de.thedevstack.conversationsplus.R;
+import de.thedevstack.conversationsplus.entities.Contact;
/**
* This listener shows the dialog with the resources of a contact.