diff options
| author | nippy <you@example.com> | 2026-04-18 13:49:56 +0200 |
|---|---|---|
| committer | nippy <you@example.com> | 2026-04-18 13:49:56 +0200 |
| commit | 5d94c0a7d44a2255b81815a52a7056a94a39842d (patch) | |
| tree | 759bdea9645c6a62f9e1e4c001f7d81cccd120d2 /raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview | |
| parent | e79cdf210b267f21a186255ce1a4d50029439d54 (diff) | |
| download | RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.tar.gz RaveOS-PKGBUILD-5d94c0a7d44a2255b81815a52a7056a94a39842d.zip | |
update Raveos themes
Diffstat (limited to 'raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview')
7 files changed, 1269 insertions, 0 deletions
diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/CalendarOverviewCard.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/CalendarOverviewCard.qml new file mode 100644 index 0000000..1972f06 --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/CalendarOverviewCard.qml @@ -0,0 +1,539 @@ +import QtQuick +import Quickshell +import qs.Common +import qs.Services +import qs.Widgets + +Rectangle { + id: root + + implicitWidth: SettingsData.showWeekNumber ? 736 : 700 + + property bool showEventDetails: false + property date selectedDate: systemClock.date + property var selectedDateEvents: [] + property bool hasEvents: selectedDateEvents && selectedDateEvents.length > 0 + + signal closeDash + + function weekStartQt() { + if (SettingsData.firstDayOfWeek >= 7 || SettingsData.firstDayOfWeek < 0) { + return Qt.locale().firstDayOfWeek; + } + return SettingsData.firstDayOfWeek; + } + + function weekStartJs() { + return weekStartQt() % 7; + } + + function startOfWeek(dateObj) { + const d = new Date(dateObj); + const jsDow = d.getDay(); + const diff = (jsDow - weekStartJs() + 7) % 7; + d.setDate(d.getDate() - diff); + return d; + } + + function endOfWeek(dateObj) { + const d = new Date(dateObj); + const jsDow = d.getDay(); + const add = (weekStartJs() + 6 - jsDow + 7) % 7; + d.setDate(d.getDate() + add); + return d; + } + + function getWeekNumber(dateObj) { + // Set time to noon to avoid potential Daylight Saving Time related bugs + const weekStartDay = startOfWeek(dateObj); + weekStartDay.setHours(12, 0, 0, 0); + + let week1Start; + + if (weekStartJs() === 1) { + // ISO 8601 Standard, week start on Monday + // A week belongs to the year its Thursday falls in + // So we have to get the yearTarget from weekStartDay instead of dateObj + let yearTarget = weekStartDay; + yearTarget.setDate(yearTarget.getDate() + 3); // Monday + 3 = Thursday + + // Week 1 is the week containing Jan 4th + const jan4 = new Date(yearTarget.getFullYear(), 0, 4); + week1Start = startOfWeek(jan4); + } else { + // Traditional / US Standard, week start on Sunday + // A week belongs to the year its Sunday falls in + let yearTarget = weekStartDay; + yearTarget.setDate(yearTarget.getDate() + 6); // Monday + 6 = Sunday + + // Week 1 is the week containing Jan 1st + const jan1 = new Date(yearTarget.getFullYear(), 0, 1); + week1Start = startOfWeek(jan1); + } + + week1Start.setHours(12, 0, 0, 0); + + const diffDays = Math.round((weekStartDay.getTime() - week1Start.getTime()) / 86400000); // Number of miliseconds in a day + return Math.floor(diffDays / 7) + 1; + } + + function updateSelectedDateEvents() { + if (CalendarService && CalendarService.khalAvailable) { + const events = CalendarService.getEventsForDate(selectedDate); + selectedDateEvents = events; + } else { + selectedDateEvents = []; + } + } + + function loadEventsForMonth() { + if (!CalendarService || !CalendarService.khalAvailable) { + return; + } + + const firstOfMonth = new Date(calendarGrid.displayDate.getFullYear(), calendarGrid.displayDate.getMonth(), 1); + const lastOfMonth = new Date(calendarGrid.displayDate.getFullYear(), calendarGrid.displayDate.getMonth() + 1, 0); + + const startDate = startOfWeek(firstOfMonth); + startDate.setDate(startDate.getDate() - 7); + + const endDate = endOfWeek(lastOfMonth); + endDate.setDate(endDate.getDate() + 7); + + CalendarService.loadEvents(startDate, endDate); + } + + onSelectedDateChanged: updateSelectedDateEvents() + Component.onCompleted: { + loadEventsForMonth(); + updateSelectedDateEvents(); + } + + Connections { + function onEventsByDateChanged() { + updateSelectedDateEvents(); + } + + function onKhalAvailableChanged() { + if (CalendarService && CalendarService.khalAvailable) { + loadEventsForMonth(); + } + updateSelectedDateEvents(); + } + + target: CalendarService + enabled: CalendarService !== null + } + + radius: Theme.cornerRadius + color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05) + border.width: 1 + + Column { + anchors.fill: parent + anchors.margins: Theme.spacingM + spacing: Theme.spacingS + + Item { + width: parent.width + height: 40 + visible: showEventDetails + + Rectangle { + width: 32 + height: 32 + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: Theme.spacingS + radius: Theme.cornerRadius + color: backButtonArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + DankIcon { + anchors.centerIn: parent + name: "arrow_back" + size: 14 + color: Theme.primary + } + + MouseArea { + id: backButtonArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: root.showEventDetails = false + } + } + + StyledText { + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 32 + Theme.spacingS * 2 + anchors.rightMargin: Theme.spacingS + height: 40 + anchors.verticalCenter: parent.verticalCenter + text: { + const dateStr = Qt.formatDate(selectedDate, "MMM d"); + if (selectedDateEvents && selectedDateEvents.length > 0) { + const eventCount = selectedDateEvents.length === 1 ? I18n.tr("1 event") : selectedDateEvents.length + " " + I18n.tr("events"); + return dateStr + " • " + eventCount; + } + return dateStr; + } + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceText + font.weight: Font.Medium + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + } + + Row { + width: parent.width + height: 28 + visible: !showEventDetails + + Rectangle { + width: 28 + height: 28 + radius: Theme.cornerRadius + color: prevMonthArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + DankIcon { + anchors.centerIn: parent + name: "chevron_left" + size: 14 + color: Theme.primary + } + + MouseArea { + id: prevMonthArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + let newDate = new Date(calendarGrid.displayDate); + newDate.setMonth(newDate.getMonth() - 1); + calendarGrid.displayDate = newDate; + loadEventsForMonth(); + } + } + } + + StyledText { + width: parent.width - 56 + height: 28 + text: calendarGrid.displayDate.toLocaleDateString(I18n.locale(), "MMMM yyyy") + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceText + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + Rectangle { + width: 28 + height: 28 + radius: Theme.cornerRadius + color: nextMonthArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" + + DankIcon { + anchors.centerIn: parent + name: "chevron_right" + size: 14 + color: Theme.primary + } + + MouseArea { + id: nextMonthArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + let newDate = new Date(calendarGrid.displayDate); + newDate.setMonth(newDate.getMonth() + 1); + calendarGrid.displayDate = newDate; + loadEventsForMonth(); + } + } + } + } + + Row { + width: parent.width + height: parent.height - 28 - Theme.spacingS + visible: !showEventDetails + spacing: SettingsData.showWeekNumber ? Theme.spacingS : 0 + + Column { + id: weekNumberColumn + visible: SettingsData.showWeekNumber + width: SettingsData.showWeekNumber ? 28 : 0 + height: parent.height + spacing: Theme.spacingS + + Item { + width: parent.width + height: 18 + } + + Grid { + width: parent.width + height: parent.height - 18 - Theme.spacingS + columns: 1 + rows: 6 + + Repeater { + model: 6 + Rectangle { + width: parent.width + height: parent.height / 6 + color: "transparent" + + StyledText { + anchors.centerIn: parent + text: { + const rowDate = new Date(calendarGrid.firstDay); + rowDate.setDate(rowDate.getDate() + index * 7); + return root.getWeekNumber(rowDate); + } + font.pixelSize: Theme.fontSizeSmall + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6) + font.weight: Font.Medium + } + } + } + } + } + + Column { + width: SettingsData.showWeekNumber ? (parent.width - weekNumberColumn.width - parent.spacing) : parent.width + height: parent.height + spacing: Theme.spacingS + + Row { + width: parent.width + height: 18 + + Repeater { + model: { + const days = []; + const qtFirst = weekStartQt(); + for (let i = 0; i < 7; ++i) { + const qtDay = ((qtFirst - 1 + i) % 7) + 1; + days.push(I18n.locale().dayName(qtDay, Locale.ShortFormat)); + } + return days; + } + + Rectangle { + width: parent.width / 7 + height: 18 + color: "transparent" + + StyledText { + anchors.centerIn: parent + text: modelData + font.pixelSize: Theme.fontSizeSmall + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6) + font.weight: Font.Medium + } + } + } + } + + Grid { + id: calendarGrid + width: parent.width + height: parent.height - 18 - Theme.spacingS + columns: 7 + rows: 6 + + property date displayDate: systemClock.date + property date selectedDate: systemClock.date + + readonly property date firstDay: { + const firstOfMonth = new Date(displayDate.getFullYear(), displayDate.getMonth(), 1); + return startOfWeek(firstOfMonth); + } + + Repeater { + model: 42 + + Rectangle { + readonly property date dayDate: { + const date = new Date(parent.firstDay); + date.setDate(date.getDate() + index); + return date; + } + readonly property bool isCurrentMonth: dayDate.getMonth() === calendarGrid.displayDate.getMonth() + readonly property bool isToday: dayDate.toDateString() === new Date().toDateString() + readonly property bool isSelected: dayDate.toDateString() === calendarGrid.selectedDate.toDateString() + + width: parent.width / 7 + height: parent.height / 6 + color: "transparent" + + Rectangle { + anchors.centerIn: parent + width: Math.min(parent.width - 4, parent.height - 4, 32) + height: width + color: isToday ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : dayArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" + radius: Theme.cornerRadius + + StyledText { + anchors.centerIn: parent + text: dayDate.getDate() + font.pixelSize: Theme.fontSizeSmall + color: isToday ? Theme.primary : isCurrentMonth ? Theme.surfaceText : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.4) + font.weight: isToday ? Font.Medium : Font.Normal + } + + Rectangle { + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 4 + width: 12 + height: 2 + radius: Theme.cornerRadius + visible: CalendarService && CalendarService.khalAvailable && CalendarService.hasEventsForDate(dayDate) + color: isToday ? Qt.lighter(Theme.primary, 1.3) : Theme.primary + opacity: isToday ? 0.9 : 0.7 + + Behavior on opacity { + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + } + } + + MouseArea { + id: dayArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { + if (CalendarService && CalendarService.khalAvailable && CalendarService.hasEventsForDate(dayDate)) { + root.selectedDate = dayDate; + root.showEventDetails = true; + } + } + } + } + } + } + } + } + + DankListView { + width: parent.width - Theme.spacingS * 2 + height: parent.height - (showEventDetails ? 40 : 28 + 18) - Theme.spacingS + anchors.horizontalCenter: parent.horizontalCenter + model: selectedDateEvents + visible: showEventDetails + clip: true + spacing: Theme.spacingXS + + delegate: Rectangle { + width: parent ? parent.width : 0 + height: eventContent.implicitHeight + Theme.spacingS + radius: Theme.cornerRadius + color: { + if (modelData.url && eventMouseArea.containsMouse) { + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12); + } else if (eventMouseArea.containsMouse) { + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.06); + } + return Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency); + } + border.color: { + if (modelData.url && eventMouseArea.containsMouse) { + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3); + } else if (eventMouseArea.containsMouse) { + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.15); + } + return "transparent"; + } + border.width: 1 + + Rectangle { + width: 3 + height: parent.height - 6 + anchors.left: parent.left + anchors.leftMargin: 3 + anchors.verticalCenter: parent.verticalCenter + radius: Theme.cornerRadius + color: Theme.primary + opacity: 0.8 + } + + Column { + id: eventContent + + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: Theme.spacingS + 6 + anchors.rightMargin: Theme.spacingXS + spacing: 2 + + StyledText { + width: parent.width + text: modelData.title + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Medium + elide: Text.ElideRight + maximumLineCount: 1 + } + + StyledText { + width: parent.width + text: { + if (!modelData || modelData.allDay) { + return I18n.tr("All day"); + } else if (modelData.start && modelData.end) { + const timeFormat = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP"; + const startTime = Qt.formatTime(modelData.start, timeFormat); + if (modelData.start.toDateString() !== modelData.end.toDateString() || modelData.start.getTime() !== modelData.end.getTime()) { + return startTime + " – " + Qt.formatTime(modelData.end, timeFormat); + } + return startTime; + } + return ""; + } + font.pixelSize: Theme.fontSizeSmall + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7) + font.weight: Font.Normal + visible: text !== "" + } + } + + MouseArea { + id: eventMouseArea + + anchors.fill: parent + hoverEnabled: true + cursorShape: modelData.url ? Qt.PointingHandCursor : Qt.ArrowCursor + enabled: modelData.url !== "" + onClicked: { + if (modelData.url && modelData.url !== "") { + if (Qt.openUrlExternally(modelData.url) === false) { + console.warn("Failed to open URL: " + modelData.url); + } else { + root.closeDash(); + } + } + } + } + } + } + } + + SystemClock { + id: systemClock + precision: SystemClock.Hours + } +} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/Card.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/Card.qml new file mode 100644 index 0000000..8996c81 --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/Card.qml @@ -0,0 +1,24 @@ +import QtQuick +import qs.Common + +Rectangle { + id: card + + LayoutMirroring.enabled: I18n.isRtl + LayoutMirroring.childrenInherit: true + + property int pad: Theme.spacingM + + radius: Theme.cornerRadius + color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) + border.width: 1 + + default property alias content: contentItem.data + + Item { + id: contentItem + anchors.fill: parent + anchors.margins: card.pad + } +} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/ClockCard.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/ClockCard.qml new file mode 100644 index 0000000..5f597c3 --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/ClockCard.qml @@ -0,0 +1,113 @@ +import QtQuick +import QtQuick.Effects +import Quickshell +import qs.Common +import qs.Widgets + +Card { + id: root + + Column { + anchors.centerIn: parent + spacing: 0 + + Column { + spacing: -8 + anchors.horizontalCenter: parent.horizontalCenter + + Row { + spacing: 0 + anchors.horizontalCenter: parent.horizontalCenter + + StyledText { + text: { + if (SettingsData.use24HourClock) { + return String(systemClock?.date?.getHours()).padStart(2, '0').charAt(0) + } else { + const hours = systemClock?.date?.getHours() + const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours + return String(display).padStart(2, '0').charAt(0) + } + } + font.pixelSize: 48 + color: Theme.primary + font.weight: Font.Medium + width: 28 + horizontalAlignment: Text.AlignHCenter + } + + StyledText { + text: { + if (SettingsData.use24HourClock) { + return String(systemClock?.date?.getHours()).padStart(2, '0').charAt(1) + } else { + const hours = systemClock?.date?.getHours() + const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours + return String(display).padStart(2, '0').charAt(1) + } + } + font.pixelSize: 48 + color: Theme.primary + font.weight: Font.Medium + width: 28 + horizontalAlignment: Text.AlignHCenter + } + } + + Row { + spacing: 0 + anchors.horizontalCenter: parent.horizontalCenter + + StyledText { + text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(0) + font.pixelSize: 48 + color: Theme.primary + font.weight: Font.Medium + width: 28 + horizontalAlignment: Text.AlignHCenter + } + + StyledText { + text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(1) + font.pixelSize: 48 + color: Theme.primary + font.weight: Font.Medium + width: 28 + horizontalAlignment: Text.AlignHCenter + } + } + } + + Row { + visible: SettingsData.showSeconds + spacing: 0 + anchors.horizontalCenter: parent.horizontalCenter + + StyledText { + text: String(systemClock?.date?.getSeconds()).padStart(2, '0') + font.pixelSize: 24 + color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.7) + font.weight: Font.Medium + horizontalAlignment: Text.AlignHCenter + } + } + + Item { + width: 1 + height: Theme.spacingXS + anchors.horizontalCenter: parent.horizontalCenter + } + + StyledText { + text: systemClock?.date?.toLocaleDateString(I18n.locale(), "MMM dd") + font.pixelSize: Theme.fontSizeSmall + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7) + anchors.horizontalCenter: parent.horizontalCenter + } + } + + SystemClock { + id: systemClock + precision: SettingsData.showSeconds ? SystemClock.Seconds : SystemClock.Minutes + } +} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/MediaOverviewCard.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/MediaOverviewCard.qml new file mode 100644 index 0000000..35f4f47 --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/MediaOverviewCard.qml @@ -0,0 +1,211 @@ +import QtQuick +import QtQuick.Effects +import QtQuick.Shapes +import Quickshell.Services.Mpris +import qs.Common +import qs.Services +import qs.Widgets + +Card { + id: root + clip: false + + signal clicked() + + property MprisPlayer activePlayer: MprisController.activePlayer + property real currentPosition: activePlayer?.positionSupported ? activePlayer.position : 0 + property real displayPosition: currentPosition + + readonly property real ratio: { + if (!activePlayer || activePlayer.length <= 0) return 0 + const pos = displayPosition % Math.max(1, activePlayer.length) + const calculatedRatio = pos / activePlayer.length + return Math.max(0, Math.min(1, calculatedRatio)) + } + + onActivePlayerChanged: { + if (activePlayer?.positionSupported) { + currentPosition = Qt.binding(() => activePlayer?.position || 0) + } else { + currentPosition = 0 + } + } + + Timer { + interval: 300 + running: activePlayer?.playbackState === MprisPlaybackState.Playing && !isSeeking + repeat: true + onTriggered: activePlayer?.positionSupported && activePlayer.positionChanged() + } + + property bool isSeeking: false + + Column { + anchors.centerIn: parent + spacing: Theme.spacingS + visible: !activePlayer + + DankIcon { + name: "music_note" + size: Theme.iconSize + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5) + anchors.horizontalCenter: parent.horizontalCenter + } + + StyledText { + text: I18n.tr("No Media") + font.pixelSize: Theme.fontSizeSmall + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7) + anchors.horizontalCenter: parent.horizontalCenter + } + } + + Column { + anchors.centerIn: parent + width: parent.width - Theme.spacingXS * 2 + spacing: Theme.spacingL + visible: activePlayer + + Item { + width: 140 + height: 110 + anchors.horizontalCenter: parent.horizontalCenter + clip: false + + DankAlbumArt { + width: 110 + height: 80 + anchors.centerIn: parent + activePlayer: root.activePlayer + albumSize: 76 + animationScale: 1.05 + } + } + + Column { + width: parent.width + spacing: Theme.spacingXS + topPadding: Theme.spacingL + + StyledText { + text: activePlayer?.trackTitle || I18n.tr("Unknown") + font.pixelSize: Theme.fontSizeSmall + font.weight: Font.Medium + color: Theme.surfaceText + width: parent.width + elide: Text.ElideRight + maximumLineCount: 1 + horizontalAlignment: Text.AlignHCenter + } + + StyledText { + text: activePlayer?.trackArtist || I18n.tr("Unknown Artist") + font.pixelSize: Theme.fontSizeSmall + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7) + width: parent.width + elide: Text.ElideRight + maximumLineCount: 1 + horizontalAlignment: Text.AlignHCenter + } + } + + DankSeekbar { + width: parent.width + 4 + height: 20 + x: -2 + activePlayer: root.activePlayer + isSeeking: root.isSeeking + onIsSeekingChanged: root.isSeeking = isSeeking + } + + Item { + width: parent.width + height: 32 + + Row { + spacing: Theme.spacingS + anchors.centerIn: parent + + Rectangle { + width: 28 + height: 28 + radius: 14 + anchors.verticalCenter: playPauseButton.verticalCenter + color: prevArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent" + + DankIcon { + anchors.centerIn: parent + name: "skip_previous" + size: 14 + color: Theme.surfaceText + } + + MouseArea { + id: prevArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: MprisController.previousOrRewind() + } + } + + Rectangle { + id: playPauseButton + width: 32 + height: 32 + radius: 16 + color: Theme.primary + + DankIcon { + anchors.centerIn: parent + name: activePlayer?.playbackState === MprisPlaybackState.Playing ? "pause" : "play_arrow" + size: 16 + color: Theme.background + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: activePlayer?.togglePlaying() + } + } + + Rectangle { + width: 28 + height: 28 + radius: 14 + anchors.verticalCenter: playPauseButton.verticalCenter + color: nextArea.containsMouse ? Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency) : "transparent" + + DankIcon { + anchors.centerIn: parent + name: "skip_next" + size: 14 + color: Theme.surfaceText + } + + MouseArea { + id: nextArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: activePlayer?.next() + } + } + } + } + } + + MouseArea { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.bottomMargin: 123 + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: root.clicked() + visible: activePlayer + } +} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/SystemMonitorCard.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/SystemMonitorCard.qml new file mode 100644 index 0000000..cb7089b --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/SystemMonitorCard.qml @@ -0,0 +1,178 @@ +import QtQuick +import QtQuick.Effects +import qs.Common +import qs.Services +import qs.Widgets + +Card { + id: root + + Component.onCompleted: { + DgopService.addRef(["cpu", "memory", "system"]) + } + Component.onDestruction: { + DgopService.removeRef(["cpu", "memory", "system"]) + } + + Row { + anchors.fill: parent + anchors.margins: Theme.spacingS + spacing: Theme.spacingM + + // CPU Bar + Column { + width: (parent.width - 2 * Theme.spacingM) / 3 + height: parent.height + spacing: Theme.spacingS + + Rectangle { + width: 8 + height: parent.height - Theme.iconSizeSmall - Theme.spacingS + radius: 4 + anchors.horizontalCenter: parent.horizontalCenter + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) + + Rectangle { + width: parent.width + height: parent.height * Math.min((DgopService.cpuUsage || 6) / 100, 1) + radius: parent.radius + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + color: { + if (DgopService.cpuUsage > 80) return Theme.error + if (DgopService.cpuUsage > 60) return Theme.warning + return Theme.primary + } + + Behavior on height { + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + } + } + + Item { + width: parent.width + height: Theme.iconSizeSmall + + DankIcon { + name: "memory" + size: Theme.iconSizeSmall + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + color: { + if (DgopService.cpuUsage > 80) return Theme.error + if (DgopService.cpuUsage > 60) return Theme.warning + return Theme.primary + } + } + } + } + + // Temperature Bar + Column { + width: (parent.width - 2 * Theme.spacingM) / 3 + height: parent.height + spacing: Theme.spacingS + + Rectangle { + width: 8 + height: parent.height - Theme.iconSizeSmall - Theme.spacingS + radius: 4 + anchors.horizontalCenter: parent.horizontalCenter + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) + + Rectangle { + width: parent.width + height: parent.height * Math.min(Math.max((DgopService.cpuTemperature || 40) / 100, 0), 1) + radius: parent.radius + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + color: { + if (DgopService.cpuTemperature > 85) return Theme.error + if (DgopService.cpuTemperature > 69) return Theme.warning + return Theme.primary + } + + Behavior on height { + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + } + } + + Item { + width: parent.width + height: Theme.iconSizeSmall + + DankIcon { + name: "device_thermostat" + size: Theme.iconSizeSmall + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + color: { + if (DgopService.cpuTemperature > 85) return Theme.error + if (DgopService.cpuTemperature > 69) return Theme.warning + return Theme.primary + } + } + } + } + + // RAM Bar + Column { + width: (parent.width - 2 * Theme.spacingM) / 3 + height: parent.height + spacing: Theme.spacingS + + Rectangle { + width: 8 + height: parent.height - Theme.iconSizeSmall - Theme.spacingS + radius: 4 + anchors.horizontalCenter: parent.horizontalCenter + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) + + Rectangle { + width: parent.width + height: parent.height * Math.min((DgopService.memoryUsage || 42) / 100, 1) + radius: parent.radius + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + color: { + if (DgopService.memoryUsage > 90) return Theme.error + if (DgopService.memoryUsage > 75) return Theme.warning + return Theme.primary + } + + Behavior on height { + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + } + } + + Item { + width: parent.width + height: Theme.iconSizeSmall + + DankIcon { + name: "developer_board" + size: Theme.iconSizeSmall + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + color: { + if (DgopService.memoryUsage > 90) return Theme.error + if (DgopService.memoryUsage > 75) return Theme.warning + return Theme.primary + } + } + } + } + } +} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/UserInfoCard.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/UserInfoCard.qml new file mode 100644 index 0000000..0d90b44 --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/UserInfoCard.qml @@ -0,0 +1,110 @@ +import QtQuick +import qs.Common +import qs.Services +import qs.Widgets + +Card { + id: root + + LayoutMirroring.enabled: I18n.isRtl + LayoutMirroring.childrenInherit: true + + Component.onCompleted: DgopService.addRef("system") + Component.onDestruction: DgopService.removeRef("system") + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingM + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingM + + DankCircularImage { + id: avatarContainer + + width: 77 + height: 77 + anchors.verticalCenter: parent.verticalCenter + imageSource: { + if (PortalService.profileImage === "") + return ""; + + if (PortalService.profileImage.startsWith("/")) + return "file://" + PortalService.profileImage; + + return PortalService.profileImage; + } + fallbackIcon: "person" + } + + Column { + spacing: Theme.spacingS + anchors.verticalCenter: parent.verticalCenter + + StyledText { + text: UserInfoService.username || I18n.tr("brandon") + font.pixelSize: Theme.fontSizeLarge + font.weight: Font.Medium + color: Theme.surfaceText + elide: Text.ElideRight + width: parent.parent.parent.width - avatarContainer.width - Theme.spacingM * 3 + horizontalAlignment: Text.AlignLeft + } + + Row { + anchors.left: parent.left + spacing: Theme.spacingS + + SystemLogo { + width: 16 + height: 16 + anchors.verticalCenter: parent.verticalCenter + colorOverride: Theme.primary + } + + StyledText { + text: { + if (CompositorService.isNiri) + return I18n.tr("on Niri"); + if (CompositorService.isHyprland) + return I18n.tr("on Hyprland"); + // technically they might not be on mangowc, but its what we support in the docs + if (CompositorService.isDwl) + return I18n.tr("on MangoWC"); + if (CompositorService.isSway) + return I18n.tr("on Sway"); + if (CompositorService.isScroll) + return I18n.tr("on Scroll"); + if (CompositorService.isMiracle) + return I18n.tr("on Miracle WM"); + return ""; + } + font.pixelSize: Theme.fontSizeSmall + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.8) + anchors.verticalCenter: parent.verticalCenter + elide: Text.ElideRight + width: parent.parent.parent.parent.width - avatarContainer.width - Theme.spacingM * 3 - 16 - Theme.spacingS + horizontalAlignment: Text.AlignLeft + } + } + + Row { + anchors.left: parent.left + spacing: Theme.spacingS + + DankIcon { + name: "schedule" + size: 16 + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter + } + + StyledText { + text: DgopService.shortUptime || I18n.tr("up") + font.pixelSize: Theme.fontSizeSmall + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7) + anchors.verticalCenter: parent.verticalCenter + } + } + } + } +} diff --git a/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/WeatherOverviewCard.qml b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/WeatherOverviewCard.qml new file mode 100644 index 0000000..0bba92e --- /dev/null +++ b/raveos-theme/hyprland/theme-data/DankMaterialShell/quickshell/Modules/DankDash/Overview/WeatherOverviewCard.qml @@ -0,0 +1,94 @@ +import QtQuick +import QtQuick.Controls +import qs.Common +import qs.Services +import qs.Widgets + +Card { + id: root + + LayoutMirroring.enabled: I18n.isRtl + LayoutMirroring.childrenInherit: true + + signal clicked + + Component.onCompleted: WeatherService.addRef() + Component.onDestruction: WeatherService.removeRef() + + Column { + anchors.centerIn: parent + spacing: Theme.spacingS + visible: !WeatherService.weather.available + + DankIcon { + name: "cloud_off" + size: 24 + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5) + anchors.horizontalCenter: parent.horizontalCenter + } + + StyledText { + text: WeatherService.weather.loading ? I18n.tr("Loading...") : I18n.tr("No Weather") + font.pixelSize: Theme.fontSizeSmall + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7) + anchors.horizontalCenter: parent.horizontalCenter + } + + Button { + text: I18n.tr("Refresh") + flat: true + visible: !WeatherService.weather.loading + anchors.horizontalCenter: parent.horizontalCenter + onClicked: WeatherService.forceRefresh() + } + } + + Row { + anchors.left: parent.left + anchors.leftMargin: Theme.spacingL + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingL + visible: WeatherService.weather.available + + DankIcon { + name: WeatherService.getWeatherIcon(WeatherService.weather.wCode) + size: 48 + color: Theme.primary + anchors.verticalCenter: parent.verticalCenter + } + + Column { + spacing: Theme.spacingXS + anchors.verticalCenter: parent.verticalCenter + + StyledText { + anchors.left: parent.left + text: { + const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp; + if (temp === undefined || temp === null) + return "--°" + (SettingsData.useFahrenheit ? "F" : "C"); + return temp + "°" + (SettingsData.useFahrenheit ? "F" : "C"); + } + font.pixelSize: Theme.fontSizeXLarge + 4 + color: Theme.surfaceText + font.weight: Font.Light + } + + StyledText { + text: WeatherService.getWeatherCondition(WeatherService.weather.wCode) + font.pixelSize: Theme.fontSizeSmall + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7) + elide: Text.ElideRight + width: parent.parent.parent.width - 48 - Theme.spacingL * 2 + horizontalAlignment: Text.AlignLeft + } + } + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: root.clicked() + } +} |