mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-22 04:21:44 +00:00
ce18a52171
Because of https://bugreports.qt.io/browse/QTBUG-90740 inline context menu causes tests for StatusChatInput crashing (stack overflow) on 5.15.2 (this version is used on CI). The easiest option to solve that problem is moving inline component to a separate file. Closes: #12435
225 lines
8.7 KiB
QML
225 lines
8.7 KiB
QML
import QtQuick 2.15
|
|
import QtQuick.Controls 2.15
|
|
import QtGraphicalEffects 1.15
|
|
import QtQuick.Layouts 1.15
|
|
|
|
import StatusQ.Core 0.1
|
|
|
|
import shared.status 1.0
|
|
import shared.controls.chat 1.0
|
|
|
|
import utils 1.0
|
|
|
|
import SortFilterProxyModel 0.2
|
|
|
|
Control {
|
|
id: root
|
|
|
|
required property var imagePreviewArray
|
|
/*
|
|
Expected roles:
|
|
string title
|
|
string url
|
|
bool unfurled
|
|
bool immutable
|
|
string hostname
|
|
string description
|
|
int linkType
|
|
int thumbnailWidth
|
|
int thumbnailHeight
|
|
string thumbnailUrl
|
|
string thumbnailDataUri
|
|
*/
|
|
required property var linkPreviewModel
|
|
required property bool showLinkPreviewSettings
|
|
|
|
readonly property alias hoveredUrl: d.hoveredUrl
|
|
readonly property bool hasContent: imagePreviewArray.length > 0 || showLinkPreviewSettings || linkPreviewRepeater.count > 0
|
|
|
|
signal imageRemoved(int index)
|
|
signal imageClicked(var chatImage)
|
|
signal linkReload(string link)
|
|
signal linkClicked(string link)
|
|
|
|
signal enableLinkPreview()
|
|
signal enableLinkPreviewForThisMessage()
|
|
signal disableLinkPreview()
|
|
signal dismissLinkPreviewSettings()
|
|
signal dismissLinkPreview(int index)
|
|
|
|
horizontalPadding: 12
|
|
topPadding: 12
|
|
|
|
contentItem: Item {
|
|
id: opacityMaskWrapper
|
|
|
|
anchors.fill: parent
|
|
|
|
implicitWidth: flickable.implicitWidth
|
|
implicitHeight: flickable.implicitHeight
|
|
|
|
opacity: 0
|
|
|
|
WheelHandler {
|
|
target: flickable
|
|
property: "contentX"
|
|
acceptedDevices: PointerDevice.Mouse
|
|
onActiveChanged: if(!active) flickable.returnToBounds()
|
|
}
|
|
|
|
Flickable {
|
|
id: flickable
|
|
|
|
anchors.fill: parent
|
|
anchors.leftMargin: root.leftPadding
|
|
anchors.rightMargin: root.rightPadding
|
|
anchors.bottomMargin: root.bottomPadding
|
|
anchors.topMargin: root.topPadding
|
|
|
|
implicitHeight: contentHeight
|
|
implicitWidth: contentWidth
|
|
|
|
contentWidth: layout.width
|
|
contentHeight: layout.height
|
|
|
|
onFlickStarted: settingsContextMenu.close()
|
|
|
|
RowLayout {
|
|
id: layout
|
|
spacing: 8
|
|
StatusChatInputImageArea {
|
|
id: imageArea
|
|
Layout.preferredHeight: 64
|
|
spacing: layout.spacing
|
|
imageSource: imagePreviewArray
|
|
onImageClicked: root.imageClicked(chatImage)
|
|
onImageRemoved: root.imageRemoved(index)
|
|
visible: !!imagePreviewArray && imagePreviewArray.length > 0
|
|
}
|
|
Repeater {
|
|
id: linkPreviewRepeater
|
|
model: d.filteredModel
|
|
delegate: LinkPreviewMiniCard {
|
|
// Model properties
|
|
|
|
required property int index
|
|
required property bool unfurled
|
|
required property bool empty
|
|
required property string url
|
|
required property bool immutable
|
|
required property int previewType
|
|
required property var standardPreview
|
|
required property var standardPreviewThumbnail
|
|
required property var statusContactPreview
|
|
required property var statusContactPreviewThumbnail
|
|
required property var statusCommunityPreview
|
|
required property var statusCommunityPreviewIcon
|
|
required property var statusCommunityPreviewBanner
|
|
required property var statusCommunityChannelPreview
|
|
required property var statusCommunityChannelCommunityPreview
|
|
required property var statusCommunityChannelCommunityPreviewIcon
|
|
required property var statusCommunityChannelCommunityPreviewBanner
|
|
|
|
readonly property var thumbnail: {
|
|
switch (previewType) {
|
|
case Constants.Standard:
|
|
return standardPreviewThumbnail
|
|
case Constants.StatusContact:
|
|
return statusContactPreviewThumbnail
|
|
case Constants.StatusCommunity:
|
|
return statusCommunityPreviewIcon
|
|
case Constants.StatusCommunityChannel:
|
|
return statusCommunityChannelCommunityPreviewIcon
|
|
}
|
|
}
|
|
|
|
readonly property string thumbnailUrl: thumbnail ? thumbnail.url : ""
|
|
readonly property string thumbnailDataUri: thumbnail ? thumbnail.dataUri : ""
|
|
|
|
|
|
Layout.preferredHeight: 64
|
|
|
|
titleStr: standardPreview ? standardPreview.title : statusContactPreview ? statusContactPreview.displayName : ""
|
|
domain: standardPreview ? standardPreview.hostname : "" //TODO: use domain when available
|
|
favIconUrl: "" //TODO: use favicon when available
|
|
communityName: statusCommunityPreview ? statusCommunityPreview.displayName : ""
|
|
channelName: statusCommunityChannelPreview ? statusCommunityChannelPreview.displayName : ""
|
|
|
|
thumbnailImageUrl: thumbnailUrl.length > 0 ? thumbnailUrl : thumbnailDataUri
|
|
type: getCardType(previewType, standardPreview)
|
|
previewState: unfurled && !empty ? LinkPreviewMiniCard.State.Loaded :
|
|
unfurled && empty ? LinkPreviewMiniCard.State.LoadingFailed :
|
|
!unfurled ? LinkPreviewMiniCard.State.Loading : LinkPreviewMiniCard.State.Invalid
|
|
|
|
onClose: root.dismissLinkPreview(d.filteredModel.mapToSource(index))
|
|
onRetry: root.linkReload(url)
|
|
onClicked: root.linkClicked(url)
|
|
onRightClicked: settingsContextMenu.popup()
|
|
onContainsMouseChanged: {
|
|
if (containsMouse) {
|
|
d.hoveredUrl = url
|
|
} else if (d.hoveredUrl === url) {
|
|
d.hoveredUrl = ""
|
|
}
|
|
}
|
|
Component.onDestruction: {
|
|
if(d.hoveredUrl === url) {
|
|
d.hoveredUrl = ""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
LinkPreviewSettingsCard {
|
|
id: settingsCard
|
|
visible: root.showLinkPreviewSettings
|
|
onDismiss: root.dismissLinkPreviewSettings()
|
|
onEnableLinkPreviewForThisMessage: root.enableLinkPreviewForThisMessage()
|
|
onEnableLinkPreview: root.enableLinkPreview()
|
|
onDisableLinkPreview: root.disableLinkPreview()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
id: horizontalClipMask
|
|
anchors.fill: opacityMaskWrapper
|
|
visible: false
|
|
gradient: Gradient {
|
|
orientation: Gradient.Horizontal
|
|
GradientStop { position: 0.0; color: "transparent" }
|
|
GradientStop { position: root.horizontalPadding / horizontalClipMask.width; color: "white" }
|
|
GradientStop { position: 1 - root.horizontalPadding / horizontalClipMask.width; color: "white" }
|
|
GradientStop { position: 1; color: "transparent" }
|
|
}
|
|
}
|
|
|
|
OpacityMask {
|
|
anchors.fill: opacityMaskWrapper
|
|
source: opacityMaskWrapper
|
|
maskSource: horizontalClipMask
|
|
}
|
|
|
|
QtObject {
|
|
id: d
|
|
property string hoveredUrl: ""
|
|
property SortFilterProxyModel filteredModel: SortFilterProxyModel {
|
|
id: filteredModel
|
|
sourceModel: root.linkPreviewModel
|
|
filters: [
|
|
ExpressionFilter {
|
|
expression: { return !model.immutable || model.unfurled } // Filter out immutable links that haven't been unfurled yet
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
LinkPreviewSettingsCardMenu {
|
|
id: settingsContextMenu
|
|
|
|
onEnableLinkPreviewForThisMessage: root.enableLinkPreviewForThisMessage()
|
|
onEnableLinkPreview: root.enableLinkPreview()
|
|
onDisableLinkPreview: root.disableLinkPreview()
|
|
}
|
|
}
|