feat(v5.5.0): Embeds & Media riche - universal embeds, bookmark cards, lightbox, inline previews, cover & icon
FlowDeck CI / lint (push) Successful in 44s
FlowDeck CI / test (push) Successful in 4m10s
FlowDeck CI / docker (push) Successful in 37s

- embeds.py: provider detection/rewrite (YouTube, Vimeo, Figma, Maps, Docs,
  Loom, CodePen, Miro, Spotify, SoundCloud, Twitch, X/Twitter, Pinterest,
  Office) + resolve_embed/inline_kind/provider; POST /board/api/embed/resolve
- editor resolves pasted URLs and caches embed_src (persisted); renderer,
  public pages and MD/HTML/PDF exports prefer embed_src
- og_fetcher.py: robust meta parsing (any attribute order), favicon,
  injectable transport, network-safe fallback
- image lightbox with keyboard nav (arrows/Esc) in editor and public pages
- inline PDF/video/audio previews
- cover (URL or upload) & page icon endpoints
- fix broken editor API paths (/api/pages -> /board/api/pages) for cover,
  icon, versions, backlinks, import, move and OG metadata
- 47 tests in tests/test_v55.py; full suite 444 green; ruff clean
- version 5.11.2
This commit is contained in:
2026-09-12 09:40:50 -04:00
parent c435e277f2
commit bdc15c7328
13 changed files with 961 additions and 167 deletions
+20
View File
@@ -1384,6 +1384,26 @@ async def og_metadata(request: Request):
return {"ok": True, **data}
@router.post("/api/embed/resolve")
async def resolve_embed(request: Request):
"""v5.5.0: rewrite a pasted URL to its provider embed src.
Powers the universal ``/embed`` block (YouTube, Vimeo, Figma, Maps,
Docs, Loom, CodePen, Miro, Spotify, SoundCloud, Twitch, X/Twitter…).
"""
try:
body = await request.json()
except Exception:
raise HTTPException(400, "Invalid JSON body") from None
url = (body.get("url") or "").strip()
if not url:
raise HTTPException(400, "url required")
from app.config import settings
from app.services.embeds import resolve_embed as _resolve
data = _resolve(url, parent=settings.app_base_url)
return {"ok": True, "url": url, **data}
@router.put("/api/pages/{page_id}/move")
async def move_page(request: Request, page_id: int):
"""Move a page to another workspace or reorder within tree.
+1 -1
View File
@@ -2230,7 +2230,7 @@ def _render_blocks_public(blocks: list) -> str:
)
elif url:
from app.services.embeds import embed_src
src = embed_src(url) or url
src = b.get("embed_src") or embed_src(url) or url
height = b.get("height") or 520
try:
height = int(height)