281 lines
10 KiB
QML
281 lines
10 KiB
QML
import QtQuick
|
||
import qs.config
|
||
import qs.services
|
||
|
||
Item {
|
||
id: root
|
||
|
||
property bool expanded: false
|
||
signal toggleExpanded
|
||
|
||
implicitHeight: content.implicitHeight
|
||
|
||
Column {
|
||
id: content
|
||
width: parent.width
|
||
spacing: 6
|
||
|
||
ControlSectionHeader {
|
||
width: parent.width
|
||
label: "Home"
|
||
action: HomeAssistant.entities.length > 0
|
||
? HomeAssistant.entities.length + " accessories " + (root.expanded ? "⌃" : "›")
|
||
: "Retry"
|
||
actionEnabled: HomeAssistant.phase !== "loading"
|
||
onActionTriggered: {
|
||
if (HomeAssistant.entities.length > 0)
|
||
root.toggleExpanded();
|
||
else
|
||
HomeAssistant.refresh();
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
id: homeCard
|
||
width: parent.width
|
||
height: visible ? homeGrid.implicitHeight + 20 : 0
|
||
visible: HomeAssistant.entities.length > 0
|
||
radius: Theme.cardRadius + 2
|
||
color: Theme.alpha(Theme.accent, 0.045)
|
||
border.width: 1
|
||
border.color: Theme.alpha(Theme.accent, 0.12)
|
||
|
||
Grid {
|
||
id: homeGrid
|
||
anchors.left: parent.left
|
||
anchors.right: parent.right
|
||
anchors.top: parent.top
|
||
anchors.margins: 10
|
||
columns: 4
|
||
spacing: 7
|
||
|
||
Repeater {
|
||
model: HomeAssistant.visibleEntities
|
||
|
||
HomeTile {
|
||
required property var modelData
|
||
width: (homeGrid.width - homeGrid.spacing * 3) / 4
|
||
entity: modelData
|
||
busy: HomeAssistant.busyEntityId === modelData.id
|
||
onActivated: HomeAssistant.toggleEntity(modelData.id)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
width: parent.width
|
||
height: visible ? 66 : 0
|
||
visible: HomeAssistant.entities.length === 0
|
||
radius: Theme.cardRadius
|
||
color: Theme.alpha(Theme.fg, 0.05)
|
||
border.width: 1
|
||
border.color: Theme.alpha(Theme.fg, 0.045)
|
||
|
||
Text {
|
||
id: stateIcon
|
||
anchors.left: parent.left
|
||
anchors.leftMargin: 12
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
text: HomeAssistant.phase === "loading" ? "\u{F0772}" : "\u{F02DC}"
|
||
color: HomeAssistant.phase === "loading" ? Theme.accent : Theme.fgDim
|
||
font.family: Theme.fontMono
|
||
font.pixelSize: 16
|
||
}
|
||
|
||
Column {
|
||
anchors.left: stateIcon.right
|
||
anchors.leftMargin: 11
|
||
anchors.right: openHome.left
|
||
anchors.rightMargin: 10
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
spacing: 3
|
||
|
||
Text {
|
||
width: parent.width
|
||
text: root.emptyTitle()
|
||
color: Theme.fg
|
||
elide: Text.ElideRight
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSize
|
||
font.weight: Font.DemiBold
|
||
}
|
||
Text {
|
||
width: parent.width
|
||
text: root.emptyDetail()
|
||
color: Theme.fgDim
|
||
elide: Text.ElideRight
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSizeSmall
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
id: openHome
|
||
anchors.right: parent.right
|
||
anchors.rightMargin: 10
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
width: 48
|
||
height: 28
|
||
radius: 9
|
||
visible: HomeAssistant.phase !== "loading"
|
||
color: openMouse.containsMouse
|
||
? Theme.alpha(Theme.accent, 0.20)
|
||
: Theme.alpha(Theme.accent, 0.11)
|
||
|
||
Text {
|
||
anchors.centerIn: parent
|
||
text: "Open"
|
||
color: Theme.accent
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSizeSmall
|
||
font.weight: Font.Medium
|
||
}
|
||
MouseArea {
|
||
id: openMouse
|
||
anchors.fill: parent
|
||
hoverEnabled: true
|
||
cursorShape: Qt.PointingHandCursor
|
||
onClicked: HomeAssistant.open()
|
||
}
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
width: parent.width
|
||
height: visible ? 30 : 0
|
||
visible: HomeAssistant.stale
|
||
radius: 9
|
||
color: Theme.alpha(Theme.warn, 0.08)
|
||
|
||
Text {
|
||
anchors.left: parent.left
|
||
anchors.leftMargin: 10
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
text: "Showing the last known state"
|
||
color: Theme.warn
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSizeSmall
|
||
}
|
||
Text {
|
||
anchors.right: parent.right
|
||
anchors.rightMargin: 10
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
text: "Retry"
|
||
color: Theme.accent
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSizeSmall
|
||
font.weight: Font.Medium
|
||
MouseArea {
|
||
anchors.fill: parent
|
||
anchors.margins: -6
|
||
cursorShape: Qt.PointingHandCursor
|
||
onClicked: HomeAssistant.refresh()
|
||
}
|
||
}
|
||
}
|
||
|
||
Section {
|
||
width: parent.width
|
||
expanded: root.expanded && HomeAssistant.entities.length > 0
|
||
|
||
ScrollColumn {
|
||
width: parent.width
|
||
maxHeight: 270
|
||
spacing: 2
|
||
|
||
Repeater {
|
||
model: HomeAssistant.entities
|
||
|
||
Rectangle {
|
||
id: entityRow
|
||
required property var modelData
|
||
width: parent.width
|
||
height: 44
|
||
radius: 10
|
||
color: entityMouse.containsMouse
|
||
? Theme.alpha(Theme.fg, 0.09)
|
||
: "transparent"
|
||
|
||
Text {
|
||
id: entityGlyph
|
||
anchors.left: parent.left
|
||
anchors.leftMargin: 11
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
text: "\u{F0335}"
|
||
color: entityRow.modelData.active ? Theme.warn : Theme.fgDim
|
||
font.family: Theme.fontMono
|
||
font.pixelSize: 14
|
||
}
|
||
Column {
|
||
anchors.left: entityGlyph.right
|
||
anchors.leftMargin: 10
|
||
anchors.right: entityState.left
|
||
anchors.rightMargin: 8
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
spacing: 2
|
||
Text {
|
||
width: parent.width
|
||
text: entityRow.modelData.name
|
||
color: Theme.fg
|
||
elide: Text.ElideRight
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSize
|
||
}
|
||
Text {
|
||
width: parent.width
|
||
text: !entityRow.modelData.available ? "Unavailable" : entityRow.modelData.state
|
||
color: Theme.fgMuted
|
||
elide: Text.ElideRight
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSizeSmall
|
||
}
|
||
}
|
||
Text {
|
||
id: entityState
|
||
anchors.right: parent.right
|
||
anchors.rightMargin: 11
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
text: HomeAssistant.busyEntityId === entityRow.modelData.id
|
||
? "Working"
|
||
: (entityRow.modelData.active ? "On" : "Off")
|
||
color: entityRow.modelData.active ? Theme.warn : Theme.fgMuted
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSizeSmall
|
||
font.weight: Font.DemiBold
|
||
}
|
||
MouseArea {
|
||
id: entityMouse
|
||
anchors.fill: parent
|
||
enabled: entityRow.modelData.available && HomeAssistant.busyEntityId === ""
|
||
hoverEnabled: true
|
||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||
onClicked: HomeAssistant.toggleEntity(entityRow.modelData.id)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function emptyTitle(): string {
|
||
if (HomeAssistant.phase === "loading")
|
||
return "Loading your home";
|
||
if (HomeAssistant.lastError === "authentication-required")
|
||
return "Authentication required";
|
||
if (HomeAssistant.lastError === "not-configured")
|
||
return "Home Assistant is not configured";
|
||
return "Home Assistant is unavailable";
|
||
}
|
||
|
||
function emptyDetail(): string {
|
||
if (HomeAssistant.phase === "loading")
|
||
return "Reading configured favourites";
|
||
if (HomeAssistant.lastError === "authentication-required")
|
||
return "Update the long-lived access token";
|
||
if (HomeAssistant.lastError === "not-configured")
|
||
return "Add a URL, token and favourites";
|
||
return "Check the connection and retry";
|
||
}
|
||
}
|