generated from just-the-docs/just-the-docs-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3674cab
commit ffb4262
Showing
3 changed files
with
172 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,46 @@ | ||
use leptos::*; | ||
use leptos::prelude::*; | ||
|
||
use crate::components::utils::{delete_board,generate_thumbnail,load_saved_boards}; | ||
use crate::components::board::SavedBoard; | ||
|
||
// In saved_boards.rs, modify the component: | ||
#[component] | ||
pub fn SavedBoards() -> impl IntoView { | ||
let boards = RwSignal::new(load_saved_boards().unwrap_or_default()); | ||
|
||
let delete = move |index: usize| { | ||
let _ = delete_board(index); | ||
boards.set(load_saved_boards().unwrap_or_default()); | ||
}; | ||
|
||
view! { | ||
<div class="grid grid-cols-4 gap-4 mt-4"> | ||
// Thumbnails will go here | ||
<For | ||
each=move || boards.get() | ||
key=|board| generate_thumbnail(&board.board) | ||
children=move |board: SavedBoard| { | ||
view! { | ||
<div class="relative"> | ||
<img | ||
src=board.thumbnail.clone() | ||
alt="Saved board" | ||
class="w-24 h-24 rounded border border-slate-700" | ||
/> | ||
<button | ||
class="absolute -top-2 -right-2 bg-red-600 hover:bg-red-700 rounded-full w-6 h-6 flex items-center justify-center" | ||
on:click=move |_| { | ||
if let Some(index) = boards.get().iter().position(|b| b.thumbnail == board.thumbnail) { | ||
delete(index) | ||
} | ||
} | ||
> | ||
"×" | ||
</button> | ||
</div> | ||
} | ||
} | ||
/> | ||
</div> | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,79 @@ | ||
use super::board::{Board, CellContent}; | ||
use web_sys::window; | ||
|
||
use std::fmt::Write; | ||
use super::board::{Board, CellContent, SavedBoard}; | ||
|
||
pub fn generate_thumbnail(board: &Board) -> String { | ||
let svg = format!( | ||
r#"<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"> | ||
let mut svg = String::from(r#"<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"> | ||
<rect width="100" height="100" fill="rgb(30, 41, 59)"/> | ||
<g transform="translate(5,5)">{}</g> | ||
</svg>"#, | ||
board.grid.iter().enumerate().map(|(i, row)| { | ||
row.iter().enumerate().map(|(j, cell)| { | ||
let x = j as f32 * 45.0; | ||
let y = i as f32 * 45.0; | ||
match cell { | ||
CellContent::Empty => format!( | ||
r#"<rect x="{}" y="{}" width="40" height="40" fill="rgb(51, 65, 85)"/>"#, | ||
x, y | ||
), | ||
CellContent::Player => format!( | ||
r#"<rect x="{}" y="{}" width="40" height="40" fill="rgb(51, 65, 85)"/> | ||
<circle cx="{:.0}" cy="{:.0}" r="15" fill="rgb(37, 99, 235)"/>"#, | ||
x, y, x + 20.0, y + 20.0 | ||
), | ||
CellContent::Trap => format!( | ||
r#"<rect x="{}" y="{}" width="40" height="40" fill="rgb(51, 65, 85)"/> | ||
<path d="M{} {} l30 30 m0 -30 l-30 30" stroke="rgb(220, 38, 38)" stroke-width="4"/>"#, | ||
x, y, x + 5.0, y + 5.0 | ||
), | ||
} | ||
}).collect::<String>() | ||
}).collect::<String>() | ||
); | ||
|
||
format!( | ||
r#"data:image/svg+xml,{}"#, | ||
urlencoding::encode(&svg) | ||
) | ||
<g transform="translate(5,5)">"#); | ||
|
||
// Draw grid and traps | ||
for (i, row) in board.grid.iter().enumerate() { | ||
for (j, cell) in row.iter().enumerate() { | ||
let x = j as f32 * 45.0; | ||
let y = i as f32 * 45.0; | ||
let _ = match cell { | ||
CellContent::Empty | CellContent::Player => write!( | ||
svg, | ||
r#"<rect x="{}" y="{}" width="40" height="40" fill="rgb(51, 65, 85)"/>"#, | ||
x, y | ||
), | ||
CellContent::Trap => write!( | ||
svg, | ||
r#"<rect x="{}" y="{}" width="40" height="40" fill="rgb(51, 65, 85)"/> | ||
<path d="M{} {} l30 30 m0 -30 l-30 30" stroke="rgb(220, 38, 38)" stroke-width="4"/>"#, | ||
x, y, x + 5.0, y + 5.0 | ||
), | ||
}; | ||
} | ||
} | ||
|
||
// Draw numbered circles for moves | ||
for (idx, &(i, j)) in board.moves.iter().enumerate() { | ||
let x = j as f32 * 45.0; | ||
let y = i as f32 * 45.0; | ||
let _ = write!( | ||
svg, | ||
r#"<circle cx="{:.0}" cy="{:.0}" r="15" fill="rgb(37, 99, 235)"/> | ||
<text x="{:.0}" y="{:.0}" font-size="16" fill="white" text-anchor="middle" dy=".3em">{}</text>"#, | ||
x + 20.0, y + 20.0, x + 20.0, y + 20.0, idx + 1 | ||
); | ||
} | ||
|
||
svg.push_str("</g></svg>"); | ||
format!(r#"data:image/svg+xml,{}"#, urlencoding::encode(&svg)) | ||
} | ||
|
||
pub fn save_board(board: Board) -> Result<(), serde_json::Error> { | ||
let storage = window().unwrap().local_storage().unwrap().unwrap(); | ||
let thumbnail = generate_thumbnail(&board); | ||
let saved_board = SavedBoard { board, thumbnail }; | ||
|
||
// Load existing boards first | ||
let mut saved_boards = load_saved_boards().unwrap_or_default(); | ||
web_sys::console::log_1(&format!("Current boards: {}", saved_boards.len()).into()); | ||
|
||
saved_boards.push(saved_board); | ||
web_sys::console::log_1(&format!("After adding: {}", saved_boards.len()).into()); | ||
|
||
let json = serde_json::to_string(&saved_boards)?; | ||
storage.set_item("saved_boards", &json).unwrap(); | ||
Ok(()) | ||
} | ||
|
||
pub fn load_saved_boards() -> Option<Vec<SavedBoard>> { | ||
let storage = window().unwrap().local_storage().unwrap().unwrap(); | ||
let data = storage.get_item("saved_boards").ok()??; | ||
serde_json::from_str(&data).ok() | ||
} | ||
|
||
// In utils.rs, add this function: | ||
pub fn delete_board(index: usize) -> Result<(), serde_json::Error> { | ||
let storage = window().unwrap().local_storage().unwrap().unwrap(); | ||
let mut saved_boards = load_saved_boards().unwrap_or_default(); | ||
saved_boards.remove(index); | ||
let json = serde_json::to_string(&saved_boards)?; | ||
storage.set_item("saved_boards", &json).unwrap(); | ||
Ok(()) | ||
} |