diff --git a/.config/quickshell/ii/modules/background/CookieClock.qml b/.config/quickshell/ii/modules/background/CookieClock.qml index 88ad5a90f..0e1474543 100644 --- a/.config/quickshell/ii/modules/background/CookieClock.qml +++ b/.config/quickshell/ii/modules/background/CookieClock.qml @@ -88,7 +88,7 @@ Item { delegate: StyledText { required property string modelData - anchors.horizontalCenter: parent.horizontalCenter + anchors.horizontalCenter: parent?.horizontalCenter font { pixelSize: modelData.match(/am|pm/i) ? 26 : 68 family: Appearance.font.family.expressive diff --git a/.config/quickshell/ii/modules/common/widgets/NotificationItem.qml b/.config/quickshell/ii/modules/common/widgets/NotificationItem.qml index 94a7c71bf..4f87b4fdd 100644 --- a/.config/quickshell/ii/modules/common/widgets/NotificationItem.qml +++ b/.config/quickshell/ii/modules/common/widgets/NotificationItem.qml @@ -4,6 +4,7 @@ import qs.services import qs.modules.common.functions import QtQuick import QtQuick.Layouts +import Qt5Compat.GraphicalEffects import Quickshell import Quickshell.Hyprland import Quickshell.Services.Notifications @@ -220,91 +221,110 @@ Item { // Notification item area PointingHandLinkHover {} } - StyledFlickable { // Notification actions - id: actionsFlickable + Item { Layout.fillWidth: true - implicitHeight: actionRowLayout.implicitHeight - contentWidth: actionRowLayout.implicitWidth - clip: !onlyNotification + implicitWidth: actionsFlickable.implicitWidth + implicitHeight: actionsFlickable.implicitHeight - Behavior on opacity { - animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) - } - Behavior on height { - animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) - } - Behavior on implicitHeight { - animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: actionsFlickable.width + height: actionsFlickable.height + radius: Appearance.rounding.small + } } - RowLayout { - id: actionRowLayout - Layout.alignment: Qt.AlignBottom + ScrollEdgeFade { + target: actionsFlickable + vertical: false + } - NotificationActionButton { - Layout.fillWidth: true - buttonText: Translation.tr("Close") - urgency: notificationObject.urgency - implicitWidth: (notificationObject.actions.length == 0) ? ((actionsFlickable.width - actionRowLayout.spacing) / 2) : - (contentItem.implicitWidth + leftPadding + rightPadding) + StyledFlickable { // Notification actions + id: actionsFlickable + anchors.fill: parent + implicitHeight: actionRowLayout.implicitHeight + contentWidth: actionRowLayout.implicitWidth - onClicked: { - root.destroyWithAnimation() - } - - contentItem: MaterialSymbol { - iconSize: Appearance.font.pixelSize.large - horizontalAlignment: Text.AlignHCenter - color: (notificationObject.urgency == NotificationUrgency.Critical) ? - Appearance.m3colors.m3onSurfaceVariant : Appearance.m3colors.m3onSurface - text: "close" - } + Behavior on opacity { + animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) + } + Behavior on height { + animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) + } + Behavior on implicitHeight { + animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) } - Repeater { - id: actionRepeater - model: notificationObject.actions + RowLayout { + id: actionRowLayout + Layout.alignment: Qt.AlignBottom + NotificationActionButton { Layout.fillWidth: true - buttonText: modelData.text + buttonText: Translation.tr("Close") urgency: notificationObject.urgency + implicitWidth: (notificationObject.actions.length == 0) ? ((actionsFlickable.width - actionRowLayout.spacing) / 2) : + (contentItem.implicitWidth + leftPadding + rightPadding) + onClicked: { - Notifications.attemptInvokeAction(notificationObject.notificationId, modelData.identifier); + root.destroyWithAnimation() } - } - } - NotificationActionButton { - Layout.fillWidth: true - urgency: notificationObject.urgency - implicitWidth: (notificationObject.actions.length == 0) ? ((actionsFlickable.width - actionRowLayout.spacing) / 2) : - (contentItem.implicitWidth + leftPadding + rightPadding) - - onClicked: { - Quickshell.clipboardText = notificationObject.body - copyIcon.text = "inventory" - copyIconTimer.restart() - } - - Timer { - id: copyIconTimer - interval: 1500 - repeat: false - onTriggered: { - copyIcon.text = "content_copy" + contentItem: MaterialSymbol { + iconSize: Appearance.font.pixelSize.large + horizontalAlignment: Text.AlignHCenter + color: (notificationObject.urgency == NotificationUrgency.Critical) ? + Appearance.m3colors.m3onSurfaceVariant : Appearance.m3colors.m3onSurface + text: "close" } } - contentItem: MaterialSymbol { - id: copyIcon - iconSize: Appearance.font.pixelSize.large - horizontalAlignment: Text.AlignHCenter - color: (notificationObject.urgency == NotificationUrgency.Critical) ? - Appearance.m3colors.m3onSurfaceVariant : Appearance.m3colors.m3onSurface - text: "content_copy" + Repeater { + id: actionRepeater + model: notificationObject.actions + NotificationActionButton { + Layout.fillWidth: true + buttonText: modelData.text + urgency: notificationObject.urgency + onClicked: { + Notifications.attemptInvokeAction(notificationObject.notificationId, modelData.identifier); + } + } } + + NotificationActionButton { + Layout.fillWidth: true + urgency: notificationObject.urgency + implicitWidth: (notificationObject.actions.length == 0) ? ((actionsFlickable.width - actionRowLayout.spacing) / 2) : + (contentItem.implicitWidth + leftPadding + rightPadding) + + onClicked: { + Quickshell.clipboardText = notificationObject.body + copyIcon.text = "inventory" + copyIconTimer.restart() + } + + Timer { + id: copyIconTimer + interval: 1500 + repeat: false + onTriggered: { + copyIcon.text = "content_copy" + } + } + + contentItem: MaterialSymbol { + id: copyIcon + iconSize: Appearance.font.pixelSize.large + horizontalAlignment: Text.AlignHCenter + color: (notificationObject.urgency == NotificationUrgency.Critical) ? + Appearance.m3colors.m3onSurfaceVariant : Appearance.m3colors.m3onSurface + text: "content_copy" + } + } + } - } } } diff --git a/.config/quickshell/ii/modules/common/widgets/ScrollEdgeFade.qml b/.config/quickshell/ii/modules/common/widgets/ScrollEdgeFade.qml new file mode 100644 index 000000000..5c19f818a --- /dev/null +++ b/.config/quickshell/ii/modules/common/widgets/ScrollEdgeFade.qml @@ -0,0 +1,59 @@ +import QtQuick +import qs.modules.common +import qs.modules.common.functions + +Item { + id: root + z: 99 + required property Item target + property real fadeSize: Appearance.m3colors.darkmode ? 40 : 20 + property color color: ColorUtils.transparentize(Appearance.colors.colShadow, Appearance.m3colors.darkmode ? 0 : 0.7) + property bool vertical: true + + anchors.fill: target + + EndGradient { + anchors { + top: parent.top + left: parent.left + right: vertical ? parent.right : undefined + bottom: vertical ? undefined : parent.bottom + } + shown: !(root.vertical ? root.target.atYBeginning : root.target.atXBeginning) + } + + EndGradient { + anchors { + bottom: parent.bottom + right: parent.right + left: vertical ? parent.left : undefined + top: vertical ? undefined : parent.top + } + shown: !(root.vertical ? root.target.atYEnd : root.target.atXEnd) + rotation: 180 + } + + component EndGradient: Rectangle { + required property bool shown + height: vertical ? root.fadeSize : parent.height + width: vertical ? parent.width : root.fadeSize + + opacity: shown ? 1 : 0 + visible: opacity > 0 + Behavior on opacity { + animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) + } + + gradient: Gradient { + orientation: root.vertical ? Gradient.Vertical : Gradient.Horizontal + GradientStop { + position: 0.0 + color: root.color + } + GradientStop { + position: 1.0 + color: ColorUtils.transparentize(root.color) + } + } + } +} diff --git a/.config/quickshell/ii/modules/common/widgets/StyledFlickable.qml b/.config/quickshell/ii/modules/common/widgets/StyledFlickable.qml index 1f32326d9..10994ee00 100644 --- a/.config/quickshell/ii/modules/common/widgets/StyledFlickable.qml +++ b/.config/quickshell/ii/modules/common/widgets/StyledFlickable.qml @@ -50,4 +50,5 @@ Flickable { root.scrollTargetY = root.contentY; } } + } diff --git a/.config/quickshell/ii/modules/sidebarLeft/AiChat.qml b/.config/quickshell/ii/modules/sidebarLeft/AiChat.qml index ef232fbaa..b746e9482 100644 --- a/.config/quickshell/ii/modules/sidebarLeft/AiChat.qml +++ b/.config/quickshell/ii/modules/sidebarLeft/AiChat.qml @@ -308,6 +308,20 @@ Inline w/ backslash and round brackets \\(e^{i\\pi} + 1 = 0\\) Item { // Messages Layout.fillWidth: true Layout.fillHeight: true + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: swipeView.width + height: swipeView.height + radius: Appearance.rounding.small + } + } + + ScrollEdgeFade { + target: messageListView + vertical: true + } + StyledListView { // Message list id: messageListView anchors.fill: parent @@ -318,8 +332,8 @@ Inline w/ backslash and round brackets \\(e^{i\\pi} + 1 = 0\\) mouseScrollFactor: Config.options.interactions.scrolling.mouseScrollFactor * 1.4 property int lastResponseLength: 0 - property bool shouldAutoScroll: true + onContentYChanged: shouldAutoScroll = atYEnd onContentHeightChanged: { if (shouldAutoScroll) positionViewAtEnd(); @@ -328,16 +342,6 @@ Inline w/ backslash and round brackets \\(e^{i\\pi} + 1 = 0\\) if (shouldAutoScroll) positionViewAtEnd(); } - clip: true - layer.enabled: true - layer.effect: OpacityMask { - maskSource: Rectangle { - width: swipeView.width - height: swipeView.height - radius: Appearance.rounding.small - } - } - add: null // Prevent function calls from being janky model: ScriptModel { diff --git a/.config/quickshell/ii/modules/sidebarLeft/Anime.qml b/.config/quickshell/ii/modules/sidebarLeft/Anime.qml index 9e7bfb480..19b930958 100644 --- a/.config/quickshell/ii/modules/sidebarLeft/Anime.qml +++ b/.config/quickshell/ii/modules/sidebarLeft/Anime.qml @@ -141,6 +141,21 @@ Item { Item { Layout.fillWidth: true Layout.fillHeight: true + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: swipeView.width + height: swipeView.height + radius: Appearance.rounding.small + } + } + + ScrollEdgeFade { + target: booruResponseListView + vertical: true + } + StyledListView { // Booru responses id: booruResponseListView anchors.fill: parent @@ -151,16 +166,6 @@ Item { property int lastResponseLength: 0 - clip: true - layer.enabled: true - layer.effect: OpacityMask { - maskSource: Rectangle { - width: swipeView.width - height: swipeView.height - radius: Appearance.rounding.small - } - } - model: ScriptModel { values: { if(root.responses.length > booruResponseListView.lastResponseLength) { diff --git a/.config/quickshell/ii/modules/sidebarLeft/Translator.qml b/.config/quickshell/ii/modules/sidebarLeft/Translator.qml index e9e3d6fe9..b56681fb2 100644 --- a/.config/quickshell/ii/modules/sidebarLeft/Translator.qml +++ b/.config/quickshell/ii/modules/sidebarLeft/Translator.qml @@ -101,7 +101,7 @@ Item { ColumnLayout { anchors.fill: parent - Flickable { + StyledFlickable { Layout.fillWidth: true Layout.fillHeight: true contentHeight: contentColumn.implicitHeight diff --git a/.config/quickshell/ii/modules/sidebarLeft/anime/BooruResponse.qml b/.config/quickshell/ii/modules/sidebarLeft/anime/BooruResponse.qml index 9e021e584..cfb2a7f9d 100644 --- a/.config/quickshell/ii/modules/sidebarLeft/anime/BooruResponse.qml +++ b/.config/quickshell/ii/modules/sidebarLeft/anime/BooruResponse.qml @@ -105,7 +105,6 @@ Rectangle { return true } implicitHeight: tagRowLayout.implicitHeight - // height: tagRowLayout.implicitHeight contentWidth: tagRowLayout.implicitWidth clip: true @@ -118,9 +117,6 @@ Rectangle { } } - Behavior on height { - animation: Appearance.animation.elementMove.numberAnimation.createObject(this) - } Behavior on implicitHeight { animation: Appearance.animation.elementMove.numberAnimation.createObject(this) }