mirror of
https://github.com/nexu-io/open-design.git
synced 2026-06-01 03:14:35 +07:00
* feat(landing-page): plugin detail page interactive preview + share dialog The new `/plugins/<manifest-id>/` detail page that shipped in #2926 landed without the two affordances PR #2679 added to the legacy `/skills/<slug>/` and `/templates/<slug>/` pages: a click-to-expand iframe of the live artifact, and a share dialog with brand-keyword copy plus four-channel jump buttons (X / LinkedIn / Reddit / Facebook). This restores both, sourced from the bundled-plugin manifest under `plugins/_official/<bucket>/<slug>/open-design.json`. ## Interactive preview Three preview-type behaviours, gated on `od.preview.type`: - `video` (Cloudflare Stream URLs already in the manifest) — inline `<video controls poster=...>` with the playable MP4 as `<source>`. Detail-page row is unchanged from #2926; controls double as the open-full affordance. - `html` (a local `example.html` referenced by `od.preview.entry`, only the `examples/` bucket today) — `<details>` toggle wraps the poster image as the summary; clicking opens a sandboxed `<iframe>` that loads the entry HTML lazily, with an "Open in new tab ↗" pill in the frame's top-right corner so the artifact can be inspected at full screen. - `image` or no entry — static `<img>` (existing behaviour). `copy-example-html.ts` is extended to mirror the local entry and any `./assets/...` siblings to `out/plugins/<manifest-id>/<entry>` so the iframe URL resolves on Cloudflare Pages instead of SPA-falling-back to the homepage. The four examples carrying sibling-asset references (flowai-live-dashboard-template, trading-analysis-dashboard-template, open-design-landing, open-design-landing-deck) all render in-place. ## Share dialog Same `<dialog data-share-dialog>` markup the legacy detail pages use, so the global click handlers in `header-enhancer.astro` (`data-share-open` / `data-share-copy` / `data-copy-link`) wire up the open / copy actions automatically — no extra client bundle. Four platform jumps (X / LinkedIn / Reddit / Facebook) plus a Copy-text / Copy-link pair, with a single English template for now (the new `/plugins/...` routes only generate English pages; localisation can land alongside the i18n catch-all follow-up). ## Bundled in - The `copy-example-html.ts` sibling-assets fix from open PR #2880. Without it the existing `/skills/<slug>/` iframe still 404s on Cloudflare Pages for after-hours-editorial-template and the four others; bundling it here means the same script handles both sources in one pass and sidesteps two PRs touching identical helper code. * fix(plugins): remove dangling preview.entry from example-hyperframes The hyperframes example folder ships a SKILL.md (it's an instruction manual for using the HyperFrames HTML format) but no runnable `example.html`. The manifest still claimed `preview.type: html` / `preview.entry: ./example.html`, which made the marketing site try to iframe a non-existent file and forced the preview pipeline into its `Path 3` fallback card — leaving the catalog row visually inconsistent with the eleven sibling `video-template-hyperframes-*` plugins that have real Cloudflare-Stream poster URLs. Drop the preview block entirely so the manifest stops promising a demo it can't deliver. The landing-page detail row continues to render the typographic fallback card (sourced from title / description / mode), which is now the honest representation: "this is an instruction skill, not a renderable template". * fix(landing-page): address PR #2958 review feedback on plugin preview pipeline Two blocking issues called out in code review: 1) `bundled-plugins.ts` exposed `previewEntryUrl` for every manifest that declared `preview.type: "html"`, even when the entry file wasn't shipped. Several first-party manifests fall in this state (example-design-brief's `./brief-preview.html`, example-x-research, example-pptx-html-fidelity-audit, example-hatch-pet, example-last30days, example-guizang-ppt, example-replit-deck, example-live-artifact, example-html-ppt, example-dcf-valuation). The detail page then rendered a click-to-expand iframe and popout link to a file that copy-example-html.ts had skipped, so the iframe URL SPA-fell-back to the homepage on Cloudflare Pages. `entryRelativeUrl()` now `existsSync()`-checks the resolved local path before returning a URL. When the file's missing the detail page falls through to the static thumbnail branch, exactly like plugins that ship no preview entry at all. 2) `copy-example-html.ts` recognised only `(src|href|poster)="./assets/..."` and then bulk-copied the entry's sibling `assets/` folder, so it missed two real ref shapes: bare-relative (`href="assets/styles.css"`, `src="assets/deck-stage.js"` under example-html-ppt-zhangzara-pin-and-paper) and cross-folder (`src="../open-design-landing/assets/hero.png"` under example-open-design-landing-deck). Replaced the heuristic with a generic walker that: - Parses every relative ref in the entry HTML (`(src|href|poster|srcset|data-src)=` plus `url(...)`), splitting srcset on whitespace/commas so multi-URL attrs are honoured. - Resolves each ref against `dirname(entrypointSrc)` for the source and against `dirname(iframeAbsPath)` for the destination — identical to how a browser resolves the same ref against the iframe URL. Files outside the source root or the iframe root are dropped. - Recurses into copied HTML / CSS / JS / SVG so multi-step chains (entry → assets/template.html → assets/fonts/foo.woff) don't strand intermediate files. - Tracks visited *destinations* rather than sources, so a single source that legitimately needs to land at two different out-paths (same-folder copy at /plugins/example-X/assets/foo.png AND a cross-folder copy at /plugins/open-design-landing/assets/foo.png for sibling decks that use `../open-design-landing/assets/foo.png`) gets both copies. Verified manually: - /plugins/example-html-ppt-zhangzara-pin-and-paper/assets/styles.css and assets/deck-stage.js → 200 (bare-relative) - /plugins/open-design-landing/assets/hero.png and assets/about.png → 200 (cross-folder destination, no manifest-id prefix because iframe URL `..` collapses the prefix) - /plugins/example-design-brief/ renders the static thumbnail only, no click-to-expand iframe (broken entry guard) - /plugins/example-flowai-live-dashboard-template/assets/template.html → 200 (existing same-folder behaviour preserved) Build now reports `copied 266 entry files + 65 referenced files`, where the 65 includes both the same-folder `./assets/...` payloads the previous heuristic captured and the bare-relative + cross-folder shapes it didn't. --------- Co-authored-by: Joey-nexu <joeylee12629@gmail.com> |
||
|---|---|---|
| .. | ||
| article-magazine | ||
| audio-jingle | ||
| blog-post | ||
| card-twitter | ||
| card-xiaohongshu | ||
| clinical-case-report | ||
| codex-interactive-capability-map | ||
| critique | ||
| dashboard | ||
| data-report | ||
| dating-web | ||
| dcf-valuation | ||
| deck-guizang-editorial | ||
| deck-open-slide-canvas | ||
| deck-swiss-international | ||
| design-brief | ||
| digital-eguide | ||
| doc-kami-parchment | ||
| docs-page | ||
| email-marketing | ||
| eng-runbook | ||
| finance-report | ||
| flowai-live-dashboard-template | ||
| frame-data-chart-nyt | ||
| frame-flowchart-sticky | ||
| frame-glitch-title | ||
| frame-light-leak-cinema | ||
| frame-liquid-bg-hero | ||
| frame-logo-outro | ||
| frame-macos-notification | ||
| gamified-app | ||
| github-dashboard | ||
| guizang-ppt | ||
| hatch-pet | ||
| hr-onboarding | ||
| html-ppt | ||
| html-ppt-course-module | ||
| html-ppt-dir-key-nav-minimal | ||
| html-ppt-graphify-dark-graph | ||
| html-ppt-hermes-cyber-terminal | ||
| html-ppt-knowledge-arch-blueprint | ||
| html-ppt-obsidian-claude-gradient | ||
| html-ppt-pitch-deck | ||
| html-ppt-presenter-mode-reveal | ||
| html-ppt-product-launch | ||
| html-ppt-taste-brutalist | ||
| html-ppt-taste-editorial | ||
| html-ppt-tech-sharing | ||
| html-ppt-testing-safety-alert | ||
| html-ppt-weekly-report | ||
| html-ppt-xhs-pastel-card | ||
| html-ppt-xhs-post | ||
| html-ppt-xhs-white-editorial | ||
| html-ppt-zhangzara-8-bit-orbit | ||
| html-ppt-zhangzara-biennale-yellow | ||
| html-ppt-zhangzara-block-frame | ||
| html-ppt-zhangzara-blue-professional | ||
| html-ppt-zhangzara-bold-poster | ||
| html-ppt-zhangzara-broadside | ||
| html-ppt-zhangzara-capsule | ||
| html-ppt-zhangzara-cartesian | ||
| html-ppt-zhangzara-cobalt-grid | ||
| html-ppt-zhangzara-coral | ||
| html-ppt-zhangzara-creative-mode | ||
| html-ppt-zhangzara-daisy-days | ||
| html-ppt-zhangzara-editorial-tri-tone | ||
| html-ppt-zhangzara-grove | ||
| html-ppt-zhangzara-long-table | ||
| html-ppt-zhangzara-mat | ||
| html-ppt-zhangzara-monochrome | ||
| html-ppt-zhangzara-neo-grid-bold | ||
| html-ppt-zhangzara-peoples-platform | ||
| html-ppt-zhangzara-pin-and-paper | ||
| html-ppt-zhangzara-pink-script | ||
| html-ppt-zhangzara-playful | ||
| html-ppt-zhangzara-raw-grid | ||
| html-ppt-zhangzara-retro-windows | ||
| html-ppt-zhangzara-retro-zine | ||
| html-ppt-zhangzara-sakura-chroma | ||
| html-ppt-zhangzara-scatterbrain | ||
| html-ppt-zhangzara-signal | ||
| html-ppt-zhangzara-soft-editorial | ||
| html-ppt-zhangzara-stencil-tablet | ||
| html-ppt-zhangzara-studio | ||
| html-ppt-zhangzara-vellum | ||
| hyperframes | ||
| ib-pitch-book | ||
| image-poster | ||
| invoice | ||
| kami-deck | ||
| kami-landing | ||
| kanban-board | ||
| last30days | ||
| live-artifact | ||
| live-dashboard | ||
| magazine-poster | ||
| meeting-notes | ||
| mobile-app | ||
| mobile-onboarding | ||
| mockup-device-3d | ||
| motion-frames | ||
| od-plugin-contribute-open-design | ||
| od-plugin-publish-github | ||
| open-design-landing | ||
| open-design-landing-deck | ||
| orbit-general | ||
| orbit-github | ||
| orbit-gmail | ||
| orbit-linear | ||
| orbit-notion | ||
| pm-spec | ||
| poster-hero | ||
| ppt-keynote | ||
| pptx-html-fidelity-audit | ||
| pricing-page | ||
| replit-deck | ||
| resume-modern | ||
| saas-landing | ||
| simple-deck | ||
| social-carousel | ||
| social-media-dashboard | ||
| social-media-matrix-tracker-template | ||
| social-reddit-card | ||
| social-spotify-card | ||
| social-x-post-card | ||
| sprite-animation | ||
| team-okrs | ||
| trading-analysis-dashboard-template | ||
| tweaks | ||
| vfx-text-cursor | ||
| video-hyperframes | ||
| video-shortform | ||
| waitlist-page | ||
| web-prototype | ||
| web-prototype-taste-brutalist | ||
| web-prototype-taste-editorial | ||
| web-prototype-taste-soft | ||
| weekly-update | ||
| wireframe-sketch | ||
| x-research | ||