The safety layer: two presses for anything you cannot take back
Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
@@ -38,6 +38,24 @@ SettingsPage {
|
||||
property string pendingInterface: ""
|
||||
property string pendingZone: ""
|
||||
|
||||
// The default is the same change with a wider blast radius: it decides for
|
||||
// every connection that does not ask for a zone by name. It used to apply
|
||||
// on the pick, one dropdown below a picker that made you confirm.
|
||||
property string pendingDefaultZone: ""
|
||||
|
||||
// Two armed changes on screen at once is how the wrong one gets pressed.
|
||||
function armInterfaceMove(iface: string, zoneName: string): void {
|
||||
root.pendingDefaultZone = "";
|
||||
root.pendingInterface = iface;
|
||||
root.pendingZone = zoneName;
|
||||
}
|
||||
|
||||
function armDefaultZone(zoneName: string): void {
|
||||
root.pendingInterface = "";
|
||||
root.pendingZone = "";
|
||||
root.pendingDefaultZone = zoneName;
|
||||
}
|
||||
|
||||
// The zone being read in the browser. Read-only: this looks at a zone
|
||||
// without applying it to anything.
|
||||
property string browsingZone: ""
|
||||
@@ -416,10 +434,7 @@ SettingsPage {
|
||||
options: root.zoneOptions
|
||||
current: placement.zone
|
||||
divider: !placement.pending
|
||||
onPicked: value => {
|
||||
root.pendingInterface = placement.iface;
|
||||
root.pendingZone = String(value);
|
||||
}
|
||||
onPicked: value => root.armInterfaceMove(placement.iface, String(value))
|
||||
}
|
||||
|
||||
SettingRow {
|
||||
@@ -482,7 +497,45 @@ SettingsPage {
|
||||
enabled: !Firewall.busy
|
||||
options: root.zoneOptions
|
||||
current: Firewall.defaultZone
|
||||
onPicked: value => Firewall.setDefaultZone(String(value))
|
||||
divider: root.pendingDefaultZone === ""
|
||||
onPicked: value => root.armDefaultZone(String(value))
|
||||
}
|
||||
|
||||
SettingRow {
|
||||
width: parent.width
|
||||
visible: root.pendingDefaultZone !== ""
|
||||
label: "Make " + root.pendingDefaultZone + " the default?"
|
||||
// What moves is named the way the per-interface confirm names its
|
||||
// interface: not "the default changes", but which machines end up
|
||||
// deciding differently because of it.
|
||||
detail: "Every connection firewalld has not placed in a zone of its "
|
||||
+ "own follows the default — each one leaves " + Firewall.defaultZone
|
||||
+ " for " + root.pendingDefaultZone
|
||||
+ ", and so does every network joined from now on."
|
||||
controlWidth: 240
|
||||
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 8
|
||||
|
||||
SettingsButton {
|
||||
text: "Keep " + Firewall.defaultZone
|
||||
enabled: !Firewall.busy
|
||||
onClicked: root.pendingDefaultZone = ""
|
||||
}
|
||||
|
||||
SettingsButton {
|
||||
text: "Change it"
|
||||
tone: "danger"
|
||||
enabled: !Firewall.busy
|
||||
onClicked: {
|
||||
const target = root.pendingDefaultZone;
|
||||
root.pendingDefaultZone = "";
|
||||
Firewall.setDefaultZone(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── The zone browser ─────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user