Restore fallback Web UI assets and fix bottom-nav emoji rendering#83
Conversation
Summary of ChangesHello @aztr0nutzs, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses critical issues affecting the Android application's fallback Web UI by restoring essential assets and correcting display problems. The changes ensure that the application's user interface remains functional and visually consistent even when the local server is not ready, improving overall stability and user experience without altering core native or Gradle configurations. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
The pull request successfully restores missing fallback Web UI assets and addresses emoji rendering issues in the bottom navigation. The added CSS, JavaScript, and HTML files provide a functional UI for the Android app's asset-hosted fallback mode. I have identified a few areas for improvement, primarily concerning the security of attribute rendering in the device list and the frequency of background port scans on the gateway.
| tbody.innerHTML = rows.map(d => { | ||
| const isSel = d.id === state.selectedDeviceId; | ||
| return ` | ||
| <tr data-id="${d.id}" class="${isSel ? "selected" : ""}"> |
There was a problem hiding this comment.
The d.id value is used directly within an HTML attribute. If a device ID (which can originate from the backend) contains double quotes or other special characters, it could break the HTML structure or lead to XSS vulnerabilities. It is safer to escape this value.
| <tr data-id="${d.id}" class="${isSel ? "selected" : ""}"> | |
| <tr data-id="${escapeHtml(d.id)}" class="${isSel ? "selected" : ""}"> |
| <td>${escapeHtml(d.firstSeen || "—")}</td> | ||
| <td>${escapeHtml(d.lastSeen || "—")}</td> | ||
| <td>${escapeHtml(d.trust)}</td> | ||
| <td><button class="kebab" data-menu="${d.id}" title="Actions">⋮</button></td> |
There was a problem hiding this comment.
Similar to the row ID, the data-menu attribute should have its value escaped to prevent HTML breakage or potential injection if the ID contains special characters.
| <td><button class="kebab" data-menu="${d.id}" title="Actions">⋮</button></td> | |
| <td><button class="kebab" data-menu="${escapeHtml(d.id)}" title="Actions">⋮</button></td> |
| fetchJson("/api/v1/actions/portscan", { | ||
| method: "POST", | ||
| headers: { "Content-Type": "application/json" }, | ||
| body: JSON.stringify({ ip: gateway, timeoutMs: 250 }) |
There was a problem hiding this comment.
A port scan is initiated on the gateway every time the network UI is refreshed, which currently happens every 20 seconds via _dashPollTick. Probing the gateway this frequently might be considered aggressive and could trigger security alerts or rate-limiting on some routers. Consider performing this scan only when the network configuration changes or on manual refresh.
Motivation
android-app/src/main/assets/web-uibreak navigation and UI behavior (MainActivity.ktbuildsassetDashboardUrlused as fallback).【android-app/src/main/java/com/netninja/MainActivity.kt:L61-L71】web-uiinto internal storage, so missing fallback assets cause the runtime UI to lack CSS/JS that implement tab switching and visibility rules (AndroidLocalServer.copyDir+installApiRoutesserve/ui).【android-app/src/main/java/com/netninja/AndroidLocalServer.kt:L363-L367】【android-app/src/main/java/com/netninja/ApiRoutes.kt:L535-L536】js/dashboard.jscontains thesetTabhandler and click listeners, (2) screens overlaying because CSS controls.tab-pagevisibility, and (3) garbled bottom-nav icons because emoji glyphs may render with a font lacking color/emoji support in WebView. Evidence:ninja_mobile_new.htmlreferences the CSS/JS and contains nav buttons, whilejs/dashboard.jsimplementssetTaband listeners.【android-app/src/main/assets/web-ui/ninja_mobile_new.html:L678-L679】【android-app/src/main/assets/web-ui/ninja_mobile_new.html:L505-L542】【android-app/src/main/assets/web-ui/js/dashboard.js:L474-L493】【android-app/src/main/assets/web-ui/css/dashboard.css:L210-L217】Description
android-app/src/main/assets/web-ui/:css/dashboard.css,js/api-client.js,js/dashboard.js, andnet_ninja_cam.htmlso the asset fallback is functionally equivalent to the primary UI at runtime.【android-app/src/main/assets/web-ui/css/dashboard.css】【android-app/src/main/assets/web-ui/js/api-client.js】【android-app/src/main/assets/web-ui/js/dashboard.js】【android-app/src/main/assets/web-ui/net_ninja_cam.html】openclaw_icon.mp4→new_assets/openclaw_icon.mp4) so the badge loads rather than producing missing-resource errors.【android-app/src/main/assets/web-ui/ninja_mobile_new.html:L24-L27】.tabbtn .ticon) to avoid tofu/garbled glyphs inside Android WebView (font stack added tocss/dashboard.cssnear the.tabbtn .ticonrule).【android-app/src/main/assets/web-ui/css/dashboard.css:L698-L707】Testing
./gradlew :app:assembleDebug,./gradlew test, and./gradlew lint, but all failed in this environment due to missing Android SDK configuration (local.properties/ANDROID_HOME) and not due to the code edits; build failure message: "SDK location not found" (environment constraint). (Result: failed).【./gradlew :app:assembleDebug output】setTabhandler injs/dashboard.jsmaps bottom-navdata-tabtosection#tab-*IDs 1:1, confirming click→handler→destination chain is present (script lines implementingsetTaband event wiring exist). (Result: passed).【android-app/src/main/assets/web-ui/js/dashboard.js:L475-L493】【android-app/src/main/assets/web-ui/ninja_mobile_new.html:L505-L542】.tab-pagevisibility rules so screens will not render simultaneously and added emoji font stack to.tabbtn .ticonto avoid glyph corruption (inspectedcss/dashboard.cssrule). (Result: passed).【android-app/src/main/assets/web-ui/css/dashboard.css:L210-L217】【android-app/src/main/assets/web-ui/css/dashboard.css:L698-L707】android-app/src/main/assets/web-uiand attempted to serve via a local static server and capture with headless browser; Playwright attempts could not complete in this sandbox for file/port reasons, but the static file server and script copies succeeded and grep-based checks confirmed expected file presence. (Result: partial due to environment).Notes: commit created with message "Fix fallback WebUI navigation assets and bottom-nav icon rendering" and changes are limited to the asset files listed above to restore correct tab navigation, prevent screens overlaying, and fix bottom-nav icon rendering in the fallback WebView environment.
Codex Task