feat: dashboard show on hover, media and weather tabs added
C++ / fmt (pull_request) Failing after 6s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 10s
JS/TS / fmt (pull_request) Successful in 13s
JS/TS / lint (pull_request) Successful in 8s
Python / static (pull_request) Successful in 30s
Rust / build (pull_request) Successful in 49s
Rust / fmt (pull_request) Successful in 26s
Python / verify (pull_request) Successful in 1m44s
Rust / clippy (pull_request) Successful in 44s

This commit is contained in:
2026-09-20 12:59:53 +02:00
parent 7bc1db7f19
commit 84d5abcaab
100 changed files with 4288 additions and 999 deletions
@@ -3,7 +3,7 @@ pragma Singleton
import QtQuick
import Quickshell
import ZShell.Llm
import qs.Helpers
import qs.Services
Singleton {
id: root
@@ -20,7 +20,7 @@ Singleton {
property bool narrowSidebarExpanded: false
property bool windowIsWide: false
property ShellScreen screen
property bool sidebarVisible: Visibilities.getForActive().sidebar
property bool sidebarVisible: ShellState.forActive().sidebar
onSidebarVisibleChanged: if (!sidebarVisible)
fabExpanded = false
@@ -3,7 +3,7 @@ pragma Singleton
import Quickshell
import QtQuick
import ZShell.Config
import qs.Helpers
import qs.Services
import qs.Services
Singleton {
@@ -11,7 +11,7 @@ Singleton {
function create(parent: Item, props: var): void {
chatComp.createObject(parent ?? dummy, props);
Visibilities.getForActive().sidebar = false;
ShellState.forActive().sidebar = false;
ChatState.isWindow = true;
}
+8 -10
View File
@@ -10,13 +10,12 @@ import qs.Services
Item {
id: root
required property Props props
required property var visibilities
required property ScreenState screenState
Connections {
function onIsWindowChanged(): void {
if (ChatState.isWindow)
root.props.currentTab = 0;
root.screenState.sidebarTab = 0;
}
target: ChatState
@@ -31,7 +30,7 @@ Item {
Tabs {
Layout.fillWidth: true
Layout.preferredHeight: ChatState.isWindow || !Config.llm.enabled ? 0 : implicitHeight
dashState: root.props
screenState: root.screenState
nonAnimWidth: layout.width
visible: height > 0
}
@@ -47,9 +46,9 @@ Item {
anchors.bottom: parent.bottom
anchors.top: parent.top
implicitWidth: parent.width
opacity: root.props.currentTab === 0 ? 1 : 0
opacity: root.screenState.sidebarTab === 0 ? 1 : 0
visible: opacity > 0
x: root.props.currentTab === 0 ? 0 : -root.width
x: root.screenState.sidebarTab === 0 ? 0 : -root.width
Behavior on opacity {
Anim {}
@@ -64,8 +63,7 @@ Item {
radius: Tokens.rounding.small
NotifDock {
props: root.props
visibilities: root.visibilities
screenState: root.screenState
}
}
}
@@ -82,9 +80,9 @@ Item {
sourceComponent: Item {
id: chatPage
opacity: root.props.currentTab === 1 ? 1 : 0
opacity: root.screenState.sidebarTab === 1 ? 1 : 0
visible: opacity > 0
x: root.props.currentTab === 0 ? root.width : 0
x: root.screenState.sidebarTab === 0 ? root.width : 0
z: 1
Behavior on opacity {
+2 -3
View File
@@ -15,8 +15,7 @@ CustomRect {
required property bool expanded
required property NotifServer.Notif modelData
readonly property real nonAnimHeight: expanded ? summary.implicitHeight + expandedContent.implicitHeight + expandedContent.anchors.topMargin + Tokens.padding.medium * 2 : summaryHeightMetrics.height
required property Props props
required property PersistentProperties visibilities
required property ScreenState screenState
color: {
const c = root.modelData?.urgency === "critical" ? Colors.palette.m3secondaryContainer : Colors.layer(Colors.palette.m3surfaceContainerHigh, 2);
@@ -137,7 +136,7 @@ CustomRect {
onLinkActivated: link => {
Qt.openUrlExternally(link);
root.visibilities.sidebar = false;
root.screenState.sidebar = false;
}
}
+2 -4
View File
@@ -14,8 +14,7 @@ Item {
id: root
readonly property int notifCount: NotifServer.list.reduce((acc, n) => n.closed ? acc : acc + 1, 0)
required property Props props
required property var visibilities
required property ScreenState screenState
anchors.fill: parent
anchors.margins: Tokens.padding.small
@@ -120,8 +119,7 @@ Item {
id: notifList
container: view
props: root.props
visibilities: root.visibilities
screenState: root.screenState
}
}
}
@@ -12,8 +12,7 @@ LazyListView {
id: root
required property Flickable container
required property Props props
required property PersistentProperties visibilities
required property ScreenState screenState
anchors.left: parent?.left
anchors.right: parent?.right
@@ -118,8 +117,7 @@ LazyListView {
container: root.container
modelData: notif.modelData
props: root.props
visibilities: root.visibilities
screenState: root.screenState
}
}
}
+6 -8
View File
@@ -16,7 +16,7 @@ CustomRect {
readonly property list<var> activeNotifs: notifs.filter(n => !n.closed)
readonly property string appIcon: activeNotifs.find(n => n.appIcon.length > 0)?.appIcon ?? ""
required property Flickable container
readonly property bool expanded: props.expandedNotifs.includes(modelData)
readonly property bool expanded: screenState.expandedNotifs.includes(modelData)
readonly property string image: activeNotifs.find(n => n.image.length > 0)?.image ?? ""
required property string modelData
readonly property int nonAnimHeight: {
@@ -26,7 +26,7 @@ CustomRect {
}
readonly property int notifCount: activeNotifs.length
readonly property list<var> notifs: NotifServer.list.filter(n => n.appName === modelData)
required property Props props
required property ScreenState screenState
readonly property int urgency: {
if (activeNotifs.find(n => n.urgency === NotificationUrgency.Critical))
return NotificationUrgency.Critical;
@@ -34,14 +34,13 @@ CustomRect {
return NotificationUrgency.Normal;
return NotificationUrgency.Low;
}
required property PersistentProperties visibilities
function toggleExpand(expand: bool): void {
if (expand) {
if (!expanded)
props.expandedNotifs.push(modelData);
screenState.expandedNotifs.push(modelData);
} else if (expanded) {
props.expandedNotifs.splice(props.expandedNotifs.indexOf(modelData), 1);
screenState.expandedNotifs.splice(screenState.expandedNotifs.indexOf(modelData), 1);
}
}
@@ -59,7 +58,7 @@ CustomRect {
Component.onDestruction: {
if (notifCount === 0 && expanded)
props.expandedNotifs.splice(props.expandedNotifs.indexOf(modelData), 1);
screenState.expandedNotifs.splice(screenState.expandedNotifs.indexOf(modelData), 1);
}
RowLayout {
@@ -233,8 +232,7 @@ CustomRect {
container: root.container
expanded: root.expanded
notifs: root.notifs
props: root.props
visibilities: root.visibilities
screenState: root.screenState
onRequestToggleExpand: expand => root.toggleExpand(expand)
}
@@ -14,8 +14,7 @@ LazyListView {
required property Flickable container
required property bool expanded
required property list<var> notifs
required property Props props
required property PersistentProperties visibilities
required property ScreenState screenState
signal requestToggleExpand(expand: bool)
@@ -122,8 +121,7 @@ LazyListView {
anchors.fill: parent
expanded: root.expanded
modelData: notif.modelData
props: root.props
visibilities: root.visibilities
screenState: root.screenState
}
}
}
-9
View File
@@ -1,9 +0,0 @@
import Quickshell
import ZShell.Llm
PersistentProperties {
property int currentTab: 0
property list<string> expandedNotifs: []
reloadableId: "sidebar"
}
+4 -4
View File
@@ -12,7 +12,7 @@ Item {
id: root
readonly property alias count: bar.count
required property PersistentProperties dashState
required property ScreenState screenState
required property real nonAnimWidth
implicitHeight: bar.implicitHeight + indicator.implicitHeight + indicator.anchors.topMargin + separator.implicitHeight
@@ -24,7 +24,7 @@ Item {
anchors.right: parent.right
anchors.top: parent.top
background: null
currentIndex: root.dashState.currentTab
currentIndex: root.screenState.sidebarTab
implicitHeight: contentHeight
contentItem: RowLayout {
@@ -35,7 +35,7 @@ Item {
}
}
onCurrentIndexChanged: root.state.currentTab = currentIndex
onCurrentIndexChanged: root.screenState.sidebarTab = currentIndex
Tab {
iconName: "notifications"
@@ -110,7 +110,7 @@ Item {
color: tab.current ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
radius: Tokens.rounding.small
onClicked: root.dashState.currentTab = tab.TabBar.index
onClicked: root.screenState.sidebarTab = tab.TabBar.index
}
MaterialIcon {
@@ -11,8 +11,8 @@ import qs.Services
CustomRect {
id: root
required property var props
required property PersistentProperties visibilities
required property ScreenState screenState
Layout.fillWidth: true
color: Colors.tPalette.m3surfaceContainer
@@ -72,7 +72,7 @@ CustomRect {
}
SplitButton {
active: menuItems.find(m => root.props.recordingMode === m.icon + m.text) ?? menuItems[0]
active: menuItems.find(m => root.screenState.recordingMode === m.icon + m.text) ?? menuItems[0]
enabled: !Recorder.running
menuOnTop: true
@@ -107,7 +107,7 @@ CustomRect {
}
]
menu.onItemSelected: item => root.props.recordingMode = item.icon + item.text
menu.onItemSelected: item => root.screenState.recordingMode = item.icon + item.text
}
}
@@ -190,8 +190,7 @@ CustomRect {
id: recordingList
RecordingList {
props: root.props
visibilities: root.visibilities
screenState: root.screenState
}
}
@@ -14,8 +14,8 @@ import qs.Services
ColumnLayout {
id: root
required property var props
required property PersistentProperties visibilities
required property ScreenState screenState
spacing: 0
@@ -23,7 +23,7 @@ ColumnLayout {
Layout.fillWidth: true
cursorShape: Qt.PointingHandCursor
onClicked: root.props.recordingListExpanded = !root.props.recordingListExpanded
onClicked: root.screenState.recordingListExpanded = !root.screenState.recordingListExpanded
RowLayout {
spacing: Tokens.spacing.small
@@ -42,11 +42,11 @@ ColumnLayout {
}
IconButton {
icon: root.props.recordingListExpanded ? "unfold_less" : "unfold_more"
icon: root.screenState.recordingListExpanded ? "unfold_less" : "unfold_more"
label.animate: true
type: IconButton.Text
onClicked: root.props.recordingListExpanded = !root.props.recordingListExpanded
onClicked: root.screenState.recordingListExpanded = !root.screenState.recordingListExpanded
}
}
}
@@ -57,7 +57,7 @@ ColumnLayout {
Layout.fillWidth: true
Layout.rightMargin: -Tokens.spacing.small
clip: true
implicitHeight: (Tokens.font.size.larger + Tokens.padding.extraSmall) * (root.props.recordingListExpanded ? 10 : 3)
implicitHeight: (Tokens.font.size.larger + Tokens.padding.extraSmall) * (root.screenState.recordingListExpanded ? 10 : 3)
CustomScrollBar.vertical: CustomScrollBar {
flickable: list
@@ -109,7 +109,7 @@ ColumnLayout {
type: IconButton.Text
onClicked: {
root.visibilities.sidebar = false;
root.screenState.sidebar = false;
if (Config.launcher.uwsm)
Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.playback, recording.modelData.path]);
else
@@ -122,7 +122,7 @@ ColumnLayout {
type: IconButton.Text
onClicked: {
root.visibilities.sidebar = false;
root.screenState.sidebar = false;
if (Config.launcher.uwsm)
Quickshell.execDetached(["app2unit", "--", ...Config.general.apps.explorer, recording.modelData.path]);
else
@@ -174,11 +174,11 @@ ColumnLayout {
MaterialIcon {
Layout.alignment: Qt.AlignHCenter
Layout.preferredHeight: root.props.recordingListExpanded ? implicitHeight : 0
Layout.preferredHeight: root.screenState.recordingListExpanded ? implicitHeight : 0
color: Colors.palette.m3outline
font.pointSize: Tokens.font.size.extraLarge
opacity: root.props.recordingListExpanded ? 1 : 0
scale: root.props.recordingListExpanded ? 1 : 0
opacity: root.screenState.recordingListExpanded ? 1 : 0
scale: root.screenState.recordingListExpanded ? 1 : 0
text: "scan_delete"
Behavior on Layout.preferredHeight {
@@ -197,10 +197,10 @@ ColumnLayout {
MaterialIcon {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: !root.props.recordingListExpanded ? implicitWidth : 0
Layout.preferredWidth: !root.screenState.recordingListExpanded ? implicitWidth : 0
color: Colors.palette.m3outline
opacity: !root.props.recordingListExpanded ? 1 : 0
scale: !root.props.recordingListExpanded ? 1 : 0
opacity: !root.screenState.recordingListExpanded ? 1 : 0
scale: !root.screenState.recordingListExpanded ? 1 : 0
text: "scan_delete"
Behavior on Layout.preferredWidth {
@@ -39,7 +39,7 @@ CustomRect {
});
}
readonly property int splitIndex: Math.ceil(quickToggles.length / 2)
required property PersistentProperties visibilities
required property ScreenState screenState
color: Colors.tPalette.m3surfaceContainer
implicitHeight: layout.implicitHeight + Tokens.padding.extraLargeIncreased
@@ -166,8 +166,8 @@ CustomRect {
isToggle: false
onClicked: {
root.visibilities.sidebar = false;
root.visibilities.settings = true;
root.screenState.sidebar = false;
root.screenState.settings = true;
}
}
}
@@ -1,14 +1,14 @@
import Quickshell
import QtQuick
import QtQuick.Layouts
import qs.Components
import qs.Modules.Notifications.Sidebar.Utils.Cards
import ZShell.Config
Item {
id: root
required property PersistentProperties props
required property var visibilities
required property ScreenState screenState
implicitHeight: layout.implicitHeight
implicitWidth: layout.implicitWidth
@@ -22,14 +22,13 @@ Item {
IdleInhibit {}
Record {
props: root.props
visibilities: root.visibilities
screenState: root.screenState
z: 1
}
Toggles {
Layout.fillWidth: true
visibilities: root.visibilities
screenState: root.screenState
}
}
}
@@ -9,16 +9,9 @@ Item {
id: root
property real offsetScale: shouldBeActive ? 0 : 1
readonly property PersistentProperties props: PersistentProperties {
property string recordingConfirmDelete
property bool recordingListExpanded: false
property string recordingMode
reloadableId: "utilities"
}
readonly property bool shouldBeActive: visibilities.sidebar && !sidebar.chatActive
readonly property bool shouldBeActive: screenState.sidebar && !sidebar.chatActive
required property Item sidebar
required property var visibilities
required property ScreenState screenState
anchors.bottomMargin: (-implicitHeight - 5) * offsetScale
implicitHeight: content.implicitHeight + Tokens.padding.small * 2
@@ -43,8 +36,7 @@ Item {
sourceComponent: Content {
implicitWidth: root.implicitWidth - 8 * 2
props: root.props
visibilities: root.visibilities
screenState: root.screenState
}
}
}
+4 -7
View File
@@ -13,11 +13,9 @@ Item {
property real offsetScale: shouldBeActive ? 0 : 1
required property var panels
readonly property Props props: Props {
}
readonly property bool shouldBeActive: root.visibilities.sidebar && Config.sidebar.enabled
readonly property bool chatActive: props.currentTab === 1
required property var visibilities
readonly property bool shouldBeActive: root.screenState.sidebar && Config.sidebar.enabled
readonly property bool chatActive: screenState.sidebarTab === 1
required property ScreenState screenState
anchors.rightMargin: (-implicitWidth - 5) * offsetScale
implicitWidth: Config.sidebar.sizes.width
@@ -54,8 +52,7 @@ Item {
sourceComponent: Content {
implicitWidth: Config.sidebar.sizes.width - Tokens.padding.small * 2
props: root.props
visibilities: root.visibilities
screenState: root.screenState
}
}
}