diff --git a/config/quickshell/.config/quickshell/Modules/Bar/Modules/Time.qml b/config/quickshell/.config/quickshell/Modules/Bar/Modules/Time.qml index 8ea928a..7a323db 100644 --- a/config/quickshell/.config/quickshell/Modules/Bar/Modules/Time.qml +++ b/config/quickshell/.config/quickshell/Modules/Bar/Modules/Time.qml @@ -1,28 +1,102 @@ import QtQuick +import QtQuick.Layouts import Quickshell.Io +import qs.Components import qs.Constants import qs.Services -Text { - text: TimeService.time + " | " + TimeService.dateString - font.pointSize: Style.fontSizeM - font.family: Fonts.primary - color: Colors.mPrimary +Item { + id: root - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton - cursorShape: Qt.PointingHandCursor - onClicked: { - action.running = !action.running; + readonly property int switchDistance: Style.barHeight + readonly property int animationDuration: Style.animationNormal + + implicitWidth: Math.max(timeLayer.implicitWidth, notiLayer.implicitWidth) + implicitHeight: Math.max(timeLayer.implicitHeight, notiLayer.implicitHeight) + clip: true + + UText { + id: timeLayer + + readonly property real restY: (root.height - implicitHeight) / 2 + + anchors.horizontalCenter: parent.horizontalCenter + y: TempNotificationService.active ? restY + root.switchDistance : restY + opacity: TempNotificationService.active ? 0 : 1 + text: TimeService.time + " | " + TimeService.dateString + color: Colors.mPrimary + + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.LeftButton + cursorShape: Qt.PointingHandCursor + onClicked: { + action.running = !action.running; + } } + + Process { + id: action + + running: false + command: ["vicinae", "toggle"] + } + + Behavior on y { + NumberAnimation { + duration: root.animationDuration + easing.type: Easing.OutCubic + } + + } + + Behavior on opacity { + NumberAnimation { + duration: root.animationDuration + easing.type: Easing.OutCubic + } + + } + } - Process { - id: action + RowLayout { + id: notiLayer + + readonly property real restY: (root.height - implicitHeight) / 2 + + anchors.horizontalCenter: parent.horizontalCenter + y: TempNotificationService.active ? restY : restY - root.switchDistance + opacity: TempNotificationService.active ? 1 : 0 + spacing: Style.marginXS + + UIcon { + visible: TempNotificationService.iconName !== "" + iconName: TempNotificationService.iconName + color: Colors.mPrimary + } + + UText { + text: TempNotificationService.message + color: Colors.mPrimary + } + + Behavior on y { + NumberAnimation { + duration: root.animationDuration + easing.type: Easing.OutCubic + } + + } + + Behavior on opacity { + NumberAnimation { + duration: root.animationDuration + easing.type: Easing.OutCubic + } + + } - running: false - command: ["vicinae", "toggle"] } } diff --git a/config/quickshell/.config/quickshell/Services/AudioService.qml b/config/quickshell/.config/quickshell/Services/AudioService.qml index 6a4ebb4..ba7e91e 100644 --- a/config/quickshell/.config/quickshell/Services/AudioService.qml +++ b/config/quickshell/.config/quickshell/Services/AudioService.qml @@ -633,4 +633,20 @@ Singleton { } Pipewire.preferredDefaultAudioSource = newSource; } + + onMutedChanged: { + if (root.muted) { + TempNotificationService.showWithIcon("volume-mute", "Muted"); + } else { + TempNotificationService.showWithIcon(root.getOutputIcon(), Math.round(root.volume * 100) + "%"); + } + } + + onInputMutedChanged: { + if (root.inputMuted) { + TempNotificationService.showWithIcon("microphone-mute", "Input Muted"); + } else { + TempNotificationService.showWithIcon("microphone", "Input Unmuted"); + } + } } diff --git a/config/quickshell/.config/quickshell/Services/Caffeine.qml b/config/quickshell/.config/quickshell/Services/Caffeine.qml index c8a0de7..093289b 100644 --- a/config/quickshell/.config/quickshell/Services/Caffeine.qml +++ b/config/quickshell/.config/quickshell/Services/Caffeine.qml @@ -1,6 +1,7 @@ import QtQuick import Quickshell import Quickshell.Io +import qs.Services import qs.Utils pragma Singleton @@ -161,6 +162,9 @@ Singleton { Component.onDestruction: { stopInhibition(); } + onIsInhibitedChanged: { + TempNotificationService.showWithIcon("mug-filled", isInhibited ? "Inhibition active: " + reason : "Inhibition stopped"); + } // Process for maintaining the inhibition (subprocess fallback only) Process { diff --git a/config/quickshell/.config/quickshell/Services/IPCService.qml b/config/quickshell/.config/quickshell/Services/IPCService.qml index adc29e8..8f7f5c4 100644 --- a/config/quickshell/.config/quickshell/Services/IPCService.qml +++ b/config/quickshell/.config/quickshell/Services/IPCService.qml @@ -153,4 +153,16 @@ Item { target: "notes" } + IpcHandler { + function showMsg(message: string, duration: int) { + TempNotificationService.show(message, duration); + } + + function showWithIcon(iconName: string, message: string, duration: int) { + TempNotificationService.showWithIcon(iconName, message, duration); + } + + target: "tempNotification" + } + } diff --git a/config/quickshell/.config/quickshell/Services/LyricsService.qml b/config/quickshell/.config/quickshell/Services/LyricsService.qml index 6fcf8ee..03d27f0 100644 --- a/config/quickshell/.config/quickshell/Services/LyricsService.qml +++ b/config/quickshell/.config/quickshell/Services/LyricsService.qml @@ -193,7 +193,10 @@ Singleton { } } onInternalPositionChanged: updateIndex() - onLyricsOffsetChanged: updateIndex() + onLyricsOffsetChanged: () => { + TempNotificationService.showWithIcon("hourglass-empty", root.lyricsOffset + "ms"); + updateIndex() + } Connections { function onCurrentPlayerChanged() { diff --git a/config/quickshell/.config/quickshell/Services/MediaService.qml b/config/quickshell/.config/quickshell/Services/MediaService.qml index af8d6c7..197e288 100644 --- a/config/quickshell/.config/quickshell/Services/MediaService.qml +++ b/config/quickshell/.config/quickshell/Services/MediaService.qml @@ -280,6 +280,9 @@ Singleton { currentPosition = 0; } + onTrackTitleChanged: { + TempNotificationService.showWithIcon("music", trackArtist + " - " + trackTitle, 3000); + } // Update progress bar every second while playing Timer { diff --git a/config/quickshell/.config/quickshell/Services/SunsetService.qml b/config/quickshell/.config/quickshell/Services/SunsetService.qml index f00dfd2..1cf59e6 100644 --- a/config/quickshell/.config/quickshell/Services/SunsetService.qml +++ b/config/quickshell/.config/quickshell/Services/SunsetService.qml @@ -46,8 +46,10 @@ Singleton { if (!sunsetProcess.running) { temperature = 0; Logger.i("Sunset", "Stopped sunset process"); + TempNotificationService.showWithIcon("sunset-2-filled", "Sunset disabled"); } else { Logger.i("Sunset", "Started sunset process"); + TempNotificationService.showWithIcon("sunset-2-filled", "Sunset enabled"); } } diff --git a/config/quickshell/.config/quickshell/Services/TempNotificationService.qml b/config/quickshell/.config/quickshell/Services/TempNotificationService.qml new file mode 100644 index 0000000..6c6aaa0 --- /dev/null +++ b/config/quickshell/.config/quickshell/Services/TempNotificationService.qml @@ -0,0 +1,38 @@ +pragma Singleton + +import QtQuick +import Quickshell + +Singleton { + id: root + + readonly property int defaultDuration: 2000 + + property bool active: false + property string message: "" + property string iconName: "" + + function show(message: string, duration: int) { + root._showInternal("", message, duration); + } + + function showWithIcon(iconName: string, message: string, duration: int) { + root._showInternal(iconName, message, duration); + } + + function _showInternal(iconName: string, message: string, duration: int) { + root.iconName = iconName; + root.message = message; + root.active = true; + resetTimer.interval = duration > 0 ? duration : root.defaultDuration; + resetTimer.restart(); + } + + Timer { + id: resetTimer + + repeat: false + onTriggered: root.active = false + } + +}