From 132b27adeef3ab4d305facda7dd035015b00766f Mon Sep 17 00:00:00 2001 From: steckbrief Date: Sat, 5 May 2018 20:28:04 +0200 Subject: introduces new message state model --- .../conversationsplus/ui/ConversationFragment.java | 46 ++-- .../conversationsplus/ui/ShareWithActivity.java | 7 +- .../ui/adapter/ConversationAdapter.java | 2 +- .../ui/adapter/MessageAdapter.java | 274 +++++++-------------- .../ui/adapter/MessageViewHolder.java | 97 ++++++++ .../ui/dialogs/MessageDetailsDialog.java | 36 +-- .../listeners/ContactPictureOnClickListener.java | 4 +- .../ContactPictureOnLongClickListener.java | 3 +- .../ResizePictureUserDecisionListener.java | 9 +- 9 files changed, 245 insertions(+), 233 deletions(-) create mode 100644 src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageViewHolder.java (limited to 'src/main/java/de/thedevstack/conversationsplus/ui') diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java index cd2ee4f8..4cecd7f8 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ConversationFragment.java @@ -43,6 +43,8 @@ import java.util.Collections; import java.util.List; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; +import de.thedevstack.conversationsplus.enums.MessageDirection; +import de.thedevstack.conversationsplus.enums.MessageStatus; import de.thedevstack.conversationsplus.services.filetransfer.FileTransferManager; import de.thedevstack.conversationsplus.services.filetransfer.http.delete.DeleteRemoteFileService; import de.thedevstack.conversationsplus.ui.dialogs.SimpleConfirmDialog; @@ -124,8 +126,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 final int KEYCHAIN_UNLOCK_NOT_REQUIRED = 0; private final int KEYCHAIN_UNLOCK_REQUIRED = 1; private final int KEYCHAIN_UNLOCK_PENDING = 2; @@ -242,16 +242,13 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa private ConversationActivity activity; private Message selectedMessage; - public void setMessagesLoaded() { - this.messagesLoaded = true; - } - private void sendMessage() { final String body = mEditMessage.getText().toString(); if (body.length() == 0 || this.conversation == null) { return; } - Message message = new Message(conversation, body, conversation.getNextEncryption()); + Message message = MessageUtil.createOutgoingMessage(conversation, body); + if (conversation.getMode() == Conversation.MODE_MULTI) { if (conversation.getNextCounterpart() != null) { message.setCounterpart(conversation.getNextCounterpart()); @@ -503,8 +500,9 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (treatAsFile || (GeoHelper.isGeoUri(m.getBody()))) { shareWith.setVisible(true); } - if (m.getStatus() == Message.STATUS_SEND_FAILED - || Message.STATUS_SEND_CANCELED == m.getStatus()) { + if (MessageUtil.isOutgoingMessage(m) + && (MessageStatus.FAILED == m.getMessageStatus() + || MessageStatus.CANCELED == m.getMessageStatus())) { sendAgain.setVisible(true); } if (m.hasFileOnRemoteHost() @@ -518,15 +516,17 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa downloadFile.setTitle(activity.getString(R.string.download_x_file,UIHelper.getFileDescriptionString(activity, m))); } if ((t != null && !(t instanceof TransferablePlaceholder)) - || (m.isFileOrImage() && (m.getStatus() == Message.STATUS_WAITING - || m.getStatus() == Message.STATUS_OFFERED))) { + || (m.isFileOrImage() && (MessageStatus.WAITING == m.getMessageStatus() || MessageStatus.TRANSMITTING == m.getMessageStatus()))) { // TODO Welche Einschraenkung noch um uebertragung abzubrechen? cancelTransmission.setVisible(true); } if (treatAsFile) { deleteFile.setVisible(true); deleteFile.setTitle(activity.getString(R.string.delete_x_file,UIHelper.getFileDescriptionString(activity, m))); } - if (m.isHttpUploaded() && MessageUtil.isMessageSent(m) && AccountUtil.isFileTransferHttpAvailable(m.getConversation().getAccount())) { + if (m.isHttpUploaded() + && AccountUtil.isFileTransferHttpAvailable(m.getConversation().getAccount()) + && MessageUtil.isOutgoingMessage(m) + && (MessageUtil.isMessageTransmittedOrDisplayedOrReceived(m) || MessageStatus.FAILED == m.getMessageStatus())) { MenuItem deleteRemoteFile = menu.findItem(R.id.msg_ctx_menu_delete_remote_file); deleteRemoteFile.setVisible(true); } @@ -613,7 +613,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa return; } } - activity.xmppConnectionService.resendFailedMessages(message); + activity.xmppConnectionService.resendFailedOrCanceledMessages(message); } private void copyUrl(Message message) { @@ -651,7 +651,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa if (transferable != null) { transferable.cancel(); } else { - MessageUtil.markMessage(message, Message.STATUS_SEND_CANCELED); + MessageUtil.setAndSaveMessageStatus(message, MessageStatus.CANCELED); } } @@ -726,7 +726,6 @@ 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); @@ -878,7 +877,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa private Message getLastPgpDecryptableMessage() { for (final Message message : this.messageList) { if (message.getEncryption() == Message.ENCRYPTION_PGP - && (message.getStatus() == Message.STATUS_RECEIVED || message.getStatus() >= Message.STATUS_SEND) + && MessageUtil.isMessageTransmittedOrDisplayedOrReceived(message) && message.getTransferable() == null) { return message; } @@ -1047,18 +1046,15 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa synchronized (this.messageList) { if (conversation.getMode() == Conversation.MODE_SINGLE) { ChatState state = conversation.getIncomingChatState(); - if (state == ChatState.COMPOSING) { - //this.messageList.add(Message.createStatusMessage(conversation, getString(R.string.contact_is_typing, conversation.getName()))); - } else if (state == ChatState.PAUSED) { - //this.messageList.add(Message.createStatusMessage(conversation, getString(R.string.contact_has_stopped_typing, conversation.getName()))); - } else { + if (state != ChatState.COMPOSING && state != ChatState.PAUSED) { // Do not show status message for (int i = this.messageList.size() - 1; i >= 0; --i) { - if (this.messageList.get(i).getStatus() == Message.STATUS_RECEIVED) { + Message message = this.messageList.get(i); + if (MessageUtil.isIncomingMessage(message)) { return; } else { - if (this.messageList.get(i).getStatus() == Message.STATUS_SEND_DISPLAYED) { + if (MessageStatus.DISPLAYED == message.getMessageStatus()) { this.messageList.add(i + 1, - Message.createStatusMessage(conversation, getString(R.string.contact_has_read_up_to_this_point, conversation.getName()))); + MessageUtil.createStatusMessage(conversation, getString(R.string.contact_has_read_up_to_this_point, conversation.getName()))); return; } } @@ -1315,7 +1311,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa updatePgpMessages(); } else if (requestCode == ConversationActivity.REQUEST_TRUST_KEYS_TEXT) { final String body = mEditMessage.getText().toString(); - Message message = new Message(conversation, body, conversation.getNextEncryption()); + Message message = MessageUtil.createOutgoingMessage(conversation, body); sendAxolotlMessage(message); } else if (requestCode == ConversationActivity.REQUEST_TRUST_KEYS_MENU) { int choice = data.getIntExtra("choice", ConversationActivity.ATTACHMENT_CHOICE_INVALID); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/ShareWithActivity.java b/src/main/java/de/thedevstack/conversationsplus/ui/ShareWithActivity.java index 8852212b..080c7a51 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/ShareWithActivity.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/ShareWithActivity.java @@ -32,6 +32,7 @@ import de.thedevstack.conversationsplus.ui.adapter.ConversationAdapter; import de.thedevstack.conversationsplus.utils.AccountUtil; import de.thedevstack.conversationsplus.utils.ConversationUtil; import de.thedevstack.conversationsplus.utils.FileUtils; +import de.thedevstack.conversationsplus.utils.MessageUtil; import de.thedevstack.conversationsplus.xmpp.jid.InvalidJidException; import de.thedevstack.conversationsplus.xmpp.jid.Jid; @@ -319,10 +320,8 @@ public class ShareWithActivity extends XmppActivity implements XmppConnectionSer final OnPresenceSelected callback = new OnPresenceSelected() { @Override public void onPresenceSelected() { - Message message = new Message(conversation,share.text, conversation.getNextEncryption()); - if (conversation.getNextEncryption() == Message.ENCRYPTION_OTR) { - message.setCounterpart(conversation.getNextCounterpart()); - } + Message message = MessageUtil.createOutgoingMessage(conversation, share.text); + xmppConnectionService.sendMessage(message); replaceToast(getString(R.string.shared_text_with_x, conversation.getName())); finish(); 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 e87cb052..97219b18 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/ConversationAdapter.java @@ -101,7 +101,7 @@ public class ConversationAdapter extends ArrayAdapter { imagePreview.setVisibility(View.GONE); CharSequence msgText = preview.first; String msgPrefix = null; - if (MessageUtil.isMessageSent(message)) { + if (MessageUtil.isOutgoingMessage(message)) { msgPrefix = activity.getString(R.string.cplus_me); } else if (conversation.getMode() == Conversation.MODE_MULTI) { msgPrefix = UIHelper.getMessageDisplayName(message); 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 7c7a6b57..331f8458 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageAdapter.java @@ -14,10 +14,7 @@ import android.view.View.OnClickListener; import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.widget.ArrayAdapter; -import android.widget.Button; import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; import java.util.List; @@ -32,6 +29,7 @@ import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.entities.Transferable; import de.thedevstack.conversationsplus.enums.FileStatus; +import de.thedevstack.conversationsplus.enums.MessageStatus; import de.thedevstack.conversationsplus.services.avatar.AvatarCache; import de.thedevstack.conversationsplus.services.avatar.AvatarService; import de.thedevstack.conversationsplus.services.filetransfer.http.download.AutomaticFileDownload; @@ -48,12 +46,12 @@ import de.thedevstack.conversationsplus.utils.UIHelper; import de.thedevstack.conversationsplus.utils.ui.TextViewUtil; import de.thedevstack.conversationsplus.utils.ui.ViewUtil; -public class MessageAdapter extends ArrayAdapter { +import static de.thedevstack.conversationsplus.ui.adapter.MessageViewHolder.ME_COMMAND; +import static de.thedevstack.conversationsplus.ui.adapter.MessageViewHolder.RECEIVED; +import static de.thedevstack.conversationsplus.ui.adapter.MessageViewHolder.SENT; +import static de.thedevstack.conversationsplus.ui.adapter.MessageViewHolder.STATUS; - private static final int SENT = 0; - private static final int RECEIVED = 1; - private static final int STATUS = 2; - private static final int ME_COMMAND = 3; +public class MessageAdapter extends ArrayAdapter { private ConversationActivity activity; @@ -81,7 +79,7 @@ public class MessageAdapter extends ArrayAdapter { return ME_COMMAND; } else if (message.getType() == Message.TYPE_STATUS) { return STATUS; - } else if (message.getStatus() <= Message.STATUS_RECEIVED) { + } else if (MessageUtil.isIncomingMessage(message)) { return RECEIVED; } @@ -101,15 +99,15 @@ public class MessageAdapter extends ArrayAdapter { } } - private void displayStatus(ViewHolder viewHolder, Message message, int type) { + private void displayStatus(MessageViewHolder viewHolder, Message message, int type) { String filesize = null; String info = null; boolean error = false; ViewUtil.gone(viewHolder.indicatorReceived); boolean multiReceived = message.getConversation().getMode() == Conversation.MODE_MULTI - && message.getStatus() <= Message.STATUS_RECEIVED; - if (message.hasFileAttached() || message.getTransferable() != null) { + && MessageUtil.isIncomingMessage(message); + if (message.hasFileAttached() || MessageUtil.hasDownloadableLink(message)) { FileParams params = message.getFileParams(); if (null != params) { filesize = UIHelper.getHumanReadableFileSize(params.getSize()); @@ -119,36 +117,45 @@ public class MessageAdapter extends ArrayAdapter { error = true; } } - switch (message.getStatus()) { - case Message.STATUS_WAITING: + Transferable d = message.getTransferable(); + switch (message.getMessageStatus()) { + case WAITING: info = getContext().getString(R.string.waiting); break; - case Message.STATUS_UNSEND: - Transferable d = message.getTransferable(); - if (d != null) { - info = getContext().getString(R.string.sending_file, d.getProgress()); + case TRANSMITTING: + if (null != d) { + int resId = R.string.receiving_file; + if (MessageUtil.isOutgoingMessage(message)) { + resId = R.string.sending_file; + } + info = getContext().getString(resId, d.getProgress()); + } else if (null != message.getFileParams() && FileStatus.NEEDS_UPLOAD == message.getFileParams().getFileStatus()) { // FIXME: Remove when Jingle is migrated + info = getContext().getString(R.string.offering); } else { - info = getContext().getString(R.string.sending); + if (!MessageUtil.needsDownload(message)) { + int resId = R.string.receiving; + if (MessageUtil.isOutgoingMessage(message)) { + resId = R.string.sending; + } + info = getContext().getString(resId); + } } break; - case Message.STATUS_OFFERED: - info = getContext().getString(R.string.offering); - break; - case Message.STATUS_SEND_RECEIVED: + case RECEIVED: if (ConversationsPlusPreferences.indicateReceived()) { viewHolder.indicatorReceived.setVisibility(View.VISIBLE); } break; - case Message.STATUS_SEND_DISPLAYED: + case DISPLAYED: if (ConversationsPlusPreferences.indicateReceived()) { viewHolder.indicatorReceived.setVisibility(View.VISIBLE); } break; - case Message.STATUS_SEND_FAILED: + case FAILED: info = getContext().getString(R.string.send_failed); error = true; break; - case Message.STATUS_SEND_CANCELED: + case CANCELED: info = getContext().getString(R.string.send_canceled); error = true; break; @@ -156,7 +163,6 @@ public class MessageAdapter extends ArrayAdapter { if (multiReceived) { info = UIHelper.getMessageDisplayName(message); } - break; } this.displayEncryptionIndicator(message, viewHolder); @@ -166,7 +172,7 @@ public class MessageAdapter extends ArrayAdapter { this.displayRemoteFileStatus(message, viewHolder); } - private void displayRemoteFileStatus(Message message, ViewHolder viewHolder) { + private void displayRemoteFileStatus(Message message, MessageViewHolder viewHolder) { if (message.hasFileAttached() && null != message.getFileParams() && null != viewHolder.remoteFileStatus) { FileStatus fileStatus = message.getFileParams().getFileStatus(); if (fileStatus == FileStatus.DELETE_FAILED || fileStatus == FileStatus.DELETED || fileStatus == FileStatus.DELETING || fileStatus == FileStatus.NOT_FOUND) { @@ -193,7 +199,7 @@ public class MessageAdapter extends ArrayAdapter { } } - private void displayMessageTime(Message message, ViewHolder viewHolder, String filesize, String info, boolean error, boolean isSent) { + private void displayMessageTime(Message message, MessageViewHolder viewHolder, String filesize, String info, boolean error, boolean isSent) { if (error && isSent) { viewHolder.time.setTextColor(ConversationsPlusColors.warning()); } else { @@ -201,7 +207,7 @@ public class MessageAdapter extends ArrayAdapter { } String formatedTime = UIHelper.readableTimeDifferenceFull(getContext(), message.getTimeSent()); String timeText = null; - if (message.getStatus() <= Message.STATUS_RECEIVED) { + if (MessageUtil.isIncomingMessage(message)) { StringBuilder timeTextBuilder = new StringBuilder(); timeTextBuilder.append((null != formatedTime) ? formatedTime + ((null != info || null != filesize) ? " \u00B7 " : "") : ""); timeTextBuilder.append((null != filesize) ? filesize + ((null != info) ? " \u00B7 " : "") : ""); @@ -227,7 +233,7 @@ public class MessageAdapter extends ArrayAdapter { TextViewUtil.setTextWithoutAutoLink(viewHolder.time, timeText); } - private void displayEncryptionIndicator(Message message, ViewHolder viewHolder) { + private void displayEncryptionIndicator(Message message, MessageViewHolder viewHolder) { if (message.getEncryption() == Message.ENCRYPTION_NONE) { viewHolder.indicator.setVisibility(View.GONE); } else { @@ -260,40 +266,28 @@ public class MessageAdapter extends ArrayAdapter { } } - private void displayInfoMessage(ViewHolder viewHolder, String text) { - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - if (null != viewHolder.image) { - viewHolder.image.setVisibility(View.GONE); - } + private void displayInfoMessage(MessageViewHolder viewHolder, String text) { + ViewUtil.gone(viewHolder.download_button, viewHolder.image); - viewHolder.messageBody.setVisibility(View.VISIBLE); - viewHolder.messageBody.setText(text); + TextViewUtil.showAndSetText(viewHolder.messageBody, text); viewHolder.messageBody.setTextColor(getMessageTextColor(viewHolder.darkBackground, false)); viewHolder.messageBody.setTypeface(null, Typeface.ITALIC); viewHolder.messageBody.setTextIsSelectable(false); } - private void displayDecryptionFailed(ViewHolder viewHolder) { - if (viewHolder.download_button != null) { - viewHolder.download_button.setVisibility(View.GONE); - } - - viewHolder.image.setVisibility(View.GONE); + private void displayDecryptionFailed(MessageViewHolder viewHolder) { + ViewUtil.gone(viewHolder.download_button, viewHolder.image); - viewHolder.messageBody.setVisibility(View.VISIBLE); - viewHolder.messageBody.setText(getContext().getString( - R.string.decryption_failed)); + TextViewUtil.showAndSetText(viewHolder.messageBody, R.string.decryption_failed); viewHolder.messageBody.setTextColor(getMessageTextColor(viewHolder.darkBackground, false)); viewHolder.messageBody.setTypeface(null, Typeface.NORMAL); viewHolder.messageBody.setTextIsSelectable(false); } - private void displayTextMessage(final ViewHolder viewHolder, final Message message) { + private void displayTextMessage(final MessageViewHolder viewHolder, final Message message) { ViewUtil.gone(viewHolder.download_button, viewHolder.image); - viewHolder.messageBody.setVisibility(View.VISIBLE); + ViewUtil.visible(viewHolder.messageBody); viewHolder.messageBody.setIncludeFontPadding(true); if (message.getBody() != null) { @@ -317,7 +311,7 @@ public class MessageAdapter extends ArrayAdapter { } } else { String privateMarker; - if (message.getStatus() <= Message.STATUS_RECEIVED) { + if (MessageUtil.isIncomingMessage(message)) { privateMarker = activity.getString(R.string.private_message); } else { final String to; @@ -352,15 +346,14 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.messageBody.setOnLongClickListener(openContextMenu); } - private void displayDownloadButton(ViewHolder viewHolder, String btnText, OnClickListener onClickListener) { - viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setText(btnText); - viewHolder.download_button.setOnClickListener(onClickListener); + private void displayDownloadButton(MessageViewHolder viewHolder, String btnText, OnClickListener onClickListener) { + TextViewUtil.showAndSetText(viewHolder.download_button, btnText) + .setOnClickListener(onClickListener); viewHolder.download_button.setOnLongClickListener(openContextMenu); } - private void displayFileInfoForFileMessage(final Message message, ViewHolder viewHolder) { - viewHolder.messageBody.setVisibility(View.VISIBLE); + private void displayFileInfoForFileMessage(final Message message, MessageViewHolder viewHolder) { + ViewUtil.visible(viewHolder.messageBody); StringBuilder fileInfos = new StringBuilder(); String filename = UIHelper.getDisplayFilename(message); fileInfos.append((null != filename && !filename.isEmpty()) ? (filename) : ""); @@ -368,8 +361,8 @@ public class MessageAdapter extends ArrayAdapter { TextViewUtil.setTextWithoutAutoLink(viewHolder.messageBody, fileInfos); } - private void displayDownloadableMessage(ViewHolder viewHolder, final Message message) { - viewHolder.image.setVisibility(View.GONE); + private void displayDownloadableMessage(MessageViewHolder viewHolder, final Message message) { + ViewUtil.gone(viewHolder.image); FileParams fileParams = message.getFileParams(); String btnText; int resId = R.string.download_x_file; @@ -393,8 +386,8 @@ public class MessageAdapter extends ArrayAdapter { }); } - private void displayOpenableMessage(ViewHolder viewHolder, final Message message) { - viewHolder.image.setVisibility(View.GONE); + private void displayOpenableMessage(MessageViewHolder viewHolder, final Message message) { + ViewUtil.gone(viewHolder.image); FileParams fileParams = message.getFileParams(); String btnText; @@ -410,19 +403,18 @@ public class MessageAdapter extends ArrayAdapter { } - private void displayLocationMessage(ViewHolder viewHolder, final Message message) { - viewHolder.image.setVisibility(View.GONE); - viewHolder.messageBody.setVisibility(View.GONE); - viewHolder.download_button.setVisibility(View.VISIBLE); - viewHolder.download_button.setText(R.string.show_location); - viewHolder.download_button.setOnClickListener(new OpenLocationOnClickListener(this.activity, message)); + private void displayLocationMessage(MessageViewHolder viewHolder, final Message message) { + ViewUtil.gone(viewHolder.image, viewHolder.messageBody); + + TextViewUtil.showAndSetText(viewHolder.download_button, R.string.show_location) + .setOnClickListener(new OpenLocationOnClickListener(this.activity, message)); viewHolder.download_button.setOnLongClickListener(openContextMenu); } - private void displayImageMessage(ViewHolder viewHolder, final Message message) { - ViewUtil.gone(viewHolder.download_button); - + private void displayImageMessage(MessageViewHolder viewHolder, final Message message) { + ViewUtil.gone(viewHolder.download_button, viewHolder.messageBody); + ViewUtil.visible(viewHolder.image); ImageUtil.loadBitmap(message, viewHolder.image, viewHolder.messageBody, true); viewHolder.image.setOnClickListener(new OpenFileOnClickListener(this.activity, message)); @@ -430,11 +422,11 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.image.setOnLongClickListener(openContextMenu); } - private View displayStatusMessage(final Message message, ViewHolder viewHolder) { + private View displayStatusMessage(final Message message, MessageViewHolder viewHolder) { final Conversation conversation = message.getConversation(); - viewHolder.status_message.setVisibility(View.VISIBLE); - viewHolder.contact_picture.setVisibility(View.VISIBLE); + ViewUtil.visible(viewHolder.status_message, viewHolder.contact_picture); + if (conversation.getMode() == Conversation.MODE_SINGLE) { viewHolder.contact_picture.setImageBitmap(AvatarCache.get(conversation.getContact(), activity.getPixel(32))); @@ -445,29 +437,20 @@ public class MessageAdapter extends ArrayAdapter { return viewHolder.view; } - private void displayFileMessage(final Message message, ViewHolder viewHolder) { + private void displayFileMessage(final Message message, MessageViewHolder viewHolder) { if (!(message.trusted() && MessageUtil.needsDownload(message) && ConversationsPlusPreferences.autoAcceptFileSize() > 0 && message.isHttpUploaded() || ConversationsPlusPreferences.autoDownloadFileLink())) { - new AutomaticFileDownload(false).transferFile(message); + new AutomaticFileDownload().transferFile(message); } Transferable transferable = message.getTransferable(); if (FileStatus.CHECKING_FILE_SIZE == message.getFileParams().getFileStatus()) { displayInfoMessage(viewHolder, activity.getString(R.string.checking_remote_filesize)); } else if (MessageUtil.isAttachedFileAnImage(message) - && (FileStatus.DOWNLOADED == message.getFileParams().getFileStatus() - || FileStatus.DELETED == message.getFileParams().getFileStatus() - || FileStatus.DELETING == message.getFileParams().getFileStatus() - || FileStatus.DELETE_FAILED == message.getFileParams().getFileStatus() - || FileStatus.NEEDS_UPLOAD == message.getFileParams().getFileStatus() - || FileStatus.UPLOADED == message.getFileParams().getFileStatus() - || FileStatus.UPLOAD_FAILED == message.getFileParams().getFileStatus() - || (null != transferable - && (transferable.isCanceled() - || Transferable.STATUS_UPLOADING == transferable.getStatus())))) { + && hasFileStatusToShowMessage(message)) { displayImageMessage(viewHolder, message); - } else if ((MessageUtil.isTypeFileAndDecrypted(message) || FileStatus.DOWNLOADED == message.getFileParams().getFileStatus()) + } else if ((MessageUtil.isTypeFileAndDecrypted(message) || hasFileStatusToShowMessage(message)) && !MessageUtil.needsDownload(message)) { displayOpenableMessage(viewHolder, message); } else if (Message.Decision.NEVER == message.treatAsDownloadable() || !MessageUtil.mayFileRemoteAvailable(message)) { @@ -478,10 +461,6 @@ public class MessageAdapter extends ArrayAdapter { case Transferable.STATUS_OFFER_CHECK_FILESIZE: displayDownloadableMessage(viewHolder, message); break; - case Transferable.STATUS_UPLOADING: - // Should not happen, since this is now covered by the other if-statements - // TODO Maybe in Jingle File Transfer?? Needs to be checked! - break; case Transferable.STATUS_DELETED: case Transferable.STATUS_CHECKING: case Transferable.STATUS_FAILED: @@ -495,7 +474,21 @@ public class MessageAdapter extends ArrayAdapter { } } - private void displayAvatar(final Message message, int type, ViewHolder viewHolder) { + private boolean hasFileStatusToShowMessage(Message message) { + Transferable transferable = message.getTransferable(); + return (FileStatus.DOWNLOADED == message.getFileParams().getFileStatus() + || FileStatus.DELETED == message.getFileParams().getFileStatus() + || FileStatus.DELETING == message.getFileParams().getFileStatus() + || FileStatus.DELETE_FAILED == message.getFileParams().getFileStatus() + || FileStatus.NEEDS_UPLOAD == message.getFileParams().getFileStatus() + || FileStatus.UPLOADED == message.getFileParams().getFileStatus() + || FileStatus.UPLOAD_FAILED == message.getFileParams().getFileStatus() + || (null != transferable + && (transferable.isCanceled() + || Transferable.STATUS_UPLOADING == transferable.getStatus()))); + } + + private void displayAvatar(final Message message, int type, MessageViewHolder viewHolder) { if (type == ME_COMMAND || (type == RECEIVED)) { // && message.getConversation().getMode() == Conversation.MODE_MULTI ImageView imageView = viewHolder.contact_picture; if (null != imageView) { @@ -509,79 +502,24 @@ public class MessageAdapter extends ArrayAdapter { } } - private View initializeView(int type, ViewGroup parent) { - Integer viewResId = null; - - switch (type) { - case SENT: - viewResId = R.layout.message_sent; - break; - case RECEIVED: - viewResId = R.layout.message_received; - break; - case STATUS: - viewResId = R.layout.message_status; - break; - case ME_COMMAND: - viewResId = R.layout.message_mecmd; - break; - } - - return activity.getLayoutInflater().inflate(viewResId, parent, false); - } - - private ViewHolder initializeViewHolderAndView(int type, ViewGroup parent) { - View view = initializeView(type, parent); - ViewHolder viewHolder = new ViewHolder(view); - if (SENT == type - || RECEIVED == type - || ME_COMMAND == type) { - viewHolder.message_box = ViewUtil.visible(view, R.id.message_box); - viewHolder.indicator = (ImageView) view.findViewById(R.id.security_indicator); - viewHolder.messageBody = (TextView) view.findViewById(R.id.message_body); - viewHolder.time = (TextView) view.findViewById(R.id.message_time); - viewHolder.indicatorReceived = (ImageView) view.findViewById(R.id.indicator_received); - } - if ((SENT == type - || RECEIVED == type)) { - viewHolder.download_button = (Button) view.findViewById(R.id.download_button); - viewHolder.image = (ImageView) view.findViewById(R.id.message_image); - } - if (ME_COMMAND == type - || (RECEIVED == type)) { // && message.getConversation().getMode() == Conversation.MODE_MULTI --> only muc received msgs - viewHolder.contact_picture = ViewUtil.visible(view, R.id.message_photo); - } - if (RECEIVED == type) { - viewHolder.encryption = (TextView) view.findViewById(R.id.message_encryption); - } - if (STATUS == type) { - viewHolder.contact_picture = ViewUtil.visible(view, R.id.message_photo); - viewHolder.status_message = TextViewUtil.visible(view, R.id.status_message); - } - if (SENT == type) { // This field is only useful for sent messages -> because of deletion of own files -> maybe a use case for recvd possible - viewHolder.remoteFileStatus = TextViewUtil.gone(view, R.id.remote_file_status); - } - view.setTag(viewHolder); - - return viewHolder; - } - @Override public View getView(int position, View view, @NonNull ViewGroup parent) { final Message message = getItem(position); - if (null == message) { + if (null == message + || MessageStatus.DISPLAYED == message.getMessageStatus() + || MessageStatus.RECEIVED == message.getMessageStatus()) { return view; } final boolean isInValidSession = message.isValidInSession(); final Conversation conversation = message.getConversation(); final Account account = conversation.getAccount(); final int type = getItemViewType(position); - ViewHolder viewHolder; + MessageViewHolder viewHolder; if (null == view) { - viewHolder = initializeViewHolderAndView(type, parent); + viewHolder = new MessageViewHolder(this.activity, type, parent); view = viewHolder.view; } else { - viewHolder = (ViewHolder) view.getTag(); + viewHolder = (MessageViewHolder) view.getTag(); if (null == viewHolder) { return view; } @@ -594,7 +532,6 @@ public class MessageAdapter extends ArrayAdapter { this.displayAvatar(message, type, viewHolder); viewHolder.darkBackground = (type == RECEIVED && !isInValidSession); - this.displayStatus(viewHolder, message, type); if (null != message.getTransferable() || message.hasFileAttached() || MessageUtil.hasDownloadableLink(message)) { displayFileMessage(message, viewHolder); @@ -607,21 +544,21 @@ public class MessageAdapter extends ArrayAdapter { } else { displayTextMessage(viewHolder, message); } + this.displayStatus(viewHolder, message, type); if (type == RECEIVED) { if (isInValidSession) { - viewHolder.encryption.setVisibility(View.GONE); + ViewUtil.gone(viewHolder.encryption); } else { viewHolder.message_box.setBackgroundResource(R.drawable.message_bubble_received_warning); - viewHolder.encryption.setVisibility(View.VISIBLE); - viewHolder.encryption.setText(CryptoHelper.encryptionTypeToText(message.getEncryption())); + TextViewUtil.showAndSetText(viewHolder.encryption, CryptoHelper.encryptionTypeToText(message.getEncryption())); } } return view; } - private void displayPgpEncryptedMessage(ViewHolder viewHolder, Account account) { + private void displayPgpEncryptedMessage(MessageViewHolder viewHolder, Account account) { if (activity.hasPgp()) { if (account.getPgpDecryptionService().isRunning()) { displayInfoMessage(viewHolder, activity.getString(R.string.message_decrypting)); @@ -638,25 +575,4 @@ public class MessageAdapter extends ArrayAdapter { }); } } - - private static class ViewHolder { - protected ViewHolder(View view) { - this.view = view; - } - - protected View view; - - protected LinearLayout message_box; - protected Button download_button; - protected ImageView image; - protected ImageView indicator; - protected ImageView indicatorReceived; - protected TextView time; - protected TextView messageBody; - protected ImageView contact_picture; - protected TextView status_message; - protected TextView encryption; - public TextView remoteFileStatus; - protected boolean darkBackground; - } } \ No newline at end of file diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageViewHolder.java b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageViewHolder.java new file mode 100644 index 00000000..d66d4f01 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/ui/adapter/MessageViewHolder.java @@ -0,0 +1,97 @@ +package de.thedevstack.conversationsplus.ui.adapter; + +import android.app.Activity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import de.thedevstack.conversationsplus.R; +import de.thedevstack.conversationsplus.utils.ui.TextViewUtil; +import de.thedevstack.conversationsplus.utils.ui.ViewUtil; + +/** + */ +class MessageViewHolder { + + static final int SENT = 0; + static final int RECEIVED = 1; + static final int STATUS = 2; + static final int ME_COMMAND = 3; + + View view; + + LinearLayout message_box; + Button download_button; + ImageView image; + ImageView indicator; + ImageView indicatorReceived; + TextView time; + TextView messageBody; + ImageView contact_picture; + TextView status_message; + TextView encryption; + TextView remoteFileStatus; + boolean darkBackground; + + MessageViewHolder(Activity activity, int type, ViewGroup parent) { + int viewResId = this.resolveViewId(type, parent); + this.view = activity.getLayoutInflater().inflate(viewResId, parent, false); + this.initializeViewElements(type); + } + + private int resolveViewId(int type, ViewGroup parent) { + Integer viewResId = null; + + switch (type) { + case SENT: + viewResId = R.layout.message_sent; + break; + case RECEIVED: + viewResId = R.layout.message_received; + break; + case STATUS: + viewResId = R.layout.message_status; + break; + case ME_COMMAND: + viewResId = R.layout.message_mecmd; + break; + } + + return viewResId; + } + + private void initializeViewElements(int type) { + if (SENT == type + || RECEIVED == type + || ME_COMMAND == type) { + this.message_box = ViewUtil.visible(view, R.id.message_box); + this.indicator = (ImageView) view.findViewById(R.id.security_indicator); + this.messageBody = (TextView) view.findViewById(R.id.message_body); + this.time = (TextView) view.findViewById(R.id.message_time); + this.indicatorReceived = (ImageView) view.findViewById(R.id.indicator_received); + } + if ((SENT == type + || RECEIVED == type)) { + this.download_button = (Button) view.findViewById(R.id.download_button); + this.image = (ImageView) view.findViewById(R.id.message_image); + } + if (ME_COMMAND == type + || (RECEIVED == type)) { // && message.getConversation().getMode() == Conversation.MODE_MULTI --> only muc received msgs + this.contact_picture = ViewUtil.visible(view, R.id.message_photo); + } + if (RECEIVED == type) { + this.encryption = (TextView) view.findViewById(R.id.message_encryption); + } + if (STATUS == type) { + this.contact_picture = ViewUtil.visible(view, R.id.message_photo); + this.status_message = TextViewUtil.visible(view, R.id.status_message); + } + if (SENT == type) { // This field is only useful for sent messages -> because of deletion of own files -> maybe a use case for recvd possible + this.remoteFileStatus = TextViewUtil.gone(view, R.id.remote_file_status); + } + view.setTag(this); + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java index b43384a4..60431d54 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/dialogs/MessageDetailsDialog.java @@ -13,6 +13,10 @@ import de.thedevstack.conversationsplus.R; import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.FileParams; import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.enums.FileStatus; +import de.thedevstack.conversationsplus.enums.MessageDirection; +import de.thedevstack.conversationsplus.enums.MessageStatus; +import de.thedevstack.conversationsplus.utils.MessageUtil; import de.thedevstack.conversationsplus.utils.UIHelper; import de.thedevstack.conversationsplus.utils.ui.TextViewUtil; @@ -78,26 +82,30 @@ public class MessageDetailsDialog extends AbstractAlertDialog { protected void displayMessageStatusInfo(View view, Message message) { TextView msgStatusTextView = (TextView) view.findViewById(R.id.dlgMsgDetMsgStatus); int msgStatusResId; - switch (message.getStatus()) { - case Message.STATUS_WAITING: + switch (message.getMessageStatus()) { + case WAITING: msgStatusResId = R.string.dlg_msg_details_msg_status_waiting; break; - case Message.STATUS_UNSEND: - msgStatusResId = R.string.dlg_msg_details_msg_status_unsend; + case TRANSMITTING: + if (MessageUtil.isOutgoingMessage(message)) { + msgStatusResId = R.string.dlg_msg_details_msg_status_unsend; + } else if (FileStatus.NEEDS_UPLOAD == message.getFileParams().getFileStatus()) { // FIXME: Remove when Jingle is migrated + msgStatusResId = R.string.dlg_msg_details_msg_status_offered; + } else { + msgStatusResId = R.string.dlg_msg_details_msg_status_receiving; + } break; - case Message.STATUS_OFFERED: - msgStatusResId = R.string.dlg_msg_details_msg_status_offered; - break; - case Message.STATUS_SEND_FAILED: + case FAILED: msgStatusResId = R.string.dlg_msg_details_msg_status_failed; msgStatusTextView.setTextColor(ConversationsPlusColors.error()); break; - case Message.STATUS_RECEIVED: - msgStatusResId = R.string.dlg_msg_details_msg_status_received; + case TRANSMITTED: + if (MessageUtil.isIncomingMessage(message)) { + msgStatusResId = R.string.dlg_msg_details_msg_status_received; + } else { + msgStatusResId = R.string.dlg_msg_details_msg_status_sent; + } break; - case Message.STATUS_SEND: - case Message.STATUS_SEND_DISPLAYED: - case Message.STATUS_SEND_RECEIVED: default: msgStatusResId = R.string.dlg_msg_details_msg_status_sent; } @@ -154,7 +162,7 @@ public class MessageDetailsDialog extends AbstractAlertDialog { // Get own nick for MUC me = conversation.getMucOptions().getActualNick(); } - if (Message.STATUS_RECEIVED == message.getStatus()) { + if (MessageUtil.isIncomingMessage(message)) { // Sender was chat partner, if the status is for my account received sender.setText(other); // Set receipient to myself in case of normal chat or private message in MUC diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnClickListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnClickListener.java index e3c85fdf..9eaec00c 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnClickListener.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnClickListener.java @@ -1,6 +1,5 @@ package de.thedevstack.conversationsplus.ui.listeners; -import android.app.Activity; import android.content.Intent; import android.view.View; import android.widget.Toast; @@ -11,6 +10,7 @@ import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.ui.ConversationActivity; import de.thedevstack.conversationsplus.ui.EditAccountActivity; +import de.thedevstack.conversationsplus.utils.MessageUtil; /** */ @@ -25,7 +25,7 @@ public class ContactPictureOnClickListener implements View.OnClickListener { @Override public void onClick(View view) { - if (message.getStatus() <= Message.STATUS_RECEIVED) { // What does this mean? + if (MessageUtil.isIncomingMessage(message)) { if (message.getConversation().getMode() == Conversation.MODE_MULTI) { if (message.getCounterpart() != null) { String user = message.getCounterpart().isBareJid() ? message.getCounterpart().toString() : message.getCounterpart().getResourcepart(); diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnLongClickListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnLongClickListener.java index 49ff764b..fef10f90 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnLongClickListener.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ContactPictureOnLongClickListener.java @@ -7,6 +7,7 @@ import de.thedevstack.conversationsplus.R; import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.ui.ConversationActivity; +import de.thedevstack.conversationsplus.utils.MessageUtil; import de.thedevstack.conversationsplus.utils.ui.QrCodeUtil; /** @@ -22,7 +23,7 @@ public class ContactPictureOnLongClickListener implements View.OnLongClickListen @Override public boolean onLongClick(View view) { - if (message.getStatus() <= Message.STATUS_RECEIVED) { + if (MessageUtil.isIncomingMessage(message)) { if (message.getConversation().getMode() == Conversation.MODE_MULTI) { if (message.getCounterpart() != null) { String user = message.getCounterpart().getResourcepart(); 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 e6ec7496..a65e9c7a 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ResizePictureUserDecisionListener.java @@ -113,19 +113,14 @@ public class ResizePictureUserDecisionListener implements UserDecisionListener { } protected Message createMessage() { - final Message message; - if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { - message = new Message(conversation, "", Message.ENCRYPTION_DECRYPTED); - } else { - message = new Message(conversation, "", conversation.getNextEncryption()); - } + final Message message = MessageUtil.createOutgoingMessage(conversation, ""); if (null != conversation.getNextCounterpart() && null == message.getCounterpart()) { message.setCounterpart(conversation.getNextCounterpart()); } //message.setType(Message.TYPE_IMAGE); message.setFileParams(new FileParams()); - message.getFileParams().setFileStatus(FileStatus.NEEDS_UPLOAD); + MessageUtil.setFileStatus(message, FileStatus.NEEDS_UPLOAD); return message; } -- cgit v1.2.3