Files
Panama/config/dot/quickshell/modules/settings/ConfirmAction.qml
T

82 lines
2.6 KiB
QML

// The two-stage destructive confirm, as one component instead of twenty
// hand-rolled copies. The first press arms ("Verb…", normal tone -- danger
// never initiates, per SettingsButton's own contract); armed, the row shows
// Cancel ("Keep") beside the confirming press ("Verb it", danger tone).
//
// One armed confirm exists app-wide: the token lives on ShellState, so arming
// this one disarms whichever other row was armed, on any page. Consumers give
// a unique actionId, the verb pair, and handle onConfirmed; the component owns
// the state, the copy shape, and the keyboard path (via SettingsButton).
//
// ConfirmAction {
// actionId: "forget-network:" + ssid
// armText: "Forget…" // default: verb + ellipsis
// confirmText: "Forget it"
// cancelText: "Keep" // the house cancel word
// enabled: !Service.busy
// onConfirmed: Service.forget(ssid)
// }
//
// The armed state is readable (`armed`) so a row can swap its detail line for
// the consequence-naming sentence while armed -- naming what is lost is the
// caller's half of the contract; this component only guarantees the two
// presses happen and the wrong button cannot be the easy one.
import QtQuick
import qs.config
import qs.services
Row {
id: root
property string actionId: ""
property string armText: "Remove…"
property string confirmText: "Remove it"
property string cancelText: "Keep"
property bool enabled: true
signal confirmed
signal armedChanged2
readonly property bool armed: root.actionId !== ""
&& ShellState.armedConfirm === root.actionId
spacing: 7
function disarm(): void {
if (root.armed)
ShellState.armedConfirm = "";
}
// Leaving the page, or the row vanishing under the armed state, must not
// leave a stale token claiming some other future row's identity. Rows more
// often hide than unload (an override pill, a conditional card), so the
// visibility guard matters as much as the destruction one.
Component.onDestruction: root.disarm()
onVisibleChanged: if (!root.visible) root.disarm()
SettingsButton {
visible: !root.armed
enabled: root.enabled
text: root.armText
onClicked: ShellState.armedConfirm = root.actionId
}
SettingsButton {
visible: root.armed
enabled: root.enabled
text: root.cancelText
onClicked: root.disarm()
}
SettingsButton {
visible: root.armed
enabled: root.enabled
tone: "danger"
text: root.confirmText
onClicked: {
root.disarm();
root.confirmed();
}
}
}