Warning, /network/neochat/src/qml/ReplyComponent.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2019 Black Hat <bhat@encom.eu.org> 0002 // SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu> 0003 // SPDX-License-Identifier: GPL-3.0-only 0004 0005 import QtQuick 0006 import QtQuick.Controls as QQC2 0007 import QtQuick.Layouts 0008 0009 import org.kde.coreaddons 0010 import org.kde.kirigami as Kirigami 0011 import org.kde.kirigamiaddons.labs.components as KirigamiComponents 0012 0013 import org.kde.neochat 0014 0015 /** 0016 * @brief A component to show a message that has been replied to. 0017 * 0018 * Similar to the main timeline delegate a reply delegate is chosen based on the type 0019 * of message being replied to. The main difference is that not all messages can be 0020 * show in their original form and are instead visualised with a MIME type delegate 0021 * e.g. Videos. 0022 */ 0023 RowLayout { 0024 id: root 0025 0026 /** 0027 * @brief The reply author. 0028 * 0029 * This should consist of the following: 0030 * - id - The matrix ID of the reply author. 0031 * - isLocalUser - Whether the reply author is the local user. 0032 * - avatarSource - The mxc URL for the reply author's avatar in the current room. 0033 * - avatarMediaId - The media ID of the reply author's avatar. 0034 * - avatarUrl - The mxc URL for the reply author's avatar. 0035 * - displayName - The display name of the reply author. 0036 * - display - The name of the reply author. 0037 * - color - The color for the reply author. 0038 * - object - The Quotient::User object for the reply author. 0039 * 0040 * @sa Quotient::User 0041 */ 0042 required property var author 0043 0044 /** 0045 * @brief The delegate type of the reply message. 0046 */ 0047 required property int type 0048 0049 /** 0050 * @brief The display text of the message. 0051 */ 0052 required property string display 0053 0054 /** 0055 * @brief The media info for the reply event. 0056 * 0057 * This could be an image, audio, video or file. 0058 * 0059 * This should consist of the following: 0060 * - source - The mxc URL for the media. 0061 * - mimeType - The MIME type of the media. 0062 * - mimeIcon - The MIME icon name. 0063 * - size - The file size in bytes. 0064 * - duration - The length in seconds of the audio media (audio/video only). 0065 * - width - The width in pixels of the audio media (image/video only). 0066 * - height - The height in pixels of the audio media (image/video only). 0067 * - tempInfo - mediaInfo (with the same properties as this except no tempInfo) for a temporary image while the file downloads (image/video only). 0068 */ 0069 required property var mediaInfo 0070 0071 property real contentMaxWidth 0072 0073 /** 0074 * @brief The reply has been clicked. 0075 */ 0076 signal replyClicked 0077 0078 spacing: Kirigami.Units.largeSpacing 0079 0080 Rectangle { 0081 id: verticalBorder 0082 Layout.fillHeight: true 0083 0084 implicitWidth: Kirigami.Units.smallSpacing 0085 color: root.author.color 0086 } 0087 ColumnLayout { 0088 spacing: Kirigami.Units.smallSpacing 0089 0090 RowLayout { 0091 spacing: Kirigami.Units.largeSpacing 0092 0093 KirigamiComponents.Avatar { 0094 id: replyAvatar 0095 0096 implicitWidth: Kirigami.Units.iconSizes.small 0097 implicitHeight: Kirigami.Units.iconSizes.small 0098 0099 source: root.author.avatarSource 0100 name: root.author.displayName 0101 color: root.author.color 0102 } 0103 QQC2.Label { 0104 id: replyName 0105 Layout.fillWidth: true 0106 0107 color: root.author.color 0108 text: root.author.displayName 0109 elide: Text.ElideRight 0110 } 0111 } 0112 Loader { 0113 id: loader 0114 0115 Layout.fillWidth: true 0116 Layout.maximumHeight: loader.item && (root.type == DelegateType.Image || root.type == DelegateType.Sticker) ? loader.item.height : loader.item.implicitHeight 0117 Layout.columnSpan: 2 0118 0119 sourceComponent: { 0120 switch (root.type) { 0121 case DelegateType.Image: 0122 case DelegateType.Sticker: 0123 return imageComponent; 0124 case DelegateType.Message: 0125 case DelegateType.Notice: 0126 return textComponent; 0127 case DelegateType.File: 0128 case DelegateType.Video: 0129 case DelegateType.Audio: 0130 return mimeComponent; 0131 case DelegateType.Encrypted: 0132 return encryptedComponent; 0133 default: 0134 return textComponent; 0135 } 0136 } 0137 } 0138 } 0139 HoverHandler { 0140 cursorShape: Qt.PointingHandCursor 0141 } 0142 TapHandler { 0143 acceptedButtons: Qt.LeftButton 0144 onTapped: root.replyClicked() 0145 } 0146 0147 Component { 0148 id: textComponent 0149 RichLabel { 0150 textMessage: root.display 0151 0152 HoverHandler { 0153 enabled: !hoveredLink 0154 cursorShape: Qt.PointingHandCursor 0155 } 0156 TapHandler { 0157 enabled: !hoveredLink 0158 acceptedButtons: Qt.LeftButton 0159 onTapped: root.replyClicked() 0160 } 0161 } 0162 } 0163 Component { 0164 id: imageComponent 0165 Image { 0166 id: image 0167 width: mediaSizeHelper.currentSize.width 0168 height: mediaSizeHelper.currentSize.height 0169 fillMode: Image.PreserveAspectFit 0170 source: root?.mediaInfo.source ?? "" 0171 0172 MediaSizeHelper { 0173 id: mediaSizeHelper 0174 contentMaxWidth: root.contentMaxWidth - verticalBorder.width - root.spacing 0175 mediaWidth: root?.mediaInfo.width ?? -1 0176 mediaHeight: root?.mediaInfo.height ?? -1 0177 } 0178 } 0179 } 0180 Component { 0181 id: mimeComponent 0182 MimeComponent { 0183 mimeIconSource: root.mediaInfo.mimeIcon 0184 label: root.display 0185 subLabel: root.type === DelegateType.File ? Format.formatByteSize(root.mediaInfo.size) : Format.formatDuration(root.mediaInfo.duration) 0186 } 0187 } 0188 Component { 0189 id: encryptedComponent 0190 RichLabel { 0191 textMessage: i18n("This message is encrypted and the sender has not shared the key with this device.") 0192 textFormat: Text.RichText 0193 } 0194 } 0195 }