diff --git a/widgetssdk/build.gradle b/widgetssdk/build.gradle index ab3f3810c..9608126cb 100644 --- a/widgetssdk/build.gradle +++ b/widgetssdk/build.gradle @@ -62,6 +62,7 @@ dependencies { api "com.glia:android-sdk:$gliaSdkVersion" // Glia sdk aar // implementation(name: "glia-core-sdk-$gliaSdkVersion", ext: 'aar') +// api "com.glia:android-sdk:0.26.6-SNAPSHOT" // Used when testing local Core SDK snapshot releases implementation "com.airbnb.android:lottie:$lottieVersion" implementation "com.google.code.gson:gson:$gson" diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatView.kt b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatView.kt index d6558aac5..a1f13029c 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/ChatView.kt +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/ChatView.kt @@ -455,19 +455,14 @@ class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defSty item.operatorProfileImgUrl, isFileDownloaded, item.isDownloading, - item.operatorId + item.operatorId, + item.messageId, + item.timestamp ) } is VisitorAttachmentItem -> { val isFileDownloaded = FileHelper.isFileDownloaded(item.attachmentFile) - VisitorAttachmentItem( - item.id, - item.viewType, - item.attachmentFile, - isFileDownloaded, - item.isDownloading, - item.showDelivered - ) + VisitorAttachmentItem.editDownloadedStatus(item, isFileDownloaded) } else -> { item @@ -1020,14 +1015,7 @@ class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defSty ): ChatItem { if (currentChatItem is VisitorAttachmentItem) { if (currentChatItem.attachmentFile.id == attachmentFile.id) { - return VisitorAttachmentItem( - currentChatItem.id, - currentChatItem.viewType, - currentChatItem.attachmentFile, - isFileExists, - isDownloading, - currentChatItem.showDelivered - ) + return VisitorAttachmentItem.editFileStatuses(currentChatItem, isFileExists, isDownloading) } } else if (currentChatItem is OperatorAttachmentItem) { if (currentChatItem.attachmentFile.id == attachmentFile.id) { @@ -1039,7 +1027,9 @@ class ChatView(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defSty currentChatItem.operatorProfileImgUrl, isFileExists, isDownloading, - currentChatItem.operatorId + currentChatItem.operatorId, + currentChatItem.messageId, + currentChatItem.timestamp ) } } diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/controller/ChatController.java b/widgetssdk/src/main/java/com/glia/widgets/chat/controller/ChatController.java index f68ab9342..8ed3f2580 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/controller/ChatController.java +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/controller/ChatController.java @@ -52,6 +52,7 @@ import com.glia.widgets.chat.model.history.OperatorChatItem; import com.glia.widgets.chat.model.history.OperatorMessageItem; import com.glia.widgets.chat.model.history.OperatorStatusItem; +import com.glia.widgets.chat.model.history.LinkedChatItem; import com.glia.widgets.chat.model.history.VisitorAttachmentItem; import com.glia.widgets.chat.model.history.VisitorMessageItem; import com.glia.widgets.core.dialog.DialogController; @@ -93,6 +94,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.Observable; @@ -459,6 +461,10 @@ private void subscribeToMessages() { private void onMessage(@NonNull ChatMessageInternal messageInternal) { ChatMessage message = messageInternal.getChatMessage(); + if (!isNewMessage(chatState.chatItems, message)) { + return; + } + boolean isUnsentMessage = !chatState.unsentMessages.isEmpty() && chatState.unsentMessages.get(0).getMessage().equals(message.getContent()); Logger.d(TAG, "onMessage: " + message.getContent() + ", id: " + message.getId() + ", isUnsentMessage: " + isUnsentMessage); if (isUnsentMessage) { @@ -469,7 +475,7 @@ private void onMessage(@NonNull ChatMessageInternal messageInternal) { List currentChatItems = new ArrayList<>(chatState.chatItems); int currentMessageIndex = currentChatItems.indexOf(currentMessage); currentChatItems.remove(currentMessage); - currentChatItems.add(currentMessageIndex, new VisitorMessageItem(message.getId(), false, message.getContent())); + currentChatItems.add(currentMessageIndex, VisitorMessageItem.asNewMessage(message)); // emitting state because no need to change recyclerview items here emitViewState(chatState @@ -518,7 +524,7 @@ private void onSendMessageOperatorOffline(String message) { private void appendUnsentMessage(String message) { Logger.d(TAG, "appendUnsentMessage: " + message); List unsentMessages = new ArrayList<>(chatState.unsentMessages); - VisitorMessageItem unsentItem = new VisitorMessageItem(VisitorMessageItem.UNSENT_MESSAGE_ID, false, message); + VisitorMessageItem unsentItem = VisitorMessageItem.asUnsentItem(message); unsentMessages.add(unsentItem); List currentChatItems = new ArrayList<>(chatState.chatItems); @@ -890,7 +896,7 @@ private void appendHistoryMessage(List currentChatItems, ChatMessage m } if (message.getContent() != null && !message.getContent().isEmpty()) { - currentChatItems.add(new VisitorMessageItem(VisitorMessageItem.HISTORY_ID, false, message.getContent())); + currentChatItems.add(VisitorMessageItem.asHistoryItem(message)); } } @@ -937,14 +943,8 @@ private void addVisitorAttachmentItemsToChatItems(List currentChatItem FilesAttachment filesAttachment = (FilesAttachment) attachment; AttachmentFile[] files = filesAttachment.getFiles(); for (AttachmentFile file : files) { - int type; - if (file.getContentType().startsWith("image")) { - type = ChatAdapter.VISITOR_IMAGE_VIEW_TYPE; - } else { - type = ChatAdapter.VISITOR_FILE_VIEW_TYPE; - } currentChatItems.add( - new VisitorAttachmentItem(chatMessage.getId(), type, file, false, false, false) + VisitorAttachmentItem.fromAttachmentFile(chatMessage.getId(), chatMessage.getTimestamp(), file) ); } } @@ -960,7 +960,7 @@ private void appendSentMessage(List items, ChatMessage message) { } if (message.getContent() != null && !message.getContent().isEmpty()) { - items.add(new VisitorMessageItem(message.getId(), false, message.getContent())); + items.add(VisitorMessageItem.asNewMessage(message)); } } @@ -991,9 +991,9 @@ private void changeDeliveredIndex(List currentChatItems, VisitorMessag break; } else if (!foundDelivered && itemId.equals(messageId)) { foundDelivered = true; - currentChatItems.set(i, new VisitorMessageItem(itemId, true, item.getMessage())); + currentChatItems.set(i, VisitorMessageItem.editDeliveredStatus(item, true)); } else if (item.isShowDelivered()) { - currentChatItems.set(i, new VisitorMessageItem(itemId, false, item.getMessage())); + currentChatItems.set(i, VisitorMessageItem.editDeliveredStatus(item, false)); } } else if (currentChatItem instanceof VisitorAttachmentItem) { VisitorAttachmentItem item = (VisitorAttachmentItem) currentChatItem; @@ -1008,17 +1008,7 @@ private void changeDeliveredIndex(List currentChatItems, VisitorMessag } private void setDelivered(List currentChatItems, int i, VisitorAttachmentItem item, boolean delivered) { - currentChatItems.set( - i, - new VisitorAttachmentItem( - item.getId(), - item.getViewType(), - item.attachmentFile, - item.isFileExists, - item.isDownloading, - delivered - ) - ); + currentChatItems.set(i, VisitorAttachmentItem.editDeliveredStatus(item, delivered)); } private void appendOperatorMessage(List currentChatItems, ChatMessageInternal chatMessageInternal) { @@ -1060,7 +1050,8 @@ private void setLastOperatorItemChatHeadVisibility(List currentChatIte lastItemInView.singleChoiceOptions, lastItemInView.selectedChoiceIndex, lastItemInView.choiceCardImageUrl, - lastItemInView.operatorId + lastItemInView.operatorId, + lastItemInView.getTimestamp() ) ); } else if (lastItem instanceof OperatorAttachmentItem) { @@ -1075,7 +1066,9 @@ private void setLastOperatorItemChatHeadVisibility(List currentChatIte lastItemInView.operatorProfileImgUrl, false, false, - lastItemInView.operatorId + lastItemInView.operatorId, + lastItemInView.getMessageId(), + lastItemInView.getTimestamp() ) ); } else if (lastItem instanceof CustomCardItem) { @@ -1114,7 +1107,9 @@ private void appendOperatorAttachmentItems(List currentChatItems, Chat messageInternal.getOperatorImageUrl().orElse(chatState.operatorProfileImgUrl), false, false, - messageInternal.getOperatorId().orElse(UUID.randomUUID().toString()) + messageInternal.getOperatorId().orElse(UUID.randomUUID().toString()), + message.getId(), + message.getTimestamp() ) ); } @@ -1128,7 +1123,7 @@ private void appendOperatorOrCustomCardItem(List currentChatItems, Cha if (viewType != null) { appendCustomCardItem(currentChatItems, message, viewType); } else { - appendOperatorMessageItem(currentChatItems, messageInternal, message); + appendOperatorMessageItem(currentChatItems, messageInternal); } } } @@ -1141,24 +1136,15 @@ private void appendCustomCardItem(List currentChatItems, ChatMessage m if (customCardShouldShowUseCase.execute(message, customCardType, true)) { currentChatItems.add(new CustomCardItem(message, viewType)); } - - String selectedOptionText = null; - if (message.getAttachment() != null && message.getAttachment() instanceof SingleChoiceAttachment) { - SingleChoiceAttachment singleChoiceAttachment = (SingleChoiceAttachment) message.getAttachment(); - if (singleChoiceAttachment != null) { - selectedOptionText = singleChoiceAttachment.getSelectedOptionText(); - } - } - if (selectedOptionText != null && !selectedOptionText.isEmpty()) { - currentChatItems.add( - new VisitorMessageItem(VisitorMessageItem.CARD_RESPONSE_ID, false, selectedOptionText) - ); + VisitorMessageItem visitorCardResponseItem = VisitorMessageItem.asCardResponseItem(message); + if (visitorCardResponseItem.getMessage() != null && !visitorCardResponseItem.getMessage().isEmpty()) { + currentChatItems.add(visitorCardResponseItem); } } private void appendOperatorMessageItem(List currentChatItems, - ChatMessageInternal messageInternal, - ChatMessage message) { + ChatMessageInternal messageInternal) { + ChatMessage message = messageInternal.getChatMessage(); MessageAttachment messageAttachment = message.getAttachment(); currentChatItems.add( new OperatorMessageItem( @@ -1170,7 +1156,8 @@ private void appendOperatorMessageItem(List currentChatItems, getSingleChoiceAttachmentOptions(messageAttachment), null, getSingleChoiceAttachmentImgUrl(messageAttachment), - messageInternal.getOperatorId().orElse(UUID.randomUUID().toString()) + messageInternal.getOperatorId().orElse(UUID.randomUUID().toString()), + message.getTimestamp() ) ); } @@ -1277,7 +1264,8 @@ public void singleChoiceOptionClicked( choiceCardItem.singleChoiceOptions, optionIndex, choiceCardItem.choiceCardImageUrl, - choiceCardItem.operatorId + choiceCardItem.operatorId, + choiceCardItem.getTimestamp() ); List modifiedItems = new ArrayList<>(chatState.chatItems); @@ -1320,7 +1308,7 @@ public void sendCustomCardResponse(String messageId, String text, String value) } chatItems.add( indexForResponseMessage, - new VisitorMessageItem(VisitorMessageItem.CARD_RESPONSE_ID, false, text) + VisitorMessageItem.asUnsentCardResponse(text) ); emitChatItems(chatState.changeItems(chatItems)); }); @@ -1377,20 +1365,53 @@ private void loadChatHistory() { disposable.add(historyDisposable); } - private void historyLoaded(List messages) { + private synchronized void historyLoaded(List messages) { Logger.d(TAG, "historyLoaded"); List items = new ArrayList<>(chatState.chatItems); + messages = removeDuplicates(items, messages); if (messages != null && !messages.isEmpty()) { for (ChatMessageInternal message : messages) { appendHistoryChatItem(items, message); } - emitChatItems(chatState.historyLoaded(items)); + emitChatItems(chatState.historyLoaded(items.stream().sorted(chatItemComparator).collect(Collectors.toList()))); initGliaEngagementObserving(); - } else { + } else if (!chatState.engagementRequested) { initGliaEngagementObserving(); queueForEngagement(); } + } + + private Comparator chatItemComparator = (chatItem1, chatItem2) -> { + if (chatItem1 instanceof LinkedChatItem && chatItem2 instanceof LinkedChatItem) { + long item1Timestamp = ((LinkedChatItem) chatItem1).getTimestamp(); + long item2Timestamp = ((LinkedChatItem) chatItem2).getTimestamp(); + if (item1Timestamp < item2Timestamp) { + return -1; + } else if (item1Timestamp > item2Timestamp) { + return 1; + } + } + return 0; + }; + + private List removeDuplicates(List oldHistory, List newHistory) { + if (newHistory == null || newHistory.isEmpty()) { + return newHistory; + } + if (oldHistory == null || oldHistory.isEmpty()) { + return newHistory; + } + return newHistory.stream() + .filter(newMessage -> isNewMessage(oldHistory, newMessage.getChatMessage())) + .collect(Collectors.toList()); + } + private boolean isNewMessage(List oldHistory, ChatMessage newMessage) { + return oldHistory.stream() + .filter(oldMessage -> oldMessage instanceof LinkedChatItem) + .map(oldMessage -> (LinkedChatItem) oldMessage) + .filter(oldMessage -> oldMessage.getMessageId() != null) + .noneMatch(oldMessage -> oldMessage.getMessageId().equals(newMessage.getId())); } private void error(Throwable error) { @@ -1411,6 +1432,9 @@ public void newEngagementLoaded(OmnicoreEngagement engagement) { Logger.d(TAG, "unsentMessage sent!"); } emitViewState(chatState.engagementStarted()); + // Loading chat history again on engagement start in case it was an-authenticated visitor that restored ongoing engagement + // Currently there is no direct way to know if Visitor is authenticated. + loadChatHistory(); } @Override @@ -1475,6 +1499,9 @@ public void notificationsDialogDismissed() { public void queueForEngagementStarted() { Logger.d(TAG, "queueForEngagementStarted"); + if (chatState.isOperatorOnline()) { + return; + } observeQueueTicketState(); viewInitQueueing(); } diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/CustomCardItem.java b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/CustomCardItem.java index c17feb212..d22e40e4e 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/CustomCardItem.java +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/CustomCardItem.java @@ -6,11 +6,11 @@ import java.util.Objects; -public class CustomCardItem extends ChatItem { +public class CustomCardItem extends LinkedChatItem { private final ChatMessage message; public CustomCardItem(ChatMessage message, int viewType) { - super(message.getId(), viewType); + super(message.getId(), viewType, message.getId(), message.getTimestamp()); this.message = message; } diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/LinkedChatItem.java b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/LinkedChatItem.java new file mode 100644 index 000000000..a6bf1e0de --- /dev/null +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/LinkedChatItem.java @@ -0,0 +1,21 @@ +package com.glia.widgets.chat.model.history; + +public class LinkedChatItem extends ChatItem { + + private final String messageId; + private final long timestamp; + + public LinkedChatItem(String id, int viewType, String messageId, long timestamp) { + super(id, viewType); + this.messageId = messageId; + this.timestamp = timestamp; + } + + public String getMessageId() { + return messageId; + } + + public long getTimestamp() { + return timestamp; + } +} diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorAttachmentItem.java b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorAttachmentItem.java index d2b206634..1c13473e8 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorAttachmentItem.java +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorAttachmentItem.java @@ -21,9 +21,11 @@ public OperatorAttachmentItem( String operatorProfileImgUrl, boolean isFileExists, boolean isDownloading, - String operatorId + String operatorId, + String messageId, + long timestamp ) { - super(chatItemId, viewType, showChatHead, operatorProfileImgUrl, operatorId); + super(chatItemId, viewType, showChatHead, operatorProfileImgUrl, operatorId, messageId, timestamp); this.attachmentFile = attachmentFile; this.isFileExists = isFileExists; this.isDownloading = isDownloading; diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorChatItem.java b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorChatItem.java index 49838256a..14b1311a4 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorChatItem.java +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorChatItem.java @@ -2,14 +2,14 @@ import java.util.Objects; -public abstract class OperatorChatItem extends ChatItem { +public abstract class OperatorChatItem extends LinkedChatItem { public final boolean showChatHead; public final String operatorProfileImgUrl; public final String operatorId; - protected OperatorChatItem(String id, int viewType, boolean showChatHead, String operatorProfileImgUrl, String operatorId) { - super(id, viewType); + protected OperatorChatItem(String id, int viewType, boolean showChatHead, String operatorProfileImgUrl, String operatorId, String messageId, long timestamp) { + super(id, viewType, messageId, timestamp); this.showChatHead = showChatHead; this.operatorProfileImgUrl = operatorProfileImgUrl; this.operatorId = operatorId; diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorMessageItem.java b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorMessageItem.java index 33d2ad86b..4418d7a9a 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorMessageItem.java +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/OperatorMessageItem.java @@ -23,9 +23,10 @@ public OperatorMessageItem( List singleChoiceOptions, Integer selectedChoiceIndex, String choiceCardImageUrl, - String operatorId + String operatorId, + long timestamp ) { - super(id, ChatAdapter.OPERATOR_MESSAGE_VIEW_TYPE, showChatHead, operatorProfileImgUrl, operatorId); + super(id, ChatAdapter.OPERATOR_MESSAGE_VIEW_TYPE, showChatHead, operatorProfileImgUrl, operatorId, id, timestamp); this.operatorName = operatorName; this.content = content; this.singleChoiceOptions = singleChoiceOptions != null ? Collections.unmodifiableList(singleChoiceOptions) : null; diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/VisitorAttachmentItem.java b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/VisitorAttachmentItem.java index 43d194431..5cde93548 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/VisitorAttachmentItem.java +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/VisitorAttachmentItem.java @@ -3,26 +3,73 @@ import androidx.annotation.NonNull; import com.glia.androidsdk.chat.AttachmentFile; +import com.glia.widgets.chat.adapter.ChatAdapter; import com.glia.widgets.helper.Utils; import java.util.Objects; -public class VisitorAttachmentItem extends ChatItem { +public class VisitorAttachmentItem extends LinkedChatItem { public final AttachmentFile attachmentFile; public final boolean isFileExists; public final boolean isDownloading; public final boolean showDelivered; - public VisitorAttachmentItem(String chatItemId, int viewType, AttachmentFile attachmentFile, - boolean isFileExists, boolean isDownloading, boolean showDelivered) { - super(chatItemId, viewType); + private VisitorAttachmentItem(String chatItemId, int viewType, AttachmentFile attachmentFile, + boolean isFileExists, boolean isDownloading, boolean showDelivered, long timestamp) { + super(chatItemId, viewType, chatItemId, timestamp); this.attachmentFile = attachmentFile; this.isFileExists = isFileExists; this.isDownloading = isDownloading; this.showDelivered = showDelivered; } + public static VisitorAttachmentItem editDeliveredStatus(VisitorAttachmentItem source, boolean isDelivered) { + return new VisitorAttachmentItem( + source.getId(), + source.getViewType(), + source.attachmentFile, + source.isFileExists, + source.isDownloading, + isDelivered, + source.getTimestamp() + ); + } + + public static VisitorAttachmentItem editDownloadedStatus(VisitorAttachmentItem source, boolean isDownloaded) { + return new VisitorAttachmentItem( + source.getId(), + source.getViewType(), + source.attachmentFile, + isDownloaded, + source.isDownloading, + source.showDelivered, + source.getTimestamp() + ); + } + + public static VisitorAttachmentItem editFileStatuses(VisitorAttachmentItem source, boolean doesFileExists, boolean isDownloading) { + return new VisitorAttachmentItem( + source.getId(), + source.getViewType(), + source.attachmentFile, + doesFileExists, + isDownloading, + source.showDelivered, + source.getTimestamp() + ); + } + + public static VisitorAttachmentItem fromAttachmentFile(String messageId, long messageTimestamp, AttachmentFile file) { + int type; + if (file.getContentType().startsWith("image")) { + type = ChatAdapter.VISITOR_IMAGE_VIEW_TYPE; + } else { + type = ChatAdapter.VISITOR_FILE_VIEW_TYPE; + } + return new VisitorAttachmentItem(messageId, type, file, false, false, false, messageTimestamp); + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/VisitorMessageItem.java b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/VisitorMessageItem.java index f4fcf0422..acb3c466e 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/VisitorMessageItem.java +++ b/widgetssdk/src/main/java/com/glia/widgets/chat/model/history/VisitorMessageItem.java @@ -2,23 +2,56 @@ import androidx.annotation.NonNull; +import com.glia.androidsdk.chat.ChatMessage; +import com.glia.androidsdk.chat.SingleChoiceAttachment; import com.glia.widgets.chat.adapter.ChatAdapter; import java.util.Objects; -public class VisitorMessageItem extends ChatItem { +public class VisitorMessageItem extends LinkedChatItem { public final static String HISTORY_ID = "history_id"; public final static String CARD_RESPONSE_ID = "card_response_id"; public final static String UNSENT_MESSAGE_ID = "unsent_message_id"; private final boolean showDelivered; private final String message; - public VisitorMessageItem(String id, boolean showDelivered, String message) { - super(id, ChatAdapter.VISITOR_MESSAGE_TYPE); + private VisitorMessageItem(String id, String messageId, String message, long timestamp, boolean showDelivered) { + super(id, ChatAdapter.VISITOR_MESSAGE_TYPE, messageId, timestamp); this.showDelivered = showDelivered; this.message = message; } + public static VisitorMessageItem asNewMessage(ChatMessage message) { + return new VisitorMessageItem(message.getId(), message.getId(), message.getContent(), message.getTimestamp(), false); + } + + public static VisitorMessageItem asUnsentItem(String unsentMessageText) { + return new VisitorMessageItem(UNSENT_MESSAGE_ID, null, unsentMessageText, System.currentTimeMillis(), false); + } + + public static VisitorMessageItem asHistoryItem(ChatMessage message) { + return new VisitorMessageItem(HISTORY_ID, message.getId(), message.getContent(), message.getTimestamp(), false); + } + + public static VisitorMessageItem asCardResponseItem(ChatMessage message) { + String selectedOptionText = null; + if (message.getAttachment() != null && message.getAttachment() instanceof SingleChoiceAttachment) { + SingleChoiceAttachment singleChoiceAttachment = (SingleChoiceAttachment) message.getAttachment(); + if (singleChoiceAttachment != null) { + selectedOptionText = singleChoiceAttachment.getSelectedOptionText(); + } + } + return new VisitorMessageItem(CARD_RESPONSE_ID, message.getId(), selectedOptionText, message.getTimestamp(), false); + } + + public static VisitorMessageItem asUnsentCardResponse(String unsentResponse) { + return new VisitorMessageItem(CARD_RESPONSE_ID, null, unsentResponse, System.currentTimeMillis(), false); + } + + public static VisitorMessageItem editDeliveredStatus(VisitorMessageItem source, boolean showDelivered) { + return new VisitorMessageItem(source.getId(), source.getMessageId(), source.getMessage(), source.getTimestamp(), showDelivered); + } + public String getMessage() { return message; } diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/GliaOnEngagementEndUseCase.java b/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/GliaOnEngagementEndUseCase.java index 8720bb301..b6b8b3bca 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/GliaOnEngagementEndUseCase.java +++ b/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/GliaOnEngagementEndUseCase.java @@ -74,6 +74,10 @@ public GliaOnEngagementEndUseCase( } public void execute(Listener listener) { + if (this.listener == listener) { + // Already listening + return; + } this.listener = listener; engagementUseCase.execute(this); } diff --git a/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/GliaOnEngagementUseCase.java b/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/GliaOnEngagementUseCase.java index 2f41e9dd5..b7af1e026 100644 --- a/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/GliaOnEngagementUseCase.java +++ b/widgetssdk/src/main/java/com/glia/widgets/core/engagement/domain/GliaOnEngagementUseCase.java @@ -37,6 +37,10 @@ public GliaOnEngagementUseCase( } public void execute(Listener listener) { + if (this.listener == listener) { + // Already listening + return; + } this.listener = listener; gliaRepository.listenForEngagement(this); }