diff --git a/Android/app/src/main/java/com/archipelago/app/ui/screens/WebViewScreen.kt b/Android/app/src/main/java/com/archipelago/app/ui/screens/WebViewScreen.kt index 2cb57488..dbf90741 100644 --- a/Android/app/src/main/java/com/archipelago/app/ui/screens/WebViewScreen.kt +++ b/Android/app/src/main/java/com/archipelago/app/ui/screens/WebViewScreen.kt @@ -197,6 +197,12 @@ private fun injectSafeAreaVars(view: WebView) { * the status-bar height: the padded strip shows the page's OWN background * (padding is inside the element), so the bar keeps the page colour while * content starts below it — the pre-edge-to-edge look, without the black bar. + * + * Body padding only moves normal-flow content. fixed/sticky elements anchored + * at the viewport top (IndeeHub's floating header) stayed glued under the + * status bar, so we also push each of those down by the inset — once, marked + * via data attribute — and keep a throttled MutationObserver running so + * headers an SPA mounts after load get the same treatment. * Idempotent; runs on start (early) and finish (after the app rewrites head). */ private fun injectTopInset(view: WebView) { val insets = view.rootWindowInsets ?: return @@ -206,6 +212,7 @@ private fun injectTopInset(view: WebView) { view.evaluateJavascript( """ (function() { + var SAT = $sat; var s = document.getElementById('archy-top-inset'); if (!s) { s = document.createElement('style'); @@ -213,7 +220,40 @@ private fun injectTopInset(view: WebView) { (document.head || document.documentElement).appendChild(s); } s.textContent = - 'body{padding-top:${sat}px!important;box-sizing:border-box!important;}'; + 'body{padding-top:' + SAT + 'px!important;box-sizing:border-box!important;}'; + function push(el) { + if (el.dataset.archyInset) return; + var cs = getComputedStyle(el); + if (cs.position !== 'fixed' && cs.position !== 'sticky') return; + var top = parseFloat(cs.top); // 'auto' -> NaN skips bottom bars + if (isNaN(top) || top >= SAT) return; + el.style.setProperty('top', (top + SAT) + 'px', 'important'); + el.dataset.archyInset = '1'; + } + function sweep() { + if (!document.body) return; + // Fixed/sticky bars live shallow in the tree (portals mount on + // body); depth cap keeps the computed-style pass off big lists. + var els = document.body.querySelectorAll( + 'body > *, body > * > *, body > * > * > *, body > * > * > * > *'); + for (var i = 0; i < els.length; i++) push(els[i]); + } + sweep(); + if (!window.__archyInsetObserver) { + var queued = false, last = 0; + window.__archyInsetObserver = new MutationObserver(function() { + if (queued) return; + queued = true; + var wait = Math.max(0, 250 - (Date.now() - last)); + setTimeout(function() { + queued = false; + last = Date.now(); + sweep(); + }, wait); + }); + window.__archyInsetObserver.observe(document.documentElement, + { childList: true, subtree: true }); + } })(); """.trimIndent(), null, diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ca2e5f6..d1088d0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - FIPS startup is more reliable on nodes that have the packaged `fips.service` instead of Archipelago's `archipelago-fips.service`. Startup self-heal, onboarding, dashboard Start, and reconnect now use the systemd unit the node actually has, so FIPS no longer looks like it needs to be installed when it only needs to be started. - App screens over the FIPS mesh now bind their relay only to the node's FIPS address instead of reserving the same host ports Podman needs. This keeps apps such as FileBrowser and Botfights from restart-looping because the backend was already holding their published ports. +- Companion WebView safe-area handling now also moves fixed and sticky top bars below the phone status bar, including headers mounted after page load by single-page apps. - Public-source preparation now includes a Nostr Git hosting plan using `ngit`, NIP-34, and GRASP: anyone can clone, fork, review, and propose changes from their Archipelago node, while canonical merge authority stays with a small signed maintainer set in the style of Bitcoin Core. - Node OS release notes for v1.7.117 are still open; add any installer, service, kernel, firewall, or package changes here before cutting the release. diff --git a/neode-ui/src/views/settings/AccountInfoSection.vue b/neode-ui/src/views/settings/AccountInfoSection.vue index edfc52be..87b8a3e3 100644 --- a/neode-ui/src/views/settings/AccountInfoSection.vue +++ b/neode-ui/src/views/settings/AccountInfoSection.vue @@ -371,6 +371,7 @@ init()

FIPS startup is more reliable on nodes that have the packaged fips.service instead of Archipelago's archipelago-fips.service. Startup self-heal, onboarding, dashboard Start, and reconnect now use the systemd unit the node actually has, so FIPS no longer looks like it needs to be installed when it only needs to be started.

App screens over the FIPS mesh now bind their relay only to the node's FIPS address instead of reserving the same host ports Podman needs. This keeps apps such as FileBrowser and Botfights from restart-looping because the backend was already holding their published ports.

+

Companion WebView safe-area handling now also moves fixed and sticky top bars below the phone status bar, including headers mounted after page load by single-page apps.

Public-source preparation now includes a Nostr Git hosting plan using ngit, NIP-34, and GRASP: anyone can clone, fork, review, and propose changes from their Archipelago node, while canonical merge authority stays with a small signed maintainer set in the style of Bitcoin Core.

Node OS release notes for v1.7.117 are still open; add any installer, service, kernel, firewall, or package changes here before cutting the release.