prevent previoulsly cleared messages from reloading. fixes #1110

This commit is contained in:
Daniel Gultsch 2016-02-04 14:39:16 +01:00
parent f88b8c703e
commit 4fdb0d92fe
9 changed files with 92 additions and 17 deletions

View file

@ -286,6 +286,14 @@ public class Conversation extends AbstractEntity implements Blockable {
return this.mFirstMamReference; return this.mFirstMamReference;
} }
public void setLastClearHistory(long time) {
setAttribute("last_clear_history",String.valueOf(time));
}
public long getLastClearHistory() {
return getLongAttribute("last_clear_history", 0);
}
public interface OnMessageFound { public interface OnMessageFound {
void onMessageFound(final Message message); void onMessageFound(final Message message);
} }
@ -720,6 +728,10 @@ public class Conversation extends AbstractEntity implements Blockable {
} }
public long getLastMessageTransmitted() { public long getLastMessageTransmitted() {
long last_clear = getLastClearHistory();
if (last_clear != 0) {
return last_clear;
}
synchronized (this.messages) { synchronized (this.messages) {
for(int i = this.messages.size() - 1; i >= 0; --i) { for(int i = this.messages.size() - 1; i >= 0; --i) {
Message message = this.messages.get(i); Message message = this.messages.get(i);

View file

@ -178,6 +178,14 @@ public class Message extends AbstractEntity {
return message; return message;
} }
public static Message createLoadMoreMessage(Conversation conversation) {
final Message message = new Message();
message.setType(Message.TYPE_STATUS);
message.setConversation(conversation);
message.setBody("LOAD_MORE");
return message;
}
@Override @Override
public ContentValues getContentValues() { public ContentValues getContentValues() {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();

View file

@ -24,13 +24,13 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
private final XmppConnectionService mXmppConnectionService; private final XmppConnectionService mXmppConnectionService;
private final HashSet<Query> queries = new HashSet<Query>(); private final HashSet<Query> queries = new HashSet<>();
private final ArrayList<Query> pendingQueries = new ArrayList<Query>(); private final ArrayList<Query> pendingQueries = new ArrayList<>();
public enum PagingOrder { public enum PagingOrder {
NORMAL, NORMAL,
REVERSE REVERSE
}; }
public MessageArchiveService(final XmppConnectionService service) { public MessageArchiveService(final XmppConnectionService service) {
this.mXmppConnectionService = service; this.mXmppConnectionService = service;
@ -137,7 +137,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
synchronized (MessageArchiveService.this.queries) { synchronized (MessageArchiveService.this.queries) {
MessageArchiveService.this.queries.remove(query); MessageArchiveService.this.queries.remove(query);
if (query.hasCallback()) { if (query.hasCallback()) {
query.callback(); query.callback(false);
} }
} }
} else if (packet.getType() != IqPacket.TYPE.RESULT) { } else if (packet.getType() != IqPacket.TYPE.RESULT) {
@ -169,7 +169,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
} }
} }
if (query.hasCallback()) { if (query.hasCallback()) {
query.callback(); query.callback(done);
} else { } else {
this.mXmppConnectionService.updateConversationUi(); this.mXmppConnectionService.updateConversationUi();
} }
@ -329,10 +329,10 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
this.callback = callback; this.callback = callback;
} }
public void callback() { public void callback(boolean done) {
if (this.callback != null) { if (this.callback != null) {
this.callback.onMoreMessagesLoaded(messageCount,conversation); this.callback.onMoreMessagesLoaded(messageCount,conversation);
if (messageCount == 0) { if (done) {
this.callback.informUser(R.string.no_more_history_on_server); this.callback.informUser(R.string.no_more_history_on_server);
} }
} }
@ -375,7 +375,8 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
if (this.muc()) { if (this.muc()) {
builder.append("to="+this.getWith().toString()); builder.append("to=");
builder.append(this.getWith().toString());
} else { } else {
builder.append("with="); builder.append("with=");
if (this.getWith() == null) { if (this.getWith() == null) {

View file

@ -1215,6 +1215,9 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) { public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) {
if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation, callback)) { if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation, callback)) {
return; return;
} else if (timestamp == 0) {
callback.onMoreMessagesLoaded(0, conversation);
return;
} }
Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp)); Log.d(Config.LOGTAG, "load more messages for " + conversation.getName() + " prior to " + MessageGenerator.getTimestamp(timestamp));
Runnable runnable = new Runnable() { Runnable runnable = new Runnable() {
@ -2911,6 +2914,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
public void clearConversationHistory(final Conversation conversation) { public void clearConversationHistory(final Conversation conversation) {
conversation.clearMessages(); conversation.clearMessages();
conversation.setHasMessagesLeftOnServer(false); //avoid messages getting loaded through mam conversation.setHasMessagesLeftOnServer(false); //avoid messages getting loaded through mam
conversation.setLastClearHistory(System.currentTimeMillis());
Runnable runnable = new Runnable() { Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {

View file

@ -1602,4 +1602,10 @@ public class ConversationActivity extends XmppActivity
public boolean highlightSelectedConversations() { public boolean highlightSelectedConversations() {
return !isConversationsOverviewHideable() || this.conversationWasSelectedByKeyboard; return !isConversationsOverviewHideable() || this.conversationWasSelectedByKeyboard;
} }
public void setMessagesLoaded() {
if (mConversationFragment != null) {
mConversationFragment.setMessagesLoaded();
}
}
} }

View file

@ -40,12 +40,9 @@ import net.java.otr4j.session.SessionStatus;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentLinkedQueue;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.PgpEngine;
import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Contact;
@ -318,6 +315,10 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
private ConversationActivity activity; private ConversationActivity activity;
private Message selectedMessage; private Message selectedMessage;
public void setMessagesLoaded() {
this.messagesLoaded = true;
}
private void sendMessage() { private void sendMessage() {
final String body = mEditMessage.getText().toString(); final String body = mEditMessage.getText().toString();
if (body.length() == 0 || this.conversation == null) { if (body.length() == 0 || this.conversation == null) {
@ -1008,6 +1009,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
protected void updateStatusMessages() { protected void updateStatusMessages() {
synchronized (this.messageList) { synchronized (this.messageList) {
if (conversation.getLastClearHistory() != 0) {
this.messageList.add(0, Message.createLoadMoreMessage(conversation));
}
if (conversation.getMode() == Conversation.MODE_SINGLE) { if (conversation.getMode() == Conversation.MODE_SINGLE) {
ChatState state = conversation.getIncomingChatState(); ChatState state = conversation.getIncomingChatState();
if (state == ChatState.COMPOSING) { if (state == ChatState.COMPOSING) {

View file

@ -428,6 +428,19 @@ public class MessageAdapter extends ArrayAdapter<Message> {
viewHolder.image.setOnLongClickListener(openContextMenu); viewHolder.image.setOnLongClickListener(openContextMenu);
} }
private void loadMoreMessages(Conversation conversation) {
conversation.setLastClearHistory(0);
conversation.setHasMessagesLeftOnServer(true);
conversation.setFirstMamReference(null);
long timestamp = conversation.getLastMessageTransmitted();
if (timestamp == 0) {
timestamp = System.currentTimeMillis();
}
activity.setMessagesLoaded();
activity.xmppConnectionService.getMessageArchiveService().query(conversation, 0, timestamp);
Toast.makeText(activity, R.string.fetching_history_from_server,Toast.LENGTH_LONG).show();
}
@Override @Override
public View getView(int position, View view, ViewGroup parent) { public View getView(int position, View view, ViewGroup parent) {
final Message message = getItem(position); final Message message = getItem(position);
@ -484,6 +497,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false); view = activity.getLayoutInflater().inflate(R.layout.message_status, parent, false);
viewHolder.contact_picture = (ImageView) view.findViewById(R.id.message_photo); viewHolder.contact_picture = (ImageView) view.findViewById(R.id.message_photo);
viewHolder.status_message = (TextView) view.findViewById(R.id.status_message); viewHolder.status_message = (TextView) view.findViewById(R.id.status_message);
viewHolder.load_more_messages = (Button) view.findViewById(R.id.load_more_messages);
break; break;
default: default:
viewHolder = null; viewHolder = null;
@ -500,16 +514,31 @@ public class MessageAdapter extends ArrayAdapter<Message> {
boolean darkBackground = (type == RECEIVED && (!isInValidSession || !mUseWhiteBackground)); boolean darkBackground = (type == RECEIVED && (!isInValidSession || !mUseWhiteBackground));
if (type == STATUS) { if (type == STATUS) {
if (conversation.getMode() == Conversation.MODE_SINGLE) { if ("LOAD_MORE".equals(message.getBody())) {
viewHolder.contact_picture.setImageBitmap(activity viewHolder.status_message.setVisibility(View.GONE);
.avatarService().get(conversation.getContact(), viewHolder.contact_picture.setVisibility(View.GONE);
activity.getPixel(32))); viewHolder.load_more_messages.setVisibility(View.VISIBLE);
viewHolder.contact_picture.setAlpha(0.5f); viewHolder.load_more_messages.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
loadMoreMessages(message.getConversation());
}
});
} else {
viewHolder.status_message.setVisibility(View.VISIBLE);
viewHolder.contact_picture.setVisibility(View.VISIBLE);
viewHolder.load_more_messages.setVisibility(View.GONE);
if (conversation.getMode() == Conversation.MODE_SINGLE) {
viewHolder.contact_picture.setImageBitmap(activity
.avatarService().get(conversation.getContact(),
activity.getPixel(32)));
viewHolder.contact_picture.setAlpha(0.5f);
}
viewHolder.status_message.setText(message.getBody()); viewHolder.status_message.setText(message.getBody());
} }
return view; return view;
} else { } else {
loadAvatar(message,viewHolder.contact_picture); loadAvatar(message, viewHolder.contact_picture);
} }
viewHolder.contact_picture viewHolder.contact_picture
@ -671,6 +700,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
protected ImageView contact_picture; protected ImageView contact_picture;
protected TextView status_message; protected TextView status_message;
protected TextView encryption; protected TextView encryption;
public Button load_more_messages;
} }
class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> { class BitmapWorkerTask extends AsyncTask<Message, Void, Bitmap> {

View file

@ -9,6 +9,15 @@
android:paddingRight="8dp" android:paddingRight="8dp"
android:paddingTop="5dp"> android:paddingTop="5dp">
<Button
android:id="@+id/load_more_messages"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/load_more_messages"
android:textColor="@color/accent" android:layout_centerVertical="true"
android:layout_centerHorizontal="true"/>
<com.makeramen.roundedimageview.RoundedImageView <com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/message_photo" android:id="@+id/message_photo"
android:layout_width="32dp" android:layout_width="32dp"

View file

@ -560,6 +560,7 @@
<item quantity="one">%d message</item> <item quantity="one">%d message</item>
<item quantity="other">%d messages</item> <item quantity="other">%d messages</item>
</plurals> </plurals>
<string name="load_more_messages">Load more messages</string>
<string name="shared_file_with_x">Shared file with %s</string> <string name="shared_file_with_x">Shared file with %s</string>
<string name="shared_image_with_x">Shared image with %s</string> <string name="shared_image_with_x">Shared image with %s</string>
<string name="no_storage_permission">Conversations need access to external storage</string> <string name="no_storage_permission">Conversations need access to external storage</string>