LearnNewsExamplesServices
Frontmatter
id12312
titlefix(portal): pulls timeline view unstyled on direct load — shared --gh palette not in proto-chain
stateClosed
labels
bugai
assigneesneo-opus-ada
createdAtJun 1, 2026, 6:44 PM
updatedAtJun 7, 2026, 7:17 PM
githubUrlhttps://github.com/neomjs/neo/issues/12312
authorneo-opus-ada
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 1, 2026, 7:32 PM

fix(portal): pulls timeline view unstyled on direct load — shared --gh palette not in proto-chain

neo-opus-ada
neo-opus-ada commented on Jun 1, 2026, 6:44 PM

Context

Operator-reported (2026-06-01), live portal: deep-linking the pulls view renders with no styling:

  • #/news/pulls/12113 → unstyled timeline.
  • Navigate to #/news/tickets/12114, then back to the pull → now styled.

Diagnosis (operator): "pulls have a HARD dependency on a different module for theming without requiring it." Confirmed.

The Problem

The GitHub-style timeline palette (--gh-bg-default, --gh-timeline-border, --gh-text-*, …) is defined under the global :root .neo-theme-neo-{light,dark} selector — but only inside the tickets and discussions leaf theme files (resources/scss/theme-neo-{light,dark}/apps/portal/news/{tickets,discussions}/Component.scss). The pulls theme file defines only its own PR badge colors and never defines (nor loads) the shared palette.

Neo loads theme CSS per component via component/Abstract.afterSetWindowId → Neo.currentWorker.insertThemeFiles(windowId, __proto__), which recurses up the prototype chain (src/worker/App.mjs insertThemeFiles). The pulls component's proto-chain is pulls.Component → Portal.view.content.Component → …; it does not include tickets/discussions. So a standalone pulls load never pulls in the palette. Visiting tickets/discussions first defines the :root vars globally, which is why back-navigation appears styled.

The Fix

Move the shared --gh-* palette to the theme of the shared timeline base Portal.view.content.Component (which tickets, pulls, and discussions all extend). It then loads for all three via the existing proto-chain insertThemeFiles recursion — making the dependency explicit and correct (the base every timeline view requires), instead of an implicit reliance on a sibling view having loaded first.

  • NEW resources/scss/theme-neo-{light,dark}/apps/portal/content/Component.scss — the shared --gh-* palette at :root .neo-theme-neo-{light,dark}.
  • Remove the now-redundant shared-palette block from the tickets + discussions leaf themes (keep their leaf-specific vars, e.g. discussions' --gh-discussion-category-*).
  • pulls leaf theme unchanged (its PR badge colors stay).

Bundled cleanup (operator-requested)

examples/calendar/weekview/MainContainer.mjs demonstrates the "one component loads an unrelated module's theme" pattern but is broken: it calls Neo.worker.App.insertThemeFiles(this.appName, null, 'Neo.calendar.view.MainContainer') in construct — passing appName where the first param is windowId. Fix to the reactive, correct shape:

afterSetWindowId(value, oldValue) {
    super.afterSetWindowId?.(value, oldValue);
    value && Neo.worker.App.insertThemeFiles(value, null, 'Neo.calendar.view.MainContainer')
}

Acceptance Criteria

  • AC1 — Deep-loading #/news/pulls/<n> directly (no prior tickets/discussions visit) renders the fully-styled PR timeline (borders, backgrounds, text colors) in both light and dark themes.
  • AC2 — The shared --gh-* palette is defined once, in Portal.view.content.Component's theme; tickets/pulls/discussions all resolve it via the proto-chain. No leaf re-defines the shared set.
  • AC3 — Theme rebuild (npm run build-themes -- -n -e dev -t all) regenerates the content-base theme CSS containing the palette, and the generated tickets/pulls/discussions CSS still resolve every --gh-* var.
  • AC4 — examples/calendar/weekview/MainContainer.mjs uses afterSetWindowId with the correct windowId arg (no appName-as-windowId).

Out of Scope

  • Chunk-folder sort order (#12309 / GPT's #12311).
  • Discussions offscreen-canvas timeline bug, avatar full-size fetch, news tab order, discussions open/closed tree state — separate tickets.

Related

  • Portal news chunked-nav track (epic #12204); pulls nav PR #12307.
tobiu closed this issue on Jun 1, 2026, 7:32 PM
tobiu referenced in commit 91a6a1e - "fix(portal): load shared --gh timeline palette from content base not tickets leaf (#12312) (#12313) on Jun 1, 2026, 7:32 PM