feat: retry sending messages

This commit is contained in:
Richard Ramos 2020-07-14 11:35:21 -04:00 committed by Iuri Matias
parent f3f0e39131
commit f9335c0969
17 changed files with 108 additions and 10 deletions

View File

@ -6,7 +6,7 @@ import ../../signals/types
import ../../status/libstatus/types as status_types
import ../../status/libstatus/wallet as status_wallet
import ../../status/[chat, contacts, status]
import view, views/channels_list
import view, views/channels_list, views/message_list
from eth/common/utils import parseAddress
@ -63,5 +63,6 @@ method onSignal(self: ChatController, data: Signal) =
of SignalType.Message: handleMessage(self, MessageSignal(data))
of SignalType.DiscoverySummary: handleDiscoverySummary(self, DiscoverySummarySignal(data))
of SignalType.EnvelopeSent: handleEnvelopeSent(self, EnvelopeSentSignal(data))
of SignalType.EnvelopeExpired: handleEnvelopeExpired(self, EnvelopeExpiredSignal(data))
else:
warn "Unhandled signal received", signalType = data.signalType

View File

@ -8,3 +8,9 @@ proc handleDiscoverySummary(self: ChatController, data: DiscoverySummarySignal)
proc handleEnvelopeSent(self: ChatController, data: EnvelopeSentSignal) =
self.status.messages.updateStatus(data.messageIds)
proc handleEnvelopeExpired(self: ChatController, data: EnvelopeExpiredSignal) =
for messageId in data.messageIds:
if self.status.messages.messages.hasKey(messageId):
let chatId = self.status.messages.messages[messageId].chatId
self.view.messageList[chatId].checkTimeout(messageId)

View File

@ -23,7 +23,7 @@ QtObject:
chats*: ChannelsList
currentSuggestions*: SuggestionsList
callResult: string
messageList: Table[string, ChatMessageList]
messageList*: Table[string, ChatMessageList]
activeChannel*: ChatItemView
stickerPacks*: StickerPackList
recentStickers*: StickerList
@ -98,6 +98,14 @@ QtObject:
self.status.chat.sendMessage(self.activeChannel.id, m, replyTo)
proc verifyMessageSent*(self: ChatsView, data: string) {.slot.} =
let messageData = data.parseJson
self.messageList[messageData["chatId"].getStr].checkTimeout(messageData["id"].getStr)
proc resendMessage*(self: ChatsView, chatId: string, messageId: string) {.slot.} =
self.status.chat.resendMessage(messageId)
self.messageList[chatId].resetTimeOut(messageId)
proc activeChannelChanged*(self: ChatsView) {.signal.}
proc userNameOrAlias*(self: ChatsView, pubKey: string): string {.slot.} =

View File

@ -1,4 +1,4 @@
import NimQml, Tables
import NimQml, Tables, sets
import ../../../status/status
import ../../../status/accounts
import ../../../status/chat
@ -26,6 +26,7 @@ type
PlainText = UserRole + 15
Index = UserRole + 16
ImageUrls = UserRole + 17
Timeout = UserRole + 18
QtObject:
type
@ -33,10 +34,12 @@ QtObject:
messages*: seq[Message]
status: Status
messageIndex: Table[string, int]
timedoutMessages: HashSet[string]
proc delete(self: ChatMessageList) =
self.messages = @[]
self.messageIndex = initTable[string, int]()
self.timedoutMessages = initHashSet[string]()
self.QAbstractListModel.delete
proc setup(self: ChatMessageList) =
@ -53,9 +56,30 @@ QtObject:
new(result, delete)
result.messages = @[result.chatIdentifier(chatId)]
result.messageIndex = initTable[string, int]()
result.timedoutMessages = initHashSet[string]()
result.status = status
result.setup
proc resetTimeOut*(self: ChatMessageList, messageId: string) =
if not self.messageIndex.hasKey(messageId): return
let msgIdx = self.messageIndex[messageId]
self.timedoutMessages.excl(messageId)
let topLeft = self.createIndex(msgIdx, 0, nil)
let bottomRight = self.createIndex(msgIdx, 0, nil)
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Timeout.int])
proc checkTimeout*(self: ChatMessageList, messageId: string) =
if not self.messageIndex.hasKey(messageId): return
let msgIdx = self.messageIndex[messageId]
if self.messages[msgIdx].outgoingStatus != "sending": return
self.timedoutMessages.incl(messageId)
let topLeft = self.createIndex(msgIdx, 0, nil)
let bottomRight = self.createIndex(msgIdx, 0, nil)
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Timeout.int])
method rowCount(self: ChatMessageList, index: QModelIndex = nil): int =
return self.messages.len
@ -84,6 +108,7 @@ QtObject:
of ChatMessageRoles.ResponseTo: result = newQVariant(message.responseTo)
of ChatMessageRoles.Index: result = newQVariant(index.row)
of ChatMessageRoles.ImageUrls: result = newQVariant(message.imageUrls)
of ChatMessageRoles.Timeout: result = newQVariant(self.timedoutMessages.contains(message.id))
method roleNames(self: ChatMessageList): Table[int, string] =
{
@ -103,7 +128,8 @@ QtObject:
ChatMessageRoles.OutgoingStatus.int: "outgoingStatus",
ChatMessageRoles.ResponseTo.int: "responseTo",
ChatMessageRoles.Index.int: "index",
ChatMessageRoles.ImageUrls.int: "imageUrls"
ChatMessageRoles.ImageUrls.int: "imageUrls",
ChatMessageRoles.Timeout.int: "timeout"
}.toTable
proc getMessageIndex(self: ChatMessageList, messageId: string): int {.slot.} =

View File

@ -123,6 +123,7 @@ proc mainProc() =
signalController.addSubscriber(SignalType.Message, profile)
signalController.addSubscriber(SignalType.DiscoverySummary, chat)
signalController.addSubscriber(SignalType.EnvelopeSent, chat)
signalController.addSubscriber(SignalType.EnvelopeExpired, chat)
signalController.addSubscriber(SignalType.NodeLogin, login)
signalController.addSubscriber(SignalType.NodeLogin, onboarding)
signalController.addSubscriber(SignalType.NodeStopped, login)

View File

@ -1,6 +1,6 @@
import NimQml, tables, json, chronicles, strutils, json_serialization
import ../status/libstatus/types as status_types
import types, messages, discovery, whisperFilter, envelopes
import types, messages, discovery, whisperFilter, envelopes, expired
logScope:
topics = "signals"
@ -59,6 +59,8 @@ QtObject:
signal = messages.fromEvent(jsonSignal)
of SignalType.EnvelopeSent:
signal = envelopes.fromEvent(jsonSignal)
of SignalType.EnvelopeExpired:
signal = expired.fromEvent(jsonSignal)
of SignalType.WhisperFilterAdded:
signal = whisperFilter.fromEvent(jsonSignal)
of SignalType.Wallet:

10
src/signals/expired.nim Normal file
View File

@ -0,0 +1,10 @@
import json
import types
proc fromEvent*(jsonSignal: JsonNode): Signal =
var signal:EnvelopeExpiredSignal = EnvelopeExpiredSignal()
if jsonSignal["event"].kind != JNull and jsonSignal["event"].hasKey("ids") and jsonSignal["event"]["ids"].kind != JNull:
for messageId in jsonSignal["event"]["ids"]:
signal.messageIds.add(messageId.getStr)
result = signal

View File

@ -20,6 +20,9 @@ type WalletSignal* = ref object of Signal
type EnvelopeSentSignal* = ref object of Signal
messageIds*: seq[string]
type EnvelopeExpiredSignal* = ref object of Signal
messageIds*: seq[string]
# Override this method
method onSignal*(self: SignalSubscriber, data: Signal) {.base.} =
error "onSignal must be overriden in controller. Signal is unhandled"

View File

@ -287,3 +287,6 @@ proc kickGroupMember*(self: ChatModel, chatId: string, pubKey: string) =
proc makeAdmin*(self: ChatModel, chatId: string, pubKey: string) =
var response = status_chat.makeAdmin(chatId, pubKey)
self.emitUpdate(response)
proc resendMessage*(self: ChatModel, messageId: string) =
discard status_chat.reSendChatMessage(messageId)

View File

@ -128,3 +128,6 @@ proc makeAdmin*(chatId: string, pubKey: string): string =
proc updateOutgoingMessageStatus*(messageId: string, status: string): string =
result = callPrivateRPC("updateMessageOutgoingStatus".prefix, %* [messageId, status])
# TODO: handle errors
proc reSendChatMessage*(messageId: string): string =
result = callPrivateRPC("reSendChatMessage".prefix, %*[messageId])

View File

@ -2,9 +2,9 @@ import tables, sets, eventemitter
import libstatus/chat
type
MessageDetails = object
status: string
chatId: string
MessageDetails* = object
status*: string
chatId*: string
MessagesModel* = ref object
events*: EventEmitter

View File

@ -155,6 +155,7 @@ ScrollView {
}
appSettings: scrollView.appSettings
scrollToBottom: scrollView.scrollToBottom
timeout: model.timeout
}
}
}

View File

@ -19,6 +19,7 @@ Item {
property string responseTo: ""
property string messageId: ""
property int prevMessageIndex: -1
property bool timeout: false
property string authorCurrentMsg: "authorCurrentMsg"
property string authorPrevMsg: "authorPrevMsg"

View File

@ -91,12 +91,17 @@ Item {
SentMessage {
id: sentMessage
visible: isCurrentUser && outgoingStatus != "sent"
anchors.verticalCenter: chatTime.verticalCenter
anchors.left: chatTime.right
anchors.rightMargin: 5
}
Retry {
id: retry
anchors.right: chatTime.right
anchors.rightMargin: 5
}
Loader {
id: imageLoader
active: showImages

View File

@ -120,6 +120,15 @@ Item {
anchors.right: chatTime.left
anchors.rightMargin: 5
}
Retry {
id: retry
anchors.top: chatTime.top
anchors.right: chatTime.left
anchors.rightMargin: 5
anchors.bottomMargin: Style.current.padding
}
Loader {
id: imageLoader
active: showImages

View File

@ -0,0 +1,19 @@
import QtQuick 2.3
import "../../../../../shared"
import "../../../../../imports"
StyledText {
id: retryLbl
color: Style.current.red
text: qsTr("Resend")
font.pixelSize: 12
visible: isCurrentUser && timeout
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
onClicked: {
chatsModel.resendMessage(chatId, messageId)
}
}
}

View File

@ -4,7 +4,7 @@ import "../../../../../imports"
StyledText {
id: sentMessage
visible: isCurrentUser && (isEmoji || isMessage || isSticker)
visible: isCurrentUser && !timeout && (isEmoji || isMessage || isSticker)
color: Style.current.darkGrey
text: outgoingStatus == "sent" ?
//% "Sent"