status-desktop/ui/imports/shared/views/chat/LinksMessageView.qml
Alex Jbanca 4a30d13bdc
feat(LinkPreviews): Integrate Link previews with the backend (#12523)
* feat(StatusQ): Adding numberToLocaleStringInCompactForm function to LocaleUtils

This function will format the number in a compact form
E.g: 1000 -> 1K; 1000000 -> 1M; 1100000 -> 1.1M

+ adding tests

fix(statusQ): Update numberToLocaleStringInCompactForm to return the locale number when greter than 999T

fix(StatusQ): extend the test_numberToLocaleStringInCompactForm with new data

* feat(LinkPreviews): Update the link preview area in StatusChatInput to use the new model

Changes:
1. Create a new component `LinkPreviewMiniCardDelegate.qml` that filters the model data to properly fill the link preview card with the needed data based on the preview type
2. Update storybook pages
3. Small updates to LinkPreviewMiniCard

* feat(LinkPreviews): Update the link previews in message history to use the new backend

Changes:
1. Create delegate items for LinkPreviewCard and gif link preview to clean the LinksMessageView component and filter the model data based on the preview type
2. Remove UserProfileCard and reuse the LinkPreviewCard to display contacts link previews
3. Update LinkPreviewCard so that it can accommodate status link previews (communities, channels, contacts). The generic properties (title, description, footer) have been dropped and replaced with specialised properties for each preview type.
4. Fix LinkPreviewCard layout to better accommodate different content variants (missing properties, long/short title, missing description, missing icon)
5. Fixing the link preview context menu and click actions

fix: Move inline components to separate files

Fixing the linux builds using Qt 5.15.2 affected by this bug:
https://bugreports.qt.io/browse/QTBUG-89180

* fix: Align LinkPreviewMiniCard implementation with LinkPreviewCard and remove state based model filtering
2023-10-25 18:20:02 +03:00

208 lines
6.7 KiB
QML

import QtQuick 2.15
import utils 1.0
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import shared.controls 1.0
import shared.status 1.0
import shared.panels 1.0
import shared.controls.delegates 1.0
Flow {
id: root
required property bool isOnline
required property bool playAnimations
required property var linkPreviewModel
required property var gifLinks
required property bool isCurrentUser
required property bool gifUnfurlingEnabled
required property bool canAskToUnfurlGifs
readonly property alias hoveredLink: linksRepeater.hoveredUrl
property string highlightLink: ""
signal imageClicked(var image, var mouse, string imageSource, string url)
signal openContextMenu(var item, string url, string domain)
signal setNeverAskAboutUnfurlingAgain(bool neverAskAgain)
function resetLocalAskAboutUnfurling() {
d.localAskAboutUnfurling = true
}
spacing: 12
//TODO: remove once GIF previews are unfurled sender side
QtObject {
id: d
property bool localAskAboutUnfurling: true
}
Loader {
visible: active
active: root.gifLinks && root.gifLinks.length > 0
&& !root.gifUnfurlingEnabled
&& d.localAskAboutUnfurling && root.canAskToUnfurlGifs
sourceComponent: enableLinkComponent
}
Repeater {
id: tempRepeater
visible: root.canAskToUnfurlGifs
model: root.gifUnfurlingEnabled ? gifLinks : []
delegate: LinkPreviewGifDelegate {
required property string modelData
link: modelData
isOnline: root.isOnline
isCurrentUser: root.isCurrentUser
playAnimation: root.playAnimations
onClicked: root.imageClicked(imageAlias, mouse, link, link)
}
}
Repeater {
id: linksRepeater
property string hoveredUrl: ""
model: root.linkPreviewModel
delegate: LinkPreviewCardDelegate {
id: delegate
isCurrentUser: root.isCurrentUser
highlight: url === root.highlightLink
onHoveredChanged: {
linksRepeater.hoveredUrl = hovered ? url : ""
}
onClicked: (mouse) => {
if(mouse.button === Qt.RightButton) {
const domain = previewType === Constants.LinkPreviewType.Standard ? linkData.domain : Constants.externalStatusLink
root.openContextMenu(delegate, url, domain)
return
}
if(previewType === Constants.LinkPreviewType.Standard) {
Global.openLinkWithConfirmation(url, linkData.domain)
return
}
Global.activateDeepLink(url)
}
}
}
Component {
id: enableLinkComponent
Rectangle {
id: enableLinkRoot
implicitWidth: 300
implicitHeight: childrenRect.height + Style.current.smallPadding
radius: 16
border.width: 1
border.color: Style.current.border
color: Style.current.background
StatusFlatRoundButton {
anchors.top: parent.top
anchors.topMargin: Style.current.smallPadding
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
icon.width: 20
icon.height: 20
icon.name: "close-circle"
onClicked: d.localAskAboutUnfurling = false
}
Image {
id: unfurlingImage
source: Style.png("unfurling-image")
width: 132
height: 94
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: Style.current.smallPadding
}
StatusBaseText {
id: enableText
text: qsTr("Enable automatic GIF unfurling")
horizontalAlignment: Text.AlignHCenter
width: parent.width
wrapMode: Text.WordWrap
anchors.top: unfurlingImage.bottom
anchors.topMargin: Style.current.halfPadding
color: Theme.palette.directColor1
}
StatusBaseText {
id: infoText
text: qsTr("Once enabled, links posted in the chat may share your metadata with their owners")
horizontalAlignment: Text.AlignHCenter
width: parent.width
wrapMode: Text.WordWrap
anchors.top: enableText.bottom
font.pixelSize: 13
color: Theme.palette.baseColor1
}
Separator {
id: sep1
anchors.top: infoText.bottom
anchors.topMargin: Style.current.smallPadding
}
StatusFlatButton {
id: enableBtn
objectName: "LinksMessageView_enableBtn"
text: qsTr("Enable in Settings")
onClicked: {
Global.changeAppSectionBySectionType(Constants.appSection.profile, Constants.settingsSubsection.messaging);
}
width: parent.width
anchors.top: sep1.bottom
Component.onCompleted: {
background.radius = 0;
}
}
Separator {
id: sep2
anchors.top: enableBtn.bottom
anchors.topMargin: 0
}
Item {
width: parent.width
height: 44
anchors.top: sep2.bottom
clip: true
StatusFlatButton {
id: dontAskBtn
width: parent.width
height: (parent.height+Style.current.padding)
anchors.top: parent.top
anchors.topMargin: -Style.current.padding
contentItem: Item {
StatusBaseText {
anchors.centerIn: parent
anchors.verticalCenterOffset: Style.current.halfPadding
font: dontAskBtn.font
color: dontAskBtn.textColor
text: qsTr("Don't ask me again")
}
}
onClicked: root.setNeverAskAboutUnfurlingAgain(true)
Component.onCompleted: {
background.radius = Style.current.padding;
}
}
}
}
}
}