confetti (#1243)
* 🎉 (confetti) message support. Thanks @LorenDB !
3 files changed, 78 insertions, 1 deletions
diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml
index 8e6ad8d2..e3e02ee9 100644
--- a/resources/qml/MessageView.qml
+++ b/resources/qml/MessageView.qml
@@ -59,7 +59,6 @@ Item {
onCountChanged: {
// Mark timeline as read
if (atYEnd && room) model.currentIndex = 0;
-
}
ScrollBar.vertical: scrollbar
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index ab1bbc28..dff23700 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -13,6 +13,7 @@ import Qt.labs.platform 1.1 as Platform
import QtQuick 2.15
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
+import QtQuick.Particles 2.15
import QtQuick.Window 2.13
import im.nheko 1.0
import im.nheko.EmojiModel 1.0
@@ -25,6 +26,8 @@ Item {
property bool showBackButton: false
clip: true
+ onRoomChanged: if (room != null) room.triggerSpecialEffects()
+
Shortcut {
sequence: StandardKey.Close
onActivated: Rooms.resetCurrentRoom()
@@ -298,6 +301,58 @@ Item {
onClicked: Rooms.resetCurrentRoom()
}
+ ParticleSystem { id: confettiParticleSystem }
+
+ Emitter {
+ id: confettiEmitter
+
+ width: parent.width * 3/4
+ enabled: false
+ anchors.horizontalCenter: parent.horizontalCenter
+ y: parent.height
+ emitRate: Math.min(400 * Math.sqrt(parent.width * parent.height) / 870, 1000)
+ lifeSpan: 15000
+ system: confettiParticleSystem
+ velocityFromMovement: 8
+ size: 16
+ sizeVariation: 4
+ velocity: PointDirection {
+ x: 0
+ y: -Math.min(450 * parent.height / 700, 1000)
+ xVariation: Math.min(4 * parent.width / 7, 450)
+ yVariation: 250
+ }
+
+ ImageParticle {
+ system: confettiParticleSystem
+ source: "qrc:/confettiparticle.svg"
+ rotationVelocity: 0
+ rotationVelocityVariation: 360
+ colorVariation: 1
+ color: "white"
+ entryEffect: ImageParticle.None
+ xVector: PointDirection {
+ x: 1
+ y: 0
+ xVariation: 0.2
+ yVariation: 0.2
+ }
+ yVector: PointDirection {
+ x: 0
+ y: 0.5
+ xVariation: 0.2
+ yVariation: 0.2
+ }
+ }
+ }
+
+ Gravity {
+ system: confettiParticleSystem
+ anchors.fill: parent
+ magnitude: 350
+ angle: 90
+ }
+
NhekoDropArea {
anchors.fill: parent
roomid: room ? room.roomId : ""
@@ -321,6 +376,15 @@ Item {
timelineRoot.destroyOnClose(dialog);
}
+ function onConfetti()
+ {
+ if (!Settings.fancyEffects)
+ return
+
+ confettiEmitter.pulse(parent.height * 2)
+ room.markSpecialEffectsDone()
+ }
+
target: room
}
diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml
index a2a44cb2..3725be05 100644
--- a/resources/qml/delegates/MessageDelegate.qml
+++ b/resources/qml/delegates/MessageDelegate.qml
@@ -76,6 +76,20 @@ Item {
}
DelegateChoice {
+ roleValue: MtxEvent.ConfettiMessage
+
+ TextMessage {
+ formatted: d.formattedBody
+ body: d.body
+ isOnlyEmoji: d.isOnlyEmoji
+ isReply: d.isReply
+ keepFullText: d.keepFullText
+ metadataWidth: d.metadataWidth
+ }
+
+ }
+
+ DelegateChoice {
roleValue: MtxEvent.NoticeMessage
NoticeMessage {
|