first commit
This commit is contained in:
83
notifications/HistoryCard.qml
Normal file
83
notifications/HistoryCard.qml
Normal file
@@ -0,0 +1,83 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
property int itemIndex: 0
|
||||
property string appName: ""
|
||||
property string summary: ""
|
||||
property string body: ""
|
||||
property int urgency: 0
|
||||
property string timeStr: ""
|
||||
|
||||
property var t
|
||||
property var urgencyColor: function(u) { return "#ffffff" }
|
||||
property var urgencyIcon: function(u) { return "" }
|
||||
|
||||
signal dismissed(int itemIndex)
|
||||
|
||||
height: histItemContent.implicitHeight + 24
|
||||
radius: 12
|
||||
clip: true
|
||||
color: histItemHover.hovered ? root.t.notifHistoryHover : "transparent"
|
||||
Behavior on color { ColorAnimation { duration: 150; easing.type: Easing.OutCubic } }
|
||||
|
||||
HoverHandler { id: histItemHover }
|
||||
|
||||
SequentialAnimation {
|
||||
id: dismissAnim
|
||||
ParallelAnimation {
|
||||
NumberAnimation { target: root; property: "opacity"; to: 0; duration: 150; easing.type: Easing.OutCubic }
|
||||
NumberAnimation { target: root; property: "scale"; to: 0.95; duration: 150; easing.type: Easing.OutCubic }
|
||||
}
|
||||
NumberAnimation { target: root; property: "height"; to: 0; duration: 150; easing.type: Easing.InOutQuad }
|
||||
ScriptAction { script: root.dismissed(root.itemIndex) }
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 3
|
||||
height: Math.max(12, root.height - 24)
|
||||
radius: 1.5
|
||||
anchors { left: parent.left; leftMargin: 10; verticalCenter: parent.verticalCenter }
|
||||
color: root.urgencyColor(root.urgency)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors { right: parent.right; top: parent.top; margins: 8 }
|
||||
width: 22; height: 22; radius: 11
|
||||
color: histCloseHover.hovered ? root.t.notifHistoryHover : "transparent"
|
||||
opacity: histItemHover.hovered ? 1 : 0
|
||||
Behavior on opacity { NumberAnimation { duration: 150 } }
|
||||
Behavior on color { ColorAnimation { duration: 150 } }
|
||||
|
||||
Text { anchors.centerIn: parent; text: "✕"; color: root.t.notifToastText; font.pixelSize: 10 }
|
||||
HoverHandler { id: histCloseHover; cursorShape: Qt.PointingHandCursor }
|
||||
TapHandler { onTapped: dismissAnim.start() }
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: histItemContent
|
||||
anchors { left: parent.left; right: parent.right; top: parent.top; leftMargin: 24; rightMargin: 36; topMargin: 12 }
|
||||
spacing: 4
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true; spacing: 5
|
||||
Text { text: root.urgencyIcon(root.urgency); color: root.urgencyColor(root.urgency); font.pixelSize: 11; Layout.alignment: Qt.AlignVCenter }
|
||||
Text {
|
||||
text: root.appName; color: root.t.notifToastAppName; font.pixelSize: 11; font.bold: true;
|
||||
font.capitalization: Font.AllUppercase; Layout.fillWidth: true; elide: Text.ElideRight; verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
Text { text: root.timeStr; color: root.t.notifToastDim; font.pixelSize: 11; verticalAlignment: Text.AlignVCenter }
|
||||
}
|
||||
|
||||
Text {
|
||||
text: root.summary; color: root.t.notifToastText; font.pixelSize: 13; font.bold: true;
|
||||
Layout.fillWidth: true; elide: Text.ElideRight; textFormat: Text.PlainText; visible: root.summary !== ""
|
||||
}
|
||||
Text {
|
||||
text: root.body; color: root.t.notifToastDim; font.pixelSize: 12; Layout.fillWidth: true;
|
||||
wrapMode: Text.WordWrap; maximumLineCount: 2; elide: Text.ElideRight; textFormat: Text.PlainText; visible: root.body !== ""; lineHeight: 1.15
|
||||
}
|
||||
}
|
||||
}
|
||||
191
notifications/NotificationCard.qml
Normal file
191
notifications/NotificationCard.qml
Normal file
@@ -0,0 +1,191 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Services.Notifications
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string toastId: ""
|
||||
property string appName: ""
|
||||
property string summary: ""
|
||||
property string body: ""
|
||||
property int urgency: NotificationUrgency.Normal
|
||||
property string timeStr: ""
|
||||
property int timeout: 5000
|
||||
|
||||
property var t
|
||||
property var urgencyColor: function(u) { return "#ffffff" }
|
||||
property var urgencyIcon: function(u) { return "" }
|
||||
|
||||
signal dismissed(string toastId)
|
||||
|
||||
width: parent ? parent.width : 350
|
||||
height: toastCard.height
|
||||
|
||||
property real progressVal: 1.0
|
||||
|
||||
Timer {
|
||||
interval: root.timeout
|
||||
running: root.timeout > 0
|
||||
repeat: false
|
||||
onTriggered: root.dismissed(root.toastId)
|
||||
}
|
||||
|
||||
NumberAnimation on progressVal {
|
||||
from: 1.0; to: 0.0
|
||||
duration: root.timeout
|
||||
running: root.urgency === NotificationUrgency.Low && root.timeout > 0
|
||||
}
|
||||
|
||||
opacity: 0
|
||||
scale: 0.90
|
||||
Component.onCompleted: {
|
||||
entranceOp.start()
|
||||
entranceSc.start()
|
||||
}
|
||||
NumberAnimation {
|
||||
id: entranceOp; target: root
|
||||
property: "opacity"; from: 0; to: 1
|
||||
duration: 240; easing.type: Easing.OutCubic
|
||||
}
|
||||
NumberAnimation {
|
||||
id: entranceSc; target: root
|
||||
property: "scale"; from: 0.90; to: 1.0
|
||||
duration: 240; easing.type: Easing.OutBack
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: toastCard
|
||||
width: parent.width
|
||||
height: toastContent.implicitHeight + (root.urgency === NotificationUrgency.Low ? 30 : 24)
|
||||
radius: 16
|
||||
|
||||
color: cardHover.hovered ? root.t.notifToastBgHover : root.t.notifToastBg
|
||||
border.color: root.urgency === NotificationUrgency.Critical
|
||||
? root.t.notifUrgencyCritical
|
||||
: (cardHover.hovered ? root.t.notifBorderActive : root.t.notifToastBorder)
|
||||
border.width: 1
|
||||
layer.enabled: true
|
||||
|
||||
Behavior on color { ColorAnimation { duration: 150; easing.type: Easing.OutCubic } }
|
||||
Behavior on border.color { ColorAnimation { duration: 150 } }
|
||||
|
||||
HoverHandler { id: cardHover }
|
||||
TapHandler { onTapped: root.dismissed(root.toastId) }
|
||||
|
||||
Rectangle {
|
||||
width: 4
|
||||
height: Math.max(16, toastCard.height - 24)
|
||||
radius: 2
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: 10
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
color: root.urgencyColor(root.urgency)
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: toastContent
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
leftMargin: 24
|
||||
rightMargin: 12
|
||||
topMargin: 12
|
||||
}
|
||||
spacing: 4
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 6
|
||||
|
||||
Text {
|
||||
text: root.urgencyIcon(root.urgency)
|
||||
color: root.urgencyColor(root.urgency)
|
||||
font.pixelSize: 12
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
Text {
|
||||
text: root.appName
|
||||
color: root.t.notifToastAppName
|
||||
font.pixelSize: 11
|
||||
font.bold: true
|
||||
font.capitalization: Font.AllUppercase
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
Text {
|
||||
text: root.timeStr
|
||||
color: root.t.notifToastDim
|
||||
font.pixelSize: 10
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
width: 20; height: 20; radius: 10
|
||||
color: closeHover.hovered ? root.t.notifHistoryHover : "transparent"
|
||||
Behavior on color { ColorAnimation { duration: 100 } }
|
||||
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: "✕"
|
||||
color: closeHover.hovered ? root.t.notifToastText : root.t.notifToastDim
|
||||
font.pixelSize: 10
|
||||
}
|
||||
HoverHandler { id: closeHover; cursorShape: Qt.PointingHandCursor }
|
||||
TapHandler { onTapped: root.dismissed(root.toastId) }
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: root.summary
|
||||
color: root.t.notifToastText
|
||||
font.pixelSize: 14
|
||||
font.bold: true
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
textFormat: Text.PlainText
|
||||
visible: root.summary !== ""
|
||||
}
|
||||
|
||||
Text {
|
||||
text: root.body
|
||||
color: root.t.notifToastDim
|
||||
font.pixelSize: 12
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
maximumLineCount: 3
|
||||
elide: Text.ElideRight
|
||||
textFormat: Text.PlainText
|
||||
visible: root.body !== ""
|
||||
Layout.bottomMargin: root.urgency === NotificationUrgency.Low ? 6 : 0
|
||||
lineHeight: 1.15
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: root.urgency === NotificationUrgency.Low && root.timeout > 0
|
||||
anchors {
|
||||
left: parent.left; right: parent.right; bottom: parent.bottom
|
||||
margins: 10; bottomMargin: 10
|
||||
}
|
||||
height: 4
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: 2
|
||||
color: root.t.notifProgressBg
|
||||
}
|
||||
Rectangle {
|
||||
width: parent.width * root.progressVal
|
||||
height: parent.height
|
||||
radius: 2
|
||||
color: root.t.notifProgressFill
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user