286 lines
10 KiB
QML
286 lines
10 KiB
QML
import QtQuick
|
||
import qs.config
|
||
import qs.services
|
||
|
||
Item {
|
||
id: root
|
||
|
||
property bool expanded: false
|
||
signal toggleExpanded
|
||
|
||
readonly property bool hasSelection: HomeAssistant.selectedEntities.length > 0
|
||
readonly property bool showSetup: HomeAssistant.phase === "ready" && !root.hasSelection
|
||
|
||
implicitHeight: content.implicitHeight
|
||
|
||
Column {
|
||
id: content
|
||
width: parent.width
|
||
spacing: 6
|
||
|
||
ControlSectionHeader {
|
||
width: parent.width
|
||
label: "Home"
|
||
action: root.headerAction()
|
||
actionEnabled: HomeAssistant.phase !== "loading"
|
||
onActionTriggered: {
|
||
if (root.hasSelection) {
|
||
root.toggleExpanded();
|
||
} else if (root.showSetup) {
|
||
root.openHomeSettings();
|
||
} else {
|
||
HomeAssistant.refresh();
|
||
}
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
id: restingCard
|
||
width: parent.width
|
||
height: visible ? restingGrid.implicitHeight + 20 : 0
|
||
visible: root.hasSelection && !root.expanded
|
||
radius: Theme.cardRadius + 2
|
||
color: Theme.alpha(Theme.warn, 0.028)
|
||
border.width: 1
|
||
border.color: Theme.alpha(Theme.warn, 0.095)
|
||
|
||
Grid {
|
||
id: restingGrid
|
||
anchors.left: parent.left
|
||
anchors.right: parent.right
|
||
anchors.top: parent.top
|
||
anchors.margins: 10
|
||
columns: 2
|
||
spacing: 8
|
||
|
||
Repeater {
|
||
model: HomeAssistant.visibleEntities
|
||
|
||
HomeTile {
|
||
required property var modelData
|
||
width: (restingGrid.width - restingGrid.spacing) / 2
|
||
entity: modelData
|
||
busy: HomeAssistant.isBusy(modelData.id)
|
||
pendingBrightness: HomeAssistant.pendingFor(modelData.id)
|
||
actionError: HomeAssistant.errorFor(modelData.id)
|
||
onPowerRequested: HomeAssistant.toggleEntity(modelData.id)
|
||
onBrightnessRequested: value => HomeAssistant.setBrightness(modelData.id, value)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
width: parent.width
|
||
height: visible ? 72 : 0
|
||
visible: !root.hasSelection
|
||
radius: Theme.cardRadius
|
||
color: root.showSetup
|
||
? Theme.alpha(Theme.accent, 0.055)
|
||
: Theme.alpha(Theme.fg, 0.045)
|
||
border.width: 1
|
||
border.color: root.showSetup
|
||
? Theme.alpha(Theme.accent, 0.12)
|
||
: Theme.alpha(Theme.fg, 0.055)
|
||
|
||
Text {
|
||
id: stateIcon
|
||
anchors.left: parent.left
|
||
anchors.leftMargin: 13
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
text: root.showSetup ? "\u{F0335}" : "\u{F02DC}"
|
||
color: root.showSetup ? Theme.accent : Theme.fgDim
|
||
font.family: Theme.fontMono
|
||
font.pixelSize: 17
|
||
}
|
||
|
||
Column {
|
||
anchors.left: stateIcon.right
|
||
anchors.leftMargin: 11
|
||
anchors.right: emptyAction.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: emptyAction
|
||
anchors.right: parent.right
|
||
anchors.rightMargin: 10
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
width: root.showSetup ? 68 : 52
|
||
height: 30
|
||
radius: 10
|
||
visible: HomeAssistant.phase !== "loading"
|
||
color: emptyActionMouse.containsMouse
|
||
? Theme.alpha(Theme.accent, 0.20)
|
||
: Theme.alpha(Theme.accent, 0.105)
|
||
|
||
Text {
|
||
anchors.centerIn: parent
|
||
text: root.showSetup ? "Manage" : "Open"
|
||
color: Theme.accent
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSizeSmall
|
||
font.weight: Font.DemiBold
|
||
}
|
||
MouseArea {
|
||
id: emptyActionMouse
|
||
anchors.fill: parent
|
||
hoverEnabled: true
|
||
cursorShape: Qt.PointingHandCursor
|
||
onClicked: {
|
||
if (root.showSetup)
|
||
root.openHomeSettings();
|
||
else
|
||
HomeAssistant.open();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
width: parent.width
|
||
height: visible ? 34 : 0
|
||
visible: HomeAssistant.stale
|
||
radius: 10
|
||
color: Theme.alpha(Theme.warn, 0.075)
|
||
|
||
Text {
|
||
anchors.left: parent.left
|
||
anchors.leftMargin: 11
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
text: "Last known state · " + root.countSummary()
|
||
color: Theme.warn
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSizeSmall
|
||
}
|
||
Text {
|
||
anchors.right: parent.right
|
||
anchors.rightMargin: 11
|
||
anchors.verticalCenter: parent.verticalCenter
|
||
text: "Retry"
|
||
color: Theme.accent
|
||
font.family: Theme.fontFamily
|
||
font.pixelSize: Theme.fontSizeSmall
|
||
font.weight: Font.DemiBold
|
||
MouseArea {
|
||
anchors.fill: parent
|
||
anchors.margins: -6
|
||
cursorShape: Qt.PointingHandCursor
|
||
onClicked: HomeAssistant.refresh()
|
||
}
|
||
}
|
||
}
|
||
|
||
Section {
|
||
width: parent.width
|
||
expanded: root.expanded && root.hasSelection
|
||
|
||
ScrollColumn {
|
||
width: parent.width
|
||
maxHeight: 324
|
||
spacing: 8
|
||
|
||
Grid {
|
||
id: expandedGrid
|
||
width: parent.width
|
||
columns: 2
|
||
spacing: 8
|
||
|
||
Repeater {
|
||
model: HomeAssistant.selectedEntities
|
||
|
||
HomeTile {
|
||
required property var modelData
|
||
width: (expandedGrid.width - expandedGrid.spacing) / 2
|
||
entity: modelData
|
||
busy: HomeAssistant.isBusy(modelData.id)
|
||
pendingBrightness: HomeAssistant.pendingFor(modelData.id)
|
||
actionError: HomeAssistant.errorFor(modelData.id)
|
||
onPowerRequested: HomeAssistant.toggleEntity(modelData.id)
|
||
onBrightnessRequested: value => HomeAssistant.setBrightness(modelData.id, value)
|
||
}
|
||
}
|
||
}
|
||
|
||
RowButton {
|
||
width: parent.width
|
||
icon: "preferences-system-symbolic"
|
||
label: "Manage in Settings"
|
||
sublabel: root.countSummary()
|
||
onClicked: root.openHomeSettings()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function headerAction(): string {
|
||
if (root.hasSelection) {
|
||
const noun = HomeAssistant.configuredCount === 1 ? "accessory" : "accessories";
|
||
return HomeAssistant.configuredCount + " " + noun + (root.expanded ? " ⌃" : " ›");
|
||
}
|
||
if (HomeAssistant.phase === "loading")
|
||
return "Loading";
|
||
if (root.showSetup)
|
||
return "Manage";
|
||
return "Retry";
|
||
}
|
||
|
||
function countSummary(): string {
|
||
return HomeAssistant.configuredCount + " selected · "
|
||
+ HomeAssistant.discoveredCount + " discovered";
|
||
}
|
||
|
||
function emptyTitle(): string {
|
||
if (root.showSetup)
|
||
return "Choose your accessories";
|
||
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 (root.showSetup) {
|
||
if (HomeAssistant.discoveredCount === 0)
|
||
return "No lights discovered yet";
|
||
const noun = HomeAssistant.discoveredCount === 1 ? "light" : "lights";
|
||
return HomeAssistant.discoveredCount + " " + noun + " ready to add";
|
||
}
|
||
if (HomeAssistant.phase === "loading")
|
||
return "Finding your selected lights";
|
||
if (HomeAssistant.lastError === "authentication-required")
|
||
return "Update the long-lived access token";
|
||
if (HomeAssistant.lastError === "not-configured")
|
||
return "Connect Home Assistant in Settings";
|
||
return "Check the connection, then retry";
|
||
}
|
||
|
||
function openHomeSettings(): void {
|
||
ShellState.close();
|
||
ShellState.openSettings("home-phone");
|
||
}
|
||
}
|