go through mam history page by page. load mam dynamically on scroll
This commit is contained in:
parent
03ca971e2e
commit
e2f50ab855
|
@ -18,13 +18,15 @@ public final class Config {
|
|||
|
||||
public static final int MESSAGE_MERGE_WINDOW = 20;
|
||||
|
||||
public static final int PAGE_SIZE = 50;
|
||||
|
||||
public static final int PROGRESS_UI_UPDATE_INTERVAL = 750;
|
||||
|
||||
public static final boolean NO_PROXY_LOOKUP = false; //useful to debug ibb
|
||||
|
||||
private static final long MILLISECONDS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
public static final long MAX_HISTORY_AGE = 7 * MILLISECONDS_IN_DAY;
|
||||
public static final long MAX_CATCHUP = MILLISECONDS_IN_DAY / 2;
|
||||
public static final long MAM_MAX_CATCHUP = MILLISECONDS_IN_DAY / 2;
|
||||
public static final int MAM_MAX_MESSAGES = 500;
|
||||
|
||||
private Config() {
|
||||
|
||||
|
|
|
@ -324,11 +324,8 @@ public class MessageParser extends AbstractParser implements
|
|||
finishedMessage.setCounterpart(counterpart);
|
||||
finishedMessage.setRemoteMsgId(message.getAttribute("id"));
|
||||
finishedMessage.setServerMsgId(result.getAttribute("id"));
|
||||
if (conversation.hasDuplicateMessage(finishedMessage)) {
|
||||
Log.d(Config.LOGTAG, "received mam message " + content+ " (duplicate)");
|
||||
return null;
|
||||
} else {
|
||||
Log.d(Config.LOGTAG, "received mam message " + content);
|
||||
if (query!=null) {
|
||||
query.incrementCount();
|
||||
}
|
||||
return finishedMessage;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import eu.siacs.conversations.Config;
|
|||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Conversation;
|
||||
import eu.siacs.conversations.generator.AbstractGenerator;
|
||||
import eu.siacs.conversations.parser.AbstractParser;
|
||||
import eu.siacs.conversations.xml.Element;
|
||||
import eu.siacs.conversations.xmpp.OnAdvancedStreamFeaturesLoaded;
|
||||
import eu.siacs.conversations.xmpp.OnIqPacketReceived;
|
||||
|
@ -40,8 +39,8 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
|||
long endCatchup = account.getXmppConnection().getLastSessionEstablished();
|
||||
if (startCatchup == 0) {
|
||||
return;
|
||||
} else if (endCatchup - startCatchup >= Config.MAX_CATCHUP) {
|
||||
startCatchup = endCatchup - Config.MAX_CATCHUP;
|
||||
} else if (endCatchup - startCatchup >= Config.MAM_MAX_CATCHUP) {
|
||||
startCatchup = endCatchup - Config.MAM_MAX_CATCHUP;
|
||||
List<Conversation> conversations = mXmppConnectionService.getConversations();
|
||||
for (Conversation conversation : conversations) {
|
||||
if (conversation.getMode() == Conversation.MODE_SINGLE && conversation.getAccount() == account && startCatchup > conversation.getLastMessageTransmitted()) {
|
||||
|
@ -67,22 +66,23 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
|||
return timestamp;
|
||||
}
|
||||
|
||||
public void query(final Conversation conversation) {
|
||||
query(conversation,conversation.getAccount().getXmppConnection().getLastSessionEstablished());
|
||||
public Query query(final Conversation conversation) {
|
||||
return query(conversation,conversation.getAccount().getXmppConnection().getLastSessionEstablished());
|
||||
}
|
||||
|
||||
public void query(final Conversation conversation, long end) {
|
||||
public Query query(final Conversation conversation, long end) {
|
||||
return this.query(conversation,conversation.getLastMessageTransmitted(),end);
|
||||
}
|
||||
|
||||
public Query query(Conversation conversation, long start, long end) {
|
||||
synchronized (this.queries) {
|
||||
final Account account = conversation.getAccount();
|
||||
long start = conversation.getLastMessageTransmitted();
|
||||
if (start > end) {
|
||||
return;
|
||||
} else if (end - start >= Config.MAX_HISTORY_AGE) {
|
||||
start = end - Config.MAX_HISTORY_AGE;
|
||||
return null;
|
||||
}
|
||||
final Query query = new Query(conversation, start, end,PagingOrder.REVERSE);
|
||||
this.queries.add(query);
|
||||
this.execute(query);
|
||||
return query;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,11 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
|||
if (conversation.setLastMessageTransmitted(query.getEnd())) {
|
||||
this.mXmppConnectionService.databaseBackend.updateConversation(conversation);
|
||||
}
|
||||
if (query.hasCallback()) {
|
||||
query.callback();
|
||||
} else {
|
||||
this.mXmppConnectionService.updateConversationUi();
|
||||
}
|
||||
} else {
|
||||
for(Conversation tmp : this.mXmppConnectionService.getConversations()) {
|
||||
if (tmp.getAccount() == query.getAccount()) {
|
||||
|
@ -170,8 +174,10 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
|||
Element last = set == null ? null : set.findChild("last");
|
||||
Element first = set == null ? null : set.findChild("first");
|
||||
Element relevant = query.getPagingOrder() == PagingOrder.NORMAL ? last : first;
|
||||
if (complete || relevant == null) {
|
||||
boolean abort = (query.getStart() == 0 && query.getTotalCount() >= Config.PAGE_SIZE) || query.getTotalCount() >= Config.MAM_MAX_MESSAGES;
|
||||
if (complete || relevant == null || abort) {
|
||||
this.finalizeQuery(query);
|
||||
Log.d(Config.LOGTAG,query.getAccount().getJid().toBareJid().toString()+": finished mam after "+query.getTotalCount()+" messages");
|
||||
} else {
|
||||
final Query nextQuery;
|
||||
if (query.getPagingOrder() == PagingOrder.NORMAL) {
|
||||
|
@ -210,6 +216,8 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
|||
}
|
||||
|
||||
public class Query {
|
||||
private int totalCount = 0;
|
||||
private int count = 0;
|
||||
private long start;
|
||||
private long end;
|
||||
private Jid with = null;
|
||||
|
@ -218,6 +226,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
|||
private Account account;
|
||||
private Conversation conversation;
|
||||
private PagingOrder pagingOrder = PagingOrder.NORMAL;
|
||||
private XmppConnectionService.OnMoreMessagesLoaded callback = null;
|
||||
|
||||
|
||||
public Query(Conversation conversation, long start, long end) {
|
||||
|
@ -243,6 +252,8 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
|||
query.reference = reference;
|
||||
query.conversation = conversation;
|
||||
query.with = with;
|
||||
query.totalCount = totalCount;
|
||||
query.callback = callback;
|
||||
return query;
|
||||
}
|
||||
|
||||
|
@ -278,6 +289,16 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
|||
return start;
|
||||
}
|
||||
|
||||
public void setCallback(XmppConnectionService.OnMoreMessagesLoaded callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void callback() {
|
||||
if (this.callback != null) {
|
||||
this.callback.onMoreMessagesLoaded(count,conversation);
|
||||
}
|
||||
}
|
||||
|
||||
public long getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
@ -290,6 +311,15 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
|||
return this.account;
|
||||
}
|
||||
|
||||
public void incrementCount() {
|
||||
this.count++;
|
||||
this.totalCount++;
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
return this.totalCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -313,5 +343,9 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
|
|||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public boolean hasCallback() {
|
||||
return this.callback != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -246,8 +246,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
account.pendingConferenceLeaves.clear();
|
||||
fetchRosterFromServer(account);
|
||||
fetchBookmarks(account);
|
||||
sendPresencePacket(account,
|
||||
mPresenceGenerator.sendPresence(account));
|
||||
sendPresencePacket(account,mPresenceGenerator.sendPresence(account));
|
||||
connectMultiModeConversations(account);
|
||||
updateConversationUi();
|
||||
}
|
||||
|
@ -893,11 +892,11 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
accountLookupTable.put(account.getUuid(), account);
|
||||
}
|
||||
this.conversations.addAll(databaseBackend.getConversations(Conversation.STATUS_AVAILABLE));
|
||||
for (Conversation conv : this.conversations) {
|
||||
Account account = accountLookupTable.get(conv.getAccountUuid());
|
||||
conv.setAccount(account);
|
||||
conv.addAll(0, databaseBackend.getMessages(conv, 50));
|
||||
checkDeletedFiles(conv);
|
||||
for (Conversation conversation : this.conversations) {
|
||||
Account account = accountLookupTable.get(conversation.getAccountUuid());
|
||||
conversation.setAccount(account);
|
||||
conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
|
||||
checkDeletedFiles(conversation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -962,17 +961,29 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
});
|
||||
}
|
||||
|
||||
public int loadMoreMessages(Conversation conversation, long timestamp) {
|
||||
public void loadMoreMessages(Conversation conversation, long timestamp, final OnMoreMessagesLoaded callback) {
|
||||
if (this.getMessageArchiveService().queryInProgress(conversation)) {
|
||||
return 0;
|
||||
Log.d(Config.LOGTAG,"query in progress");
|
||||
return;
|
||||
}
|
||||
List<Message> messages = databaseBackend.getMessages(conversation, 50,timestamp);
|
||||
if (messages.size() == 0 && (conversation.getAccount().getXmppConnection() != null && conversation.getAccount().getXmppConnection().getFeatures().mam())) {
|
||||
Log.d(Config.LOGTAG,"load more messages with mam");
|
||||
MessageArchiveService.Query query = getMessageArchiveService().query(conversation,0,timestamp - 1);
|
||||
if (query != null) {
|
||||
query.setCallback(callback);
|
||||
}
|
||||
return;
|
||||
}
|
||||
List<Message> messages = databaseBackend.getMessages(conversation, 50,
|
||||
timestamp);
|
||||
for (Message message : messages) {
|
||||
message.setConversation(conversation);
|
||||
}
|
||||
conversation.addAll(0, messages);
|
||||
return messages.size();
|
||||
callback.onMoreMessagesLoaded(messages.size(),conversation);
|
||||
}
|
||||
|
||||
public interface OnMoreMessagesLoaded {
|
||||
public void onMoreMessagesLoaded(int count,Conversation conversation);
|
||||
}
|
||||
|
||||
public List<Account> getAccounts() {
|
||||
|
@ -1022,7 +1033,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
} else {
|
||||
conversation.setMode(Conversation.MODE_SINGLE);
|
||||
}
|
||||
conversation.addAll(0, databaseBackend.getMessages(conversation, 50));
|
||||
conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
|
||||
this.databaseBackend.updateConversation(conversation);
|
||||
} else {
|
||||
String conversationName;
|
||||
|
@ -1244,11 +1255,12 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
|
|||
Log.d(Config.LOGTAG, "app switched into background");
|
||||
}
|
||||
|
||||
public void connectMultiModeConversations(Account account) {
|
||||
private void connectMultiModeConversations(Account account) {
|
||||
List<Conversation> conversations = getConversations();
|
||||
for (Conversation conversation : conversations) {
|
||||
if ((conversation.getMode() == Conversation.MODE_MULTI)
|
||||
&& (conversation.getAccount() == account)) {
|
||||
conversation.resetMucOptions();
|
||||
joinMuc(conversation);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.content.Intent;
|
|||
import android.content.IntentSender;
|
||||
import android.content.IntentSender.SendIntentException;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.Gravity;
|
||||
|
@ -38,6 +39,7 @@ import java.util.List;
|
|||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.crypto.PgpEngine;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
|
@ -104,6 +106,7 @@ public class ConversationFragment extends Fragment {
|
|||
private TextView snackbarMessage;
|
||||
private TextView snackbarAction;
|
||||
private boolean messagesLoaded = false;
|
||||
|
||||
private OnScrollListener mOnScrollListener = new OnScrollListener() {
|
||||
|
||||
@Override
|
||||
|
@ -119,14 +122,30 @@ public class ConversationFragment extends Fragment {
|
|||
if (firstVisibleItem == 0 && messagesLoaded) {
|
||||
long timestamp = ConversationFragment.this.messageList.get(0).getTimeSent();
|
||||
messagesLoaded = false;
|
||||
int size = activity.xmppConnectionService.loadMoreMessages(conversation, timestamp);
|
||||
conversation.populateWithMessages(ConversationFragment.this.messageList);
|
||||
Log.d(Config.LOGTAG,"load more messages");
|
||||
activity.xmppConnectionService.loadMoreMessages(conversation, timestamp, new XmppConnectionService.OnMoreMessagesLoaded() {
|
||||
@Override
|
||||
public void onMoreMessagesLoaded(final int count, Conversation conversation) {
|
||||
if (ConversationFragment.this.conversation != conversation) {
|
||||
return;
|
||||
}
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int firstItem = messagesView.getFirstVisiblePosition();
|
||||
Log.d(Config.LOGTAG, "done loading more messages. first item: " + firstItem);
|
||||
ConversationFragment.this.conversation.populateWithMessages(ConversationFragment.this.messageList);
|
||||
updateStatusMessages();
|
||||
messageListAdapter.notifyDataSetChanged();
|
||||
if (size != 0) {
|
||||
if (count != 0) {
|
||||
messagesLoaded = true;
|
||||
}
|
||||
messagesView.setSelectionFromTop(size + 1, 0);
|
||||
messagesView.setSelectionFromTop(firstItem + count, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -580,6 +599,7 @@ public class ConversationFragment extends Fragment {
|
|||
}
|
||||
}
|
||||
conversation.populateWithMessages(ConversationFragment.this.messageList);
|
||||
this.messagesLoaded = this.messageList.size() > 0;
|
||||
for (Message message : this.messageList) {
|
||||
if (message.getEncryption() == Message.ENCRYPTION_PGP
|
||||
&& (message.getStatus() == Message.STATUS_RECEIVED || message
|
||||
|
|
Loading…
Reference in a new issue