Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ the dialog. Opening settings again starts at the menu.
Phone settings use a screen-width view while open. Closing the dialog restores
the dashboard's existing scaling. Desktop settings keep their side menus and
expand/collapse sections.
Settings switch to the compact layout when the window is at most 700 CSS pixels
wide. Before phone scaling is enabled, a valid screen width of at most 700 CSS
pixels also selects it when the browser reports a coarse (touch-style) pointer.
A small or unavailable screen-width report alone does not select phone settings
in a wide desktop window, including the Raspberry Pi pywebview desktop.

### General Settings Pane

Expand Down
2 changes: 1 addition & 1 deletion sensorius/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
release notes, and supporting tooling can report a consistent build identity.
"""

__version__ = "v0.26.258.2"
__version__ = "v0.26.259.1"
47 changes: 47 additions & 0 deletions tests/desktop-settings.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { test, expect } from '@playwright/test';

// Screen geometry can disagree with the available desktop window geometry.
for (const screenWidth of [1, 600]) {
test(`wide desktop settings ignore a ${screenWidth}px screen report`, async ({ browser, baseURL }) => {
const page = await browser.newPage({
baseURL,
viewport: { width: 1280, height: 900 },
screen: { width: screenWidth, height: 900 },
hasTouch: false,
isMobile: false,
});
try {
await page.route('https://cdn.jsdelivr.net/**', route => route.fulfill({ contentType: 'application/javascript', body: '' }));
await page.goto('/', { waitUntil: 'domcontentloaded' });
// Confirm the browser really matches the old, faulty screen-only fallback.
expect(await page.evaluate(() => matchMedia('(max-device-width:700px)').matches)).toBe(true);
await page.getByRole('link', { name: 'Open General Settings' }).click();
const general = page.locator('#setupPiModal');
await expect(general).toBeVisible();
await expect(general).not.toHaveClass(/(^|\s)mobile-settings(\s|$)/);
await expect(general.locator('.mobile-settings-nav')).toBeHidden();
await expect(general.locator('.system-settings-menu')).toBeVisible();
await expect(general.locator('.system-settings-content')).toBeVisible();
const display = general.locator('[data-runtime-section="system-display"]');
await display.locator(':scope > summary').click();
await expect(display.locator('#metric_set')).toBeVisible();
await general.getByRole('button', { name: 'Close General Settings' }).click();
for (const kind of ['Sensor', 'Switch']) {
await page.evaluate(kind => kind === 'Sensor'
? window.editSensorSettings('aht-pr-check')
: window.editSwitchSettings('switch-pr-check'), kind);
const root = page.locator(`#${kind.toLowerCase()}SettingsModal`);
await expect(root).toBeVisible();
await expect(root).not.toHaveClass(/(^|\s)mobile-settings(\s|$)/);
await expect(root.locator('.mobile-settings-nav')).toBeHidden();
await expect(root.locator('.mobile-settings-menu')).toBeVisible();
await expect(root.locator('.mobile-settings-content')).toBeVisible();
await expect(root.locator('#location')).toBeVisible();
await page.goto('/', { waitUntil: 'domcontentloaded' });
}
await expect(page.locator('meta[name="viewport"]')).toHaveCount(0);
} finally {
await page.close();
}
});
}
3 changes: 2 additions & 1 deletion ui_static/css/mobile_settings.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* Drill-down settings apply only to phone-sized viewports. */
.mobile-settings-nav, .mobile-settings-chevron { display:none; }
.mobile-settings-chevron::after { content:'›'; }
@media (max-width:700px), (max-device-width:700px) {
/* Keep the screen fallback aligned with phoneQuery in mobile_settings.js. */
@media (max-width:700px), (min-device-width:1px) and (max-device-width:700px) and (pointer:coarse) {
.modal-backdrop:has(.mobile-settings), #setupPiModal.mobile-settings {
padding:.35rem;
box-sizing:border-box;
Expand Down
5 changes: 4 additions & 1 deletion ui_static/js/mobile_settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

(() => {
if (window.initMobileSettings) return;
const phoneQuery = "(max-width: 700px), (max-device-width: 700px)";
// Phones need the screen fallback before their settings viewport is installed.
// A missing/small screen report alone must not classify desktop WebKit as mobile.
// Keep this query aligned with mobile_settings.css.
const phoneQuery = "(max-width: 700px), (min-device-width: 1px) and (max-device-width: 700px) and (pointer: coarse)";
const viewportOwners = new Set();
let settingsViewport = null;
window.setMobileWorkspaceViewport = function setMobileWorkspaceViewport(root, open, query = phoneQuery) {
Expand Down