Warning, /network/neochat/src/qml/ImageDelegate.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2018-2020 Black Hat <bhat@encom.eu.org>
0002 // SPDX-License-Identifier: GPL-3.0-only
0003 
0004 import QtQuick
0005 import QtQuick.Window
0006 import QtQuick.Controls as QQC2
0007 import QtQuick.Layouts
0008 import QtQml.Models
0009 
0010 import org.kde.kirigami as Kirigami
0011 
0012 import org.kde.neochat
0013 
0014 /**
0015  * @brief A timeline delegate for an image message.
0016  *
0017  * @inherit MessageDelegate
0018  */
0019 MessageDelegate {
0020     id: root
0021 
0022     /**
0023      * @brief The media info for the event.
0024      *
0025      * This should consist of the following:
0026      *  - source - The mxc URL for the media.
0027      *  - mimeType - The MIME type of the media (should be image/xxx for this delegate).
0028      *  - mimeIcon - The MIME icon name (should be image-xxx).
0029      *  - size - The file size in bytes.
0030      *  - width - The width in pixels of the audio media.
0031      *  - height - The height in pixels of the audio media.
0032      *  - tempInfo - mediaInfo (with the same properties as this except no tempInfo) for a temporary image while the file downloads.
0033      */
0034     required property var mediaInfo
0035 
0036     /**
0037      * @brief Whether the media has been downloaded.
0038      */
0039     readonly property bool downloaded: root.progressInfo && root.progressInfo.completed
0040 
0041     /**
0042      * @brief Whether the image should be automatically opened when downloaded.
0043      */
0044     property bool openOnFinished: false
0045 
0046     /**
0047      * @brief The maximum width of the image.
0048      */
0049     readonly property var maxWidth: Kirigami.Units.gridUnit * 30
0050 
0051     /**
0052      * @brief The maximum height of the image.
0053      */
0054     readonly property var maxHeight: Kirigami.Units.gridUnit * 30
0055 
0056     onOpenContextMenu: RoomManager.viewEventMenu(eventId, author, delegateType, plainText, "", "", mediaInfo.mimeType, progressInfo)
0057 
0058     bubbleContent: Item {
0059         id: imageContainer
0060 
0061         property var imageItem: root.mediaInfo.animated ? animatedImageLoader.item : imageLoader.item
0062 
0063         implicitWidth: mediaSizeHelper.currentSize.width
0064         implicitHeight: mediaSizeHelper.currentSize.height
0065 
0066         Loader {
0067             id: imageLoader
0068 
0069             anchors.fill: parent
0070 
0071             active: !root.mediaInfo.animated
0072             sourceComponent: Image {
0073                 source: root.mediaInfo.source
0074                 sourceSize.width: mediaSizeHelper.currentSize.width * Screen.devicePixelRatio
0075                 sourceSize.height: mediaSizeHelper.currentSize.height * Screen.devicePixelRatio
0076 
0077                 fillMode: Image.PreserveAspectFit
0078             }
0079         }
0080 
0081         Loader {
0082             id: animatedImageLoader
0083 
0084             anchors.fill: parent
0085 
0086             active: root.mediaInfo.animated
0087             sourceComponent: AnimatedImage {
0088                 source: root.mediaInfo.source
0089 
0090                 fillMode: Image.PreserveAspectFit
0091 
0092                 paused: !applicationWindow().active
0093             }
0094         }
0095 
0096         Image {
0097             anchors.fill: parent
0098             source: root.mediaInfo.tempInfo.source
0099             visible: imageContainer.imageItem.status !== Image.Ready
0100         }
0101 
0102         QQC2.ToolTip.text: root.display
0103         QQC2.ToolTip.visible: hoverHandler.hovered
0104         QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
0105 
0106         HoverHandler {
0107             id: hoverHandler
0108         }
0109 
0110         Rectangle {
0111             anchors.fill: parent
0112 
0113             visible: (root.progressInfo.active && !downloaded) || imageContainer.imageItem.status !== Image.Ready
0114 
0115             color: "#BB000000"
0116 
0117             QQC2.ProgressBar {
0118                 anchors.centerIn: parent
0119 
0120                 width: parent.width * 0.8
0121 
0122                 from: 0
0123                 to: root.progressInfo.total
0124                 value: root.progressInfo.progress
0125             }
0126         }
0127 
0128         TapHandler {
0129             acceptedButtons: Qt.LeftButton
0130             gesturePolicy: TapHandler.ReleaseWithinBounds | TapHandler.WithinBounds
0131             onTapped: {
0132                 imageContainer.QQC2.ToolTip.hide();
0133                 if (root.mediaInfo.animated) {
0134                     imageContainer.imageItem.paused = true;
0135                 }
0136                 root.ListView.view.interactive = false;
0137                 // We need to make sure the index is that of the MediaMessageFilterModel.
0138                 if (root.ListView.view.model instanceof MessageFilterModel) {
0139                     RoomManager.maximizeMedia(RoomManager.mediaMessageFilterModel.getRowForSourceItem(root.index));
0140                 } else {
0141                     RoomManager.maximizeMedia(root.index);
0142                 }
0143             }
0144         }
0145 
0146         function downloadAndOpen() {
0147             if (downloaded) {
0148                 openSavedFile();
0149             } else {
0150                 openOnFinished = true;
0151                 root.room.downloadFile(root.eventId, StandardPaths.writableLocation(StandardPaths.CacheLocation) + "/" + root.eventId.replace(":", "_").replace("/", "_").replace("+", "_") + root.room.fileNameToDownload(root.eventId));
0152             }
0153         }
0154 
0155         function openSavedFile() {
0156             if (UrlHelper.openUrl(root.progressInfo.localPath))
0157                 return;
0158             if (UrlHelper.openUrl(root.progressInfo.localDir))
0159                 return;
0160         }
0161 
0162         MediaSizeHelper {
0163             id: mediaSizeHelper
0164             contentMaxWidth: root.contentMaxWidth
0165             mediaWidth: root.mediaInfo.width
0166             mediaHeight: root.mediaInfo.height
0167         }
0168     }
0169 }