Skip to content

feat(examples/elk): scaffold Elk-on-Lynx example with PRD#196

Open
Huxpro wants to merge 12 commits into
mainfrom
claude/elk-vue-lynx-port-rh9gpd
Open

feat(examples/elk): scaffold Elk-on-Lynx example with PRD#196
Huxpro wants to merge 12 commits into
mainfrom
claude/elk-vue-lynx-port-rh9gpd

Conversation

@Huxpro

@Huxpro Huxpro commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Fresh Vue Lynx shell for porting the Elk Mastodon client. Builds for
both lynx and web targets. PRD.md carries the full Elk feature
inventory with parity status and Lynx-suitability notes.

Co-Authored-By: Claude Fable 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr

claude added 10 commits July 11, 2026 12:02
Fresh Vue Lynx shell for porting the Elk Mastodon client. Builds for
both lynx and web targets. PRD.md carries the full Elk feature
inventory with parity status and Lynx-suitability notes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
Reused from Elk (near-verbatim): masto.js client setup, content-parse
pipeline (ultrahtml sanitize + emoji/markdown/mention transforms),
paginator state machine, timeline filter/reorder, status action
optimistic updates, search composable, cache, account helpers, theme.

Rebuilt for Lynx: content renderer emits <view>/<text>/<image> instead
of DOM tags, native <list> timeline with scrolltolower infinite scroll,
RemixIcon SVG data-URIs (Elk's i-ri:* set), token sign-in instead of
OAuth redirect, in-memory session instead of localStorage/IndexedDB.

Notable Lynx adaptations:
- free-identifier web globals (fetch/Request/AbortSignal...) rewritten
  to globalThis.* via source.define — the BG eval scope hides them
- tiny-decode replaced with a DOMParser-free entity decoder
- custom emoji use staticUrl (no <picture> reduced-motion sources)

Verified on Lynx for Web via @lynx-js/web-core harness: local/federated
timelines, explore trends (posts+tags), search, thread, account profile,
settings all render against live mas.to data (screenshots/lynx/).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
…k.zone

Compared against the original Elk (mobile viewport, same mas.to instance,
captured minutes apart) and fixed the visible deltas: heart favourite
icon, stacked name/handle header, vertical preview cards for wide images,
icon + primary-colored page titles, full @user@server handles, Elk-style
relative timestamps.

Adds PORTING.md (reused-vs-rebuilt map + Lynx landmines), screenshot
comparison doc (screenshots/{lynx,elk}), and the verification harness
(web-core host page, API relay for TLS-blocked sandboxes, Playwright
capture scripts).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
…ollections

- Dark mode: Elk's .dark palette as cascading CSS vars on the app root,
  toggle in Settings; verified side-by-side against elk.zone dark.
- Fullscreen media preview overlay (tap attachment; alt text panel).
- Quote posts (Mastodon 4.5) as nested cards like Elk's StatusQuote.
- Following/Followers list pages wired from profile stats.
- Bookmarks/Favourites pages (auth-gated, shared paginator).
- Hashtag timeline verified (CJK tags, remote content).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
…ot badges

- Deep-link any route via Lynx globalProps initialPath (native LynxView
  globalProps / <lynx-view global-props> on web) — lynx is a card-wrapper
  bare identifier, not a globalThis property
- Explore gains Elk's trending-links News tab
- Timeline header refresh button (replaces Elk's streaming prepend)
- Follow/unfollow hashtag button on tag pages (auth-gated)
- Bot/locked account badges beside display names

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
… typecheck

Edit history: 'Edited … (view history)' on the thread page fetches
v1/statuses/:id/history and renders versions — verified against a live
edited status (capture doubles as quote-post rendering proof).

Adds the example README with feature overview and run instructions,
a gallery preview image, and a bundler-resolution tsconfig so the app
sources typecheck cleanly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
All/Mentions notification filter tabs (Elk notifications/[filter] via the
types param). Every remaining unported feature in the PRD now carries an
explicit reason (auth-only, editor-stack, or non-vanilla-API). Verified
the production build (no ELK_API_PROXY) contains zero relay references.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
… code

Adds /guide/elk (en + zh): the Go embed runs the Elk example on Lynx for
Web against a live Mastodon instance, and its QR Code tab serves the same
dist/main.lynx.bundle for native rendering in Lynx Go / Lynx Explorer.
prepare-examples picks the example up automatically (metadata: lynx +
web template files, preview image, 63 browsable sources).

Also adds a 'Showcase' sidebar section and an Elk card on the home
showcase grid (extends the ShowCase component to accept static image
posters alongside videos).

Verified: dev-server render with live timeline data in the embedded
preview, QR tab, home card, and a full production rspress build
(doc_build contains guide/elk.html, zh twin, and both bundles).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
generate-api.ts mirrors member pages into website/docs/zh/guide/api/
(the en twin was already ignored); the two hand-written zh index.mdx
files stay tracked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vue-lynx Ready Ready Preview, Comment Jul 11, 2026 7:54pm

…cons

First on-device run (Lynx Go) failed every request: masto.js calls
AbortSignal.any unconditionally per request, and also needs the Headers
and URL constructors — none of which exist in the native background
runtime (@lynx-js/types guarantees only fetch/Request/Response/timers).
src/polyfills.ts now installs fill-if-missing AbortController/AbortSignal
(.any/.timeout), Headers, URL, URLSearchParams, Object.hasOwn and
Array.prototype.at before anything else; inert on Lynx for Web.

Icons rendered blank on device too: the native image element has no SVG
decoder, so data:image/svg+xml sources silently fail. AppIcon now uses
the built-in <svg content> element (x-svg on web) with raw tinted XML.

Web target regression-verified (icons + live timeline unchanged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
Three defensive changes for the native fetch pipeline, where masto's
request objects cross into the platform implementation:
- AbortSignal.any([]) (polyfill) now returns undefined — masto calls it
  unconditionally per request, and this keeps foreign signal objects out
  of the native fetch's RequestInit entirely (no real signals exist in
  this app: no timeout configured, no per-request aborts)
- the polyfill URL gains a non-standard .url getter — native Request
  constructors may duck-type non-string inputs as Request-like and read
  .url, which would otherwise be undefined
- the timeline error state now prints the actual exception plus a
  bare fetch('https://mas.to/...') probe result, so a device screenshot
  pinpoints whether fetch itself or masto's request construction fails

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BXJVSwkbxbk9AbDTfeY7Lr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants