gh-glance 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/index.mjs +40 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ All notable changes to this project are documented here.
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.5.1] - 2026-08-04
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **The blank-icons hint waits for a start that is actually stuck.** It shipped
|
|
13
|
+
in 0.5.0 on the loading line unconditionally, so every start put a line naming
|
|
14
|
+
an environment variable in front of everyone for the second or two the first
|
|
15
|
+
fetch takes -- a dim `loading actions…` reads as "working", the same line with
|
|
16
|
+
a remedy attached reads as a warning about a problem you do not have. It now
|
|
17
|
+
appears only once a first fetch has been running 3s, which is past the slow end
|
|
18
|
+
of what `gh run list` costs on the tab you land on (measured: 1.4-3.0s after
|
|
19
|
+
the first frame, against 0.6-1.1s for the other three tabs). An ordinary start
|
|
20
|
+
never shows it; a pane of blank boxes that is genuinely waiting still explains
|
|
21
|
+
itself.
|
|
22
|
+
|
|
8
23
|
## [0.5.0] - 2026-08-04
|
|
9
24
|
|
|
10
25
|
Findings from a cross-functional audit, filtered hard: everything that would
|
|
@@ -516,6 +531,7 @@ engineering, security, QA and UX. What follows is what changed as a result.
|
|
|
516
531
|
- The `main` field from `package.json`. It advertised the file as importable,
|
|
517
532
|
but importing it took over the terminal or exited the host process.
|
|
518
533
|
|
|
534
|
+
[0.5.1]: https://github.com/juan294/gh-glance/releases/tag/v0.5.1
|
|
519
535
|
[0.5.0]: https://github.com/juan294/gh-glance/releases/tag/v0.5.0
|
|
520
536
|
[0.4.1]: https://github.com/juan294/gh-glance/releases/tag/v0.4.1
|
|
521
537
|
[0.4.0]: https://github.com/juan294/gh-glance/releases/tag/v0.4.0
|
package/index.mjs
CHANGED
|
@@ -53,6 +53,23 @@ const REFRESH_MS = 5000;
|
|
|
53
53
|
// last movement, not from tab switches or Enter) quietly drops it.
|
|
54
54
|
const SELECTION_IDLE_MS = 60_000;
|
|
55
55
|
|
|
56
|
+
// How long a first fetch has to still be unresolved before the loading line
|
|
57
|
+
// offers the Nerd Font escape hatch. The hint used to be unconditional, which
|
|
58
|
+
// put a line naming an environment variable in front of every user on every
|
|
59
|
+
// start to catch the minority whose terminal cannot draw the glyphs -- a dim
|
|
60
|
+
// "loading actions…" reads as "working", the same line with a remedy attached
|
|
61
|
+
// reads as a warning, and it was on screen for the whole first fetch every time.
|
|
62
|
+
//
|
|
63
|
+
// The threshold is set from the fetch that actually gates it, not from a round
|
|
64
|
+
// number: the hint hangs off the *visible* tab's loading line, and the tab you
|
|
65
|
+
// land on is Actions, whose `gh run list` is by far the slowest call here
|
|
66
|
+
// (measured against this repo: issues/PRs/alerts resolve 0.6-1.1s after the
|
|
67
|
+
// first frame, runs 1.4-3.0s). 1.5s would have fired on most ordinary starts --
|
|
68
|
+
// i.e. changed nothing. 3s sits past the slow end of that range, so a start that
|
|
69
|
+
// reaches it is genuinely stuck rather than merely fetching, which is exactly
|
|
70
|
+
// the moment the remedy is worth a line.
|
|
71
|
+
const ICON_HINT_AFTER_MS = 3000;
|
|
72
|
+
|
|
56
73
|
// `gh run list` costs roughly linearly in --limit (measured: ~1.2s at 20 runs,
|
|
57
74
|
// ~3.0s at 100, ~4.9s at 150), so asking for a fixed 150 to render ~35 visible
|
|
58
75
|
// rows was paying several seconds per refresh for rows nobody sees. Actions is
|
|
@@ -2207,6 +2224,10 @@ function App() {
|
|
|
2207
2224
|
// The `?` overlay. Renders only on a keypress, so consecutive idle frames are
|
|
2208
2225
|
// still byte-identical and the redraw suppression is untouched.
|
|
2209
2226
|
const [showHelp, setShowHelp] = useState(false);
|
|
2227
|
+
// Set once, ICON_HINT_AFTER_MS into a first load that is still running. Never
|
|
2228
|
+
// reset: it only gates a line that a resolved tab stops rendering anyway, and
|
|
2229
|
+
// clearing it would cost a second state write for no visible difference.
|
|
2230
|
+
const [iconHintDue, setIconHintDue] = useState(false);
|
|
2210
2231
|
const [errors, setErrors] = useState({ actions: null, issues: null, prs: null, security: null });
|
|
2211
2232
|
const [loading, setLoading] = useState({ actions: true, issues: true, prs: true, security: true });
|
|
2212
2233
|
const [now, setNow] = useState(new Date());
|
|
@@ -2613,6 +2634,18 @@ function App() {
|
|
|
2613
2634
|
return () => clearInterval(id);
|
|
2614
2635
|
}, [showSpinner]);
|
|
2615
2636
|
|
|
2637
|
+
// Armed on the same condition the loading line renders on, so a start that
|
|
2638
|
+
// resolves inside ICON_HINT_AFTER_MS clears the timer on the way past and
|
|
2639
|
+
// never writes state at all -- the fast path stays exactly as many renders as
|
|
2640
|
+
// it was. `anyFirstLoad` excludes tabs that failed (see firstLoad above), so a
|
|
2641
|
+
// wedged tab cannot hold this armed: an error line already says what happened,
|
|
2642
|
+
// and a font hint underneath it would be answering a question nobody asked.
|
|
2643
|
+
useEffect(() => {
|
|
2644
|
+
if (!anyFirstLoad || iconHintDue) return;
|
|
2645
|
+
const timer = setTimeout(() => setIconHintDue(true), ICON_HINT_AFTER_MS);
|
|
2646
|
+
return () => clearTimeout(timer);
|
|
2647
|
+
}, [anyFirstLoad, iconHintDue]);
|
|
2648
|
+
|
|
2616
2649
|
const items = data[tab.key];
|
|
2617
2650
|
const error = errors[tab.key];
|
|
2618
2651
|
const spin = SPINNER[frame % SPINNER.length];
|
|
@@ -2834,12 +2867,13 @@ function App() {
|
|
|
2834
2867
|
{ dimColor: true },
|
|
2835
2868
|
firstLoad[tab.key]
|
|
2836
2869
|
? `${showSpinner ? spin : SPINNER[0]} loading ${tab.label.toLowerCase()}…` +
|
|
2837
|
-
//
|
|
2838
|
-
//
|
|
2839
|
-
//
|
|
2840
|
-
//
|
|
2841
|
-
// then there is
|
|
2842
|
-
|
|
2870
|
+
// Appended only once a first fetch has been running for
|
|
2871
|
+
// ICON_HINT_AFTER_MS, so an ordinary start never shows it: the
|
|
2872
|
+
// remedy is for someone looking at a pane of blank boxes, and by
|
|
2873
|
+
// then they have been looking long enough to want an explanation.
|
|
2874
|
+
// Suppressed once icons are already ASCII, since then there is
|
|
2875
|
+
// nothing to fix.
|
|
2876
|
+
(USING_NERD_ICONS && iconHintDue ? " (icons blank? GH_GLANCE_ICONS=unicode)" : "")
|
|
2843
2877
|
: tab.key === "security" && securityNotes.length === ALERT_SOURCES.length
|
|
2844
2878
|
? "no alert sources available"
|
|
2845
2879
|
: `no ${tab.countLabel}`,
|
package/package.json
CHANGED