refactor(messages): make message sending async (#15237)
Fixes #12411 Makes message sending async and adds a placeholder "Sending.." message
This commit is contained in:
parent
033bf99974
commit
8ca51c34cc
|
@ -95,6 +95,18 @@ proc init*(self: Controller) =
|
|||
self.unfurlingPlanActiveRequest = ""
|
||||
self.handleUnfurlingPlan(self.unfurlingPlanActiveRequestUnfurlAfter)
|
||||
|
||||
self.events.on(SIGNAL_SENDING_SUCCESS) do(e:Args):
|
||||
let args = MessageSendingSuccess(e)
|
||||
if self.chatId != args.chat.id:
|
||||
return
|
||||
self.delegate.onSendingMessageSuccess()
|
||||
|
||||
self.events.on(SIGNAL_SENDING_FAILED) do(e:Args):
|
||||
let args = MessageSendingFailure(e)
|
||||
if self.chatId != args.chatId:
|
||||
return
|
||||
self.delegate.onSendingMessageFailure()
|
||||
|
||||
proc getChatId*(self: Controller): string =
|
||||
return self.chatId
|
||||
|
||||
|
@ -116,9 +128,9 @@ proc sendImages*(self: Controller,
|
|||
msg: string,
|
||||
replyTo: string,
|
||||
preferredUsername: string = "",
|
||||
linkPreviews: seq[LinkPreview]): string =
|
||||
linkPreviews: seq[LinkPreview]) =
|
||||
self.resetLinkPreviews()
|
||||
self.chatService.sendImages(
|
||||
self.chatService.asyncSendImages(
|
||||
self.chatId,
|
||||
imagePathsAndDataJson,
|
||||
msg,
|
||||
|
@ -134,7 +146,7 @@ proc sendChatMessage*(self: Controller,
|
|||
preferredUsername: string = "",
|
||||
linkPreviews: seq[LinkPreview]) =
|
||||
self.resetLinkPreviews()
|
||||
self.chatService.sendChatMessage(self.chatId,
|
||||
self.chatService.asyncSendChatMessage(self.chatId,
|
||||
msg,
|
||||
replyTo,
|
||||
contentType,
|
||||
|
|
|
@ -22,7 +22,7 @@ method getModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
|
|||
method sendChatMessage*(self: AccessInterface, msg: string, replyTo: string, contentType: int, linkPreviews: seq[LinkPreview]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method sendImages*(self: AccessInterface, imagePathsJson: string, msg: string, replyTo: string, linkPreviews: seq[LinkPreview]): string {.base.} =
|
||||
method sendImages*(self: AccessInterface, imagePathsJson: string, msg: string, replyTo: string, linkPreviews: seq[LinkPreview]) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method requestAddressForTransaction*(self: AccessInterface, fromAddress: string, amount: string, tokenAddress: string) {.base.} =
|
||||
|
@ -138,3 +138,9 @@ method setUrls*(self: AccessInterface, urls: seq[string]) {.base.} =
|
|||
|
||||
method getContactDetails*(self: AccessInterface, contactId: string): ContactDetails {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onSendingMessageSuccess*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onSendingMessageFailure*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
|
|
@ -65,7 +65,7 @@ method getModuleAsVariant*(self: Module): QVariant =
|
|||
proc getChatId*(self: Module): string =
|
||||
return self.controller.getChatId()
|
||||
|
||||
method sendImages*(self: Module, imagePathsAndDataJson: string, msg: string, replyTo: string, linkPreviews: seq[LinkPreview]): string =
|
||||
method sendImages*(self: Module, imagePathsAndDataJson: string, msg: string, replyTo: string, linkPreviews: seq[LinkPreview]) =
|
||||
self.controller.sendImages(imagePathsAndDataJson, msg, replyTo, singletonInstance.userProfile.getPreferredName(), linkPreviews)
|
||||
|
||||
method sendChatMessage*(
|
||||
|
@ -136,3 +136,9 @@ method setUrls*(self: Module, urls: seq[string]) =
|
|||
|
||||
method getContactDetails*(self: Module, contactId: string): ContactDetails =
|
||||
return self.controller.getContactDetails(contactId)
|
||||
|
||||
method onSendingMessageSuccess*(self: Module) =
|
||||
self.view.emitSendingMessageSuccess()
|
||||
|
||||
method onSendingMessageFailure*(self: Module) =
|
||||
self.view.emitSendingMessageFailure()
|
||||
|
|
|
@ -15,10 +15,13 @@ QtObject:
|
|||
linkPreviewModelVariant: QVariant
|
||||
urlsModel: urls_model.Model
|
||||
urlsModelVariant: QVariant
|
||||
sendingInProgress: bool
|
||||
askToEnableLinkPreview: bool
|
||||
emojiReactionsModel: emoji_reactions_model.Model
|
||||
emojiReactionsModelVariant: QVariant
|
||||
|
||||
proc setSendingInProgress*(self: View, value: bool)
|
||||
|
||||
proc delete*(self: View) =
|
||||
self.QObject.delete
|
||||
self.preservedPropertiesVariant.delete
|
||||
|
@ -53,11 +56,13 @@ QtObject:
|
|||
replyTo: string,
|
||||
contentType: int) {.slot.} =
|
||||
# FIXME: Update this when `setText` is async.
|
||||
self.setSendingInProgress(true)
|
||||
self.delegate.setText(msg, false)
|
||||
self.delegate.sendChatMessage(msg, replyTo, contentType, self.linkPreviewModel.getUnfuledLinkPreviews())
|
||||
|
||||
proc sendImages*(self: View, imagePathsAndDataJson: string, msg: string, replyTo: string): string {.slot.} =
|
||||
proc sendImages*(self: View, imagePathsAndDataJson: string, msg: string, replyTo: string) {.slot.} =
|
||||
# FIXME: Update this when `setText` is async.
|
||||
self.setSendingInProgress(true)
|
||||
self.delegate.setText(msg, false)
|
||||
self.delegate.sendImages(imagePathsAndDataJson, msg, replyTo, self.linkPreviewModel.getUnfuledLinkPreviews())
|
||||
|
||||
|
@ -154,3 +159,21 @@ QtObject:
|
|||
QtProperty[QVariant] urlsModel:
|
||||
read = getUrlsModel
|
||||
notify = urlsModelChanged
|
||||
|
||||
proc sendingInProgressChanged(self: View) {.signal.}
|
||||
proc getSendingInProgress*(self: View): bool {.slot.} =
|
||||
return self.sendingInProgress
|
||||
|
||||
QtProperty[bool] sendingInProgress:
|
||||
read = getSendingInProgress
|
||||
notify = sendingInProgressChanged
|
||||
|
||||
proc setSendingInProgress*(self: View, value: bool) =
|
||||
self.sendingInProgress = value
|
||||
self.sendingInProgressChanged()
|
||||
|
||||
proc emitSendingMessageSuccess*(self: View) =
|
||||
self.setSendingInProgress(false)
|
||||
|
||||
proc emitSendingMessageFailure*(self: View) =
|
||||
self.setSendingInProgress(false)
|
||||
|
|
|
@ -79,10 +79,10 @@ proc init*(self: Controller) =
|
|||
self.delegate.onSendingMessageSuccess(args.message)
|
||||
|
||||
self.events.on(SIGNAL_SENDING_FAILED) do(e:Args):
|
||||
let args = ChatArgs(e)
|
||||
let args = MessageSendingFailure(e)
|
||||
if(self.chatId != args.chatId):
|
||||
return
|
||||
self.delegate.onSendingMessageError()
|
||||
self.delegate.onSendingMessageError(args.error)
|
||||
|
||||
self.events.on(SIGNAL_ENVELOPE_SENT) do(e:Args):
|
||||
let args = EnvelopeSentArgs(e)
|
||||
|
|
|
@ -60,7 +60,7 @@ method messagesAdded*(self: AccessInterface, messages: seq[MessageDto]) {.base.}
|
|||
method onSendingMessageSuccess*(self: AccessInterface, message: MessageDto) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onSendingMessageError*(self: AccessInterface) {.base.} =
|
||||
method onSendingMessageError*(self: AccessInterface, error: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onEnvelopeSent*(self: AccessInterface, messagesIds: seq[string]) {.base.} =
|
||||
|
|
|
@ -433,8 +433,8 @@ method onSendingMessageSuccess*(self: Module, message: MessageDto) =
|
|||
self.view.emitSendingMessageSuccessSignal()
|
||||
self.removeNewMessagesMarker()
|
||||
|
||||
method onSendingMessageError*(self: Module) =
|
||||
self.view.emitSendingMessageErrorSignal()
|
||||
method onSendingMessageError*(self: Module, error: string) =
|
||||
self.view.emitSendingMessageErrorSignal(error)
|
||||
|
||||
method onEnvelopeSent*(self: Module, messagesIds: seq[string]) =
|
||||
for messageId in messagesIds:
|
||||
|
|
|
@ -106,10 +106,10 @@ QtObject:
|
|||
proc emitSendingMessageSuccessSignal*(self: View) =
|
||||
self.messageSuccessfullySent()
|
||||
|
||||
proc sendingMessageFailed*(self: View) {.signal.}
|
||||
proc sendingMessageFailed*(self: View, error: string) {.signal.}
|
||||
|
||||
proc emitSendingMessageErrorSignal*(self: View) =
|
||||
self.sendingMessageFailed()
|
||||
proc emitSendingMessageErrorSignal*(self: View, error: string) =
|
||||
self.sendingMessageFailed(error)
|
||||
|
||||
proc deleteMessage*(self: View, messageId: string) {.slot.} =
|
||||
self.delegate.deleteMessage(messageId)
|
||||
|
|
|
@ -151,7 +151,7 @@ proc sendSticker*(
|
|||
replyTo: string,
|
||||
sticker: StickerDto,
|
||||
preferredUsername: string) =
|
||||
self.stickerService.sendSticker(channelId, replyTo, sticker, preferredUsername)
|
||||
self.stickerService.asyncSendSticker(channelId, replyTo, sticker, preferredUsername)
|
||||
|
||||
proc wei2Eth*(self: Controller, price: Stuint[256]): string =
|
||||
eth_utils.wei2Eth(price)
|
||||
|
|
|
@ -62,3 +62,77 @@ proc asyncCheckAllChannelsPermissionsTask(argEncoded: string) {.gcsafe, nimcall.
|
|||
"communityId": arg.communityId,
|
||||
"error": e.msg,
|
||||
})
|
||||
|
||||
type
|
||||
AsyncSendMessageTaskArg = ref object of QObjectTaskArg
|
||||
chatId: string
|
||||
processedMsg: string
|
||||
replyTo: string
|
||||
contentType: int
|
||||
preferredUsername: string
|
||||
communityId: string
|
||||
standardLinkPreviews: JsonNode
|
||||
statusLinkPreviews: JsonNode
|
||||
|
||||
const asyncSendMessageTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncSendMessageTaskArg](argEncoded)
|
||||
try:
|
||||
|
||||
let response = status_chat.sendChatMessage(
|
||||
arg.chatId,
|
||||
arg.processedMsg,
|
||||
arg.replyTo,
|
||||
arg.contentType,
|
||||
arg.preferredUsername,
|
||||
arg.standardLinkPreviews,
|
||||
arg.statusLinkPreviews,
|
||||
arg.communityId)
|
||||
|
||||
arg.finish(%* {
|
||||
"response": response,
|
||||
"chatId": arg.chatId,
|
||||
"error": "",
|
||||
})
|
||||
except Exception as e:
|
||||
arg.finish(%* {
|
||||
"error": e.msg,
|
||||
"chatId": arg.chatId,
|
||||
})
|
||||
|
||||
type
|
||||
AsyncSendImagesTaskArg = ref object of QObjectTaskArg
|
||||
chatId: string
|
||||
imagePathsAndDataJson: string
|
||||
tempDir: string
|
||||
msg: string
|
||||
replyTo: string
|
||||
preferredUsername: string
|
||||
linkPreviews: JsonNode
|
||||
|
||||
const asyncSendImagesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncSendImagesTaskArg](argEncoded)
|
||||
try:
|
||||
var images = Json.decode(arg.imagePathsAndDataJson, seq[string])
|
||||
var imagePaths: seq[string] = @[]
|
||||
|
||||
for imagePathOrSource in images.mitems:
|
||||
let imagePath = image_resizer(imagePathOrSource, 2000, arg.tempDir)
|
||||
if imagePath != "":
|
||||
imagePaths.add(imagePath)
|
||||
|
||||
let response = status_chat.sendImages(arg.chatId, imagePaths, arg.msg, arg.replyTo, arg.preferredUsername,
|
||||
arg.linkPreviews)
|
||||
|
||||
for imagePath in imagePaths:
|
||||
removeFile(imagePath)
|
||||
|
||||
arg.finish(%* {
|
||||
"response": response,
|
||||
"chatId": arg.chatId,
|
||||
"error": "",
|
||||
})
|
||||
except Exception as e:
|
||||
arg.finish(%* {
|
||||
"error": e.msg,
|
||||
"chatId": arg.chatId,
|
||||
})
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import NimQml, Tables, json, sequtils, stew/shims/strformat, chronicles, os, strutils, uuids, base64
|
||||
import NimQml, Tables, json, sequtils, chronicles, os, strutils, uuids, base64
|
||||
import std/[times, os]
|
||||
|
||||
import ../../../app/core/tasks/[qt, threadpool]
|
||||
import ./dto/chat as chat_dto
|
||||
import ../message/dto/message as message_dto
|
||||
import ../message/dto/link_preview
|
||||
import ../message/dto/[link_preview, standard_link_preview, status_link_preview]
|
||||
import ../activity_center/dto/notification as notification_dto
|
||||
import ../community/dto/community as community_dto
|
||||
import ../contacts/service as contact_service
|
||||
|
@ -47,6 +47,10 @@ type
|
|||
chat*: ChatDto
|
||||
message*: MessageDto
|
||||
|
||||
MessageSendingFailure* = ref object of Args
|
||||
chatId*: string
|
||||
error*: string
|
||||
|
||||
MessageArgs* = ref object of Args
|
||||
id*: string
|
||||
channel*: string
|
||||
|
@ -420,61 +424,94 @@ QtObject:
|
|||
error "Error deleting channel", chatId, msg = e.msg
|
||||
return
|
||||
|
||||
proc sendImages*(self: Service,
|
||||
proc asyncSendImages*(self: Service,
|
||||
chatId: string,
|
||||
imagePathsAndDataJson: string,
|
||||
msg: string,
|
||||
replyTo: string,
|
||||
preferredUsername: string = "",
|
||||
linkPreviews: seq[LinkPreview] = @[]): string =
|
||||
result = ""
|
||||
linkPreviews: seq[LinkPreview] = @[]) =
|
||||
|
||||
|
||||
let arg = AsyncSendImagesTaskArg(
|
||||
tptr: asyncSendImagesTask,
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onAsyncSendImagesDone",
|
||||
chatId: chatId,
|
||||
imagePathsAndDataJson: imagePathsAndDataJson,
|
||||
tempDir: TMPDIR,
|
||||
msg: msg,
|
||||
replyTo: replyTo,
|
||||
preferredUsername: preferredUsername,
|
||||
linkPreviews: %linkPreviews,
|
||||
)
|
||||
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc onAsyncSendImagesDone*(self: Service, rpcResponseJson: string) {.slot.} =
|
||||
let rpcResponseObj = rpcResponseJson.parseJson
|
||||
try:
|
||||
var images = Json.decode(imagePathsAndDataJson, seq[string])
|
||||
let base64JPGPrefix = "data:image/jpeg;base64,"
|
||||
var imagePaths: seq[string] = @[]
|
||||
|
||||
for imagePathOrSource in images.mitems:
|
||||
let imagePath = image_resizer(imagePathOrSource, 2000, TMPDIR)
|
||||
if imagePath != "":
|
||||
imagePaths.add(imagePath)
|
||||
let errorString = rpcResponseObj{"error"}.getStr()
|
||||
if errorString != "":
|
||||
raise newException(CatchableError, errorString)
|
||||
|
||||
let response = status_chat.sendImages(chatId, imagePaths, msg, replyTo, preferredUsername, linkPreviews)
|
||||
let rpcResponse = Json.decode($rpcResponseObj["response"], RpcResponse[JsonNode])
|
||||
|
||||
for imagePath in imagePaths:
|
||||
removeFile(imagePath)
|
||||
|
||||
discard self.processMessengerResponse(response)
|
||||
discard self.processMessengerResponse(rpcResponse)
|
||||
except Exception as e:
|
||||
error "Error sending images", msg = e.msg
|
||||
result = fmt"Error sending images: {e.msg}"
|
||||
self.events.emit(SIGNAL_SENDING_FAILED, MessageSendingFailure(chatId: rpcResponseObj["chatId"].getStr, error: e.msg))
|
||||
|
||||
proc sendChatMessage*(
|
||||
self: Service,
|
||||
chatId: string,
|
||||
msg: string,
|
||||
replyTo: string,
|
||||
contentType: int,
|
||||
preferredUsername: string = "",
|
||||
linkPreviews: seq[LinkPreview] = @[],
|
||||
communityId: string = "") =
|
||||
proc asyncSendChatMessage*(self: Service,
|
||||
chatId: string,
|
||||
msg: string,
|
||||
replyTo: string,
|
||||
contentType: int,
|
||||
preferredUsername: string = "",
|
||||
linkPreviews: seq[LinkPreview] = @[],
|
||||
communityId: string = "") =
|
||||
try:
|
||||
let allKnownContacts = self.contactService.getContactsByGroup(ContactsGroup.AllKnownContacts)
|
||||
let processedMsg = message_common.replaceMentionsWithPubKeys(allKnownContacts, msg)
|
||||
|
||||
let response = status_chat.sendChatMessage(
|
||||
chatId,
|
||||
processedMsg,
|
||||
replyTo,
|
||||
contentType,
|
||||
preferredUsername,
|
||||
linkPreviews,
|
||||
communityId) # Only send a community ID for the community invites
|
||||
let (standardLinkPreviews, statusLinkPreviews) = extractLinkPreviewsLists(linkPreviews)
|
||||
|
||||
let (chats, messages) = self.processMessengerResponse(response)
|
||||
if chats.len == 0 or messages.len == 0:
|
||||
self.events.emit(SIGNAL_SENDING_FAILED, ChatArgs(chatId: chatId))
|
||||
let arg = AsyncSendMessageTaskArg(
|
||||
tptr: asyncSendMessageTask,
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onAsyncSendMessageDone",
|
||||
chatId: chatId,
|
||||
processedMsg: processedMsg,
|
||||
replyTo: replyTo,
|
||||
contentType: contentType,
|
||||
preferredUsername: preferredUsername,
|
||||
communityId: communityId, # Only send a community ID for the community invites
|
||||
standardLinkPreviews: %standardLinkPreviews,
|
||||
statusLinkPreviews: %statusLinkPreviews,
|
||||
)
|
||||
|
||||
self.threadpool.start(arg)
|
||||
except Exception as e:
|
||||
error "Error sending message", msg = e.msg
|
||||
self.events.emit(SIGNAL_SENDING_FAILED, MessageSendingFailure(chatId: chatId, error: e.msg))
|
||||
|
||||
proc onAsyncSendMessageDone*(self: Service, rpcResponseJson: string) {.slot.} =
|
||||
let rpcResponseObj = rpcResponseJson.parseJson
|
||||
try:
|
||||
|
||||
let errorString = rpcResponseObj{"error"}.getStr()
|
||||
if errorString != "":
|
||||
raise newException(CatchableError, errorString)
|
||||
|
||||
let rpcResponse = Json.decode($rpcResponseObj["response"], RpcResponse[JsonNode])
|
||||
|
||||
let (chats, messages) = self.processMessengerResponse(rpcResponse)
|
||||
if chats.len == 0 or messages.len == 0:
|
||||
raise newException(CatchableError, "no chat or message returned")
|
||||
except Exception as e:
|
||||
error "Error sending message", msg = e.msg
|
||||
self.events.emit(SIGNAL_SENDING_FAILED, MessageSendingFailure(chatId: rpcResponseObj["chatId"].getStr, error: e.msg))
|
||||
|
||||
proc requestAddressForTransaction*(self: Service, chatId: string, fromAddress: string, amount: string, tokenAddress: string) =
|
||||
try:
|
||||
|
|
|
@ -93,3 +93,38 @@ proc installStickerPackTask(argEncoded: string) {.gcsafe, nimcall.} =
|
|||
error "Error installing stickers", message = getCurrentExceptionMsg()
|
||||
let tpl: tuple[packId: string, installed: bool] = (arg.packId, installed)
|
||||
arg.finish(tpl)
|
||||
|
||||
type
|
||||
AsyncSendStickerTaskArg = ref object of QObjectTaskArg
|
||||
chatId: string
|
||||
replyTo: string
|
||||
stickerHash: string
|
||||
stickerPackId: string
|
||||
preferredUsername: string
|
||||
|
||||
const asyncSendStickerTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncSendStickerTaskArg](argEncoded)
|
||||
try:
|
||||
let response = status_chat.sendChatMessage(
|
||||
arg.chatId,
|
||||
"You can see a nice sticker here!",
|
||||
arg.replyTo,
|
||||
ContentType.Sticker.int,
|
||||
arg.preferredUsername,
|
||||
standardLinkPreviews = JsonNode(),
|
||||
statusLinkPreviews = JsonNode(),
|
||||
communityId = "", # communityId is not necessary when sending a sticker
|
||||
arg.stickerHash,
|
||||
arg.stickerPackId,
|
||||
)
|
||||
|
||||
arg.finish(%* {
|
||||
"response": response,
|
||||
"chatId": arg.chatId,
|
||||
"error": "",
|
||||
})
|
||||
except Exception as e:
|
||||
arg.finish(%* {
|
||||
"error": e.msg,
|
||||
"chatId": arg.chatId,
|
||||
})
|
||||
|
|
|
@ -345,25 +345,39 @@ QtObject:
|
|||
except RpcException:
|
||||
error "Error removing installed sticker", message = getCurrentExceptionMsg()
|
||||
|
||||
proc sendSticker*(
|
||||
proc asyncSendSticker*(
|
||||
self: Service,
|
||||
chatId: string,
|
||||
replyTo: string,
|
||||
sticker: StickerDto,
|
||||
preferredUsername: string) =
|
||||
let response = status_chat.sendChatMessage(
|
||||
chatId,
|
||||
"Update to latest version to see a nice sticker here!",
|
||||
replyTo,
|
||||
ContentType.Sticker.int,
|
||||
preferredUsername,
|
||||
linkPreviews = @[],
|
||||
communityId = "", # communityId is not necessary when sending a sticker
|
||||
sticker.hash,
|
||||
sticker.packId)
|
||||
discard self.chatService.processMessengerResponse(response)
|
||||
let arg = AsyncSendStickerTaskArg(
|
||||
tptr: asyncSendStickerTask,
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onAsyncSendStickerDone",
|
||||
chatId: chatId,
|
||||
replyTo: replyTo,
|
||||
stickerHash: sticker.hash,
|
||||
stickerPackId: sticker.packId,
|
||||
preferredUsername: preferredUsername,
|
||||
)
|
||||
|
||||
self.threadpool.start(arg)
|
||||
self.addStickerToRecent(sticker)
|
||||
|
||||
proc onAsyncSendStickerDone*(self: Service, rpcResponseJson: string) {.slot.} =
|
||||
let rpcResponseObj = rpcResponseJson.parseJson
|
||||
try:
|
||||
let errorString = rpcResponseObj{"error"}.getStr()
|
||||
if errorString != "":
|
||||
raise newException(CatchableError, errorString)
|
||||
|
||||
let rpcResponse = Json.decode($rpcResponseObj["response"], RpcResponse[JsonNode])
|
||||
discard self.chatService.processMessengerResponse(rpcResponse)
|
||||
except Exception as e:
|
||||
error "Error sending sticker", msg = e.msg
|
||||
self.events.emit(SIGNAL_SENDING_FAILED, ChatArgs(chatId: rpcResponseObj["chatId"].getStr))
|
||||
|
||||
proc removeRecentStickers*(self: Service, packId: string) =
|
||||
self.recentStickers.keepItIf(it.packId != packId)
|
||||
|
||||
|
|
|
@ -2,9 +2,6 @@ import json, sequtils, sugar, strutils
|
|||
import core, ../app_service/common/utils
|
||||
import response_type
|
||||
import interpret/cropped_image
|
||||
import ../app_service/service/message/dto/link_preview
|
||||
import ../app_service/service/message/dto/standard_link_preview
|
||||
import ../app_service/service/message/dto/status_link_preview
|
||||
|
||||
export response_type
|
||||
|
||||
|
@ -59,12 +56,12 @@ proc sendChatMessage*(
|
|||
replyTo: string,
|
||||
contentType: int,
|
||||
preferredUsername: string = "",
|
||||
linkPreviews: seq[LinkPreview],
|
||||
standardLinkPreviews: JsonNode,
|
||||
statusLinkPreviews: JsonNode,
|
||||
communityId: string = "",
|
||||
stickerHash: string = "",
|
||||
stickerPack: string = "0",
|
||||
): RpcResponse[JsonNode] =
|
||||
let (standardLinkPreviews, statusLinkPreviews) = extractLinkPreviewsLists(linkPreviews)
|
||||
result = callPrivateRPC("sendChatMessage".prefix, %* [
|
||||
{
|
||||
"chatId": chatId,
|
||||
|
@ -87,7 +84,7 @@ proc sendImages*(chatId: string,
|
|||
msg: string,
|
||||
replyTo: string,
|
||||
preferredUsername: string,
|
||||
linkPreviews: seq[LinkPreview],
|
||||
linkPreviews: JsonNode,
|
||||
): RpcResponse[JsonNode] =
|
||||
let imagesJson = %* images.map(image => %*
|
||||
{
|
||||
|
|
|
@ -80,6 +80,8 @@ Item {
|
|||
id: d
|
||||
readonly property var activeChatContentModule: d.getChatContentModule(root.activeChatId)
|
||||
|
||||
property bool sendingInProgress: !!d.activeChatContentModule? d.activeChatContentModule.inputAreaModule.sendingInProgress : false
|
||||
|
||||
readonly property var urlsList: {
|
||||
if (!d.activeChatContentModule) {
|
||||
return
|
||||
|
@ -276,6 +278,7 @@ Item {
|
|||
&& root.rootStore.sectionDetails.joined
|
||||
&& !root.rootStore.sectionDetails.amIBanned
|
||||
&& root.rootStore.isUserAllowedToSendMessage
|
||||
&& !d.sendingInProgress
|
||||
}
|
||||
|
||||
store: root.rootStore
|
||||
|
@ -298,6 +301,9 @@ Item {
|
|||
if (!root.canPost) {
|
||||
return qsTr("Sorry, you don't have permissions to post in this channel.")
|
||||
}
|
||||
if (d.sendingInProgress) {
|
||||
return qsTr("Sending...")
|
||||
}
|
||||
return root.rootStore.chatInputPlaceHolderText
|
||||
} else {
|
||||
return "";
|
||||
|
@ -339,19 +345,19 @@ Item {
|
|||
return
|
||||
}
|
||||
|
||||
if (root.rootStore.sendMessage(d.activeChatContentModule.getMyChatId(),
|
||||
event,
|
||||
chatInput.getTextWithPublicKeys(),
|
||||
chatInput.isReply? chatInput.replyMessageId : "",
|
||||
chatInput.fileUrlsAndSources
|
||||
))
|
||||
{
|
||||
Global.playSendMessageSound()
|
||||
if (root.rootStore.sendMessage(d.activeChatContentModule.getMyChatId(),
|
||||
event,
|
||||
chatInput.getTextWithPublicKeys(),
|
||||
chatInput.isReply? chatInput.replyMessageId : "",
|
||||
chatInput.fileUrlsAndSources
|
||||
))
|
||||
{
|
||||
Global.playSendMessageSound()
|
||||
|
||||
chatInput.setText("")
|
||||
chatInput.textInput.textFormat = TextEdit.PlainText;
|
||||
chatInput.textInput.textFormat = TextEdit.RichText;
|
||||
}
|
||||
chatInput.setText("")
|
||||
chatInput.textInput.textFormat = TextEdit.PlainText;
|
||||
chatInput.textInput.textFormat = TextEdit.RichText;
|
||||
}
|
||||
}
|
||||
|
||||
onKeyUpPress: {
|
||||
|
|
|
@ -86,7 +86,8 @@ Item {
|
|||
chatLogView.positionViewAtBeginning()
|
||||
}
|
||||
|
||||
function onSendingMessageFailed() {
|
||||
function onSendingMessageFailed(error) {
|
||||
sendingMsgFailedPopup.error = error
|
||||
sendingMsgFailedPopup.open()
|
||||
}
|
||||
|
||||
|
@ -377,9 +378,11 @@ Item {
|
|||
}
|
||||
|
||||
MessageDialog {
|
||||
property string error
|
||||
|
||||
id: sendingMsgFailedPopup
|
||||
standardButtons: StandardButton.Ok
|
||||
text: qsTr("Failed to send message.")
|
||||
text: qsTr("Failed to send message.\n" + error)
|
||||
icon: StandardIcon.Critical
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue