diff --git a/resources/qml/ChatPage.qml b/resources/qml/ChatPage.qml index 26e7c181..d4d2b845 100644 --- a/resources/qml/ChatPage.qml +++ b/resources/qml/ChatPage.qml @@ -126,6 +126,7 @@ Rectangle { TimelineView { id: timeline + privacyScreen: privacyScreen showBackButton: adaptiveView.singlePageMode room: Rooms.currentRoom roomPreview: Rooms.currentRoomPreview.roomid ? Rooms.currentRoomPreview : null @@ -138,6 +139,8 @@ Rectangle { } PrivacyScreen { + id: privacyScreen + anchors.fill: parent visible: Settings.privacyScreen screenTimeout: Settings.privacyScreenTimeout diff --git a/resources/qml/PrivacyScreen.qml b/resources/qml/PrivacyScreen.qml index 037cd91d..5967f25d 100644 --- a/resources/qml/PrivacyScreen.qml +++ b/resources/qml/PrivacyScreen.qml @@ -10,6 +10,7 @@ import im.nheko 1.0 Item { id: privacyScreen + readonly property bool active: Settings.privacyScreen && screenSaver.state === "Visible" property var timelineRoot property int screenTimeout @@ -59,7 +60,6 @@ Item { target: screenSaver opacity: 1 } - }, State { name: "Invisible" @@ -73,34 +73,13 @@ Item { target: screenSaver visible: false } - } ] transitions: [ - Transition { - from: "Visible" - to: "Invisible" - - SequentialAnimation { - NumberAnimation { - target: screenSaver - property: "opacity" - duration: 250 - easing.type: Easing.InQuad - } - - NumberAnimation { - target: screenSaver - property: "visible" - duration: 0 - } - - } - - }, Transition { from: "Invisible" to: "Visible" + reversible: true SequentialAnimation { NumberAnimation { @@ -112,8 +91,8 @@ Item { NumberAnimation { target: screenSaver property: "opacity" - duration: 500 - easing.type: Easing.InQuad + duration: 300 + easing.type: Easing.Linear } } diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index a56f817e..49a36d8f 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -108,17 +108,21 @@ Page { } TimelineView { - id: timelineView + id: timeline + + privacyScreen: privacyScreen anchors.fill: parent room: roomWindowW.room roomPreview: roomWindowW.roomPreview.roomid ? roomWindowW.roomPreview : null } PrivacyScreen { + id: privacyScreen + anchors.fill: parent visible: Settings.privacyScreen screenTimeout: Settings.privacyScreenTimeout - timelineRoot: timelineView + timelineRoot: timeline windowTarget: roomWindowW } diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index aa39560a..e836f60f 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -24,6 +24,7 @@ Item { property var roomPreview: null property bool showBackButton: false property bool shouldEffectsRun: false + required property PrivacyScreen privacyScreen clip: true onRoomChanged: if (room != null) room.triggerSpecialEffects() diff --git a/resources/qml/delegates/ImageMessage.qml b/resources/qml/delegates/ImageMessage.qml index d4441367..bed4b659 100644 --- a/resources/qml/delegates/ImageMessage.qml +++ b/resources/qml/delegates/ImageMessage.qml @@ -26,21 +26,88 @@ AbstractButton { height: width*proportionalHeight hoverEnabled: true + state: (img.status != Image.Ready || timeline.privacyScreen.active) ? "BlurhashVisible" : "ImageVisible" + states: [ + State { + name: "BlurhashVisible" + + PropertyChanges { + target: blurhash_ + opacity: (img.status != Image.Ready) || (timeline.privacyScreen.active && blurhash) ? 1 : 0 + visible: (img.status != Image.Ready) || (timeline.privacyScreen.active && blurhash) + } + + PropertyChanges { + target: img + opacity: 0 + } + + PropertyChanges { + target: mxcimage + opacity: 0 + } + }, + State { + name: "ImageVisible" + + PropertyChanges { + target: blurhash_ + opacity: 0 + visible: false + } + + PropertyChanges { + target: img + opacity: 1 + } + + PropertyChanges { + target: mxcimage + opacity: 1 + } + } + ] + transitions: [ + Transition { + from: "ImageVisible" + to: "BlurhashVisible" + reversible: true + + SequentialAnimation { + PropertyAction { + target: blurhash_ + property: "visible" + } + + ParallelAnimation { + NumberAnimation { + target: blurhash_ + property: "opacity" + duration: 300 + easing.type: Easing.Linear + } + + NumberAnimation { + target: img + property: "opacity" + duration: 300 + easing.type: Easing.Linear + } + + NumberAnimation { + target: mxcimage + property: "opacity" + duration: 300 + easing.type: Easing.Linear + } + } + } + } + ] + property int metadataWidth property bool fitsMetadata: (parent.width - width) > metadataWidth+4 - Image { - id: blurhash_ - - anchors.fill: parent - visible: img.status != Image.Ready - source: blurhash ? ("image://blurhash/" + blurhash) : ("image://colorimage/:/icons/icons/ui/image-failed.svg?" + Nheko.colors.buttonText) - asynchronous: true - fillMode: Image.PreserveAspectFit - sourceSize.width: parent.width * Screen.devicePixelRatio - sourceSize.height: parent.height * Screen.devicePixelRatio - } - Image { id: img @@ -66,7 +133,18 @@ AbstractButton { eventId: parent.eventId } - onClicked :Settings.openImageExternal ? room.openMedia(eventId) : TimelineManager.openImageOverlay(room, url, eventId, originalWidth, proportionalHeight); + Image { + id: blurhash_ + + anchors.fill: parent + source: blurhash ? ("image://blurhash/" + blurhash) : ("image://colorimage/:/icons/icons/ui/image-failed.svg?" + Nheko.colors.buttonText) + asynchronous: true + fillMode: Image.PreserveAspectFit + sourceSize.width: parent.width * Screen.devicePixelRatio + sourceSize.height: parent.height * Screen.devicePixelRatio + } + + onClicked: Settings.openImageExternal ? room.openMedia(eventId) : TimelineManager.openImageOverlay(room, url, eventId, originalWidth, proportionalHeight); Item { id: overlay