Split the bar panel into one QML file per stage
Panel.qml keeps the state, the CLI calls and the stage switch (889 lines, was 2360); each stage is its own file taking the panel as a required property. The omarchy installer copies every QML/JS file and clears stale ones. tests/static.sh filters qmllint on [syntax], not the word error. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
import qs.Ui
|
||||
|
||||
// BrokenSessions.qml - Sessions that a switch cut short. Shown in the list, because the point is to be noticed without going looking.
|
||||
//
|
||||
// One stage of the claude-mode panel. Panel.qml hands itself in as `panel`
|
||||
// and owns all the state and actions; this file only draws them.
|
||||
Column {
|
||||
id: stage
|
||||
required property var panel
|
||||
|
||||
width: parent.width
|
||||
visible: stage.panel.stage === "list" && (stage.panel.broken.length > 0 || stage.panel.ignored.length > 0)
|
||||
spacing: Style.space(4)
|
||||
|
||||
PanelSeparator { width: parent.width }
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
visible: stage.panel.broken.length > 0
|
||||
text: stage.panel.broken.length === 1
|
||||
? "1 session cannot be resumed"
|
||||
: stage.panel.broken.length + " sessions cannot be resumed"
|
||||
color: stage.panel.urgentColor
|
||||
wrapMode: Text.WordWrap
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(11)
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: stage.panel.stage === "list" ? stage.panel.broken : []
|
||||
|
||||
Item {
|
||||
id: brokenRow
|
||||
required property var modelData
|
||||
width: stage.width
|
||||
height: Style.space(26)
|
||||
|
||||
Column {
|
||||
anchors.left: parent.left
|
||||
anchors.right: ignoreBtn.left
|
||||
anchors.rightMargin: Style.space(6)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 0
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
text: String(brokenRow.modelData.sessionId).substring(0, 8)
|
||||
+ " · " + stage.panel.projectLabel(brokenRow.modelData.project)
|
||||
color: Color.popups.text
|
||||
elide: Text.ElideMiddle
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(10)
|
||||
}
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
text: brokenRow.modelData.dropLines + " turn lines after the last good message"
|
||||
color: Color.muted
|
||||
elide: Text.ElideRight
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(9)
|
||||
}
|
||||
}
|
||||
|
||||
PillButton { fontFamily: stage.panel.uiFont;
|
||||
id: ignoreBtn
|
||||
anchors.right: repairBtn.left
|
||||
anchors.rightMargin: Style.space(5)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
label: "Ignore"
|
||||
onTriggered: stage.panel.setIgnored(brokenRow.modelData, true)
|
||||
}
|
||||
|
||||
PillButton { fontFamily: stage.panel.uiFont;
|
||||
id: repairBtn
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
label: "Repair"
|
||||
onTriggered: stage.panel.askRepair(brokenRow.modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Hidden: dismissed here, or broken but untouched for longer than
|
||||
// the age limit. Collapsed, because the point of hiding them was that
|
||||
// they stop taking up attention - but never gone without a trace.
|
||||
Item {
|
||||
width: parent.width
|
||||
height: Style.space(20)
|
||||
visible: stage.panel.ignored.length > 0
|
||||
|
||||
Text {
|
||||
id: hiddenLabel
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "hidden (" + stage.panel.ignored.length + ")"
|
||||
color: hiddenArea.containsMouse ? Color.popups.text : Color.muted
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(10)
|
||||
}
|
||||
|
||||
Text {
|
||||
anchors.left: hiddenLabel.right
|
||||
anchors.leftMargin: Style.space(4)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: String.fromCodePoint(stage.panel.hiddenExpanded ? 0xF0140 : 0xF0142)
|
||||
color: hiddenLabel.color
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(11)
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: hiddenArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: stage.panel.hiddenExpanded = !stage.panel.hiddenExpanded
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
visible: stage.panel.hiddenExpanded && stage.panel.ignored.length > 0
|
||||
spacing: Style.space(3)
|
||||
|
||||
Text {
|
||||
visible: stage.panel.dismissedList.length > 0
|
||||
text: "Ignored (" + stage.panel.dismissedList.length + ")"
|
||||
color: Color.popups.text
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(10)
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: stage.panel.hiddenExpanded ? stage.panel.dismissedList.slice(0, stage.panel.hiddenCap) : []
|
||||
|
||||
Item {
|
||||
id: dismissedRow
|
||||
required property var modelData
|
||||
width: stage.width
|
||||
height: Style.space(26)
|
||||
|
||||
Text {
|
||||
anchors.left: parent.left
|
||||
anchors.right: restoreBtn.left
|
||||
anchors.rightMargin: Style.space(6)
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: String(dismissedRow.modelData.sessionId).substring(0, 8)
|
||||
+ " · " + stage.panel.projectLabel(dismissedRow.modelData.project)
|
||||
color: Color.muted
|
||||
elide: Text.ElideMiddle
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(10)
|
||||
}
|
||||
|
||||
PillButton { fontFamily: stage.panel.uiFont;
|
||||
id: restoreBtn
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
label: "Restore"
|
||||
onTriggered: stage.panel.setIgnored(dismissedRow.modelData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
visible: stage.panel.dismissedList.length > stage.panel.hiddenCap
|
||||
text: "… and " + (stage.panel.dismissedList.length - stage.panel.hiddenCap)
|
||||
+ " more · claude-mode repair-session --ignored"
|
||||
color: Color.muted
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(9)
|
||||
}
|
||||
|
||||
Text {
|
||||
visible: stage.panel.staleList.length > 0
|
||||
text: "Older than " + stage.panel.ageDays + " days (" + stage.panel.staleList.length + ")"
|
||||
color: Color.popups.text
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(10)
|
||||
font.bold: true
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: stage.panel.hiddenExpanded ? stage.panel.staleList.slice(0, stage.panel.hiddenCap) : []
|
||||
|
||||
Text {
|
||||
required property var modelData
|
||||
width: stage.width
|
||||
text: String(modelData.sessionId).substring(0, 8)
|
||||
+ " · " + Math.floor((Date.now() / 1000 - Number(modelData.mtime)) / 86400) + "d"
|
||||
+ " · " + stage.panel.projectLabel(modelData.project)
|
||||
color: Color.muted
|
||||
elide: Text.ElideMiddle
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(10)
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
visible: stage.panel.staleList.length > 0
|
||||
text: (stage.panel.staleList.length > stage.panel.hiddenCap
|
||||
? "… and " + (stage.panel.staleList.length - stage.panel.hiddenCap) + " more. " : "")
|
||||
+ "Not counted because nothing has touched them since. "
|
||||
+ "claude-mode repair-session --all --max-age 0 lists them."
|
||||
color: Color.muted
|
||||
opacity: 0.85
|
||||
wrapMode: Text.WordWrap
|
||||
font.family: stage.panel.uiFont
|
||||
font.pixelSize: Style.space(9)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user