mirror of
https://github.com/arthur-pbty/arthur-os.git
synced 2026-08-01 20:28:16 +02:00
Massage it
This commit is contained in:
@@ -18,6 +18,7 @@ Panel {
|
||||
property int peerIndex: 0
|
||||
property int exitNodeIndex: 0
|
||||
property bool cursorActive: false
|
||||
property bool copyMenuOpen: false
|
||||
property int phraseIndex: 0
|
||||
readonly property var activePhrases: [
|
||||
"Encrypting connections",
|
||||
@@ -129,7 +130,7 @@ Panel {
|
||||
var account = selectedAccount()
|
||||
if (account) tailscale.switchAccount(account.id)
|
||||
} else if (focusSection === "peers") {
|
||||
tailscale.copyPeerIp(selectedPeer())
|
||||
openSelectedPeerCopyMenu()
|
||||
} else if (focusSection === "exitNodes") {
|
||||
tailscale.setExitNode(selectedExitNode())
|
||||
}
|
||||
@@ -163,6 +164,12 @@ Panel {
|
||||
scrollCursorIntoView()
|
||||
}
|
||||
|
||||
function openSelectedPeerCopyMenu() {
|
||||
if (!peerColumn || peerIndex < 0 || peerIndex >= peerColumn.children.length) return
|
||||
var item = peerColumn.children[peerIndex]
|
||||
if (item && item.openCopyMenu) item.openCopyMenu()
|
||||
}
|
||||
|
||||
function setExitNodeCursor(index) {
|
||||
cursorActive = true
|
||||
focusSection = "exitNodes"
|
||||
@@ -224,7 +231,7 @@ Panel {
|
||||
Item {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
implicitWidth: root.bar && root.bar.vertical ? root.bar.barSize : Style.space(26)
|
||||
implicitWidth: root.bar && root.bar.vertical ? root.bar.barSize : Style.space(32)
|
||||
implicitHeight: root.bar && root.bar.vertical ? Style.space(26) : (root.bar ? root.bar.barSize : Style.space(26))
|
||||
|
||||
property var registeredBar: null
|
||||
@@ -282,6 +289,7 @@ Panel {
|
||||
PanelKeyCatcher {
|
||||
id: keyCatcher
|
||||
anchors.fill: parent
|
||||
blocked: root.copyMenuOpen
|
||||
onMoveRequested: function(dx, dy) {
|
||||
if (!root.cursorActive) { root.cursorActive = true; return }
|
||||
root.moveCursor(dx, dy)
|
||||
@@ -626,16 +634,14 @@ Panel {
|
||||
width: Style.space(22)
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
opacity: accountRow.switchingAccount ? 0.45 : 1.0
|
||||
|
||||
NumberAnimation on rotation {
|
||||
SequentialAnimation on opacity {
|
||||
running: accountRow.switchingAccount
|
||||
from: 0
|
||||
to: 360
|
||||
duration: 900
|
||||
NumberAnimation { to: 1.0; duration: 420; easing.type: Easing.InOutQuad }
|
||||
NumberAnimation { to: 0.45; duration: 420; easing.type: Easing.InOutQuad }
|
||||
loops: Animation.Infinite
|
||||
}
|
||||
|
||||
onRotationChanged: if (!accountRow.switchingAccount && rotation !== 0) rotation = 0
|
||||
}
|
||||
|
||||
Text {
|
||||
@@ -670,12 +676,50 @@ Panel {
|
||||
return String(peer.TailscaleIPv6[0] || "")
|
||||
}
|
||||
readonly property string peerDns: peer ? String(peer.DNSName || "") : ""
|
||||
readonly property var copyOptions: {
|
||||
var options = []
|
||||
if (peerName !== "") options.push({ kind: "name", label: peerName })
|
||||
if (peerDns !== "") options.push({ kind: "dns", label: peerDns })
|
||||
if (peerIpv6 !== "") options.push({ kind: "ipv6", label: peerIpv6 })
|
||||
if (peerIp !== "") options.push({ kind: "ip", label: peerIp })
|
||||
return options
|
||||
}
|
||||
property int copyIndex: 0
|
||||
|
||||
hasCursor: root.cursorActive && root.focusSection === "peers" && root.peerIndex === rowIndex
|
||||
foreground: root.foreground
|
||||
|
||||
implicitHeight: Math.max(peerContent.implicitHeight, copyButton.implicitHeight) + Style.spacing.rowPaddingX
|
||||
|
||||
function clampCopyIndex() {
|
||||
copyIndex = Math.max(0, Math.min(copyIndex, copyOptions.length - 1))
|
||||
}
|
||||
|
||||
function openCopyMenu() {
|
||||
if (copyOptions.length === 0) return
|
||||
clampCopyIndex()
|
||||
copyPopup.open()
|
||||
}
|
||||
|
||||
function moveCopyCursor(delta) {
|
||||
if (copyOptions.length === 0) return
|
||||
copyIndex = Math.max(0, Math.min(copyOptions.length - 1, copyIndex + delta))
|
||||
}
|
||||
|
||||
function copyOption(kind) {
|
||||
if (kind === "name") tailscale.copyPeerName(peer)
|
||||
else if (kind === "dns") tailscale.copyPeerDnsName(peer)
|
||||
else if (kind === "ipv6") tailscale.copyToClipboard(peerIpv6, peerName + " IPv6")
|
||||
else if (kind === "ip") tailscale.copyPeerIp(peer)
|
||||
copyPopup.close()
|
||||
}
|
||||
|
||||
function copyCurrentOption() {
|
||||
clampCopyIndex()
|
||||
if (copyOptions.length === 0) return
|
||||
copyOption(copyOptions[copyIndex].kind)
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
@@ -736,7 +780,7 @@ Panel {
|
||||
fontFamily: root.fontFamily
|
||||
enabled: peerRow.peerIp !== "" || peerRow.peerName !== "" || peerRow.peerDns !== "" || peerRow.peerIpv6 !== ""
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onClicked: copyPopup.open()
|
||||
onClicked: peerRow.openCopyMenu()
|
||||
}
|
||||
|
||||
Popup {
|
||||
@@ -748,6 +792,34 @@ Panel {
|
||||
modal: false
|
||||
focus: true
|
||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
|
||||
onOpenedChanged: {
|
||||
root.copyMenuOpen = opened
|
||||
if (opened) {
|
||||
peerRow.clampCopyIndex()
|
||||
forceActiveFocus()
|
||||
}
|
||||
}
|
||||
Keys.onPressed: function(event) {
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
close()
|
||||
event.accepted = true
|
||||
return
|
||||
}
|
||||
if (event.key === Qt.Key_Down || event.text === "j") {
|
||||
peerRow.moveCopyCursor(1)
|
||||
event.accepted = true
|
||||
return
|
||||
}
|
||||
if (event.key === Qt.Key_Up || event.text === "k") {
|
||||
peerRow.moveCopyCursor(-1)
|
||||
event.accepted = true
|
||||
return
|
||||
}
|
||||
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter || event.key === Qt.Key_Space) {
|
||||
peerRow.copyCurrentOption()
|
||||
event.accepted = true
|
||||
}
|
||||
}
|
||||
background: Rectangle {
|
||||
color: Color.background
|
||||
border.color: root.dim
|
||||
@@ -758,43 +830,16 @@ Panel {
|
||||
contentItem: Column {
|
||||
width: parent.width
|
||||
|
||||
CopyChoice {
|
||||
width: parent.width
|
||||
label: peerRow.peerName
|
||||
enabled: peerRow.peerName !== ""
|
||||
onChosen: {
|
||||
copyPopup.close()
|
||||
tailscale.copyPeerName(peerRow.peer)
|
||||
}
|
||||
}
|
||||
|
||||
CopyChoice {
|
||||
width: parent.width
|
||||
label: peerRow.peerDns
|
||||
enabled: peerRow.peerDns !== ""
|
||||
onChosen: {
|
||||
copyPopup.close()
|
||||
tailscale.copyPeerDnsName(peerRow.peer)
|
||||
}
|
||||
}
|
||||
|
||||
CopyChoice {
|
||||
width: parent.width
|
||||
label: peerRow.peerIpv6
|
||||
enabled: peerRow.peerIpv6 !== ""
|
||||
onChosen: {
|
||||
copyPopup.close()
|
||||
tailscale.copyToClipboard(peerRow.peerIpv6, peerRow.peerName + " IPv6")
|
||||
}
|
||||
}
|
||||
|
||||
CopyChoice {
|
||||
width: parent.width
|
||||
label: peerRow.peerIp
|
||||
enabled: peerRow.peerIp !== ""
|
||||
onChosen: {
|
||||
copyPopup.close()
|
||||
tailscale.copyPeerIp(peerRow.peer)
|
||||
Repeater {
|
||||
model: peerRow.copyOptions
|
||||
CopyChoice {
|
||||
required property var modelData
|
||||
required property int index
|
||||
width: parent.width
|
||||
label: String(modelData.label || "")
|
||||
selected: peerRow.copyIndex === index
|
||||
onHovered: peerRow.copyIndex = index
|
||||
onChosen: peerRow.copyOption(String(modelData.kind || ""))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -805,10 +850,13 @@ Panel {
|
||||
component CopyChoice: CursorSurface {
|
||||
id: copyChoice
|
||||
signal chosen()
|
||||
signal hovered()
|
||||
property string label: ""
|
||||
property bool selected: false
|
||||
|
||||
visible: enabled
|
||||
foreground: root.foreground
|
||||
hasCursor: selected
|
||||
implicitHeight: Style.space(48)
|
||||
radius: 0
|
||||
|
||||
@@ -816,6 +864,7 @@ Panel {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onEntered: copyChoice.hovered()
|
||||
onClicked: copyChoice.chosen()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user