Conversation
append new keys to 'en' language
Adds npm run lang:check and npm run lang:sort. The sort order in the js and mjs are the same order that VSCode natively uses with its built-in sorter.
85vh is measured against the full viewport including browser chrome (address bar, nav buttons), so on mobile the modal could overflow the visible area and push the footer button off-screen. Switch to `100svh - 40px` (small viewport height minus the backdrop's 20px padding on each side), which always equals the guaranteed visible area. 85vh is kept as a CSS fallback for older browsers that don't support svh units. Also adds -webkit-overflow-scrolling and overscroll-behavior: contain to the feature list for smooth iOS momentum scrolling. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(whats-new): OK button unreachable on mobile — use svh units
Workflow change to check src/lang/*.json key order, additional tools provided
Regression in 26.3.1 (commit c2bddcd): the UDP spot path unconditionally filled `spotterGrid` with `CONFIG.gridSquare` when the payload lacked one. For N1MM network broadcasts received from other contesters, this short- circuits the downstream HamQTH/prefix lookups and pins every spotter at the user's home, drawing lines from DX to the user instead of to the real spotter (#961, reported by VK3GA). Now only fall back to CONFIG.gridSquare when the spotter callsign matches the user's own callsign (base, SSID-stripped). For all other spots, leave spotterGrid null and let the existing HamQTH/prefix resolution locate the real spotter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a trash-icon button in the PSKReporter panel header (between the filter and refresh buttons) that wipes all currently displayed TX/RX spots from local state. The map auto-clears on the next render since its useEffect depends on the spots array. Use case: contesters changing bands often have stale spots from the prior band cluttering the map, especially when the new band is near the old one and the band-color is similar. The existing band filter takes multiple clicks; this is one click (#933, reported by tedszypulski-ui). - Adds IconTrash to Icons.jsx - Adds clear() to usePSKReporter hook (returns from hook surface) - Button is disabled when there are no spots to clear - New translation key pskReporterPanel.psk.clearTooltip across all 16 langs Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three small cleanups surfaced while diagnosing issue #875, where a user set ROTATOR_HOST/ROTATOR_PORT/ROTATOR_PROVIDER=pstrotator_http and ended up with UDP traffic going to our hardcoded 192.168.1.43 default — none of their config was actually being read. 1. Remove ROTATOR_HOST / ROTATOR_PORT from server/config.js + server.js. They were exported into the context but never consumed by rotator.js, which reads PSTROTATOR_HOST / PSTROTATOR_UDP_PORT directly. Having both pairs in the codebase invited exactly the misconfig in #875. 2. Validate ROTATOR_PROVIDER against a known set ({none, pstrotator_udp}). Unknown values like 'pstrotator_http' previously triggered the UDP path silently; now we warn and disable the rotator instead. 3. Stop defaulting PSTROTATOR_HOST to '192.168.1.43'. When the provider is enabled but no host is set, log a warning and disable the rotator rather than leak a hardcoded LAN IP into other users' logs. Also tightens the .env.example block to say the server only speaks UDP and that 'pstrotator_udp' is currently the only non-'none' value. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New BandActivityHeatmap panel mirrors DX-Heat's Band Activity view: a continent×band matrix with gaussian-blurred SVG blobs colored by spot count over the selected time window. Defaults match the DX-Heat layout exactly — 6/10/12/15/17/20/30/40/80/160m rows, EU/NA/SA/AS/AF/OC columns, 60-minute window, blue→cyan→green→yellow→orange→red legend at the 0/9/11/13/19/20 stops. Behavioral notes: - The "Your continent" picker defaults to the continent derived from the user's callsign via cty.dat; user override is persisted to localStorage. - A spot lands in column X on row B when the spot's band is B and at least one party (spotter or DX) is on the user's continent — the "other" party determines the column. Intra-continental spots count toward the user's own column. - A 15/30/60 min window selector (DX-Heat only offers 60) is added, and per-cell numeric overlay shows the exact count for accessibility. Wired into DockableApp as panel id 'band-activity'. Users add via the panel picker; not in the DEFAULT_LAYOUT so existing layouts are unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The spot list shape produced by useDXClusterData stores the DX callsign as `call`, not `dxCall` (see src/hooks/useDXClusterData.js:140). The new BandActivityHeatmap panel was reading spot.dxCall — always undefined — so the DX continent always resolved to null and every spot got filtered out, leaving the matrix empty. Now reads spot.call with a fallback to spot.dxCall in case the panel is ever fed from a source that uses the path/proxy shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a Settings → Display → Monospace font selector with three options: - JetBrains Mono (default — dotted zero) - Fira Code (slashed zero) - IBM Plex Mono (slashed zero, slightly wider) The reporter (N4HNH) couldn't reliably distinguish 0 from 8 in the default font at small sizes. Fira Code and IBM Plex Mono both ship with a slashed-zero variant that resolves the ambiguity. Implementation: - New --font-mono CSS variable in themes.css (theme-independent). - ~210 inline JSX styles and CSS rules that hardcoded 'JetBrains Mono, monospace' swapped to var(--font-mono). Intentional override stacks (e.g. 'Orbitron, JetBrains Mono, ...') left alone, as are canvas ctx.font strings (CSS vars don't resolve in canvas). - vendor-download.sh now pulls Fira Code and IBM Plex Mono alongside the existing fonts. - useTheme reads openhamclock_monoFont from localStorage on init and applies the value to --font-mono; the dropdown writes the same key. - New i18n key station.settings.monoFont(+.describe) across all 16 langs. Heads-up for deployers: rerun bash scripts/vendor-download.sh to fetch the new font files. Existing installs that don't run it will fall back to system monospace when the user picks Fira Code or IBM Plex Mono. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
append new keys to 'en' language
…MichaelWheeley/openhamclock into language_translations_satellite_feature # Conflicts: # src/lang/ca.json # src/lang/de.json # src/lang/en.json # src/lang/es.json # src/lang/fr.json # src/lang/it.json # src/lang/ja.json # src/lang/ka.json # src/lang/ko.json # src/lang/ms.json # src/lang/nl.json # src/lang/pt.json # src/lang/ru.json # src/lang/sl.json # src/lang/th.json # src/lang/zh.json
…ellite_feature [Translation] [feature/satellite] Language translations for all satellite features
VK3GA reported that scheduled display sleep correctly blacks out the
screen but his TV then goes to standby because the host's DPMS kicks in
and kills the HDMI signal. TVs that latch into standby on signal loss
won't return when the signal comes back — only the remote will.
Root cause was intentional: useScreenWakeLock released the wake lock
when displaySleeping was true so the OS could power off the monitor
("so your TV or monitor can sleep" — the literal SettingsPanel text).
That's the right move for dedicated monitors but wrong for TVs.
Fix: add a displaySchedule.keepSignalActive flag, default true. When
held, the wake lock stays acquired through the sleep window — only the
black CSS overlay covers the screen, the HDMI signal continues, and the
TV stays "awake" (just showing black). At wake time the overlay clears
and the dashboard reappears with no remote intervention.
Users who want the monitor to actually power down can opt out via a new
checkbox under the time pickers. The explainer text now describes both
modes and points TV users at the setting.
- Config default flips to keepSignalActive: true (fix-by-default)
- Existing saved configs without the flag inherit the new default via
`keepSignalActive !== false` reads in both the hook and the panel
- No change for users who untoggle the new checkbox
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…satellite is visible
Self-contained Reveal.js presentation about OpenHamClock, originally written for the DVRA (W2ZQ) club night on 2026-05-13. Designed to also serve as a template that other hams can fork for their own club talks. - `presentations/README.md` indexes available decks - `dvra-w2zq-2026-05-13/index.html` is the deck (16 slides, 16:9, CDN-loaded reveal.js, no build step) - Per-deck README documents how to present, customize, and trim - `speaker-notes.md` has script-grade talking points, transitions, and a Q&A bank Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Title and closer slides get the OHC logo (explicit centering that beats reveal theme's `.reveal section img` rule) - Hero screenshots on the big-picture and map slides (1.png, 2.png) - Side-panel screenshots on DX cluster, activations, satellites - 3-up screenshot grid on the propagation slide - Live-demo slide gets a ghosted full-slide background screenshot - Install slide reflowed to a 2x2 card grid with proper CLI wrapping (min-width:0 + overflow-wrap:anywhere fixes grid overflow) - Closer slide tightened so "Questions?" fits without cutoff - WB0OEW SK date corrected to early 2026; quote line dropped on slide 3 - Final slide no longer leads with Elwood; switched to contributors-only - New DVRA-member callout thanking N2EHL (Rich Freedman) on the DX cluster and closer slides for his cluster-filtering contributions Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
[Fix] use language coded version of 'VISIBLE' inside prediction table
…re lat/lon d1ab3d5 replaced calculateGridSquare(lat, lon) with latLonToMaidenhead but kept the two-positional-arg call style. latLonToMaidenhead expects ({lat, lon}) as its first argument; passing a bare number caused lat/lon to destructure as undefined, producing NaN and invisible characters in both DE and DX grid squares. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(grid-display): restore Maidenhead grid square in DE/DX panels
…soning Production cache was holding 9 unresolved sats (ISS, SO-50, AO-91, AO-123, SO-125, PO-101, EWS-G2, GK-2A, HIMAWARI-9) for ~7h after a single bad refresh. Root cause: CelesTrak rate-limits parallel CATNR lookups by returning HTTP 200 with an empty body; the first batch of 5 hit that limit, fell through to SatNOGS which doesn't carry the weather geos, and the partial result poisoned the 12h cache. - Drop per-NORAD parallelism from 5 → 2 and bump inter-batch delay to 500ms - Retry CelesTrak CATNR once after 1s on empty/short responses before giving up to SatNOGS - If a refresh ends up materially worse than the previous cache (5+ sats unresolved, prior cache still within stale-serve window), keep the old cache and mark X-TLE-Stale instead of overwriting Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous resolver hardening (58f1cb6) made the cold-start refresh path worse, not better: per-NORAD retries + smaller batches pushed worst-case refresh latency past Cloudflare's 100s edge timeout. Users hitting /tle during a cold-cache window got 524s; the CDN then cached the error HTML for an hour, breaking the satellite layer for everyone in that region. - Drop the 1s CelesTrak CATNR retry — kept smaller batches (2-parallel) and 400ms inter-batch delay, which already addresses the original CelesTrak throttling without doubling worst-case latency - Per-request timeout 5s → 4s to keep total worst case under CF window - Add a single in-flight refresh Promise (refreshInFlight) so concurrent /tle requests share one upstream refresh instead of fanning out N parallel CelesTrak hammering attempts - Add stale-while-revalidate: if any cached data exists, return it immediately and kick the refresh off in the background. The only request that blocks on a slow refresh is the very first one after a cold boot — no chance of CF 524 once the cache has been seeded - Keep the "refuse to overwrite a materially worse cache" safeguard Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Post-26.3.2 accumulated work: - NEW: Band Activity heatmap dockable panel (#913) - NEW: User-selectable monospace font in Settings (#923) - NEW: PSK Reporter clear-all-spots button (#933) - fix(display-schedule) #901: TV-standby HDMI keep-alive - fix(satellites) 58f1cb6/d8948a3: CelesTrak rate-limit resilience + stale-while-revalidate to avoid CF 524s during cold-cache windows - fix(dxcluster) #961: N1MM UDP spot lines run DX→spotter again (VK3GA) - fix(satellites) #970/#973: localized "VISIBLE" badge (Michael Wheeley) - fix(whats-new) #972: OK button reachable on mobile (DO1HOZ) - fix(grid-display): pass location object to latLonToMaidenhead (DO1HOZ) - refactor(rotator): drop dead config knobs, validate ROTATOR_PROVIDER - CI: lang:sort/lang:check gate for src/lang/*.json (#971, Michael Wheeley) Updates ANNOUNCEMENT banner to point at 26.3.3 content and the Hamvention 2026 booth (May 15-17, Booth #9518). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Release v26.3.3. Cuts Staging into main — 37 commits, ~3.4k LOC.
New features
--font-monoCSS variable replaces ~210 inline'JetBrains Mono'references. Adds Fira Code and IBM Plex Mono (slashed 0 options).vendor-download.shextended — deployers must rerun it to fetch the new font files.useSatelliteLayer.jsconverted tot()calls; new keys across all 16 languages including the prediction-table VISIBLE badge.Bug fixes
58f1cb6hardens against CelesTrak rate-limit poisoning. Reported by Alan 2026-05-12: prod cache had stranded 9 sats (ISS, SO-50, AO-91, AO-123, SO-125, PO-101, EWS-G2, GK-2A, HIMAWARI-9) for ~7h after one bad refresh. CelesTrak rate-limits parallel CATNR lookups by returning HTTP 200 with empty bodies; the first batch of 5 hit that limit, SatNOGS doesn't carry the three weather geos, partial result poisoned the 12h cache. Drops per-NORAD parallelism 5→2, refuses to overwrite a materially worse cache.d8948a3follow-up: the previous commit's added retry expanded worst-case refresh latency past Cloudflare's 100s edge timeout, briefly stranding Staging users with 524s after redeploy. Drops the retry, shrinks per-request timeout 5s→4s, adds a single in-flight refresh Promise (concurrent /tle requests share one upstream pass), and adds stale-while-revalidate so any cached data is served immediately while refresh runs in the background. Only the very first cold-boot request blocks.keepSignalActiveflag (default on) holds wake-lock so HDMI stays alive and the TV stays awake on the black overlay. Opt-out checkbox in Settings → Display Schedule.CONFIG.gridSquarefallback to self-spots only.latLonToMaidenhead, not bare lat/lon.Refactor / tooling
ROTATOR_HOST/ROTATOR_PORTexports, validateROTATOR_PROVIDER, kill the hardcoded192.168.1.43PSTRotator fallback (warn+disable instead).check-json-keysworkflow +npm run lang:sort/lang:checkscripts ensure allsrc/lang/*.jsonfiles stay in VSCode-native key order.Release notes
package.json/package-lock.jsonbumped 26.3.2 → 26.3.3 (commitab61680).vendor-download.shmust be rerun to pick up Fira Code / IBM Plex Mono assets, otherwise the new font picker falls back to system mono.Test plan
npm run lang:checkpasses (CI gate)vendor-download.sh)/api/satellites/tleonce, then/api/satellites/debugshould showtotalResolved ≥ 35/38(the only legit holdouts EWS-G2/GK-2A/HIMAWARI-9 when CelesTrak throttles, since SatNOGS doesn't carry them)🤖 Generated with Claude Code