Skip to content

Full product audit, Part 2: 11 bugs in settings, sharing, navigation, and large-data behavior #560

Description

@nickhamze

This is the follow-up to #559. The point of this pass was to catch the things users usually find first: the second quick click, the stale browser tab, the narrow screen, the shared folder after reload, and the site with enough content to make a visualization fall over.

I updated to current origin/trunk (c670170) before the final verification pass, then replayed every candidate from the older checkout. Anything already fixed upstream was removed from this issue.

The bugs below still reproduce on current trunk. The two settings problems are the most urgent because OpenStation tells the user everything is saved while silently keeping the wrong value. Screenshot evidence is attached in the first comment.

1. A quick second toggle in Extended Options is silently lost

Why this matters: The control ends in one state, the server saves the opposite state, and the user is not told anything went wrong.

To reproduce:

  1. Open OpenStation Preferences → Features as an administrator.
  2. Toggle Enable drag-and-drop in the Media Library off and immediately back on while the first save is still running.
  3. The checkbox finishes enabled.
  4. Reload or read desktop-mode/v1/extended-options; the server persisted disabled.

The save function returns early while a request is in flight, but the still-enabled control keeps accepting changes and never queues a trailing save.

Where to look: src/settings/sections/extended.ts

2. Two open sessions can overwrite each other’s unrelated settings

Why this matters: A setting that already showed as saved can be silently undone by a stale tab or another device changing something unrelated.

To reproduce:

  1. Open OpenStation in two browser sessions for the same user.
  2. In session A, change the wallpaper and wait for it to save.
  3. Without reloading session B, change only the accent color and wait for it to save.
  4. Reload. Session B’s stale full-settings snapshot restores the old wallpaper while keeping the new accent.

Each save replaces the complete server-side settings object. There is no revision check, conflict response, field merge, or patch request.

Where to look: src/settings/state.ts, includes/os-settings.php

3. Owned folder windows lose their Share button after reload

Why this matters: Folder sharing works on the server, but the owner loses the main way to manage it from the folder window.

To reproduce:

  1. Enable folder sharing and create or share a folder.
  2. Reload the owner’s desktop.
  3. Open the folder from the wallpaper.
  4. The title bar has its normal window and breadcrumb controls, but no Share folder action.

The button matcher requires folder ownership from the client folder store. Normal persisted-placement hydration does not populate that store.

Where to look: src/desktop-files/share-menu-items.ts

4. Accepted shared folders never show the shared badge

Why this matters: Neither owner nor recipient can tell from the desktop that a folder is shared, even after an invitation has been accepted.

To reproduce:

  1. Share an owned folder with a second user.
  2. Accept the invitation as the recipient.
  3. Reload both desktops.
  4. The folder tile has no shared badge for either person.

The badge reads placement.file.shareSummary, but placement responses omit that field. It exists only in the separate folder response shape.

Where to look: includes/desktop-files/rest.php, src/desktop-files/share-menu-items.ts

5. OpenStation Preferences is mostly unreachable at 390px

Why this matters: On a phone-sized viewport or under magnification, most of the window and every right-side title-bar action can sit outside the visible page with no horizontal recovery path.

To reproduce:

  1. Set the viewport to 390×844.
  2. Open OpenStation Preferences as a normal window.
  3. The fresh window renders 820px wide. Its right edge lands at 849px, while the viewport ends at 390px.
  4. Window actions, Minimize, Maximize, Fullscreen, Close, and much of the content are unreachable.

The window keeps its desktop minimum width instead of switching to a compact contract or clamping itself to the viewport.

Where to look: src/desktop.ts, src/window-manager/index.ts

6. Arrow keys do not operate tabs—and can switch desktops instead

Why this matters: Keyboard users cannot move through tab strips using the standard Left/Right Arrow behavior. In Preferences, the unhandled key can bubble to the shell shortcut and switch virtual desktops, making the entire window disappear.

To reproduce:

  1. Open Preferences and focus the selected Appearance tab.
  2. Press Right Arrow.
  3. Focus and selection stay on Appearance instead of moving to Themes.
  4. In the reproduced shell, the key also switched virtual desktops and hid Preferences.
  5. Repeat in Posts: Right Arrow on All posts does not move to Categories.

The tab component handles clicks but has no ARIA tab-pattern keyboard behavior.

Where to look: src/ui/components/os-tabs/os-tabs.ts, src/window/dom.ts

7. Cron’s custom interval field is invisible and unusable

Why this matters: The Cron app opens and lists jobs, but users cannot finish creating a custom recurrence because the required number field never upgrades into a real control.

To reproduce:

  1. Open Cron Jobs.
  2. Choose Create.
  3. Select Custom interval.
  4. The intended <os-number-field> remains an undefined, zero-size element with no focusable input.

The component exists in source but is not present in the production component registration path used by the extension.

Where to look: extensions/desktop-mode-cron-manager/includes/window.php, src/ui/components/os-number-field/

8. Spatial desktop shortcuts ignore enabled native windows

Why this matters: A user can explicitly enable native Posts, Pages, Comments, Plugins, and Users, but clicking their Spatial-layout wallpaper shortcuts still opens the old iframe versions.

To reproduce:

  1. Choose the Spatial desktop layout.
  2. Enable the native Posts, Pages, Comments, Plugins, and Users features.
  3. Click any matching wallpaper shortcut.
  4. OpenStation opens the classic URL/iframe window instead of the enabled native app.
  5. Opening the same app from the canonical native API or dock correctly uses the native renderer.

The synthesized shortcut carries only a URL and bypasses the native replacement registry used by the dock.

Where to look: src/settings/desktop-shortcuts-sync.ts, src/desktop-files/built-in-openers.ts, src/desktop-layout.ts

9. Plugin fallback icons render as blank gray squares

Why this matters: Bundled and locally installed plugins without working WordPress.org artwork lose their identity in the native Plugins window.

To reproduce:

  1. Open native Plugins and wait for the remote icon fallback chain to finish.
  2. Look at a plugin without usable WordPress.org artwork, such as a bundled extension or Hello Dolly.
  3. Its fallback is a blank gray square instead of the intended plugin icon.

The fallback inserts a Dashicons class inside the table’s Shadow DOM, where the document-level Dashicons font and pseudo-element CSS cannot reach it.

Where to look: src/plugins-window/installed-view.ts, src/plugins-window/icon-fallback.ts

10. Firefox drops Gravatars on WordPress 6.0/local HTTP installs

Why this matters: Real user avatars are replaced with initials in the native Users window on a supported minimum environment.

To reproduce:

  1. Run the supported WordPress 6.0/PHP 7.4 environment over local HTTP.
  2. Open native Users in Firefox.
  3. The REST response supplies http://*.gravatar.com URLs.
  4. OpenStation probes them with crossOrigin=anonymous; the HTTP→HTTPS redirect fails CORS, and the UI falls back to initials.

Normalizing known Gravatar URLs to HTTPS before the probe avoids the redirect/CORS failure.

Where to look: src/ui/util/avatar-resolve.ts

11. Content Graph freezes the browser with a large site

Why this matters: A site within the lab’s stress profile can lock the entire OpenStation shell for more than ten seconds just by opening Content Graph. The completed view is also too dense to read or operate meaningfully.

To reproduce:

  1. Use a site whose Content Graph contains roughly 8,890 nodes.
  2. Open Content Graph.
  3. On the final trunk replay, Chromium took 11.59 seconds to become usable and 28.64 seconds on the evidence replay. The longest single main-thread blocks were 10.85–14.12 seconds. Earlier cross-browser runs also blocked Firefox for about 16 seconds and WebKit for about 13 seconds.
  4. The Fit overview renders thousands of tiny marks with no useful visual hierarchy.

The current path performs synchronous simulation warm-up work over the full graph and creates a Pixi object/text workload for every node before yielding.

Where to look: src/content-graph/index.ts, src/content-graph/scene.ts, src/content-graph/sim.ts

Suggested order of attack

  1. Fix the two silent settings-loss paths (Uploading demo video  #1 and ci: make npm run test:php actually work #2).
  2. Make Preferences and tab navigation safe for narrow and keyboard use (Add command palette registration APIs and sync functionality #5 and feat: enable media library enhancement by default with opt-out option #6).
  3. Restore the broken Cron and sharing controls (chore: fix all ESLint + tsc --noEmit errors #3, fix: resolve 3 PHPUnit failures + 1 error on trunk test code #4, and ci: wire PHP tests through wp-env + fix 4 pre-existing failures #7).
  4. Correct the alternate entry points and compatibility fallbacks (Feat/os settings help tab #8docs: marketing-first README + stage technical content for the wiki #10).
  5. Move Content Graph loading off the long synchronous path and introduce a real large-graph display strategy (Feat/unify command palettes #11).

Each fix should get a focused regression test at the owning state/component layer, plus one browser replay of the user-visible flow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions