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

211 lines
8.7 KiB
QML

// What this machine offers to other machines on the network.
//
// Every row states what is true right now, including "the software for this is
// not installed" -- which is the honest answer for file sharing here, and is
// what the panel this replaces hides behind a switch that silently does
// nothing.
//
// Turning remote login on changes the whole system and prompts. Remote desktop
// is a user service and does not.
import Quickshell
import QtQuick
import qs.config
import qs.services
SettingsPage {
id: root
objectName: "sharing"
title: "Sharing"
lede: "What this machine offers to other machines on the network."
Component.onCompleted: Sharing.refresh()
SettingsCard {
title: "This machine"
subtitle: "The name other machines see."
// The error belongs to the machine, not to a floating banner above the
// title: a bare row above the first card read as part of the page
// furniture, which is exactly what an error must not do.
TextRow {
width: parent.width
visible: Sharing.lastError !== ""
label: "Sharing needs attention"
detail: Sharing.lastError
value: ""
}
TextFieldRow {
label: "Network name"
detail: "Used for ssh and for anything else that finds this machine by name"
text: Sharing.hostname
placeholder: "desktop"
enabled: !Sharing.busy
divider: false
onAccepted: value => Sharing.setHostname(value)
}
}
SettingsCard {
title: "Remote login"
subtitle: Sharing.remoteLoginOn
? "Sign in to a terminal on this machine with: ssh " + Sharing.networkName
: "Sign in to a terminal on this machine over SSH."
// Port and the password-sign-in claim used to be two rows of their own
// below this one. They describe this switch rather than standing beside
// it, so they read as its detail line -- and the card is three rows
// shorter for saying the same things.
//
// "Keys only" is reported from sshd's configuration rather than assumed:
// claiming it on a machine that actually accepts passwords would be a
// security claim this page cannot back up.
SwitchRow {
label: "Allow remote login"
detail: Sharing.remoteLogin?.installed === true
? "OpenSSH · port " + String(Sharing.remoteLogin?.port ?? "22")
+ " · password sign-in: " + Sharing.passwordLoginSummary().toLowerCase()
+ (Sharing.remoteLoginOn ? " · starts at boot" : "")
: "OpenSSH server is not installed"
checked: Sharing.remoteLoginOn
enabled: !Sharing.busy && Sharing.remoteLogin?.installed === true
divider: Sharing.remoteLoginOn
onToggled: value => Sharing.setRemoteLogin(value)
}
TextRow {
visible: Sharing.remoteLoginOn && Sharing.remoteSessions.length === 0
label: "Nobody is signed in remotely"
detail: "Remote login is on, and no one is connected from another machine."
value: ""
divider: false
}
Repeater {
model: Sharing.remoteSessions
delegate: TextRow {
required property var modelData
required property int index
width: parent.width
label: String(modelData.user ?? "") + " is signed in from " + String(modelData.from ?? "")
detail: "Since " + String(modelData.since ?? "") + " · " + String(modelData.line ?? "")
value: ""
divider: index < Sharing.remoteSessions.length - 1
}
}
}
SettingsCard {
title: "Remote desktop"
subtitle: "See and control this desktop from another machine."
SwitchRow {
label: "Allow remote desktop"
detail: Sharing.remoteDesktop?.available === true
? "RDP · port " + String(Sharing.remoteDesktop?.port ?? "3389") + " · "
+ (Sharing.remoteDesktopOn
? "running for your session"
: (Sharing.remoteDesktop?.hasCredentials === true
? "not running"
: "set a username and password before turning this on"))
: "Remote desktop support is not installed"
checked: Sharing.remoteDesktopOn
enabled: !Sharing.busy
&& Sharing.remoteDesktop?.available === true
&& Sharing.remoteDesktop?.hasCredentials === true
onToggled: value => Sharing.setRemoteDesktop(value)
}
TextFieldRow {
visible: Sharing.remoteDesktop?.available === true
label: "Port"
detail: "The RDP port other machines connect to"
text: String(Sharing.remoteDesktop?.port ?? "")
placeholder: "3389"
enabled: !Sharing.busy
onAccepted: value => Sharing.setRdpPort(value)
}
SwitchRow {
visible: Sharing.remoteDesktop?.available === true
label: "View only"
detail: "Let someone watch this desktop without controlling the pointer or keyboard"
checked: Sharing.remoteDesktop?.viewOnly === true
enabled: !Sharing.busy
onToggled: value => Sharing.setRdpViewOnly(value)
}
// The password is typed into gnome-remote-desktop's own tool in a
// terminal, never into this page. grdctl prompts for it on a terminal
// and crashes without one, and passing it as an argument would publish
// it through /proc to every process on this machine.
//
// The row says why rather than naming the mechanism: "opens kitty" is
// an implementation detail, and the reason -- the password never passes
// through Panama -- is the part worth reading.
ActionRow {
visible: Sharing.remoteDesktop?.available === true
label: "Credentials"
detail: Sharing.remoteDesktop?.hasCredentials === true
? "Stored in the login keyring · set in a terminal so the password never passes through Panama"
: "None stored yet · set in a terminal so the password never passes through Panama"
action: "Set…"
enabled: !Sharing.busy
onTriggered: Sharing.setRdpCredentials(Quickshell.env("USER") || "")
}
ActionRow {
visible: Sharing.remoteDesktop?.available === true
&& Sharing.remoteDesktop?.hasCredentials === true
label: "Forget the stored credentials"
detail: "Remote desktop cannot be turned on again until new ones are set"
action: "Clear"
enabled: !Sharing.busy
divider: false
onTriggered: Sharing.clearRdpCredentials()
}
}
SettingsCard {
title: "File and media sharing"
subtitle: "Sharing folders and media needs software this machine does not necessarily have."
// Not a switch, because there is nothing behind it. Naming what
// installing Samba would unlock is the difference between a dead row
// and an answer -- the panel this replaces shows a switch that silently
// does nothing.
TextRow {
label: "Share folders on the network"
detail: Sharing.fileSharing?.installed === true
? "Samba is installed, so folders can be published to Windows, macOS and Linux machines alike"
: "Samba is not installed — install it and this becomes a switch. Settings does not install software."
value: Sharing.fileSharing?.installed === true ? "Available" : "Not installed"
}
SwitchRow {
visible: Sharing.mediaSharing?.installed === true
label: "Share music and video to devices"
// Said before it happens, not after: this advertises on the network
// to anything that speaks DLNA, with no password in front of it.
detail: Sharing.mediaSharing?.active === true
? "Rygel is serving your media to devices on the network"
: "Publishes your media folders to every device on the network. No password is asked for."
checked: Sharing.mediaSharing?.active === true
enabled: !Sharing.busy
divider: false
onToggled: value => Sharing.setMediaSharing(value)
}
TextRow {
visible: Sharing.mediaSharing?.installed !== true
label: "Share music and video to devices"
detail: "Needs Rygel, which is not installed."
value: "Not installed"
divider: false
}
}
}