feat: show unfurled youtube links
This commit is contained in:
parent
a679758230
commit
b583a4d4bf
|
@ -438,6 +438,9 @@ QtObject:
|
|||
proc copyToClipboard*(self: ChatsView, content: string) {.slot.} =
|
||||
setClipBoardText(content)
|
||||
|
||||
proc getLinkPreviewData*(self: ChatsView, link: string): string {.slot.} =
|
||||
result = $self.status.chat.getLinkPreviewData(link)
|
||||
|
||||
proc sendSticker*(self: ChatsView, hash: string, pack: int) {.slot.} =
|
||||
let sticker = Sticker(hash: hash, packId: pack)
|
||||
self.addRecentStickerToList(sticker)
|
||||
|
|
|
@ -32,6 +32,7 @@ type
|
|||
AudioDurationMs = UserRole + 21
|
||||
EmojiReactions = UserRole + 22
|
||||
CommandParameters = UserRole + 23
|
||||
LinkUrls = UserRole + 24
|
||||
|
||||
QtObject:
|
||||
type
|
||||
|
@ -136,6 +137,7 @@ QtObject:
|
|||
of ChatMessageRoles.Audio: result = newQVariant(message.audio)
|
||||
of ChatMessageRoles.AudioDurationMs: result = newQVariant(message.audioDurationMs)
|
||||
of ChatMessageRoles.EmojiReactions: result = newQVariant(self.getReactions(message.id))
|
||||
of ChatMessageRoles.LinkUrls: result = newQVariant(message.linkUrls)
|
||||
# Pass the command parameters as a JSON string
|
||||
of ChatMessageRoles.CommandParameters: result = newQVariant($(%*{
|
||||
"id": message.commandParameters.id,
|
||||
|
@ -172,6 +174,7 @@ QtObject:
|
|||
ChatMessageRoles.Audio.int: "audio",
|
||||
ChatMessageRoles.AudioDurationMs.int: "audioDurationMs",
|
||||
ChatMessageRoles.EmojiReactions.int: "emojiReactions",
|
||||
ChatMessageRoles.LinkUrls.int: "linkUrls",
|
||||
ChatMessageRoles.CommandParameters.int: "commandParameters"
|
||||
}.toTable
|
||||
|
||||
|
|
|
@ -182,6 +182,9 @@ proc clearHistory*(self: ChatModel, chatId: string) =
|
|||
let chat = self.channels[chatId]
|
||||
self.events.emit("chatHistoryCleared", ChannelArgs(chat: chat))
|
||||
|
||||
proc getLinkPreviewData*(self: ChatModel, link: string): JsonNode =
|
||||
result = status_chat.getLinkPreviewData(link)
|
||||
|
||||
proc setActiveChannel*(self: ChatModel, chatId: string) =
|
||||
self.events.emit("activeChannelChanged", ChatIdArg(chatId: chatId))
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ type Message* = object
|
|||
stickerHash*: string
|
||||
outgoingStatus*: string
|
||||
imageUrls*: string
|
||||
linkUrls*: string
|
||||
image*: string
|
||||
audio*: string
|
||||
audioDurationMs*: int
|
||||
|
|
|
@ -198,3 +198,6 @@ proc muteChat*(chatId: string): string =
|
|||
|
||||
proc unmuteChat*(chatId: string): string =
|
||||
result = callPrivateRPC("unmuteChat".prefix, %*[chatId])
|
||||
|
||||
proc getLinkPreviewData*(link: string): JsonNode =
|
||||
result = callPrivateRPC("getLinkPreviewData".prefix, %*[link]).parseJSON()["result"]
|
|
@ -1,5 +1,7 @@
|
|||
import json, random, strutils, sequtils, sugar, chronicles
|
||||
import json_serialization
|
||||
import ../libstatus/core
|
||||
import ../libstatus/utils
|
||||
import ../libstatus/accounts as status_accounts
|
||||
import ../libstatus/accounts/constants as constants
|
||||
import ../libstatus/settings as status_settings
|
||||
|
@ -187,6 +189,7 @@ proc toMessage*(jsonMsg: JsonNode): Message =
|
|||
stickerHash: "",
|
||||
parsedText: @[],
|
||||
imageUrls: "",
|
||||
linkUrls: "",
|
||||
image: $jsonMsg{"image"}.getStr,
|
||||
audio: $jsonMsg{"audio"}.getStr,
|
||||
audioDurationMs: jsonMsg{"audioDurationMs"}.getInt,
|
||||
|
@ -202,6 +205,12 @@ proc toMessage*(jsonMsg: JsonNode): Message =
|
|||
.map(t => t.destination)
|
||||
.join(" ")
|
||||
|
||||
|
||||
message.linkUrls = concat(message.parsedText.map(t => t.children.filter(c => c.textType == "link")))
|
||||
.filter(t => t.destination.startsWith("http"))
|
||||
.map(t => t.destination)
|
||||
.join(" ")
|
||||
|
||||
if message.contentType == ContentType.Sticker:
|
||||
message.stickerHash = jsonMsg["sticker"]["hash"].getStr
|
||||
|
||||
|
|
|
@ -141,6 +141,18 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: linksLoader
|
||||
active: !!linkUrls
|
||||
anchors.left: chatText.left
|
||||
anchors.leftMargin: 8
|
||||
anchors.top: chatText.bottom
|
||||
|
||||
sourceComponent: Component {
|
||||
LinksMessage {}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: audioPlayerLoader
|
||||
active: isAudio
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
import QtQuick 2.3
|
||||
import "../../../../../imports"
|
||||
import "../../../../../shared"
|
||||
|
||||
Item {
|
||||
id: linksItem
|
||||
height: {
|
||||
let h = 0
|
||||
for (let i = 0; i < linksRepeater.count; i++) {
|
||||
h += linksRepeater.itemAt(i).height
|
||||
}
|
||||
return h
|
||||
}
|
||||
width: {
|
||||
let w = 0
|
||||
for (let i = 0; i < linksRepeater.count; i++) {
|
||||
if (linksRepeater.itemAt(i).width > w) {
|
||||
w = linksRepeater.itemAt(i).width
|
||||
}
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: linksRepeater
|
||||
model: {
|
||||
if (!linkUrls) {
|
||||
return []
|
||||
}
|
||||
|
||||
return linkUrls.split(" ")
|
||||
}
|
||||
|
||||
delegate: Loader {
|
||||
property string linkString: modelData
|
||||
active: true
|
||||
sourceComponent: {
|
||||
let linkExists = false
|
||||
let linkWhiteListed = false
|
||||
Object.keys(appSettings.whitelistedUnfurlingSites).some(function (site) {
|
||||
// Check if our link contains the string part of the url
|
||||
// TODO this might become not a reliable way to check since youtube has mutliple ways of being shown
|
||||
if (modelData.includes(site)) {
|
||||
linkExists = true
|
||||
// check if it was enabled
|
||||
linkWhiteListed = appSettings.whitelistedUnfurlingSites[site] === true
|
||||
return true
|
||||
}
|
||||
return
|
||||
})
|
||||
|
||||
if (linkWhiteListed) {
|
||||
return unfurledLinkComponent
|
||||
}
|
||||
if (linkExists) {
|
||||
return enableLinkComponent
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: unfurledLinkComponent
|
||||
Loader {
|
||||
property var linkData: {
|
||||
try {
|
||||
const data = chatsModel.getLinkPreviewData(linkString)
|
||||
return JSON.parse(data)
|
||||
} catch (e) {
|
||||
console.error("Error parsing link data", e)
|
||||
return undfined
|
||||
}
|
||||
}
|
||||
enabled: linkData !== undefined && !!linkData.title
|
||||
sourceComponent: Component {
|
||||
Rectangle {
|
||||
id: rectangle
|
||||
width: 200
|
||||
height: childrenRect.height + Style.current.halfPadding
|
||||
radius: 16
|
||||
clip: true
|
||||
border.width: 1
|
||||
border.color: Style.current.border
|
||||
color:Style.current.background
|
||||
|
||||
// TODO the clip doesnt seem to work. Find another way to have rounded corners and wait for designs
|
||||
Image {
|
||||
id: linkImage
|
||||
source: linkData.thumbnailUrl
|
||||
fillMode: Image.PreserveAspectFit
|
||||
width: 200
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: linkTitle
|
||||
text: linkData.title
|
||||
elide: Text.ElideRight
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: linkImage.bottom
|
||||
anchors.rightMargin: Style.current.halfPadding
|
||||
anchors.leftMargin: Style.current.halfPadding
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: linkSite
|
||||
text: linkData.site
|
||||
color: Style.current.secondaryText
|
||||
anchors.top: linkTitle.bottom
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
anchors.left: linkTitle.left
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.top: linkImage.top
|
||||
anchors.left: linkImage.left
|
||||
anchors.right: linkImage.right
|
||||
anchors.bottom: linkSite.bottom
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: Qt.openUrlExternally(linkString)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: enableLinkComponent
|
||||
Rectangle {
|
||||
width: 300
|
||||
height: 200
|
||||
radius: 16
|
||||
|
||||
border.width: 1
|
||||
border.color: Style.current.border
|
||||
color:Style.current.background
|
||||
|
||||
StyledText {
|
||||
text: qsTr("You need to enable this before being able to see it")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -216,6 +216,21 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: linksLoader
|
||||
active: !!linkUrls
|
||||
anchors.left: !isCurrentUser ? chatImage.right : undefined
|
||||
anchors.leftMargin: !isCurrentUser ? 8 : 0
|
||||
anchors.right: !isCurrentUser ? undefined : parent.right
|
||||
anchors.rightMargin: !isCurrentUser ? 0 : Style.current.padding
|
||||
anchors.top: chatBox.bottom
|
||||
anchors.topMargin: Style.current.smallPadding
|
||||
|
||||
sourceComponent: Component {
|
||||
LinksMessage {}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: emojiReactionLoader
|
||||
active: emojiReactions !== ""
|
||||
|
|
|
@ -148,6 +148,7 @@ DISTFILES += \
|
|||
app/AppLayouts/Chat/ChatColumn/MessageComponents/EmojiReactions.qml \
|
||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/ImageLoader.qml \
|
||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/ImageMessage.qml \
|
||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/LinksMessage.qml \
|
||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/MessageMouseArea.qml \
|
||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/NormalMessage.qml \
|
||||
app/AppLayouts/Chat/ChatColumn/MessageComponents/RectangleCorner.qml \
|
||||
|
|
Loading…
Reference in New Issue