Build the Panama Control Center
This commit is contained in:
@@ -0,0 +1,280 @@
|
||||
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";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user