diff --git a/TODO.md b/TODO.md index 46e3cea0..c18d6dc8 100644 --- a/TODO.md +++ b/TODO.md @@ -13,6 +13,7 @@ - When qml syntax highlighting supports ES6 string interpolation, use that - Fixes + - Image tooltips - Time on their own lines - When selecting text and scrolling up, selection stops working after a while - Ensure all the text that should be copied is copied @@ -70,7 +71,6 @@ - Replies - Messages editing and redaction - Code highlighting - - Support GIF avatars and images - Adapt shortcuts flicking speed to font size and DPI - EditAccount page: diff --git a/src/qml/Base/HAvatar.qml b/src/qml/Base/HAvatar.qml index 36f5f5c8..db65dc10 100644 --- a/src/qml/Base/HAvatar.qml +++ b/src/qml/Base/HAvatar.qml @@ -12,6 +12,7 @@ Rectangle { property var imageUrl: "" property var toolTipImageUrl: imageUrl property alias fillMode: avatarImage.fillMode + property alias animate: avatarImage.animate readonly property alias hovered: hoverHandler.hovered @@ -49,6 +50,7 @@ Rectangle { sourceSize.height: params.height fillMode: Image.PreserveAspectCrop source: Qt.resolvedUrl(imageUrl) + animate: false HoverHandler { id: hoverHandler } diff --git a/src/qml/Base/HImage.qml b/src/qml/Base/HImage.qml index c73639e7..a2ef427b 100644 --- a/src/qml/Base/HImage.qml +++ b/src/qml/Base/HImage.qml @@ -5,14 +5,49 @@ Image { id: image autoTransform: true asynchronous: true - cache: true fillMode: Image.PreserveAspectFit + cache: ! loader.sourceComponent && + (sourceSize.width + sourceSize.height) <= 512 + + + property bool animate: true property color colorize: "transparent" + layer.enabled: ! Qt.colorEqual(colorize, "transparent") layer.effect: ColorOverlay { color: image.colorize cached: image.cache } + + + Component { + id: animatedImage + + AnimatedImage { + source: image.source + autoTransform: image.autoTransform + asynchronous: image.asynchronous + fillMode: image.fillMode + mirror: image.mirror + mipmap: image.mipmap + smooth: image.smooth + horizontalAlignment: image.horizontalAlignment + verticalAlignment: image.verticalAlignment + + cache: true // Needed to allow GIFs to loop + paused: ! visible || window.hidden + } + } + + HLoader { + id: loader + anchors.fill: parent + sourceComponent: + animate && + image.source.toString() + .split("/").splice(-1)[0].split("?")[0].toLowerCase() + .endsWith(".gif") ? animatedImage : null + } } diff --git a/src/qml/Pages/EditAccount/Profile.qml b/src/qml/Pages/EditAccount/Profile.qml index d3a27a73..95b8ef24 100644 --- a/src/qml/Pages/EditAccount/Profile.qml +++ b/src/qml/Pages/EditAccount/Profile.qml @@ -61,6 +61,7 @@ HGridLayout { avatarUrl: accountInfo.avatar_url imageUrl: fileDialog.selectedFile || fileDialog.file || defaultImageUrl toolTipImageUrl: "" + animate: true // note: matrix doesn't actually support gif avatars Layout.alignment: Qt.AlignHCenter diff --git a/src/qml/Window.qml b/src/qml/Window.qml index d1cf618e..4aabbee7 100644 --- a/src/qml/Window.qml +++ b/src/qml/Window.qml @@ -12,6 +12,13 @@ ApplicationWindow { visible: true color: "transparent" + + readonly property bool hidden: + Qt.application.state == Qt.ApplicationSuspended || + Qt.application.state == Qt.ApplicationHidden || + window.visibility == window.Minimized || + window.visibility == window.Hidden + // Note: For JS object variables, the corresponding method to notify // key/value changes must be called manually, e.g. settingsChanged(). property var modelSources: ({})