Finish Home and Phone settings cohesion
This commit is contained in:
@@ -2,9 +2,11 @@ import QtQuick
|
||||
import qs.config
|
||||
import qs.services
|
||||
|
||||
Item {
|
||||
SettingsPage {
|
||||
id: root
|
||||
objectName: "home-phone-page"
|
||||
title: "Home & Phone"
|
||||
lede: "Choose what appears in Control Center and keep phone continuity close at hand."
|
||||
|
||||
property string lightQuery: searchInput.text.trim().toLowerCase()
|
||||
|
||||
@@ -41,274 +43,242 @@ Item {
|
||||
return "Home Assistant is unavailable";
|
||||
}
|
||||
|
||||
Flickable {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
contentWidth: width
|
||||
contentHeight: content.implicitHeight + 64
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
SettingsCard {
|
||||
title: "Home Assistant"
|
||||
subtitle: root.homeStatus()
|
||||
|
||||
Column {
|
||||
id: content
|
||||
width: parent.width - 68
|
||||
x: 34
|
||||
y: 30
|
||||
spacing: 16
|
||||
SettingRow {
|
||||
label: "Light catalog"
|
||||
detail: "Panama reads light state through the Home Assistant helper."
|
||||
divider: false
|
||||
controlWidth: 176
|
||||
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 8
|
||||
|
||||
SettingsButton {
|
||||
id: refreshButton
|
||||
text: "Refresh"
|
||||
activeFocusOnTab: true
|
||||
border.width: activeFocus ? 2 : 1
|
||||
border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
|
||||
onClicked: HomeAssistant.refresh()
|
||||
Keys.onReturnPressed: HomeAssistant.refresh()
|
||||
Keys.onSpacePressed: HomeAssistant.refresh()
|
||||
}
|
||||
|
||||
SettingsButton {
|
||||
id: openHomeButton
|
||||
text: "Open"
|
||||
activeFocusOnTab: true
|
||||
border.width: activeFocus ? 2 : 1
|
||||
border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
|
||||
onClicked: HomeAssistant.open()
|
||||
Keys.onReturnPressed: HomeAssistant.open()
|
||||
Keys.onSpacePressed: HomeAssistant.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
title: "Control Center lights"
|
||||
subtitle: HomeAssistant.selectedEntities.length === 0
|
||||
? "Select the lights that belong on your shelf."
|
||||
: `${Math.min(4, HomeAssistant.selectedEntities.length)} in Control Center · ${HomeAssistant.selectedEntities.length} selected`
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
visible: HomeAssistant.selectedEntities.length === 0
|
||||
text: "Choose lights below to build your Control Center shelf."
|
||||
color: Theme.fgDim
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSize
|
||||
wrapMode: Text.WordWrap
|
||||
topPadding: 3
|
||||
bottomPadding: 13
|
||||
}
|
||||
|
||||
GridView {
|
||||
id: favoritesGrid
|
||||
width: parent.width
|
||||
height: Math.ceil(count / 2) * cellHeight
|
||||
visible: count > 0
|
||||
interactive: false
|
||||
clip: false
|
||||
cellWidth: width / 2
|
||||
cellHeight: 116
|
||||
model: HomeAssistant.selectedEntities
|
||||
|
||||
delegate: HomeFavoriteCard {
|
||||
required property var modelData
|
||||
width: GridView.view.cellWidth - 6
|
||||
height: 108
|
||||
favorite: ({
|
||||
id: modelData.id,
|
||||
alias: modelData.name === modelData.sourceName ? "" : modelData.name
|
||||
})
|
||||
sourceName: modelData.sourceName
|
||||
featured: index < 4
|
||||
onAliasCommitted: (id, alias) => HomePreferences.setAlias(id, alias)
|
||||
onMoveRequested: (id, targetIndex) => HomePreferences.move(id, targetIndex)
|
||||
onRemoveRequested: id => HomePreferences.remove(id)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 46
|
||||
visible: HomePreferences.saveError !== ""
|
||||
radius: 9
|
||||
color: Theme.alpha(Theme.warn, 0.09)
|
||||
border.width: 1
|
||||
border.color: Theme.alpha(Theme.warn, 0.24)
|
||||
|
||||
Text {
|
||||
text: "Home & Phone"
|
||||
color: Theme.fg
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 12
|
||||
anchors.right: retryButton.left
|
||||
anchors.rightMargin: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: HomePreferences.saveError
|
||||
color: Theme.warn
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 27
|
||||
font.weight: Font.DemiBold
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
SettingsButton {
|
||||
id: retryButton
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 8
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "Retry"
|
||||
activeFocusOnTab: true
|
||||
border.width: activeFocus ? 2 : 1
|
||||
border.color: activeFocus ? Theme.warn : Theme.alpha(Theme.fg, 0.08)
|
||||
onClicked: HomePreferences.retrySave()
|
||||
Keys.onReturnPressed: HomePreferences.retrySave()
|
||||
Keys.onSpacePressed: HomePreferences.retrySave()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
title: "Available lights"
|
||||
subtitle: "Search the Home Assistant catalog by source name or entity ID."
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 38
|
||||
radius: 10
|
||||
color: Theme.alpha(Theme.fg, searchInput.activeFocus ? 0.08 : 0.05)
|
||||
border.width: searchInput.activeFocus ? 2 : 1
|
||||
border.color: searchInput.activeFocus
|
||||
? Theme.alpha(Theme.accent, 0.72)
|
||||
: Theme.alpha(Theme.fg, 0.065)
|
||||
|
||||
Text {
|
||||
text: "Choose what appears in Control Center and keep phone continuity close at hand."
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 11
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "\u{F0349}"
|
||||
color: Theme.fgDim
|
||||
font.family: Theme.fontMono
|
||||
font.pixelSize: 14
|
||||
}
|
||||
|
||||
TextInput {
|
||||
id: searchInput
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 36
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 11
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
activeFocusOnTab: true
|
||||
color: Theme.fg
|
||||
selectionColor: Theme.accent
|
||||
selectedTextColor: Theme.bgDark
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSize
|
||||
bottomPadding: 6
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
title: "Home Assistant"
|
||||
subtitle: root.homeStatus()
|
||||
|
||||
SettingRow {
|
||||
label: "Light catalog"
|
||||
detail: "Panama reads light state through the Home Assistant helper."
|
||||
divider: false
|
||||
controlWidth: 176
|
||||
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 8
|
||||
|
||||
SettingsButton {
|
||||
id: refreshButton
|
||||
text: "Refresh"
|
||||
activeFocusOnTab: true
|
||||
border.width: activeFocus ? 2 : 1
|
||||
border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
|
||||
onClicked: HomeAssistant.refresh()
|
||||
Keys.onReturnPressed: HomeAssistant.refresh()
|
||||
Keys.onSpacePressed: HomeAssistant.refresh()
|
||||
}
|
||||
|
||||
SettingsButton {
|
||||
id: openHomeButton
|
||||
text: "Open"
|
||||
activeFocusOnTab: true
|
||||
border.width: activeFocus ? 2 : 1
|
||||
border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
|
||||
onClicked: HomeAssistant.open()
|
||||
Keys.onReturnPressed: HomeAssistant.open()
|
||||
Keys.onSpacePressed: HomeAssistant.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
title: "Control Center lights"
|
||||
subtitle: HomeAssistant.selectedEntities.length === 0
|
||||
? "Select the lights that belong on your shelf."
|
||||
: `${Math.min(4, HomeAssistant.selectedEntities.length)} in Control Center · ${HomeAssistant.selectedEntities.length} selected`
|
||||
clip: true
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
visible: HomeAssistant.selectedEntities.length === 0
|
||||
text: "Choose lights below to build your Control Center shelf."
|
||||
color: Theme.fgDim
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSize
|
||||
wrapMode: Text.WordWrap
|
||||
topPadding: 3
|
||||
bottomPadding: 13
|
||||
}
|
||||
|
||||
GridView {
|
||||
id: favoritesGrid
|
||||
width: parent.width
|
||||
height: Math.ceil(count / 2) * cellHeight
|
||||
visible: count > 0
|
||||
interactive: false
|
||||
clip: false
|
||||
cellWidth: width / 2
|
||||
cellHeight: 116
|
||||
model: HomeAssistant.selectedEntities
|
||||
|
||||
delegate: HomeFavoriteCard {
|
||||
required property var modelData
|
||||
width: GridView.view.cellWidth - 6
|
||||
height: 108
|
||||
favorite: ({
|
||||
id: modelData.id,
|
||||
alias: modelData.name === modelData.sourceName ? "" : modelData.name
|
||||
})
|
||||
sourceName: modelData.sourceName
|
||||
featured: index < 4
|
||||
onAliasCommitted: (id, alias) => HomePreferences.setAlias(id, alias)
|
||||
onMoveRequested: (id, targetIndex) => HomePreferences.move(id, targetIndex)
|
||||
onRemoveRequested: id => HomePreferences.remove(id)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 46
|
||||
visible: HomePreferences.saveError !== ""
|
||||
radius: 9
|
||||
color: Theme.alpha(Theme.warn, 0.09)
|
||||
border.width: 1
|
||||
border.color: Theme.alpha(Theme.warn, 0.24)
|
||||
|
||||
Text {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 12
|
||||
anchors.right: retryButton.left
|
||||
anchors.rightMargin: 12
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: HomePreferences.saveError
|
||||
color: Theme.warn
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
SettingsButton {
|
||||
id: retryButton
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 8
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "Retry"
|
||||
activeFocusOnTab: true
|
||||
border.width: activeFocus ? 2 : 1
|
||||
border.color: activeFocus ? Theme.warn : Theme.alpha(Theme.fg, 0.08)
|
||||
onClicked: HomePreferences.retrySave()
|
||||
Keys.onReturnPressed: HomePreferences.retrySave()
|
||||
Keys.onSpacePressed: HomePreferences.retrySave()
|
||||
}
|
||||
anchors.fill: parent
|
||||
visible: searchInput.text === "" && !searchInput.activeFocus
|
||||
text: "Search available lights"
|
||||
color: Theme.fgMuted
|
||||
font: searchInput.font
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
title: "Available lights"
|
||||
subtitle: "Search the Home Assistant catalog by source name or entity ID."
|
||||
Column {
|
||||
width: parent.width
|
||||
visible: root.availableLights.length > 0
|
||||
|
||||
Rectangle {
|
||||
Repeater {
|
||||
model: root.availableLights
|
||||
|
||||
AvailableLightRow {
|
||||
required property var modelData
|
||||
width: parent.width
|
||||
height: 38
|
||||
radius: 10
|
||||
color: Theme.alpha(Theme.fg, searchInput.activeFocus ? 0.08 : 0.05)
|
||||
border.width: searchInput.activeFocus ? 2 : 1
|
||||
border.color: searchInput.activeFocus
|
||||
? Theme.alpha(Theme.accent, 0.72)
|
||||
: Theme.alpha(Theme.fg, 0.065)
|
||||
|
||||
Text {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 11
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "\u{F0349}"
|
||||
color: Theme.fgDim
|
||||
font.family: Theme.fontMono
|
||||
font.pixelSize: 14
|
||||
}
|
||||
|
||||
TextInput {
|
||||
id: searchInput
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 36
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 11
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
activeFocusOnTab: true
|
||||
color: Theme.fg
|
||||
selectionColor: Theme.accent
|
||||
selectedTextColor: Theme.bgDark
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSize
|
||||
clip: true
|
||||
|
||||
Text {
|
||||
anchors.fill: parent
|
||||
visible: searchInput.text === "" && !searchInput.activeFocus
|
||||
text: "Search available lights"
|
||||
color: Theme.fgMuted
|
||||
font: searchInput.font
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
entity: modelData
|
||||
onAddRequested: id => HomePreferences.add(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
visible: root.availableLights.length > 0
|
||||
Text {
|
||||
width: parent.width
|
||||
visible: root.availableLights.length === 0
|
||||
text: root.availableEmptyText
|
||||
color: Theme.fgDim
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
topPadding: 18
|
||||
bottomPadding: 10
|
||||
}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: root.availableLights
|
||||
SettingsCard {
|
||||
title: "Phone continuity"
|
||||
subtitle: "Keep the Messages handoff independent from phone connectivity."
|
||||
|
||||
AvailableLightRow {
|
||||
required property var modelData
|
||||
width: parent.width
|
||||
entity: modelData
|
||||
onAddRequested: id => HomePreferences.add(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
SettingRow {
|
||||
label: "Messages"
|
||||
detail: "Opens BlueBubbles"
|
||||
divider: false
|
||||
controlWidth: 204
|
||||
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 12
|
||||
|
||||
Text {
|
||||
width: parent.width
|
||||
visible: root.availableLights.length === 0
|
||||
text: root.availableEmptyText
|
||||
color: Theme.fgDim
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: SystemSettings.bluebubblesAvailable ? "Installed" : "Unavailable"
|
||||
color: SystemSettings.bluebubblesAvailable ? Theme.ok : Theme.fgMuted
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSize
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
wrapMode: Text.WordWrap
|
||||
topPadding: 18
|
||||
bottomPadding: 10
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
title: "Phone continuity"
|
||||
subtitle: "Keep the Messages handoff independent from phone connectivity."
|
||||
|
||||
SettingRow {
|
||||
label: "Messages"
|
||||
detail: "Opens BlueBubbles"
|
||||
divider: false
|
||||
controlWidth: 204
|
||||
|
||||
Row {
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
spacing: 12
|
||||
|
||||
Text {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: SystemSettings.bluebubblesAvailable ? "Installed" : "Unavailable"
|
||||
color: SystemSettings.bluebubblesAvailable ? Theme.ok : Theme.fgMuted
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: Theme.fontSizeSmall
|
||||
}
|
||||
|
||||
SettingsButton {
|
||||
id: openBlueBubblesButton
|
||||
text: "Open"
|
||||
enabled: SystemSettings.bluebubblesAvailable
|
||||
activeFocusOnTab: enabled
|
||||
border.width: activeFocus ? 2 : 1
|
||||
border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
|
||||
onClicked: SystemSettings.openApplication("bluebubbles")
|
||||
Keys.onReturnPressed: if (enabled) SystemSettings.openApplication("bluebubbles")
|
||||
Keys.onSpacePressed: if (enabled) SystemSettings.openApplication("bluebubbles")
|
||||
}
|
||||
}
|
||||
SettingsButton {
|
||||
id: openBlueBubblesButton
|
||||
text: "Open"
|
||||
enabled: SystemSettings.bluebubblesAvailable
|
||||
activeFocusOnTab: enabled
|
||||
border.width: activeFocus ? 2 : 1
|
||||
border.color: activeFocus ? Theme.accent : Theme.alpha(Theme.fg, 0.08)
|
||||
onClicked: SystemSettings.openApplication("bluebubbles")
|
||||
Keys.onReturnPressed: if (enabled) SystemSettings.openApplication("bluebubbles")
|
||||
Keys.onSpacePressed: if (enabled) SystemSettings.openApplication("bluebubbles")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user