mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-14 13:22:37 +00:00
* fix(app): sync Android system bar icon style with app theme With edge-to-edge enabled the app draws under the Android system bars, but the bars keep their default light icon style regardless of theme, so the status bar clock/battery/icons are invisible on light themes (white on white). Call SystemBars.setStyle from the appearance provider whenever the theme is applied: dark icons on light themes, light icons on dark themes, auto following the system for adaptive themes and plugin-contributed themes. Refs #1272 (runtime only; the splash screen phase is not covered). * fix(app): keep Android status icons readable as themes change Keep system-bar contrast subscribed to the resolved app theme so automatic appearance changes update the icons as well as the app surface. Add a native regression covering explicit and automatic themes. Co-authored-by: TeraYang <4110825+terayang@users.noreply.github.com> * fix(app): map system-bar appearance through color scheme Unistyles reserves style mappings for React Native style objects. Keep SystemBars style selection inside its appearance adapter and map the colorScheme prop instead. --------- Co-authored-by: TeraYang <4110825+terayang@users.noreply.github.com> Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
63 lines
2.4 KiB
JavaScript
63 lines
2.4 KiB
JavaScript
// Open Settings > Appearance in a native Android app loaded from this checkout.
|
|
// AGENT_DEVICE_STATE_DIR=<state-dir> node packages/app/e2e/mobile/system-bars/android.mjs <session> <adb-serial> <app-id>
|
|
// Requires English UI and a dedicated emulator. Leaves System theme and light OS appearance.
|
|
import assert from "node:assert/strict";
|
|
import { execFileSync } from "node:child_process";
|
|
import { setTimeout as delay } from "node:timers/promises";
|
|
|
|
const [, , session, serial, appId] = process.argv;
|
|
assert(session && serial && appId, "Pass the agent-device session, adb serial, and app ID");
|
|
|
|
function ad(...args) {
|
|
return execFileSync("agent-device", [...args, "--session", session], {
|
|
encoding: "utf8",
|
|
timeout: 60_000,
|
|
});
|
|
}
|
|
|
|
function windowState() {
|
|
const state = execFileSync("adb", ["-s", serial, "shell", "dumpsys", "window"], {
|
|
encoding: "utf8",
|
|
timeout: 10_000,
|
|
});
|
|
assert(state.match(/mCurrentFocus=.*\n/)?.[0].includes(`${appId}/`), "App must be focused");
|
|
const regions = state.match(/mLastStatusBarAppearanceRegions=\s*\n([^\n]+)/)?.[1];
|
|
assert(regions, "Android must report the status-bar appearance region");
|
|
return regions.includes("LIGHT_STATUS_BARS");
|
|
}
|
|
|
|
async function expectDarkIcons(expected, context) {
|
|
const deadline = Date.now() + 5_000;
|
|
do {
|
|
if (windowState() === expected) {
|
|
console.log(`PASS: ${context}`);
|
|
return;
|
|
}
|
|
await delay(100);
|
|
} while (Date.now() < deadline);
|
|
assert.equal(windowState(), expected, context);
|
|
}
|
|
|
|
function selectTheme(theme) {
|
|
const current = ad("snapshot", "-i").match(/"Theme: ([^"]+)"/)?.[1];
|
|
assert(current, "Start on Settings > Appearance");
|
|
ad("press", `label="Theme: ${current}"`, "--settle");
|
|
ad("press", `label="${theme}"`, "--settle");
|
|
ad("wait", "text", `Theme: ${theme}`, "5000");
|
|
}
|
|
|
|
ad("settings", "appearance", "light");
|
|
selectTheme("Light");
|
|
await expectDarkIcons(true, "Light app theme uses dark status icons");
|
|
selectTheme("Dark");
|
|
await expectDarkIcons(false, "Dark app theme uses light status icons");
|
|
selectTheme("System");
|
|
await expectDarkIcons(true, "System theme starts with dark icons on light OS appearance");
|
|
ad("settings", "appearance", "dark");
|
|
await expectDarkIcons(
|
|
false,
|
|
"System theme follows an OS change to dark without reopening settings",
|
|
);
|
|
ad("settings", "appearance", "light");
|
|
await expectDarkIcons(true, "System theme follows an OS change back to light");
|