import QtQuick import Quickshell import Quickshell.Wayland import "../../config" as Cfg PanelWindow { required property var modelData screen: modelData color: "transparent" anchors { top: true; bottom: true; left: true; right: true } WlrLayershell.layer: WlrLayer.Background WlrLayershell.exclusiveZone: -1 mask: Region {} property string fullDateString: "" property int typedChars: 0 property string secondsString: "" function startTyping() { typedChars = 0; secondsText.opacity = 0; typingTimer.start(); } function updateDate() { let d = new Date(); fullDateString = d.toLocaleDateString(Qt.locale(), "dddd, d MMMM yyyy"); startTyping(); } function updateSeconds() { let d = new Date(); secondsString = Qt.formatTime(d, "hh:mm:ss"); } Component.onCompleted: { updateSeconds(); updateDate(); } Column { anchors.centerIn: parent spacing: 10 Text { id: dateText anchors.horizontalCenter: parent.horizontalCenter color: Cfg.Config.theme.bgDateText styleColor: Cfg.Config.theme.bgDateShadow font.pixelSize: 64 font.weight: Font.ExtraLight font.letterSpacing: 4 opacity: 0.55 style: Text.DropShadow text: fullDateString.substring(0, typedChars) } Text { id: secondsText anchors.horizontalCenter: parent.horizontalCenter color: Cfg.Config.theme.bgDateSecondsText styleColor: Cfg.Config.theme.bgDateShadow font.pixelSize: 22 font.weight: Font.ExtraLight font.letterSpacing: 6 opacity: 0 style: Text.DropShadow text: secondsString Behavior on opacity { NumberAnimation { duration: 700 easing.type: Easing.InOutQuad } } } } Timer { id: typingTimer interval: 55 repeat: true onTriggered: { if (typedChars < fullDateString.length) { typedChars++; } else { stop(); secondsText.opacity = 0.55; } } } Timer { interval: 1000 running: true repeat: true onTriggered: { updateSeconds(); let d = new Date(); if (d.getSeconds() === 0 && d.getMinutes() === 0 && d.getHours() === 0) updateDate(); } } }