fix(nosignal): hardware-test feedback — additions icons, power menu, weather picker
From the 2026-06-15 hardware-test feedback (redesign passed end-to-end):
- Glyphs: map the 12 unmapped additions-page icon names (brush, cloud_sync,
data_object, deployed_code, movie_edit, neurology, psychology, robot_2,
smart_toy, sports_esports, videocam, vpn_lock) so the nexus Additional
Software page stops rendering "?" boxes. Verified Nerd Font codepoints.
- Glyphs: cp() now uses String.fromCodePoint, not fromCharCode — the 5 MDI
glyphs above 0xFFFF were being truncated by the 16-bit fromCharCode.
- Shortcuts: Super+Escape (session) now drives the redesigned full-screen
Power Menu via NsShell.toggle("power"); old caelestia session panel is
now dead code.
- nexus LanguageAndRegion: replace the "coming soon" weather placeholder with
a real location input bound to GlobalConfig.services.weatherLocation (the
Weather backend already geocodes / IP-auto-detects).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
83c6b62c13
commit
f21e5b5eaf
3 changed files with 73 additions and 27 deletions
|
|
@ -54,8 +54,9 @@ Scope {
|
||||||
onPressed: {
|
onPressed: {
|
||||||
if (root.hasFullscreen)
|
if (root.hasFullscreen)
|
||||||
return;
|
return;
|
||||||
const visibilities = Visibilities.getForActive();
|
// NoSignal: drive the redesigned full-screen Power Menu (NsOverlay),
|
||||||
visibilities.session = !visibilities.session;
|
// not the old caelestia session panel (now dead code).
|
||||||
|
NsShell.toggle("power", 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,41 +92,71 @@ PageBase {
|
||||||
text: qsTr("Weather")
|
text: qsTr("Weather")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Placeholder until the map-based location picker lands
|
// Location for the weather service. Weather.qml accepts a city name
|
||||||
|
// (geocoded) or a "lat,lon" string, and auto-detects via IP when empty.
|
||||||
ConnectedRect {
|
ConnectedRect {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
first: true
|
first: true
|
||||||
last: true
|
last: true
|
||||||
implicitHeight: comingSoon.implicitHeight + Tokens.padding.extraLarge * 2
|
implicitHeight: weatherLayout.implicitHeight + weatherLayout.anchors.margins * 2
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: comingSoon
|
id: weatherLayout
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.fill: parent
|
||||||
width: parent.width - Tokens.padding.largeIncreased * 2
|
anchors.margins: Tokens.padding.medium
|
||||||
spacing: Tokens.padding.extraSmall
|
anchors.leftMargin: Tokens.padding.largeIncreased
|
||||||
|
anchors.rightMargin: Tokens.padding.largeIncreased
|
||||||
NsIcon {
|
spacing: Tokens.spacing.small
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
icon: "map"
|
|
||||||
color: Colours.palette.m3outlineVariant
|
|
||||||
fontStyle: Tokens.font.icon.extraLarge
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.fillWidth: true
|
||||||
text: qsTr("Location picker coming soon")
|
text: qsTr("Location")
|
||||||
color: Colours.palette.m3outlineVariant
|
font: Tokens.font.body.small
|
||||||
font: Tokens.font.title.small
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledRect {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: locField.implicitHeight + Tokens.padding.medium * 2
|
||||||
|
|
||||||
|
radius: Tokens.rounding.small
|
||||||
|
color: Colours.tPalette.m3surfaceContainerLowest
|
||||||
|
border.color: Colours.palette.m3outlineVariant
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
CAnim {}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.IBeamCursor
|
||||||
|
onClicked: locField.focus = true
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledTextField {
|
||||||
|
id: locField
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.leftMargin: Tokens.padding.large
|
||||||
|
anchors.rightMargin: Tokens.padding.large
|
||||||
|
|
||||||
|
text: GlobalConfig.services.weatherLocation
|
||||||
|
placeholderText: qsTr("City name or lat,long — empty = auto (IP)")
|
||||||
|
placeholderTextColor: Colours.palette.m3onSurfaceVariant
|
||||||
|
color: Colours.palette.m3onSurface
|
||||||
|
onEditingFinished: GlobalConfig.services.weatherLocation = text
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
text: qsTr("Choose your weather location on a map in a future update")
|
text: qsTr("Leave empty to detect your location automatically.")
|
||||||
color: Colours.palette.m3outlineVariant
|
color: Colours.palette.m3outline
|
||||||
font: Tokens.font.body.small
|
font: Tokens.font.label.small
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ pragma Singleton
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
// NoSignal icon remap: Material Symbol name -> Nerd Font (JetBrainsMono NF)
|
// NoSignal icon remap: Material Symbol name -> Nerd Font (JetBrainsMono NF)
|
||||||
// codepoint (Font Awesome range), via String.fromCharCode so the source stays
|
// codepoint (Font Awesome + MDI ranges), via String.fromCodePoint so the source
|
||||||
// pure ASCII. Used by components/NsIcon. Covers bar/panel icons + the dynamic
|
// stays pure ASCII. Used by components/NsIcon. Covers bar/panel icons + the dynamic
|
||||||
// Icons.getX() returns. get() falls back to a question glyph so anything
|
// Icons.getX() returns. get() falls back to a question glyph so anything
|
||||||
// unmapped is visible (easy to spot + add a mapping).
|
// unmapped is visible (easy to spot + add a mapping).
|
||||||
|
|
||||||
|
|
@ -14,7 +14,9 @@ Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
function cp(code: int): string {
|
function cp(code: int): string {
|
||||||
return String.fromCharCode(code);
|
// fromCodePoint (not fromCharCode) so astral-plane glyphs (Nerd Font
|
||||||
|
// MDI range, > 0xFFFF) emit correct surrogate pairs, not truncated.
|
||||||
|
return String.fromCodePoint(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property var map: {
|
readonly property var map: {
|
||||||
|
|
@ -232,7 +234,20 @@ Singleton {
|
||||||
"stop": root.cp(0xf04d),
|
"stop": root.cp(0xf04d),
|
||||||
"thermostat": root.cp(0xf2c9),
|
"thermostat": root.cp(0xf2c9),
|
||||||
"water_drop": root.cp(0xf043),
|
"water_drop": root.cp(0xf043),
|
||||||
"wb_twilight": root.cp(0xf185)
|
"wb_twilight": root.cp(0xf185),
|
||||||
|
// additions-page icons (nexus Additional Software)
|
||||||
|
"brush": root.cp(0xf1fc), // fa-paintbrush
|
||||||
|
"cloud_sync": root.cp(0xf063f), // md-cloud_sync
|
||||||
|
"data_object": root.cp(0xf0169), // md-code_braces
|
||||||
|
"deployed_code": root.cp(0xf1b2), // fa-cube
|
||||||
|
"movie_edit": root.cp(0xf008), // fa-film
|
||||||
|
"neurology": root.cp(0xee9c), // fa-brain
|
||||||
|
"psychology": root.cp(0xf133c), // md-head_cog
|
||||||
|
"robot_2": root.cp(0xee0d), // fa-robot
|
||||||
|
"smart_toy": root.cp(0xf06a9), // md-robot
|
||||||
|
"sports_esports": root.cp(0xf11b), // fa-gamepad
|
||||||
|
"videocam": root.cp(0xf03d), // fa-video_camera
|
||||||
|
"vpn_lock": root.cp(0xf099d) // md-shield_lock
|
||||||
}
|
}
|
||||||
|
|
||||||
function get(name: string): string {
|
function get(name: string): string {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue