diff options
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/utils')
7 files changed, 355 insertions, 165 deletions
diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java index 709b3f20..616cf962 100644 --- a/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java +++ b/src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java @@ -8,6 +8,7 @@ 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.MessageStatus; import de.thedevstack.conversationsplus.exceptions.FileCopyException; import de.thedevstack.conversationsplus.persistance.FileBackend; import de.thedevstack.conversationsplus.ui.UiCallback; @@ -17,18 +18,22 @@ import de.thedevstack.conversationsplus.ui.UiCallback; */ public class ConversationUtil { + public static void markMessagesAsDisplayedUpToMessage(Message message) { + Conversation conversation = message.getConversation(); + + while (null != message && (MessageStatus.RECEIVED == message.getMessageStatus() || MessageStatus.TRANSMITTED == message.getMessageStatus())) { + MessageUtil.setAndSaveMessageStatus(message, MessageStatus.DISPLAYED); + + message = conversation.getMessageBefore(message); + } + } + public static void attachLocationToConversation(final Conversation conversation, final Uri uri, final UiCallback<Message> callback) { - int encryption = conversation.getNextEncryption(); - if (encryption == Message.ENCRYPTION_PGP) { - encryption = Message.ENCRYPTION_DECRYPTED; - } - Message message = new Message(conversation, uri.toString(), encryption); - if (conversation.getNextCounterpart() != null) { - message.setCounterpart(conversation.getNextCounterpart()); - } - if (encryption == Message.ENCRYPTION_DECRYPTED) { + Message message = MessageUtil.createOutgoingMessage(conversation, uri.toString()); + + if (message.getEncryption() == Message.ENCRYPTION_DECRYPTED) { PgpEngine.getInstance().encrypt(message, callback); } else { callback.success(message); @@ -38,18 +43,12 @@ public class ConversationUtil { public static void attachFileToConversation(final Conversation conversation, final Uri uri, final UiCallback<Message> callback) { - final Message message; - if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) { - message = new Message(conversation, "", Message.ENCRYPTION_DECRYPTED); - } else { - message = new Message(conversation, "", conversation.getNextEncryption()); - } - message.setCounterpart(conversation.getNextCounterpart()); - //message.setType(Message.TYPE_FILE); + final Message message = MessageUtil.createOutgoingMessage(conversation, ""); + if (null == message.getFileParams()) { message.setFileParams(new FileParams()); } - message.getFileParams().setFileStatus(FileStatus.NEEDS_UPLOAD); + MessageUtil.setFileStatus(message, FileStatus.NEEDS_UPLOAD); String path = FileUtils.getPath(uri); if (path != null) { message.getFileParams().setPath(path); diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/ExceptionHelper.java b/src/main/java/de/thedevstack/conversationsplus/utils/ExceptionHelper.java index 913f2ab5..907e7fd7 100644 --- a/src/main/java/de/thedevstack/conversationsplus/utils/ExceptionHelper.java +++ b/src/main/java/de/thedevstack/conversationsplus/utils/ExceptionHelper.java @@ -95,8 +95,7 @@ public class ExceptionHelper { Jid.fromString(activity.getString(R.string.cplus_bugreport_jabberid)), false); } catch (final InvalidJidException ignored) { } - Message message = new Message(conversation, report - .toString(), Message.ENCRYPTION_NONE); + Message message = MessageUtil.createOutgoingMessage(conversation, report.toString()); service.sendMessage(message); } }); diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/GeoHelper.java b/src/main/java/de/thedevstack/conversationsplus/utils/GeoHelper.java index 662f797a..b4be2d35 100644 --- a/src/main/java/de/thedevstack/conversationsplus/utils/GeoHelper.java +++ b/src/main/java/de/thedevstack/conversationsplus/utils/GeoHelper.java @@ -41,7 +41,7 @@ public class GeoHelper { } final Conversation conversation = message.getConversation(); String label; - if (conversation.getMode() == Conversation.MODE_SINGLE && message.getStatus() == Message.STATUS_RECEIVED) { + if (conversation.getMode() == Conversation.MODE_SINGLE && MessageUtil.isIncomingMessage(message)) { try { label = "(" + URLEncoder.encode(message.getConversation().getName(), "UTF-8") + ")"; } catch (UnsupportedEncodingException e) { @@ -55,7 +55,7 @@ public class GeoHelper { locationPluginIntent.putExtra("latitude",latitude); locationPluginIntent.putExtra("longitude",longitude); if (conversation.getMode() == Conversation.MODE_SINGLE) { - if (message.getStatus() == Message.STATUS_RECEIVED) { + if (MessageUtil.isIncomingMessage(message)) { locationPluginIntent.putExtra("name",conversation.getName()); locationPluginIntent.putExtra("jid",message.getCounterpart().toString()); } diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/MessageParserUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/MessageParserUtil.java new file mode 100644 index 00000000..5044d132 --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/utils/MessageParserUtil.java @@ -0,0 +1,164 @@ +package de.thedevstack.conversationsplus.utils; + +import java.net.MalformedURLException; +import java.net.URL; + +import de.thedevstack.conversationsplus.entities.FileParams; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.entities.Transferable; +import de.thedevstack.conversationsplus.enums.FileStatus; +import de.thedevstack.conversationsplus.enums.MessageConfirmation; +import de.thedevstack.conversationsplus.xmpp.chatmarkers.ChatMarkers; +import de.thedevstack.conversationsplus.xmpp.receipts.MessageDeliveryReceipts; +import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket; + +/** + */ +public class MessageParserUtil { + public static MessageConfirmation extractMessageConfirmation(MessagePacket messagePacket) { + if (messagePacket.hasChild(ChatMarkers.MARKABLE) + && messagePacket.hasChild(MessageDeliveryReceipts.REQUEST)) { + return MessageConfirmation.DELIVERY_RECEIPT_CHAT_MARKERS; + } else if (messagePacket.hasChild(ChatMarkers.MARKABLE)) { + return MessageConfirmation.CHAT_MARKERS; + } else if (messagePacket.hasChild(MessageDeliveryReceipts.REQUEST)) { + return MessageConfirmation.DELIVERY_RECEIPT; + } else { + return MessageConfirmation.NONE; + } + } + + public static void extractFileParamsFromBody(Message message) { + if (null == message) { + return; + } + + // Ensure that for every message the fileParams are set after calling this method + FileParams fileParams = message.getFileParams(); + if (null == fileParams) { + fileParams = new FileParams(); + message.setFileParams(fileParams); + } + + String body = message.getBody(); + /** + * there are a few cases where spaces result in an unwanted behavior, e.g. + * "http://example.com/image.jpg" text that will not be shown /abc.png" + * or more than one image link in one message. + */ + if (null == body || body.isEmpty() || body.contains(" ")) { + return; + } + + URL url = MessageParserUtil.extractValidUrlFromBody(message); + if (null != url) { + String extension = FileUtils.getRelevantExtension(url); + if (message.isHttpUploaded()) { + fileParams.setUrl(url.toString()); + if (null != extension + && (Transferable.WELL_KNOWN_EXTENSIONS.contains(extension.toLowerCase()) || Transferable.VALID_IMAGE_EXTENSIONS.contains(extension.toLowerCase()))) { + message.setTreatAsDownloadable(Message.Decision.MUST); + } else { + MessageParserUtil.setParamsToAvoidDownload(message, fileParams); + } + + extractFilename(message, url.toString()); + return; + } + + if (extension == null) { + MessageParserUtil.setParamsToAvoidDownload(message, fileParams); + return; + } + byte[] ivAndKey = UrlUtil.getIvAndKeyFromURL(url); + + if (null != ivAndKey) { + if (MimeUtils.guessMimeTypeFromExtension(extension) != null) { + message.setTreatAsDownloadable(Message.Decision.MUST); + fileParams.setKeyAndIv(ivAndKey); + } else { + MessageParserUtil.setParamsToAvoidDownload(message, fileParams); + } + } else if (Transferable.VALID_IMAGE_EXTENSIONS.contains(extension) + || Transferable.WELL_KNOWN_EXTENSIONS.contains(extension)) { + message.setTreatAsDownloadable(Message.Decision.SHOULD); + MessageUtil.setFileStatus(message, FileStatus.NEEDS_DOWNLOAD); + } else { + MessageParserUtil.setParamsToAvoidDownload(message, fileParams); + } + + if (message.treatAsDownloadable() == Message.Decision.MUST + || message.treatAsDownloadable() == Message.Decision.SHOULD) { + fileParams.setUrl(url.toString()); + extractFilename(message, url.toString()); + MessageUtil.setFileStatus(message, FileStatus.NEEDS_DOWNLOAD); + } + } else { + MessageParserUtil.setParamsToAvoidDownload(message, fileParams); + } + } + + private static void setParamsToAvoidDownload(Message message, FileParams fileParams) { + message.setTreatAsDownloadable(Message.Decision.NEVER); + MessageUtil.setFileStatus(message, FileStatus.UNDEFINED); + } + + private static void extractFilename(Message message, String url) { + String originalFilename = FileUtils.getFilenameFromPath(url); + final String lowerCaseFilename = originalFilename.toLowerCase(); + final String lastPart = FileUtils.getLastExtension(lowerCaseFilename); + + detectAndSetEncryption(lastPart, message); + + String filenameExtension; + if (!lastPart.isEmpty() && Transferable.VALID_CRYPTO_EXTENSIONS.contains(lastPart)) { + filenameExtension = FileUtils.getSecondToLastExtension(lowerCaseFilename); + originalFilename = originalFilename.replace("." + lastPart, ""); + } else { + filenameExtension = lastPart; + } + message.setRelativeFilePath(message.getUuid() + "." + filenameExtension); + + message.getFileParams().setOriginalFilename(originalFilename); + } + + private static void detectAndSetEncryption(String lastPart, Message message) { + if (!lastPart.isEmpty() && ("pgp".equals(lastPart) || "gpg".equals(lastPart))) { + message.setEncryption(Message.ENCRYPTION_PGP); + } else if (message.getEncryption() != Message.ENCRYPTION_OTR + && message.getEncryption() != Message.ENCRYPTION_AXOLOTL) { + message.setEncryption(Message.ENCRYPTION_NONE); + } else if ((message.getEncryption() == Message.ENCRYPTION_OTR + || message.getEncryption() == Message.ENCRYPTION_AXOLOTL) + && message.getFileParams() != null && message.getFileParams().getKey() == null) { + // If an encryption is set for the message, but no key given -> decryption not possible + message.setEncryption(Message.ENCRYPTION_NONE); + } + } + + private static URL extractValidUrlFromBody(Message message) { + if (null == message) { + return null; + } + String body = message.getBody(); + /** + * there are a few cases where spaces result in an unwanted behavior, e.g. + * "http://example.com/image.jpg" text that will not be shown /abc.png" + * or more than one image link in one message. + */ + if (null == body || body.isEmpty() || body.contains(" ")) { + return null; + } + + try { + URL url = new URL(body); + if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { + return null; + } + + return url; + } catch (MalformedURLException e) { + return null; + } + } +} diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java index 2e346486..0be1461b 100644 --- a/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java +++ b/src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java @@ -3,138 +3,35 @@ package de.thedevstack.conversationsplus.utils; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import java.net.MalformedURLException; import java.net.URL; import java.util.regex.Matcher; import java.util.regex.Pattern; +import de.thedevstack.android.logcat.Logging; import de.thedevstack.conversationsplus.ConversationsPlusApplication; import de.thedevstack.conversationsplus.ConversationsPlusPreferences; +import de.thedevstack.conversationsplus.entities.Account; import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.DownloadableFile; import de.thedevstack.conversationsplus.entities.FileParams; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.entities.Transferable; +import de.thedevstack.conversationsplus.entities.TransferablePlaceholder; import de.thedevstack.conversationsplus.enums.FileStatus; +import de.thedevstack.conversationsplus.enums.MessageConfirmation; +import de.thedevstack.conversationsplus.enums.MessageDirection; +import de.thedevstack.conversationsplus.enums.MessageStatus; import de.thedevstack.conversationsplus.persistance.DatabaseBackend; import de.thedevstack.conversationsplus.persistance.FileBackend; +import de.thedevstack.conversationsplus.utils.messaging.MessageReceiptUtil; +import de.thedevstack.conversationsplus.xmpp.jid.Jid; +import de.tzur.conversations.Settings; /** * Utility class to work with messages. */ public final class MessageUtil { - public static void extractFileParamsFromBody(Message message) { - if (null == message) { - return; - } - - // Ensure that for every message the fileParams are set after calling this method - FileParams fileParams = message.getFileParams(); - if (null == fileParams) { - fileParams = new FileParams(); - message.setFileParams(fileParams); - } - - String body = message.getBody(); - /** - * there are a few cases where spaces result in an unwanted behavior, e.g. - * "http://example.com/image.jpg" text that will not be shown /abc.png" - * or more than one image link in one message. - */ - if (null == body || body.isEmpty() || body.contains(" ")) { - return; - } - - try { - URL url = new URL(body); - if (!url.getProtocol().equalsIgnoreCase("http") && !url.getProtocol().equalsIgnoreCase("https")) { - message.setTreatAsDownloadable(Message.Decision.NEVER); - fileParams.setFileStatus(FileStatus.UNDEFINED); - return; - } - String extension = FileUtils.getRelevantExtension(url); - if (message.isHttpUploaded()) { - fileParams.setUrl(url.toString()); - if (null != extension - && (Transferable.WELL_KNOWN_EXTENSIONS.contains(extension.toLowerCase()) || Transferable.VALID_IMAGE_EXTENSIONS.contains(extension.toLowerCase()))) { - message.setTreatAsDownloadable(Message.Decision.MUST); - } else { - message.setTreatAsDownloadable(Message.Decision.NEVER); - fileParams.setFileStatus(FileStatus.UNDEFINED); - } - - extractFilename(message, url.toString()); - return; - } - - if (extension == null) { - message.setTreatAsDownloadable(Message.Decision.NEVER); - fileParams.setFileStatus(FileStatus.UNDEFINED); - return; - } - byte[] ivAndKey = UrlUtil.getIvAndKeyFromURL(url); - - if (null != ivAndKey) { - if (MimeUtils.guessMimeTypeFromExtension(extension) != null) { - message.setTreatAsDownloadable(Message.Decision.MUST); - fileParams.setKeyAndIv(ivAndKey); - } else { - message.setTreatAsDownloadable(Message.Decision.NEVER); - fileParams.setFileStatus(FileStatus.UNDEFINED); - } - } else if (Transferable.VALID_IMAGE_EXTENSIONS.contains(extension) - || Transferable.WELL_KNOWN_EXTENSIONS.contains(extension)) { - message.setTreatAsDownloadable(Message.Decision.SHOULD); - } else { - message.setTreatAsDownloadable(Message.Decision.NEVER); - fileParams.setFileStatus(FileStatus.UNDEFINED); - } - - if (message.treatAsDownloadable() == Message.Decision.MUST - || message.treatAsDownloadable() == Message.Decision.SHOULD) { - fileParams.setUrl(url.toString()); - extractFilename(message, url.toString()); - } - } catch (MalformedURLException e) { - message.setTreatAsDownloadable(Message.Decision.NEVER); - fileParams.setFileStatus(FileStatus.UNDEFINED); - } - } - - private static void extractFilename(Message message, String url) { - String originalFilename = FileUtils.getFilenameFromPath(url); - final String lowerCaseFilename = originalFilename.toLowerCase(); - final String lastPart = FileUtils.getLastExtension(lowerCaseFilename); - - detectAndSetEncryption(lastPart, message); - - String filenameExtension; - if (!lastPart.isEmpty() && Transferable.VALID_CRYPTO_EXTENSIONS.contains(lastPart)) { - filenameExtension = FileUtils.getSecondToLastExtension(lowerCaseFilename); - originalFilename = originalFilename.replace("." + lastPart, ""); - } else { - filenameExtension = lastPart; - } - message.setRelativeFilePath(message.getUuid() + "." + filenameExtension); - - message.getFileParams().setOriginalFilename(originalFilename); - } - - private static void detectAndSetEncryption(String lastPart, Message message) { - if (!lastPart.isEmpty() && ("pgp".equals(lastPart) || "gpg".equals(lastPart))) { - message.setEncryption(Message.ENCRYPTION_PGP); - } else if (message.getEncryption() != Message.ENCRYPTION_OTR - && message.getEncryption() != Message.ENCRYPTION_AXOLOTL) { - message.setEncryption(Message.ENCRYPTION_NONE); - } else if ((message.getEncryption() == Message.ENCRYPTION_OTR - || message.getEncryption() == Message.ENCRYPTION_AXOLOTL) - && message.getFileParams() != null && message.getFileParams().getKey() == null) { - // If an encryption is set for the message, but no key given -> decryption not possible - message.setEncryption(Message.ENCRYPTION_NONE); - } - } - /** * Checks if an attached file is an image or not. * Prerequisite for calling this method: The check if a file is attached is done before. @@ -179,8 +76,8 @@ public final class MessageUtil { public static boolean needsDownload(Message message) { FileStatus fileStatus = (null != message.getFileParams()) ? message.getFileParams().getFileStatus() : null; return (message.hasFileAttached() || MessageUtil.hasDownloadableLink(message)) - &&(null == fileStatus - || (null != fileStatus && (fileStatus == FileStatus.NEEDS_DOWNLOAD || fileStatus == FileStatus.UNDEFINED))) + && (null == fileStatus + || (fileStatus == FileStatus.NEEDS_DOWNLOAD || fileStatus == FileStatus.UNDEFINED)) && message.treatAsDownloadable() != Message.Decision.NEVER; } @@ -190,31 +87,75 @@ public final class MessageUtil { && null != url; } + public static boolean isOutgoingMessage(Message message) { + return MessageDirection.OUT == message.getDirection(); + } + + public static boolean isIncomingMessage(Message message) { + return MessageDirection.IN == message.getDirection(); + } + public static boolean isMessageSent(Message message) { - switch (message.getStatus()) { - case Message.STATUS_SEND: - case Message.STATUS_SEND_DISPLAYED: - case Message.STATUS_SEND_FAILED: - case Message.STATUS_SEND_RECEIVED: - return true; - default: - return false; + return MessageUtil.isOutgoingMessage(message) + && MessageStatus.TRANSMITTED == message.getMessageStatus(); + } + + public static boolean isMessageReceived(Message message) { + return MessageUtil.isIncomingMessage(message) + && MessageStatus.TRANSMITTED == message.getMessageStatus(); + } + + public static boolean isMessageTransmittedOrDisplayedOrReceived(Message message) { + MessageStatus status = message.getMessageStatus(); + return MessageStatus.TRANSMITTED == status + || MessageStatus.RECEIVED == status + || MessageStatus.DISPLAYED == status; + } + + public static void setAndSaveStatusForFileDeleted(Message message) { + message.setTransferable(new TransferablePlaceholder(Transferable.STATUS_DELETED)); + //FIXME: File Status needs to be changed + MessageStatus msgStatus = message.getMessageStatus(); + if (MessageUtil.isOutgoingMessage(message) + && (MessageStatus.TRANSMITTING == msgStatus || MessageStatus.WAITING == msgStatus)) { + MessageUtil.setAndSaveMessageStatus(message, MessageStatus.FAILED); // FIXME: add some information why this is failed } } public static void setAndSaveFileStatus(Message message, FileStatus fileStatus) { + if (setFileStatus(message, fileStatus)) { + DatabaseBackend.getInstance().updateMessage(message); + UiUpdateHelper.updateConversationUi(); + } + } + + public static boolean setFileStatus(Message message, FileStatus fileStatus) { message.getFileParams().setFileStatus(fileStatus); - DatabaseBackend.getInstance().updateMessage(message); - UiUpdateHelper.updateConversationUi(); + if (FileStatus.DOWNLOAD_FAILED == fileStatus + || FileStatus.UPLOAD_FAILED == fileStatus) { + setMessageStatus(message, MessageStatus.FAILED); + } else if (FileStatus.DOWNLOADED == fileStatus) { + setMessageStatus(message, MessageStatus.TRANSMITTED); + } + return true; + } + + public static boolean markMessageAsReceived(Account account, Jid from, String id) { + Message message = XmppConnectionServiceAccessor.xmppConnectionService.getMessage(account, from, id); + if (null != message) { + MessageUtil.setAndSaveMessageStatus(message, MessageStatus.RECEIVED); + return true; + } + return false; } - public static boolean markMessage(Conversation conversation, String uuid, int status) { + public static boolean setAndSaveMessageStatus(Conversation conversation, String uuid, MessageStatus newStatus) { if (uuid == null) { return false; } else { Message message = conversation.findSentMessageWithUuid(uuid); if (message != null) { - markMessage(message, status); + setAndSaveMessageStatus(message, newStatus); return true; } else { return false; @@ -222,15 +163,38 @@ public final class MessageUtil { } } - public static void markMessage(Message message, int status) { - if (status == Message.STATUS_SEND_FAILED - && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message - .getStatus() == Message.STATUS_SEND_DISPLAYED)) { - return; + public static void setAndSaveMessageStatus(Message message, MessageStatus newStatus) { + if (setMessageStatus(message, newStatus)) { + DatabaseBackend.getInstance(ConversationsPlusApplication.getAppContext()).updateMessage(message); + UiUpdateHelper.updateConversationUi(); + } + } + + private static boolean sendReceipt(Message message) { + return Settings.CONFIRM_MESSAGE_RECEIVED // Only if user allows to send message confirmations + && isIncomingMessage(message) // Only if a message is incoming + && MessageConfirmation.NONE != message.getConfirmation() // Only if message contained an confirmation request + && message.getRemoteMsgId() != null // Only if there is an remote id + && !message.isMamReceived() // Only if it is not received using MAM + && !message.isCarbon() // Only if it is not received with carbons + && !message.isRead(); // Only if the message is not read yet + } + + public static boolean setMessageStatus(Message message, MessageStatus newStatus) { + MessageStatus currentStatus = message.getMessageStatus(); + if ((MessageStatus.FAILED == newStatus && (MessageStatus.RECEIVED == currentStatus || MessageStatus.DISPLAYED == currentStatus))) { + return false; + } + message.setMessageStatus(newStatus); + if (MessageStatus.TRANSMITTED == newStatus) { + if (sendReceipt(message)) { + Logging.d("message-util", "Send message receipt from setMessageStatus"); + MessageReceiptUtil.sendMessageReceipts(message); + } + Logging.d("message-util", "Push notification for message"); + XmppConnectionServiceAccessor.xmppConnectionService.getNotificationService().push(message); } - message.setStatus(status); - DatabaseBackend.getInstance(ConversationsPlusApplication.getAppContext()).updateMessage(message); - UiUpdateHelper.updateConversationUi(); + return true; } public static boolean wasHighlightedOrPrivate(final Message message) { @@ -302,6 +266,29 @@ public final class MessageUtil { } } + public static Message createStatusMessage(Conversation conversation, String body) { + final Message message = new Message(); + message.setType(Message.TYPE_STATUS); + message.setConversation(conversation); + message.setBody(body); + return message; + } + + public static Message createOutgoingMessage(Conversation conversation, String body) { + int encryption = conversation.getNextEncryption(); + if (encryption == Message.ENCRYPTION_PGP) { + encryption = Message.ENCRYPTION_DECRYPTED; + } + Message message = new Message(conversation, body, encryption); + message.setMessageStatus(MessageStatus.WAITING); + message.setDirection(MessageDirection.OUT); + if (conversation.getNextCounterpart() != null) { + message.setCounterpart(conversation.getNextCounterpart()); + } + + return message; + } + private MessageUtil() { // Static helper class } diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java b/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java index d27481df..31089a62 100644 --- a/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java +++ b/src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java @@ -20,6 +20,7 @@ import de.thedevstack.conversationsplus.entities.Conversation; import de.thedevstack.conversationsplus.entities.Message; import de.thedevstack.conversationsplus.entities.Presence; import de.thedevstack.conversationsplus.entities.Transferable; +import de.thedevstack.conversationsplus.enums.FileStatus; import de.thedevstack.conversationsplus.xmpp.jid.Jid; public class UIHelper { @@ -89,8 +90,8 @@ public class UIHelper { return sameDay(date,new Date(System.currentTimeMillis())); } - public static boolean sameDay(long timestamp1, long timestamp2) { - return sameDay(new Date(timestamp1),new Date(timestamp2)); + public static boolean sameDay(long timestamp, long timestamp2) { + return sameDay(new Date(timestamp),new Date(timestamp2)); } private static boolean sameDay(Date a, Date b) { @@ -147,8 +148,7 @@ public class UIHelper { getFileDescriptionString(context,message)),true); case Transferable.STATUS_DOWNLOADING: return new Pair<>(context.getString(R.string.receiving_x_file, - getFileDescriptionString(context,message), - d.getProgress()),true); + getFileDescriptionString(context,message)),true); case Transferable.STATUS_OFFER: case Transferable.STATUS_OFFER_CHECK_FILESIZE: return new Pair<>(context.getString(R.string.x_file_offered_for_download, @@ -158,7 +158,7 @@ public class UIHelper { case Transferable.STATUS_FAILED: return new Pair<>(context.getString(R.string.file_transmission_failed),true); case Transferable.STATUS_UPLOADING: - if (message.getStatus() == Message.STATUS_OFFERED) { + if (message.getFileParams().getFileStatus() == FileStatus.NEEDS_UPLOAD) { return new Pair<>(context.getString(R.string.offering_x_file, getFileDescriptionString(context, message)), true); } else { @@ -173,7 +173,7 @@ public class UIHelper { } else if (message.getEncryption() == Message.ENCRYPTION_DECRYPTION_FAILED) { return new Pair<>(context.getString(R.string.decryption_failed), true); } else if (message.getType() == Message.TYPE_FILE || message.getType() == Message.TYPE_IMAGE) { - if (message.getStatus() == Message.STATUS_RECEIVED) { + if (MessageUtil.isMessageReceived(message)) {// Todo: Check if Transmitted && Displayed && Received should be used here return new Pair<>(context.getString(R.string.received_x_file, getFileDescriptionString(context, message)), true); } else { @@ -183,7 +183,7 @@ public class UIHelper { if (message.hasMeCommand()) { return new Pair<>(message.getBodyReplacedMeCommand(UIHelper.getMessageDisplayName(message)), false); } else if (GeoHelper.isGeoUri(message.getBody())) { - if (message.getStatus() == Message.STATUS_RECEIVED) { + if (MessageUtil.isMessageReceived(message)) { // Todo: Check if Transmitted && Displayed && Received should be used here return new Pair<>(context.getString(R.string.received_location), true); } else { return new Pair<>(context.getString(R.string.location), true); @@ -233,7 +233,7 @@ public class UIHelper { public static String getMessageDisplayName(final Message message) { final Conversation conversation = message.getConversation(); - if (message.getStatus() == Message.STATUS_RECEIVED) { + if (MessageUtil.isIncomingMessage(message)) { final Contact contact = message.getContact(); if (conversation.getMode() == Conversation.MODE_MULTI) { if (contact != null) { @@ -304,7 +304,7 @@ public class UIHelper { public static boolean receivedLocationQuestion(Message message) { if (message == null - || message.getStatus() != Message.STATUS_RECEIVED + || MessageUtil.isOutgoingMessage(message) || message.getType() != Message.TYPE_TEXT) { return false; } diff --git a/src/main/java/de/thedevstack/conversationsplus/utils/messaging/MessageReceiptUtil.java b/src/main/java/de/thedevstack/conversationsplus/utils/messaging/MessageReceiptUtil.java new file mode 100644 index 00000000..a3ac1c3a --- /dev/null +++ b/src/main/java/de/thedevstack/conversationsplus/utils/messaging/MessageReceiptUtil.java @@ -0,0 +1,41 @@ +package de.thedevstack.conversationsplus.utils.messaging; + +import java.util.ArrayList; + +import de.thedevstack.conversationsplus.entities.Account; +import de.thedevstack.conversationsplus.entities.Conversation; +import de.thedevstack.conversationsplus.entities.Message; +import de.thedevstack.conversationsplus.enums.MessageConfirmation; +import de.thedevstack.conversationsplus.utils.XmppSendUtil; +import de.thedevstack.conversationsplus.xml.Element; +import de.thedevstack.conversationsplus.xmpp.chatmarkers.ChatMarkers; +import de.thedevstack.conversationsplus.xmpp.receipts.MessageDeliveryReceipts; +import de.thedevstack.conversationsplus.xmpp.stanzas.MessagePacket; + +/** + */ +public final class MessageReceiptUtil { + public static void sendMessageReceipts(Message message) { + MessageConfirmation confirmation = message.getConfirmation(); + ArrayList<Element> receipts = new ArrayList<>(); + if (MessageConfirmation.DELIVERY_RECEIPT_CHAT_MARKERS == confirmation) { + receipts.add(ChatMarkers.RECEIVED.getXmlElement()); + receipts.add(MessageDeliveryReceipts.RECEIVED.getXmlElement()); + } else if (MessageConfirmation.CHAT_MARKERS == confirmation) { + receipts.add(ChatMarkers.RECEIVED.getXmlElement()); + } else { + receipts.add(MessageDeliveryReceipts.RECEIVED.getXmlElement()); + } + + Account account = message.getConversation().getAccount(); + MessagePacket receivedPacket = new MessagePacket(); + receivedPacket.setType((message.getConversation().getMode() == Conversation.MODE_SINGLE ? MessagePacket.TYPE_CHAT : MessagePacket.TYPE_GROUPCHAT)); + receivedPacket.setTo(message.getCounterpart()); + receivedPacket.setFrom(account.getJid()); + for (Element receipt : receipts) { + receivedPacket.addChild(receipt).setAttribute("id", message.getRemoteMsgId()); + } + + XmppSendUtil.sendMessagePacket(account, receivedPacket); + } +} |