feat(web): add solitaire_web Bevy WASM build targeting play.html canvas
Build and Deploy / build-and-push (push) Failing after 58s
Build and Deploy / build-and-push (push) Failing after 58s
Adds a new `solitaire_web` crate that compiles the full `solitaire_engine` to `wasm32-unknown-unknown` and renders to a `<canvas id="bevy-canvas">` element in `play.html` — the same ECS code path as desktop and Android. Changes to enable the WASM target: - .cargo/config.toml: add wasm32-unknown-unknown rustflags for getrandom - Workspace Cargo.toml: add solitaire_web member - solitaire_data/Cargo.toml: gate tokio/reqwest/dirs/keyring to non-wasm - solitaire_data/src: add wasm32 branch to data_dir() (returns None); cfg-gate sync_client network types, auth_tokens, matomo_client - solitaire_engine/Cargo.toml: gate tokio/reqwest/kira/arboard/dirs/zip to non-wasm (mio/cpal/arboard don't compile for wasm32-unknown-unknown) - solitaire_engine/src/lib.rs: cfg-gate module declarations and re-exports for analytics, audio, sync, sync_setup, avatar, leaderboard plugins - solitaire_engine/src/core_game_plugin.rs: cfg-gate plugin registrations that require TokioRuntime (audio, sync, analytics, leaderboard, avatar) - solitaire_engine/src/resources.rs: cfg-gate TokioRuntimeResource - solitaire_engine/src/game_plugin.rs: cfg-gate std::fs::remove_file (x10) - solitaire_engine/src/theme/mod.rs: cfg-gate importer module (uses dirs+zip) - solitaire_engine/src/settings_plugin.rs: cfg-gate theme ZIP import UI - solitaire_engine/src/assets/sources.rs: cfg-gate FileAssetReader/user_theme_dir - solitaire_engine/src/auto_complete_plugin.rs: cfg-gate audio system - solitaire_engine/src/daily_challenge_plugin.rs: cfg-gate server fetch - solitaire_engine/src/hud_plugin.rs: cfg-gate AvatarResource import - solitaire_engine/src/profile_plugin.rs: cfg-gate AvatarResource import - solitaire_server/web/play.html: minimal HTML canvas shell - solitaire_web/: new crate (Cargo.toml + src/lib.rs) - build_wasm.sh: add Bevy WASM build step (cargo + wasm-bindgen + wasm-opt) All tests pass; clippy --workspace -- -D warnings clean; native build (solitaire_engine, solitaire_app) unaffected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -24,6 +24,7 @@ use solitaire_data::{
|
||||
|
||||
use solitaire_data::settings::SyncBackend;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::assets::user_theme_dir;
|
||||
use crate::events::{
|
||||
DeleteAccountRequestEvent, InfoToastEvent, ManualSyncRequestEvent, SyncConfigureRequestEvent,
|
||||
@@ -32,9 +33,9 @@ use crate::events::{
|
||||
use crate::font_plugin::FontResource;
|
||||
use crate::progress_plugin::ProgressResource;
|
||||
use crate::resources::{SettingsScrollPos, SyncStatus, SyncStatusResource};
|
||||
use crate::theme::{
|
||||
ImportError, ThemeThumbnailCache, ThemeThumbnailPair, import_theme, refresh_registry,
|
||||
};
|
||||
use crate::theme::{ThemeThumbnailCache, ThemeThumbnailPair, refresh_registry};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use crate::theme::{ImportError, import_theme};
|
||||
use crate::ui_focus::{FocusGroup, FocusRow, Focusable, FocusedButton};
|
||||
use crate::ui_modal::{
|
||||
ButtonVariant, ModalButton, ModalScrim, spawn_modal, spawn_modal_actions, spawn_modal_button,
|
||||
@@ -404,6 +405,7 @@ impl Plugin for SettingsPlugin {
|
||||
sync_settings_panel_visibility,
|
||||
handle_settings_buttons,
|
||||
handle_sync_buttons,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
handle_scan_themes,
|
||||
update_sync_status_text,
|
||||
update_card_back_text,
|
||||
@@ -1857,6 +1859,7 @@ fn spawn_settings_panel(
|
||||
font_res,
|
||||
);
|
||||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
import_themes_row(body, font_res);
|
||||
|
||||
// --- Privacy (only shown when a Matomo URL is configured) ---
|
||||
@@ -2641,6 +2644,7 @@ fn value_text_font(font_res: Option<&FontResource>) -> TextFont {
|
||||
/// [`InfoToastEvent`] is fired per imported theme. `IdCollision` errors (theme
|
||||
/// already installed) are silently skipped; all other errors produce a warning
|
||||
/// toast. A final toast tells the player to reopen Settings to see new themes.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn handle_scan_themes(
|
||||
interaction_query: Query<(&Interaction, &SettingsButton), Changed<Interaction>>,
|
||||
mut toast: MessageWriter<InfoToastEvent>,
|
||||
@@ -2759,6 +2763,7 @@ fn pill_button(
|
||||
/// then presses the button. [`handle_scan_themes`] picks them up, validates,
|
||||
/// and installs them. Reopen Settings to see newly imported themes in the
|
||||
/// card-theme picker.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn import_themes_row(parent: &mut ChildSpawnerCommands, font_res: Option<&FontResource>) {
|
||||
let caption_font = TextFont {
|
||||
font: font_res.map(|f| f.0.clone()).unwrap_or_default(),
|
||||
|
||||
Reference in New Issue
Block a user