Sync config from arch
- hypr/apps.lua - hypr/autostart.lua - hypr/envs.lua - hypr/hyprland.lua - hypr/hyprsunset.conf - hypr/input.lua - hypr/looknfeel.lua - hypr/omasettings.lua - hypr/xdph.conf - omarchy/branding/about.txt - omarchy/branding/screensaver.txt - omarchy/extensions/omarchy-menu.jsonc - omarchy/hooks/battery-low.d/play-warning-sound.sample - omarchy/hooks/font-set.d/show-font-notification.sample - omarchy/hooks/post-boot.d/weather.sample - omarchy/hooks/post-update.d/install-voxtype.hook - omarchy/hooks/post-update.d/setup-agent.hook - omarchy/hooks/post-update.d/setup-fingerprint.hook - omarchy/hooks/post-update.d/show-update-notification.sample - omarchy/hooks/pre-refresh-pacman.d/add-custom-repo.sample - omarchy/hooks/theme-set.d/show-theme-notification.sample - omarchy/shell.json - omarchy/shell.toml - omarchy/theme.name - omarchy/themes/azure-glow/README.md - omarchy/themes/azure-glow/alacritty.toml - omarchy/themes/azure-glow/btop.theme - omarchy/themes/azure-glow/hyprland.conf - omarchy/themes/azure-glow/hyprlock.conf - omarchy/themes/azure-glow/icons.theme - … 269 more
This commit is contained in:
@@ -0,0 +1,341 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import qs.Commons
|
||||
import qs.Ui
|
||||
import "format.js" as Fmt
|
||||
|
||||
// The default tab: is it me or is it them, in one glance.
|
||||
Column {
|
||||
id: tab
|
||||
|
||||
required property var panel
|
||||
readonly property var live: panel.live
|
||||
|
||||
spacing: Style.space(12)
|
||||
|
||||
readonly property bool outage: live
|
||||
&& (live.state === "wan-down" || live.state === "local-down")
|
||||
|
||||
// Same shape the bar shows, so the two agree at a glance.
|
||||
function elapsed(since) {
|
||||
if (!since) return ""
|
||||
var s = Math.max(0, Math.round(Date.now() / 1000 - since))
|
||||
var m = Math.floor(s / 60)
|
||||
return m > 0 ? m + "m" + (s % 60) + "s" : s + "s"
|
||||
}
|
||||
|
||||
// Only on a captive network, so it costs no height the rest of the time.
|
||||
// It goes first because it is the one thing worth reading here: without
|
||||
// it, every number below is the portal answering rather than the
|
||||
// connection, and the panel would be blaming the router for a sign-in
|
||||
// page.
|
||||
Text {
|
||||
textFormat: Text.PlainText
|
||||
visible: tab.live && tab.live.state === "captive"
|
||||
height: visible ? implicitHeight : 0
|
||||
width: parent.width
|
||||
wrapMode: Text.WordWrap
|
||||
text: "This network wants you to sign in. Something here is answering "
|
||||
+ "for the internet, so treat the numbers below as the sign-in page, "
|
||||
+ "not your connection."
|
||||
color: tab.panel.warnTone
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.caption
|
||||
}
|
||||
|
||||
Text {
|
||||
textFormat: Text.PlainText
|
||||
text: "PATH"
|
||||
color: tab.panel.dim
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.caption
|
||||
font.letterSpacing: 1
|
||||
}
|
||||
|
||||
PathChain {
|
||||
width: parent.width
|
||||
live: tab.live
|
||||
panel: tab.panel
|
||||
anchor: tab.panel.setting("internetAnchor", "1.1.1.1")
|
||||
textColor: tab.panel.fg
|
||||
dimColor: tab.panel.dim
|
||||
}
|
||||
|
||||
// Lag summary line, Orb vocabulary: best / typical / worst.
|
||||
Item {
|
||||
width: parent.width
|
||||
height: lagLabel.implicitHeight
|
||||
|
||||
Text {
|
||||
id: lagLabel
|
||||
textFormat: Text.PlainText
|
||||
text: "LAG"
|
||||
color: tab.panel.dim
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.caption
|
||||
font.letterSpacing: 1
|
||||
}
|
||||
Text {
|
||||
textFormat: Text.PlainText
|
||||
anchors.right: parent.right
|
||||
text: {
|
||||
var l = tab.live
|
||||
if (!l || !l.lag) return "--"
|
||||
// The band is null when the whole window was lost. `lag.now` is
|
||||
// still 1500 there because Responsiveness needs an anchor to land
|
||||
// on, but 1500 is not a round trip and printing it three times
|
||||
// said the link was replying slowly when it was not replying.
|
||||
if (l.lag.typical === null || l.lag.typical === undefined)
|
||||
return tab.outage ? "no reply" : "--"
|
||||
var best = l.lag.best !== null ? Math.round(l.lag.best) : "--"
|
||||
var worst = l.lag.worst !== null ? Math.round(l.lag.worst) : "--"
|
||||
return "best " + best + " · typical " + Math.round(l.lag.typical)
|
||||
+ " ms · worst " + worst
|
||||
}
|
||||
color: tab.panel.fg
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.bodySmall
|
||||
}
|
||||
}
|
||||
|
||||
PanelSeparator { width: parent.width }
|
||||
|
||||
// The three pillars.
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Style.space(14)
|
||||
|
||||
readonly property real cell: (width - Style.space(14) * 2) / 3
|
||||
readonly property var scores: tab.live && tab.live.scores ? tab.live.scores : {}
|
||||
|
||||
ScorePillar {
|
||||
width: parent.cell
|
||||
label: "RESPONSIVENESS"
|
||||
value: parent.scores.responsiveness !== undefined ? parent.scores.responsiveness : null
|
||||
note: {
|
||||
var l = tab.live
|
||||
if (!l || !l.lag) return "no data yet"
|
||||
if (l.lag.typical === null || l.lag.typical === undefined)
|
||||
return tab.outage ? "nothing is answering" : "no data yet"
|
||||
return "lag " + Math.round(l.lag.typical) + " ms typical"
|
||||
}
|
||||
textColor: tab.panel.fg
|
||||
dimColor: tab.panel.dim
|
||||
}
|
||||
ScorePillar {
|
||||
width: parent.cell
|
||||
label: "RELIABILITY"
|
||||
value: parent.scores.reliability !== undefined ? parent.scores.reliability : null
|
||||
// A 24-hour score barely moves in the first minute of an outage, so
|
||||
// the number stays 100 and is honest. Green is not: it reads as
|
||||
// reassurance next to a dead link. The caption carries the live fact
|
||||
// instead of restating the window, and it is short enough to fit —
|
||||
// the previous wording truncated mid-word in this column.
|
||||
toneOverride: tab.outage ? tab.panel.warnTone : null
|
||||
note: {
|
||||
var l = tab.live
|
||||
if (!l) return ""
|
||||
if (l.state === "captive") return "not signed in yet"
|
||||
if (tab.outage) {
|
||||
var d = tab.elapsed(l.down_since)
|
||||
return d ? "down " + d : "outage now"
|
||||
}
|
||||
return "last 24 h"
|
||||
}
|
||||
textColor: tab.panel.fg
|
||||
dimColor: tab.panel.dim
|
||||
}
|
||||
ScorePillar {
|
||||
width: parent.cell
|
||||
label: "SPEED"
|
||||
value: parent.scores.speed !== undefined ? parent.scores.speed : null
|
||||
// A figure the index is ignoring must not shout in red as though it
|
||||
// were the verdict — it is being reported, not counted.
|
||||
toneOverride: {
|
||||
var c = tab.live ? tab.live.speed_ctx : null
|
||||
return c && c.scored === false ? tab.panel.dim : null
|
||||
}
|
||||
note: {
|
||||
// Say why it is blank, or the pause reads as a fault. This is the
|
||||
// whole point of detecting the hotspot: the checks are ~14 MB each
|
||||
// and hourly, which is data the user did not offer.
|
||||
var m = tab.live ? tab.live.metered : null
|
||||
var ctx = tab.live ? tab.live.speed_ctx : null
|
||||
var held = m && m.care
|
||||
if (!ctx || ctx.last_down === null || ctx.last_down === undefined)
|
||||
return held ? "checks paused on " + m.label : "no content check yet"
|
||||
var mbps = Math.round(ctx.last_down) + " Mbps"
|
||||
// No content check runs while the line is down, so this figure is
|
||||
// from before it. Saying "measured" would imply it is current.
|
||||
if (tab.outage) return mbps + " before the drop"
|
||||
if (held) return mbps + " · checks paused"
|
||||
if (ctx.basis === "plan")
|
||||
return mbps + " vs " + Math.round(ctx.plan_down) + " plan"
|
||||
// Not counted, and why. One check is the arrival check on a link
|
||||
// that may still have been settling; a peak test that read far
|
||||
// higher has already disproved this figure.
|
||||
// Kept inside the column: "63 Mbps · usually 384" is the widest
|
||||
// caption that fits here, so anything longer elides mid-word. The
|
||||
// dim number already says it is not counted; this says why.
|
||||
if (ctx.scored === false) {
|
||||
if (ctx.peak_down)
|
||||
return mbps + " · test: " + Math.round(ctx.peak_down)
|
||||
return mbps + " · unconfirmed"
|
||||
}
|
||||
if (ctx.baseline_down && ctx.last_down < ctx.baseline_down * 0.6)
|
||||
return mbps + " · usually " + Math.round(ctx.baseline_down)
|
||||
return mbps + " measured"
|
||||
}
|
||||
textColor: tab.panel.fg
|
||||
dimColor: tab.panel.dim
|
||||
}
|
||||
}
|
||||
|
||||
PanelSeparator { width: parent.width }
|
||||
|
||||
// 30-minute latency chart from recent.json.
|
||||
Item {
|
||||
width: parent.width
|
||||
height: chartLabel.implicitHeight
|
||||
|
||||
Text {
|
||||
id: chartLabel
|
||||
textFormat: Text.PlainText
|
||||
text: "LATENCY · LAST 30 MIN"
|
||||
color: tab.panel.dim
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.caption
|
||||
font.letterSpacing: 1
|
||||
}
|
||||
Text {
|
||||
textFormat: Text.PlainText
|
||||
anchors.right: parent.right
|
||||
text: {
|
||||
var l = tab.live
|
||||
if (!l || !l.total || l.total.p50 === null) return ""
|
||||
return "p50 " + Math.round(l.total.p50) + " ms · p95 "
|
||||
+ Math.round(l.total.p95) + " ms · jitter "
|
||||
+ (l.total.jitter !== null ? l.total.jitter.toFixed(1) : "--") + " ms"
|
||||
}
|
||||
color: tab.panel.dim
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.caption
|
||||
}
|
||||
}
|
||||
|
||||
LegChart {
|
||||
width: parent.width
|
||||
height: Style.space(96)
|
||||
points: tab.panel.recentPoints
|
||||
wanColor: Color.accent
|
||||
localColor: tab.panel.dim
|
||||
showScale: true
|
||||
fontFamily: tab.panel.fontFamily
|
||||
}
|
||||
|
||||
Row {
|
||||
spacing: Style.space(16)
|
||||
|
||||
component LegendEntry: Row {
|
||||
property color tint: "white"
|
||||
property string label: ""
|
||||
property bool tick: false
|
||||
spacing: Style.space(6)
|
||||
Rectangle {
|
||||
width: parent.tick ? 2 : Style.space(10)
|
||||
height: parent.tick ? Style.space(8) : 2
|
||||
color: parent.tint
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Text {
|
||||
textFormat: Text.PlainText
|
||||
text: parent.label
|
||||
color: tab.panel.dim
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.caption
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
|
||||
LegendEntry { tint: Color.accent; label: "wan leg" }
|
||||
LegendEntry { tint: tab.panel.dim; label: "local leg" }
|
||||
LegendEntry { tint: Color.urgent; label: "packet loss"; tick: true }
|
||||
}
|
||||
|
||||
PanelSeparator { width: parent.width }
|
||||
|
||||
// Speed strip + the run button.
|
||||
Item {
|
||||
width: parent.width
|
||||
height: speedCol.implicitHeight
|
||||
|
||||
Column {
|
||||
id: speedCol
|
||||
spacing: Style.space(4)
|
||||
|
||||
Text {
|
||||
textFormat: Text.PlainText
|
||||
text: "THROUGHPUT NOW"
|
||||
color: tab.panel.dim
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.caption
|
||||
font.letterSpacing: 1
|
||||
}
|
||||
Row {
|
||||
spacing: Style.space(14)
|
||||
|
||||
Text {
|
||||
textFormat: Text.PlainText
|
||||
text: {
|
||||
var r = tab.live && tab.live.rates ? tab.live.rates.rx_bps : null
|
||||
return " " + Fmt.rate(r)
|
||||
}
|
||||
color: Color.accent
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.subtitle
|
||||
}
|
||||
Text {
|
||||
textFormat: Text.PlainText
|
||||
text: {
|
||||
var r = tab.live && tab.live.rates ? tab.live.rates.tx_bps : null
|
||||
return " " + Fmt.rate(r)
|
||||
}
|
||||
color: tab.panel.warnTone
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.subtitle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: runLabel.implicitWidth + Style.space(24)
|
||||
height: Style.space(28)
|
||||
color: runHover.hovered
|
||||
? Style.hoverFillFor(tab.panel.fg, Color.accent)
|
||||
: Style.normalFillFor(tab.panel.fg, Color.accent)
|
||||
border.width: Style.normalBorderWidth
|
||||
border.color: Style.normalBorderFor(tab.panel.fg, Color.accent)
|
||||
|
||||
Text {
|
||||
id: runLabel
|
||||
textFormat: Text.PlainText
|
||||
anchors.centerIn: parent
|
||||
text: tab.live && tab.live.peak_running ? " Testing…"
|
||||
: tab.panel.peakArmed ? " Uses data · press again"
|
||||
: " Run test"
|
||||
color: tab.panel.fg
|
||||
font.family: tab.panel.fontFamily
|
||||
font.pixelSize: Style.font.bodySmall
|
||||
}
|
||||
HoverHandler { id: runHover }
|
||||
TapHandler {
|
||||
enabled: !(tab.live && tab.live.peak_running)
|
||||
onTapped: tab.panel.runPeakTest()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user