fix(@chat): display link urls

This commit is contained in:
Anthony Laibe 2022-01-25 13:56:53 +01:00 committed by Sale Djenic
parent 219d7b46c0
commit 16225a3af9
18 changed files with 154 additions and 56 deletions

View File

@ -89,7 +89,8 @@ method convertToItems*[T](
ContentType(n.message.contentType),
n.message.messageType,
self.controller.decodeContentHash(n.message.sticker.hash),
n.message.sticker.pack
n.message.sticker.pack,
n.message.links,
))
return notification_item.initItem(

View File

@ -136,6 +136,10 @@ method init*(self: Controller) =
self.events.on(SignalType.HistoryRequestFailed.event) do(e:Args):
self.delegate.setLoadingHistoryMessagesInProgress(false)
self.events.on(SIGNAL_MESSAGE_LINK_PREVIEW_DATA_LOADED) do(e: Args):
let args = LinkPreviewDataArgs(e)
self.delegate.onPreviewDataLoaded(args.response)
method getMySectionId*(self: Controller): string =
return self.sectionId
@ -190,3 +194,6 @@ method decodeContentHash*(self: Controller, hash: string): string =
method editMessage*(self: Controller, messageId: string, updatedMsg: string) =
self.messageService.editMessage(messageId, updatedMsg)
method getLinkPreviewData*(self: Controller, link: string, uuid: string): string =
self.messageService.asyncGetLinkPreviewData(link, uuid)

View File

@ -63,9 +63,11 @@ method getMessageDetails*(self: AccessInterface, messageId: string):
method deleteMessage*(self: AccessInterface, messageId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method decodeContentHash*(self: AccessInterface, hash: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method editMessage*(self: AccessInterface, messageId: string, updatedMsg: string) {.base.} =
raise newException(ValueError, "No implementation available")
method getLinkPreviewData*(self: AccessInterface, link: string, uuid: string): string {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -90,7 +90,8 @@ proc createChatIdentifierItem(self: Module): Item =
ContentType.ChatIdentifier,
messageType = -1,
sticker = "",
stickerPack = -1
stickerPack = -1,
@[],
)
method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: seq[ReactionDto],
@ -120,7 +121,8 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
m.contentType.ContentType,
m.messageType,
sticker = self.controller.decodeContentHash(m.sticker.hash),
m.sticker.pack
m.sticker.pack,
m.links,
)
for r in reactions:
@ -177,7 +179,8 @@ method messageAdded*(self: Module, message: MessageDto) =
message.contentType.ContentType,
message.messageType,
sticker = self.controller.decodeContentHash(message.sticker.hash),
message.sticker.pack
message.sticker.pack,
message.links
)
self.view.model().insertItemBasedOnTimestamp(item)
@ -308,3 +311,9 @@ method updateChatIdentifier*(self: Module) =
method setLoadingHistoryMessagesInProgress*(self: Module, isLoading: bool) =
self.view.setLoadingHistoryMessagesInProgress(isLoading)
method getLinkPreviewData*(self: Module, link: string, uuid: string): string =
return self.controller.getLinkPreviewData(link, uuid)
method onPreviewDataLoaded*(self: Module, previewData: string) =
self.view.onPreviewDataLoaded(previewData)

View File

@ -33,3 +33,9 @@ method editMessage*(self: AccessInterface, messageId: string, updatedMsg: string
method onHistoryCleared*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getLinkPreviewData*(self: AccessInterface, link: string, uuid: string): string {.base.} =
raise newException(ValueError, "No implementation available")
method onPreviewDataLoaded*(self: AccessInterface, previewData: string) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -123,3 +123,11 @@ QtObject:
proc editMessage*(self: View, messageId: string, updatedMsg: string) {.slot.} =
self.delegate.editMessage(messageId, updatedMsg)
proc getLinkPreviewData*(self: View, link: string, uuid: string): string {.slot.} =
return self.delegate.getLinkPreviewData(link, uuid)
proc linkPreviewDataWasReceived*(self: View, previewData: string) {.signal.}
proc onPreviewDataLoaded*(self: View, previewData: string) {.slot.} =
self.linkPreviewDataWasReceived(previewData)

View File

@ -151,7 +151,8 @@ proc buildPinnedMessageItem(self: Module, messageId: string, actionInitiatedBy:
m.contentType.ContentType,
m.messageType,
self.controller.decodeContentHash(m.sticker.hash),
m.sticker.pack
m.sticker.pack,
m.links,
)
item.pinned = true
item.pinnedBy = actionInitiatedBy

View File

@ -31,6 +31,7 @@ type
pinnedBy: string
editMode: bool
isEdited: bool
links: seq[string]
proc initItem*(
id,
@ -50,7 +51,8 @@ proc initItem*(
contentType: ContentType,
messageType: int,
sticker: string,
stickerPack: int
stickerPack: int,
links: seq[string],
): Item =
result = Item()
result.id = id
@ -75,6 +77,7 @@ proc initItem*(
result.stickerPack = stickerPack
result.editMode = false
result.isEdited = false
result.links = links
proc `$`*(self: Item): string =
result = fmt"""Item(
@ -97,6 +100,7 @@ proc `$`*(self: Item): string =
messageReactions: [{$self.reactionsModel}],
editMode:{$self.editMode},
isEdited:{$self.isEdited}
links:{$self.links}
)"""
proc id*(self: Item): string {.inline.} =
@ -199,6 +203,9 @@ proc addReaction*(self: Item, emojiId: EmojiId, didIReactWithThisEmoji: bool, us
proc removeReaction*(self: Item, emojiId: EmojiId, reactionId: string, didIRemoveThisReaction: bool) =
self.reactionsModel.removeReaction(emojiId, reactionId, didIRemoveThisReaction)
proc links*(self: Item): seq[string] {.inline.} =
self.links
proc toJsonNode*(self: Item): JsonNode =
result = %* {
"id": self.id,
@ -224,7 +231,8 @@ proc toJsonNode*(self: Item): JsonNode =
"pinned": self.pinned,
"pinnedBy": self.pinnedBy,
"editMode": self.editMode,
"isEdited": self.isEdited
"isEdited": self.isEdited,
"links": self.links
}
proc editMode*(self: Item): bool {.inline.} =

View File

@ -30,6 +30,7 @@ type
Reactions
EditMode
IsEdited
Links
QtObject:
type
@ -89,7 +90,8 @@ QtObject:
ModelRole.PinnedBy.int:"pinnedBy",
ModelRole.Reactions.int:"reactions",
ModelRole.EditMode.int: "editMode",
ModelRole.IsEdited.int: "isEdited"
ModelRole.IsEdited.int: "isEdited",
ModelRole.Links.int: "links",
}.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant =
@ -153,6 +155,8 @@ QtObject:
result = newQVariant(item.editMode)
of ModelRole.IsEdited:
result = newQVariant(item.isEdited)
of ModelRole.Links:
result = newQVariant(item.links.join(" "))
proc findIndexForMessageId(self: Model, messageId: string): int =
for i in 0 ..< self.items.len:

View File

@ -1,6 +1,9 @@
include ../../common/json_utils
include ../../../app/core/tasks/common
import status/statusgo_backend_new/chat as status_go_chat
#################################################
# Async load messages
#################################################
@ -142,3 +145,32 @@ const asyncMarkCertainMessagesReadTask: Task = proc(argEncoded: string) {.gcsafe
}
arg.finish(responseJson)
#################################################
#################################################
# Async GetLinkPreviewData
#################################################
type
AsyncGetLinkPreviewDataTaskArg = ref object of QObjectTaskArg
link: string
uuid: string
const asyncGetLinkPreviewDataTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncGetLinkPreviewDataTaskArg](argEncoded)
var success = true
var result: JsonNode = %* {}
try:
let response = status_go_chat.getLinkPreviewData(arg.link)
result = response.result
except:
success = false
let responseJson = %*{
"link": arg.link,
"uuid": arg.uuid,
"success": success,
"result": result,
}
arg.finish(responseJson)

View File

@ -35,6 +35,7 @@ const SIGNAL_MESSAGE_REACTION_REMOVED* = "messageReactionRemoved"
const SIGNAL_MESSAGE_REACTION_FROM_OTHERS* = "messageReactionFromOthers"
const SIGNAL_MESSAGE_DELETION* = "messageDeleted"
const SIGNAL_MESSAGE_EDITED* = "messageEdited"
const SIGNAL_MESSAGE_LINK_PREVIEW_DATA_LOADED* = "messageLinkPreviewDataLoaded"
include async_tasks
@ -77,6 +78,9 @@ type
chatId*: string
message*: MessageDto
LinkPreviewDataArgs* = ref object of Args
response*: string
QtObject:
type Service* = ref object of QObject
events: EventEmitter
@ -530,6 +534,19 @@ QtObject:
proc getNumOfPinnedMessages*(self: Service, chatId: string): int =
return self.numOfPinnedMessagesPerChat[chatId]
proc onAsyncGetLinkPreviewData*(self: Service, response: string) {.slot.} =
self.events.emit(SIGNAL_MESSAGE_LINK_PREVIEW_DATA_LOADED, LinkPreviewDataArgs(response: response))
proc asyncGetLinkPreviewData*(self: Service, link: string, uuid: string) =
let arg = AsyncGetLinkPreviewDataTaskArg(
tptr: cast[ByteAddress](asyncGetLinkPreviewDataTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncGetLinkPreviewData",
link: link,
uuid: uuid
)
self.threadpool.start(arg)
# See render-inline in status-react/src/status_im/ui/screens/chat/message/message.cljs
proc renderInline(self: Service, parsedTextChild: ParsedTextChild): string =
let value = escape_html(parsedTextChild.literal)

View File

@ -129,6 +129,7 @@ ModalPopup {
pinnedMessage: model.pinned
messagePinnedBy: model.pinnedBy
reactionsModel: model.reactions
linkUrls: model.links
// This is possible since we have all data loaded before we load qml.
// When we fetch messages to fulfill a gap we have to set them at once.

View File

@ -187,4 +187,11 @@ QtObject {
return msg
}
function getLinkPreviewData(url, uuid) {
if(!messageModule)
return
return messageModule.getLinkPreviewData(url, uuid)
}
}

View File

@ -122,6 +122,7 @@ Item {
amISender: model.message.amISender
messageImage: model.message.messageImage
messageTimestamp: model.timestamp
linkUrls: model.links
//timestamp: model.message.timestamp
messageOutgoingStatus: model.message.outgoingStatus
messageContentType: model.message.contentType

View File

@ -340,6 +340,7 @@ Item {
stickerPack: model.stickerPack
editModeOn: model.editMode
isEdited: model.isEdited
linkUrls: model.links
// This is possible since we have all data loaded before we load qml.
// When we fetch messages to fulfill a gap we have to set them at once.

View File

@ -52,6 +52,7 @@ Item {
}
}
property bool editModeOn: false
property string linkUrls: ""
signal openStickerPackPopup(string stickerPackId)
signal addEmoji(bool isProfileClick, bool isSticker, bool isImage , var image, bool emojiOnly, bool hideEmojiPicker)
@ -468,8 +469,6 @@ Item {
visible: !editModeOn
ChatTextView {
id: chatText
// Not Refactored Yet
// store: rootStore
readonly property int leftPadding: chatImage.anchors.leftMargin + chatImage.width + chatHorizontalPadding
visible: {
const urls = linkUrls.split(" ")
@ -586,10 +585,9 @@ Item {
sourceComponent: Component {
LinksMessageView {
// Not Refactored Yet
// store: rootStore
linkUrls: linkUrls
linkUrls: root.linkUrls
container: root.container
messageStore: root.messageStore
isCurrentUser: isCurrentUser
}
}

View File

@ -9,14 +9,14 @@ import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import shared.status 1.0
import shared.stores 1.0
import shared.panels 1.0
import shared.stores 1.0
import shared.panels.chat 1.0
import shared.controls.chat 1.0
Column {
id: root
property var store
property var messageStore
property var container
property string linkUrls: ""
property bool isCurrentUser: false
@ -66,42 +66,37 @@ Column {
}
}
// Not Refactored Yet
// Connections {
// id: linkFetchConnections
// enabled: false
// target: root.store.chatsModelInst
// onLinkPreviewDataWasReceived: {
// let response
// try {
// response = JSON.parse(previewData)
Connections {
id: linkFetchConnections
enabled: false
target: root.messageStore.messageModule
onLinkPreviewDataWasReceived: {
let response
try {
response = JSON.parse(previewData)
} catch (e) {
console.error(previewData, e)
return
}
if (response.uuid !== linkMessageLoader.uuid) return
linkFetchConnections.enabled = false
// } catch (e) {
// console.error(previewData, e)
// return
// }
if (!response.success) {
console.error("could not get preview data")
return undefined
}
linkData = response.result
// if (response.uuid !== linkMessageLoader.uuid) return
// linkFetchConnections.enabled = false
// if (!response.success) {
// console.error(response.result.error)
// return undefined
// }
// linkData = response.result
// if (linkData.contentType.startsWith("image/")) {
// return linkMessageLoader.sourceComponent = unfurledImageComponent
// }
// if (linkData.site && linkData.title) {
// linkData.address = link
// return linkMessageLoader.sourceComponent = unfurledLinkComponent
// }
// }
// }
if (linkData.contentType.startsWith("image/")) {
return linkMessageLoader.sourceComponent = unfurledImageComponent
}
if (linkData.site && linkData.title) {
linkData.address = link
return linkMessageLoader.sourceComponent = unfurledLinkComponent
}
}
}
// Not Refactored Yet
// Connections {
@ -185,9 +180,8 @@ Column {
}
linkFetchConnections.enabled = true
// Not Refactored Yet
return ""
// return root.store.chatsModelInst.getLinkPreviewData(link, linkMessageLoader.uuid)
root.messageStore.getLinkPreviewData(link, linkMessageLoader.uuid)
}
// setting the height to 0 allows the "enable link" dialog to
// disappear correctly when RootStore.neverAskAboutUnfurlingAgain
@ -226,7 +220,7 @@ Column {
Component {
id: invitationBubble
InvitationBubbleView {
store: root.store
// store: root.store
communityId: linkData.communityId
isLink: true
anchors.left: parent.left

View File

@ -37,6 +37,7 @@ Column {
property bool pinnedMessage: false
property string messagePinnedBy: ""
property var reactionsModel: []
property string linkUrls: ""
property int prevMessageIndex: -1
property var prevMessageAsJsonObj
@ -101,7 +102,6 @@ Column {
property string emojiReactions: ""
property bool timeout: false
property bool hasMention: false
property string linkUrls: ""
property bool placeholderMessage: false
property bool activityCenterMessage: false
property bool read: true
@ -353,6 +353,7 @@ Column {
isCurrentUser: root.amISender
isHovered: root.isHovered
editModeOn: root.editModeOn
linkUrls: root.linkUrls
onAddEmoji: {
root.clickMessage(isProfileClick, isSticker, isImage , image, emojiOnly, hideEmojiPicker)