Files

150 lines
5.2 KiB
QML

// One light on the My Home page: power square, name, state, and a brightness
// slider when the light dims. The slider is Control Center's — one dimmer
// implementation everywhere, covered by home-brightness-slider-contract.
import QtQuick
import qs.config
import qs.services
import qs.modules.quicksettings
Rectangle {
id: root
// A catalog entity: { id, sourceName, name, state, available, active,
// dimmable, brightnessPct }.
property var entity: ({})
// Whether this light sits in the first four favorites, and therefore in
// Control Center.
property bool featured: false
readonly property string entityId: String(root.entity.id ?? "")
readonly property bool busy: HomeAssistant.isBusy(root.entityId)
readonly property int pending: HomeAssistant.pendingFor(root.entityId)
readonly property string entityError: HomeAssistant.errorFor(root.entityId)
readonly property bool showsSlider: root.entity.dimmable === true && root.entity.available === true
radius: 14
color: Theme.alpha(Theme.fg, 0.05)
border.width: 1
border.color: Theme.alpha(Theme.fg, 0.07)
implicitHeight: header.implicitHeight + (showsSlider ? 36 : 0)
+ (entityError !== "" ? errorLine.implicitHeight + 4 : 0) + 22
Row {
id: header
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: 11
spacing: 11
Rectangle {
id: power
width: 30
height: 29
radius: 10
anchors.verticalCenter: parent.verticalCenter
color: root.entity.active === true
? Theme.alpha(Theme.warn, 0.16)
: Theme.alpha(Theme.fg, 0.07)
border.width: 1
border.color: root.entity.active === true
? Theme.alpha(Theme.warn, 0.4)
: Theme.alpha(Theme.fg, 0.09)
opacity: root.entity.available === true && !root.busy ? 1 : 0.45
Text {
anchors.centerIn: parent
text: "\u{F0335}"
color: root.entity.active === true ? Theme.warn : Theme.fgDim
font.family: Theme.fontMono
font.pixelSize: 14
}
MouseArea {
anchors.fill: parent
enabled: root.entity.available === true && !root.busy
cursorShape: Qt.PointingHandCursor
onClicked: HomeAssistant.toggleEntity(root.entityId)
}
Accessible.role: Accessible.Button
Accessible.name: (root.entity.active === true ? "Turn off " : "Turn on ")
+ String(root.entity.name ?? root.entity.sourceName ?? "")
}
Column {
width: parent.width - power.width - parent.spacing
anchors.verticalCenter: parent.verticalCenter
spacing: 2
Row {
width: parent.width
spacing: 8
Text {
text: String(root.entity.name ?? root.entity.sourceName ?? "")
color: Theme.fg
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSize
font.weight: Font.DemiBold
elide: Text.ElideRight
}
StatusBadge {
visible: root.featured
anchors.verticalCenter: parent.verticalCenter
text: "Control Center"
tone: Theme.accent
}
}
Text {
width: parent.width
text: {
if (root.entity.available !== true)
return "Unavailable";
if (root.entity.active !== true)
return "Off";
const pct = root.pending >= 0 ? root.pending : Number(root.entity.brightnessPct ?? 0);
return root.entity.dimmable === true ? "On · " + pct + "%" : "On";
}
color: Theme.fgDim
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall
elide: Text.ElideRight
}
}
}
HomeBrightnessSlider {
visible: root.showsSlider
anchors.left: parent.left
anchors.leftMargin: 11
anchors.right: parent.right
anchors.rightMargin: 11
anchors.top: header.bottom
accessibleName: String(root.entity.name ?? root.entity.sourceName ?? "Light") + " brightness"
value: root.pending >= 0 ? root.pending : Number(root.entity.brightnessPct ?? 0)
onCommitted: value => HomeAssistant.setBrightness(root.entityId, value)
}
Text {
id: errorLine
visible: root.entityError !== ""
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: 11
text: root.entityError === "unreachable"
? "Home Assistant did not respond"
: "That change did not apply"
color: Theme.warn
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall
wrapMode: Text.WordWrap
}
}