waffles: expandable notifs

This commit is contained in:
end-4
2025-11-29 00:23:19 +01:00
parent b4038dafa9
commit 6b90e37b0f
9 changed files with 185 additions and 50 deletions
@@ -5,17 +5,12 @@ import qs.modules.common
import qs.modules.common.functions
import qs.modules.waffle.looks
WButton {
AcrylicButton {
id: root
property var altAction: () => {}
property var middleClickAction: () => {}
colBackground: ColorUtils.transparentize(Looks.colors.bg1)
colBackgroundHover: Looks.colors.bg1Hover
colBackgroundActive: Looks.colors.bg1Active
property color colBackgroundBorder
property color color
Layout.fillHeight: true
topInset: 4
bottomInset: 4
@@ -23,16 +18,7 @@ WButton {
rightInset: 0
horizontalPadding: 8
colBackgroundBorder: ColorUtils.transparentize(Looks.colors.bg1Border, (root.checked || root.hovered) ? Looks.backgroundTransparency : 1)
color: {
if (root.down) {
return root.colBackgroundActive
} else if ((root.hovered && !root.down) || root.checked) {
return root.colBackgroundHover
} else {
return root.colBackground
}
}
colBackground: ColorUtils.transparentize(Looks.colors.bg1)
MouseArea {
anchors.fill: parent
@@ -50,15 +36,4 @@ WButton {
}
}
background: AcrylicRectangle {
shiny: ((root.hovered && !root.down) || root.checked)
color: root.color
radius: Looks.radius.medium
border.width: 1
border.color: root.colBackgroundBorder
Behavior on border.color {
animation: Looks.transition.color.createObject(this)
}
}
}
@@ -0,0 +1,42 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.modules.common
import qs.modules.common.functions
import qs.modules.waffle.looks
WButton {
id: root
colBackground: Looks.colors.bg1
colBackgroundHover: Looks.colors.bg1Hover
colBackgroundActive: Looks.colors.bg1Active
property color colBackgroundBorder
property color color
property alias border: background.border
property alias shinyColor: background.borderColor
colBackgroundBorder: ColorUtils.transparentize(color, (root.checked || root.hovered) ? Looks.backgroundTransparency : 0)
color: {
if (root.down) {
return root.colBackgroundActive
} else if ((root.hovered && !root.down) || root.checked) {
return root.colBackgroundHover
} else {
return root.colBackground
}
}
background: AcrylicRectangle {
id: background
shiny: ((root.hovered && !root.down) || root.checked)
color: root.color
radius: Looks.radius.medium
border.width: 1
border.color: root.colBackgroundBorder
Behavior on border.color {
animation: Looks.transition.color.createObject(this)
}
}
}
@@ -9,16 +9,17 @@ Rectangle {
id: root
property bool shiny: true // Top border
property color borderColor: ColorUtils.transparentize(Looks.colors.bg2Border, shiny ? 0.5 : 1)
property color borderColor: ColorUtils.transparentize(Looks.colors.bg1Hover, 0.7)
property color internalBorderColor: ColorUtils.transparentize(borderColor, shiny ? 0.0 : 1)
color: Looks.colors.bg1Hover
radius: Looks.radius.medium
Behavior on color {
animation: Looks.transition.color.createObject(this)
}
Behavior on borderColor {
Behavior on internalBorderColor {
animation: Looks.transition.color.createObject(this)
}
onBorderColorChanged: {
onInternalBorderColorChanged: {
borderCanvas.requestPaint();
}
@@ -32,7 +33,7 @@ Rectangle {
var ctx = getContext("2d");
ctx.clearRect(0, 0, width, height);
var borderColor = root.borderColor;
var borderColor = root.internalBorderColor;
var r = root.radius;
var fadeLength = Math.max(1, r);
@@ -53,6 +53,7 @@ Singleton {
property color controlBgHover: '#57575B'
property color controlFg: "#FFFFFF"
property color accentUnfocused: "#848484"
property color link: "#235CCF"
}
darkColors: QtObject {
id: darkColors
@@ -80,6 +81,7 @@ Singleton {
property color controlBgHover: "#CFCED1"
property color controlFg: "#454545"
property color accentUnfocused: "#989898"
property color link: "#A7C9FC"
}
colors: QtObject {
id: colors
@@ -110,6 +112,7 @@ Singleton {
property color controlBg: root.dark ? root.darkColors.controlBg : root.lightColors.controlBg
property color controlBgHover: root.dark ? root.darkColors.controlBgHover : root.lightColors.controlBgHover
property color controlFg: root.dark ? root.darkColors.controlFg : root.lightColors.controlFg
property color link: root.dark ? root.darkColors.link : root.lightColors.link
property color danger: "#C42B1C"
property color dangerActive: "#B62D1F"
property color warning: "#FF9900"
@@ -8,8 +8,11 @@ Text {
color: Looks.colors.fg
font {
hintingPreference: Font.PreferFullHinting
family: Looks.font.family.ui
pixelSize: Looks.font.pixelSize.normal
weight: Looks.font.weight.regular
}
linkColor: Looks.colors.link
}
@@ -8,18 +8,24 @@ import qs.modules.common.functions
import qs.modules.waffle.looks
WBorderlessButton {
id: headerButton
id: root
Layout.fillWidth: false
implicitWidth: 16
implicitHeight: 16
property real implicitSize: 16
implicitWidth: implicitSize
implicitHeight: implicitSize
color: "transparent"
colForeground: root.hovered && !root.pressed ? Looks.colors.fg : Looks.colors.fg1
Behavior on colForeground {
animation: Looks.transition.color.createObject(this)
}
contentItem: Item {
FluentIcon {
anchors.centerIn: parent
implicitSize: 16
icon: headerButton.icon.name
color: headerButton.hovered && !headerButton.pressed ? Looks.colors.fg : Looks.colors.fg1
implicitSize: root.implicitSize
icon: root.icon.name
color: root.colForeground
}
}
}
@@ -2,18 +2,27 @@ import QtQuick
import qs
import qs.services
import qs.modules.common
import qs.modules.common.functions
import qs.modules.waffle.looks
SmallBorderedIconButton {
AcrylicButton {
id: root
property bool iconVisible: true
property string iconName: ""
property bool iconFilled: true
colBackground: Looks.colors.bg2
colBackgroundHover: Looks.colors.bg2Hover
colBackgroundActive: Looks.colors.bg2Active
property color colBorder: Looks.colors.bg2Border
property color colBorderToggled: Looks.colors.accent
border.color: checked ? colBorderToggled : colBorder
leftPadding: 12
rightPadding: 12
implicitWidth: focusButtonContent.implicitWidth + leftPadding + rightPadding
implicitHeight: 24
contentItem: Row {
id: focusButtonContent
@@ -12,6 +12,7 @@ MouseArea {
required property var notificationGroup
readonly property var notifications: notificationGroup?.notifications ?? []
property bool expanded: false
implicitWidth: contentLayout.implicitWidth
implicitHeight: contentLayout.implicitHeight
@@ -34,12 +35,23 @@ MouseArea {
interactive: false
spacing: 4
model: ScriptModel {
values: root.notifications.slice().reverse()
values: root.expanded ? root.notifications.slice().reverse() : root.notifications.slice(-1)
objectProp: "notificationId"
}
delegate: WSingleNotification {
required property int index
required property var modelData
width: ListView.view.width
notification: modelData
groupExpandControlMessage: {
if (root.notifications.length === 0) return "";
if (!root.expanded) return Translation.tr("+%1 notifications").arg(root.notifications.length - 1);
if (index === root.notifications.length - 1) return Translation.tr("See fewer");
return "";
}
onGroupExpandToggle: {
root.expanded = !root.expanded;
}
}
}
}
@@ -13,10 +13,17 @@ MouseArea {
required property var notification
property bool expanded: false
property string groupExpandControlMessage: ""
signal groupExpandToggle
hoverEnabled: true
implicitHeight: contentItem.implicitHeight
implicitWidth: contentItem.implicitWidth
Behavior on implicitHeight {
animation: Looks.transition.enter.createObject(this)
}
Rectangle {
id: contentItem
anchors.fill: parent
@@ -26,32 +33,109 @@ MouseArea {
implicitHeight: notificationContent.implicitHeight + padding * 2
implicitWidth: notificationContent.implicitWidth + padding * 2
border.width: 1
border.color: Looks.applyContentTransparency(Looks.colors.ambientShadow)
border.color: ColorUtils.applyAlpha(Looks.colors.ambientShadow, 0.1)
ColumnLayout {
id: notificationContent
anchors.fill: parent
anchors.margins: contentItem.padding
spacing: 19
RowLayout {
Layout.fillWidth: true
WText {
text: NotificationUtils.getFriendlyNotifTimeString(root.notification?.time)
ExpandButton {
Layout.topMargin: -2
}
Item {
Layout.fillWidth: true
}
NotificationHeaderButton {
Layout.rightMargin: 4
opacity: root.containsMouse ? 1 : 0
icon.name: "dismiss"
implicitSize: 12
onClicked: {
Qt.callLater(() => {
Notifications.discardNotification(root.notification?.notificationId);
});
}
}
}
ColumnLayout {
Layout.fillWidth: true
WText {
Layout.fillWidth: true
elide: Text.ElideRight
text: root.notification.summary
spacing: 3
SummaryText {}
BodyText {}
}
AcrylicButton {
id: groupExpandButton
visible: root.groupExpandControlMessage !== ""
Layout.bottomMargin: 2
horizontalPadding: 10
implicitHeight: 24
implicitWidth: expandButtonText.implicitWidth + horizontalPadding * 2
onClicked: root.groupExpandToggle()
contentItem: Item {
WText {
id: expandButtonText
anchors.centerIn: parent
text: root.groupExpandControlMessage
}
}
}
}
}
component SummaryText: WText {
Layout.fillWidth: true
elide: Text.ElideRight
text: root.notification?.summary
font.pixelSize: Looks.font.pixelSize.large
}
component BodyText: WText {
Layout.fillWidth: true
Layout.fillHeight: true
elide: Text.ElideRight
verticalAlignment: Text.AlignTop
wrapMode: Text.Wrap
maximumLineCount: root.expanded ? 100 : 1
text: root.notification?.body
color: Looks.colors.subfg
}
component ExpandButton: NotificationHeaderButton {
id: expandButton
implicitWidth: expandButtonContent.implicitWidth
onClicked: root.expanded = !root.expanded
contentItem: Item {
id: expandButtonContent
implicitWidth: expandButtonRow.implicitWidth
implicitHeight: expandButtonRow.implicitHeight
RowLayout {
id: expandButtonRow
anchors.centerIn: parent
spacing: 8
WText {
Layout.fillWidth: true
elide: Text.ElideRight
wrapMode: Text.Wrap
maximumLineCount: root.expanded ? 100 : 1
color: expandButton.colForeground
text: NotificationUtils.getFriendlyNotifTimeString(root.notification?.time)
}
FluentIcon {
Layout.rightMargin: 12
icon: "chevron-down"
implicitSize: 18
rotation: root.expanded ? -180 : 0
color: expandButton.colForeground
Behavior on rotation {
animation: Looks.transition.rotate.createObject(this)
}
}
}
}