aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/de/thedevstack/conversationsplus/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/thedevstack/conversationsplus/utils')
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/ConversationUtil.java35
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/ExceptionHelper.java3
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/GeoHelper.java4
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/MessageParserUtil.java164
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/MessageUtil.java255
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/UIHelper.java18
-rw-r--r--src/main/java/de/thedevstack/conversationsplus/utils/messaging/MessageReceiptUtil.java41
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);
+ }
+}