synchronized message list in conversation fragment

This commit is contained in:
iNPUTmice 2014-11-18 14:43:15 +01:00
parent dcebc120ac
commit 10bf2b77a8
1 changed files with 118 additions and 113 deletions

View File

@ -114,19 +114,20 @@ public class ConversationFragment extends Fragment {
@Override @Override
public void onScroll(AbsListView view, int firstVisibleItem, public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) { int visibleItemCount, int totalItemCount) {
if (firstVisibleItem == 0 && messagesLoaded) { synchronized (ConversationFragment.this.messageList) {
long timestamp = messageList.get(0).getTimeSent(); if (firstVisibleItem == 0 && messagesLoaded) {
messagesLoaded = false; long timestamp = ConversationFragment.this.messageList.get(0).getTimeSent();
int size = activity.xmppConnectionService.loadMoreMessages( messagesLoaded = false;
conversation, timestamp); int size = activity.xmppConnectionService.loadMoreMessages(conversation, timestamp);
messageList.clear(); ConversationFragment.this.messageList.clear();
messageList.addAll(conversation.getMessages()); ConversationFragment.this.messageList.addAll(conversation.getMessages());
updateStatusMessages(); updateStatusMessages();
messageListAdapter.notifyDataSetChanged(); messageListAdapter.notifyDataSetChanged();
if (size != 0) { if (size != 0) {
messagesLoaded = true; messagesLoaded = true;
}
messagesView.setSelectionFromTop(size + 1, 0);
} }
messagesView.setSelectionFromTop(size + 1, 0);
} }
} }
}; };
@ -284,10 +285,8 @@ public class ConversationFragment extends Fragment {
messagesView = (ListView) view.findViewById(R.id.messages_view); messagesView = (ListView) view.findViewById(R.id.messages_view);
messagesView.setOnScrollListener(mOnScrollListener); messagesView.setOnScrollListener(mOnScrollListener);
messagesView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL); messagesView.setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
messageListAdapter = new MessageAdapter( messageListAdapter = new MessageAdapter((ConversationActivity) getActivity(), this.messageList);
(ConversationActivity) getActivity(), this.messageList); messageListAdapter.setOnContactPictureClicked(new OnContactPictureClicked() {
messageListAdapter
.setOnContactPictureClicked(new OnContactPictureClicked() {
@Override @Override
public void onContactPictureClicked(Message message) { public void onContactPictureClicked(Message message) {
@ -342,10 +341,12 @@ public class ConversationFragment extends Fragment {
@Override @Override
public void onCreateContextMenu(ContextMenu menu, View v, public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) { ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo); synchronized (this.messageList) {
AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo; super.onCreateContextMenu(menu, v, menuInfo);
this.selectedMessage = this.messageList.get(acmi.position); AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
populateContextMenu(menu); this.selectedMessage = this.messageList.get(acmi.position);
populateContextMenu(menu);
}
} }
private void populateContextMenu(ContextMenu menu) { private void populateContextMenu(ContextMenu menu) {
@ -512,95 +513,97 @@ public class ConversationFragment extends Fragment {
} }
public void updateMessages() { public void updateMessages() {
if (getView() == null) { synchronized (this.messageList) {
return; if (getView() == null) {
} return;
hideSnackbar();
final ConversationActivity activity = (ConversationActivity) getActivity();
if (this.conversation != null) {
final Contact contact = this.conversation.getContact();
if (this.conversation.isMuted()) {
showSnackbar(R.string.notifications_disabled, R.string.enable,
new OnClickListener() {
@Override
public void onClick(View v) {
activity.unmuteConversation(conversation);
}
});
} else if (!contact.showInRoster()
&& contact
.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
showSnackbar(R.string.contact_added_you, R.string.add_back,
new OnClickListener() {
@Override
public void onClick(View v) {
activity.xmppConnectionService
.createContact(contact);
activity.switchToContactDetails(contact);
}
});
} else if (conversation.getMode() == Conversation.MODE_SINGLE) {
makeFingerprintWarning();
} else if (!conversation.getMucOptions().online()
&& conversation.getAccount().getStatus() == Account.State.ONLINE) {
int error = conversation.getMucOptions().getError();
switch (error) {
case MucOptions.ERROR_NICK_IN_USE:
showSnackbar(R.string.nick_in_use, R.string.edit,
clickToMuc);
break;
case MucOptions.ERROR_ROOM_NOT_FOUND:
showSnackbar(R.string.conference_not_found,
R.string.leave, leaveMuc);
break;
case MucOptions.ERROR_PASSWORD_REQUIRED:
showSnackbar(R.string.conference_requires_password,
R.string.enter_password, enterPassword);
break;
case MucOptions.ERROR_BANNED:
showSnackbar(R.string.conference_banned,
R.string.leave, leaveMuc);
break;
case MucOptions.ERROR_MEMBERS_ONLY:
showSnackbar(R.string.conference_members_only,
R.string.leave, leaveMuc);
break;
case MucOptions.KICKED_FROM_ROOM:
showSnackbar(R.string.conference_kicked, R.string.join,
joinMuc);
break;
default:
break;
}
} }
for (Message message : this.conversation.getMessages()) { hideSnackbar();
if (message.getEncryption() == Message.ENCRYPTION_PGP final ConversationActivity activity = (ConversationActivity) getActivity();
&& (message.getStatus() == Message.STATUS_RECEIVED || message if (this.conversation != null) {
.getStatus() >= Message.STATUS_SEND) final Contact contact = this.conversation.getContact();
&& message.getDownloadable() == null) { if (this.conversation.isMuted()) {
if (!mEncryptedMessages.contains(message)) { showSnackbar(R.string.notifications_disabled, R.string.enable,
mEncryptedMessages.add(message); new OnClickListener() {
@Override
public void onClick(View v) {
activity.unmuteConversation(conversation);
}
});
} else if (!contact.showInRoster()
&& contact
.getOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST)) {
showSnackbar(R.string.contact_added_you, R.string.add_back,
new OnClickListener() {
@Override
public void onClick(View v) {
activity.xmppConnectionService
.createContact(contact);
activity.switchToContactDetails(contact);
}
});
} else if (conversation.getMode() == Conversation.MODE_SINGLE) {
makeFingerprintWarning();
} else if (!conversation.getMucOptions().online()
&& conversation.getAccount().getStatus() == Account.State.ONLINE) {
int error = conversation.getMucOptions().getError();
switch (error) {
case MucOptions.ERROR_NICK_IN_USE:
showSnackbar(R.string.nick_in_use, R.string.edit,
clickToMuc);
break;
case MucOptions.ERROR_ROOM_NOT_FOUND:
showSnackbar(R.string.conference_not_found,
R.string.leave, leaveMuc);
break;
case MucOptions.ERROR_PASSWORD_REQUIRED:
showSnackbar(R.string.conference_requires_password,
R.string.enter_password, enterPassword);
break;
case MucOptions.ERROR_BANNED:
showSnackbar(R.string.conference_banned,
R.string.leave, leaveMuc);
break;
case MucOptions.ERROR_MEMBERS_ONLY:
showSnackbar(R.string.conference_members_only,
R.string.leave, leaveMuc);
break;
case MucOptions.KICKED_FROM_ROOM:
showSnackbar(R.string.conference_kicked, R.string.join,
joinMuc);
break;
default:
break;
} }
} }
for (Message message : this.conversation.getMessages()) {
if (message.getEncryption() == Message.ENCRYPTION_PGP
&& (message.getStatus() == Message.STATUS_RECEIVED || message
.getStatus() >= Message.STATUS_SEND)
&& message.getDownloadable() == null) {
if (!mEncryptedMessages.contains(message)) {
mEncryptedMessages.add(message);
}
}
}
decryptNext();
this.messageList.clear();
if (this.conversation.getMessages().size() == 0) {
messagesLoaded = false;
} else {
this.messageList.addAll(this.conversation.getMessages());
messagesLoaded = true;
updateStatusMessages();
}
this.messageListAdapter.notifyDataSetChanged();
updateChatMsgHint();
if (!activity.isConversationsOverviewVisable() || !activity.isConversationsOverviewHideable()) {
activity.xmppConnectionService.markRead(conversation, true);
activity.updateConversationList();
}
this.updateSendButton();
} }
decryptNext();
this.messageList.clear();
if (this.conversation.getMessages().size() == 0) {
messagesLoaded = false;
} else {
this.messageList.addAll(this.conversation.getMessages());
messagesLoaded = true;
updateStatusMessages();
}
this.messageListAdapter.notifyDataSetChanged();
updateChatMsgHint();
if (!activity.isConversationsOverviewVisable() || !activity.isConversationsOverviewHideable()) {
activity.xmppConnectionService.markRead(conversation, true);
activity.updateConversationList();
}
this.updateSendButton();
} }
} }
@ -695,15 +698,17 @@ public class ConversationFragment extends Fragment {
} }
protected void updateStatusMessages() { protected void updateStatusMessages() {
if (conversation.getMode() == Conversation.MODE_SINGLE) { synchronized (this.messageList) {
for (int i = this.messageList.size() - 1; i >= 0; --i) { if (conversation.getMode() == Conversation.MODE_SINGLE) {
if (this.messageList.get(i).getStatus() == Message.STATUS_RECEIVED) { for (int i = this.messageList.size() - 1; i >= 0; --i) {
return; if (this.messageList.get(i).getStatus() == Message.STATUS_RECEIVED) {
} else {
if (this.messageList.get(i).getStatus() == Message.STATUS_SEND_DISPLAYED) {
this.messageList.add(i + 1,
Message.createStatusMessage(conversation));
return; return;
} else {
if (this.messageList.get(i).getStatus() == Message.STATUS_SEND_DISPLAYED) {
this.messageList.add(i + 1,
Message.createStatusMessage(conversation));
return;
}
} }
} }
} }