feat(canvas): waveflow:canvas/v1 world for per-track Canvas plugins (#473) - #478
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughCette PR ajoute le monde ChangesIntégration Canvas par plugin
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Possibly related PRs
Sequence Diagram(s)sequenceDiagram
participant Interface
participant useTrackCanvas
participant Tauri
participant CanvasRuntime
participant CanvasPlugin
participant Video
Interface->>useTrackCanvas: transmet currentTrack
useTrackCanvas->>Tauri: demande un Canvas plugin si aucun Canvas manuel
Tauri->>CanvasRuntime: transmet les métadonnées du morceau
CanvasRuntime->>CanvasPlugin: appelle track-canvas
CanvasPlugin-->>CanvasRuntime: retourne canvas ou erreur
CanvasRuntime-->>Tauri: retourne le premier résultat valide
Tauri-->>useTrackCanvas: retourne PluginCanvas ou null
useTrackCanvas-->>Video: fournit une source locale ou distante
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src-tauri/crates/app/src/commands/canvas.rs`:
- Around line 161-193: Inspect the waveflow:host/http.send implementation in
host_impl.rs and add an independent request timeout if none exists, using the
existing HTTP client/request path and timeout conventions. Ensure a stalled host
HTTP call returns within the configured limit without relying on the outer
CANVAS_PLUGIN_TIMEOUT or Wasmtime interruption, while preserving normal
successful responses and error propagation.
In `@src-tauri/crates/core/src/plugin/runtime.rs`:
- Around line 733-748: Factor the duplicated plugin-instantiation logic shared
by instantiate_source and instantiate_canvas into a macro_rules! helper that
accepts the function name and generated Plugin type. Use the macro to generate
both functions while preserving plugin loading, linker/store creation,
instantiation, and SourceError conversion behavior.
In `@src-tauri/plugins/canvas-fixture/Cargo.toml`:
- Around line 26-27: Alignez la dépendance wit-bindgen-rt de la fixture
canvas-fixture sur la version 0.41 utilisée par les bindings générés dans
bindings.rs, en conservant la fonctionnalité bitflags. Vérifiez les autres
fixtures et plugins pour appliquer leur convention d’appariement, sans régénérer
les bindings sauf si le projet standardise plutôt la version 0.44.
In `@src-tauri/plugins/canvas-fixture/src/lib.rs`:
- Around line 21-38: Étendez l’implémentation de Fixture::track_canvas avec des
branches déterministes basées sur title pour retourner des URL rejetables,
notamment file:///etc/passwd pour « scheme », une adresse IP privée pour «
private » et une URL .m3u8 pour « hls ». Conservez les comportements existants
pour les titres vides, « boom » et les autres titres afin que le test
d’intégration puisse vérifier que l’hôte refuse ces valeurs et retourne None.
In `@src-tauri/plugins/canvas-fixture/wit/world.wit`:
- Around line 16-46: Les définitions WIT du SDK et de la fixture doivent être
liées et vérifiées pour éviter toute divergence. Dans
src-tauri/plugins/canvas-fixture/wit/world.wit lignes 16-46, remplacez la copie
locale de package waveflow:canvas@1.0.0 en configurant
[package.metadata.component.target] dans
src-tauri/plugins/canvas-fixture/Cargo.toml pour pointer vers le WIT Canvas du
SDK. Dans src-tauri/crates/plugin-sdk/wit/canvas/deps/host/host.wit lignes 1-49,
ajoutez une assertion CI comparant les empreintes de toutes les copies de
package waveflow:host@1.0.0.
In `@src/components/player/CanvasStage.tsx`:
- Around line 68-71: Centralize remote Canvas URL detection in a shared
isRemoteCanvasUrl(path: string) helper and replace the duplicated regex in
src/components/player/CanvasStage.tsx lines 68-71, using it to choose between
the raw URL and convertFileSrc(path). Update
src/components/player/ImmersiveView.tsx lines 99-102 to use the same helper when
computing hasManualCanvas.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8ced7173-0686-4b68-9518-cebb9ad370da
⛔ Files ignored due to path filters (2)
src-tauri/crates/core/tests/fixtures/canvas-fixture/plugin.wasmis excluded by!**/*.wasmsrc-tauri/plugins/canvas-fixture/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (24)
CLAUDE.mddocs/features/plugins.mddocs/features/ui.mdsrc-tauri/crates/app/src/commands/canvas.rssrc-tauri/crates/app/src/lib.rssrc-tauri/crates/core/src/plugin/bindings.rssrc-tauri/crates/core/src/plugin/runtime.rssrc-tauri/crates/core/tests/fixtures/canvas-fixture/manifest.tomlsrc-tauri/crates/core/tests/plugin_canvas.rssrc-tauri/crates/plugin-sdk/src/lib.rssrc-tauri/crates/plugin-sdk/wit/canvas/deps/host/host.witsrc-tauri/crates/plugin-sdk/wit/canvas/plugin.witsrc-tauri/plugins/canvas-fixture/.gitignoresrc-tauri/plugins/canvas-fixture/Cargo.tomlsrc-tauri/plugins/canvas-fixture/src/bindings.rssrc-tauri/plugins/canvas-fixture/src/lib.rssrc-tauri/plugins/canvas-fixture/wit/deps/waveflow-host/host.witsrc-tauri/plugins/canvas-fixture/wit/world.witsrc/components/layout/NowPlayingPanel.tsxsrc/components/player/CanvasStage.tsxsrc/components/player/ImmersiveNowPlaying.tsxsrc/components/player/ImmersiveView.tsxsrc/hooks/useTrackCanvas.tssrc/lib/tauri/canvas.ts
|
@coderabbitai verified each finding against current code. Applied 2, skipped 4 with reasons — pushed in 0a17f91. Applied
Skipped (still-valid check)
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '== Current commit and changed files =='
git rev-parse --short HEAD
git show --stat --oneline 0a17f91d -- 2>/dev/null || true
echo '== Runtime symbols and timeout configuration =='
ast-grep outline src-tauri/crates/core/src/plugin/runtime.rs --items all --view expanded | sed -n '1,240p'
rg -n -C 4 'define_instantiate|instantiate_(source|metadata|canvas|ui)|connect_timeout|\.timeout\(' \
src-tauri/crates/core/src/plugin/runtime.rs
echo '== Canvas URL helper and call sites =='
ast-grep outline src/lib/tauri/canvas.ts --items all --view expanded
rg -n -C 4 'isRemoteCanvasUrl|fetchTrackCanvas' \
src/lib/tauri/canvas.ts \
src/components/player/CanvasStage.tsx \
src/components/player/ImmersiveView.tsx
echo '== App-side Canvas SSRF validation and core helper =='
ast-grep outline src-tauri/crates/app/src/commands/canvas.rs --items all --view expanded
rg -n -C 5 'fetch_track_canvas|canvas_track_canvas|is_safe_motion_url|timeout' \
src-tauri/crates/app/src/commands/canvas.rs \
src-tauri/crates/core/src/plugin/runtime.rs \
src-tauri/crates/core/src/artwork/motion_cache.rs
echo '== Fixture dependency and local WIT conventions =='
fd -a -t f 'Cargo.toml|world.wit' src-tauri/plugins | sort | while read -r f; do
printf '\n--- %s ---\n' "$f"
rg -n -C 2 'wit-bindgen-rt|Local copy|local copy|WIT|world' "$f" || true
done
echo '== Canvas integration test =='
ast-grep outline src-tauri/crates/core/tests/plugin_canvas.rs --items all --view expanded
sed -n '1,220p' src-tauri/crates/core/tests/plugin_canvas.rsLength of output: 45973
Les deux corrections sont présentes :
Les quatre éléments non appliqués ne nécessitent pas de modification :
Je retire donc les quatre constats non applicables. Je n’ai pas exécuté les tests dans cette vérification. ✏️ Learnings added
You are interacting with an AI system. |
Phase A of #473 (Spotify Canvas) — the generic core foundation. Adds a new versioned plugin world,
waveflow:canvas/v1, that lets a plugin resolve a per-track Canvas (a short looping video the host renders behind the now-playing view). The grey-area Spotify sourcing is NOT here — it will live in a separate, unsigned plugin repo (Phase B). This PR only lands the reusable, non-grey world + wiring, isolated exactly like theuiworld was in #443.The world
provider.track-canvas(artist, title, album?, duration-ms?) -> result<option<canvas>, string>,canvas = { url, entity-id? }. Host imports are the standard four (http/log/storage/config) — nolibraryread.urlmust be a directly-playable mp4 (the webview has no HLS.js).Distinct from a
metadataplugin's per-albummotion-cover-url: Canvas is per-track and sits above motion artwork in the backdrop precedence — manual Canvas > plugin Canvas > motion > slideshow > static cover.Backend
worlds::CANVAS_V1+ WIT (wit/canvas/{plugin,deps/host/host}.wit).manifest.rsalready validates viaworlds::is_known, so it accepts the label automatically.bindings::canvasbindgen (reusessource's host types viawith:, no new host import),runtime::canvas_track_canvas+ProviderCanvasDTO.commands::canvas::fetch_track_canvasfans out to enabled canvas plugins (per-plugin lock + blocking task + 20 s timeout), returns the first hit that passes the sharedis_safe_motion_urlSSRF guard, and is fail-soft — a plugin error, panic, or timeout is logged + skipped, never surfaced, so a misbehaving provider can't break playback. Registered inlib.rs.plugins/canvas-fixture/+ committed wasm, exercised bytests/plugin_canvas.rs(hit / miss / provider-error — 3 tests green).Frontend
fetchTrackCanvaswrapper +PluginCanvastype.useTrackCanvasnow takes the track (wastrackId) and resolves manual local Canvas first, then the plugin fallback; its careful per-id caching / generation / profile-switch guards are unchanged.CanvasStagetells a local path from a remote URL by thehttp(s)prefix (same split asMotionCoverOverlay).ImmersiveNowPlaying/ImmersiveView/NowPlayingPanel) passcurrentTrack.Nothing changes at runtime until a
canvas-world plugin is installed (none ships yet), so this is inert for current users.Docs
CLAUDE.md(canvas-world clause + updated Track Canvas catalogue line),docs/features/plugins.md(new "The Canvas world" section),docs/features/ui.md(Track Canvas plugin-sourcing paragraph).Deferred (Phase B/C)
The Spotify Canvas plugin itself (separate unsigned repo — TOTP + protobuf canvaz, sp_dc cookie once + ban warning, fail-soft) and the registry
worldenum gainingwaveflow:canvas/v1(needed only to list the plugin).Validation
cargo clippy -p waveflow-core -p waveflow --features waveflow-core/plugins --all-targets— cleancargo test -p waveflow-core --features plugins(plugin_canvas + plugin_ui + plugin_web_radio) — all green, no regressionsbun run typecheck/bun run lint— cleanSummary by CodeRabbit
Nouvelles fonctionnalités
Documentation