add: movie input, refactor things, and fix vscode config
This commit is contained in:
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"rust-analyzer.cargo.features": ["ssr"]
|
||||
}
|
||||
@@ -15,6 +15,7 @@ leptos_axum = { version = "0.7.0", optional = true }
|
||||
leptos_meta = { version = "0.7.0" }
|
||||
tokio = { version = "1", features = ["rt-multi-thread"], optional = true }
|
||||
wasm-bindgen = { version = "=0.2.100", optional = true }
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
|
||||
[features]
|
||||
hydrate = [
|
||||
|
||||
37
src/app.rs
37
src/app.rs
@@ -1,9 +1,12 @@
|
||||
use leptos::{prelude::*, task::spawn_local};
|
||||
use leptos::prelude::*;
|
||||
use leptos_meta::{provide_meta_context, MetaTags, Stylesheet, Title};
|
||||
use leptos_router::{
|
||||
components::{Route, Router, Routes},
|
||||
StaticSegment,
|
||||
};
|
||||
use movies::Movies;
|
||||
|
||||
mod movies;
|
||||
|
||||
pub fn shell(options: LeptosOptions) -> impl IntoView {
|
||||
view! {
|
||||
@@ -25,21 +28,18 @@ pub fn shell(options: LeptosOptions) -> impl IntoView {
|
||||
|
||||
#[server]
|
||||
pub async fn load_counter() -> Result<usize, ServerFnError> {
|
||||
use tokio::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
let data = use_context::<Arc<Mutex<usize>>>().unwrap();
|
||||
let mut data = data.lock().await;
|
||||
use crate::common::Context;
|
||||
let data = use_context::<Context>().unwrap();
|
||||
let data = data.counter.lock().await;
|
||||
Ok(*data)
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn increment_counter() -> Result<usize, ServerFnError> {
|
||||
use tokio::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
let data = use_context::<Arc<Mutex<usize>>>().unwrap();
|
||||
let mut data = data.lock().await;
|
||||
use crate::common::Context;
|
||||
let data = use_context::<Context>().unwrap();
|
||||
let mut data = data.counter.lock().await;
|
||||
*data += 1;
|
||||
println!("Counter {}", *data);
|
||||
Ok(*data)
|
||||
}
|
||||
|
||||
@@ -72,27 +72,24 @@ pub fn App() -> impl IntoView {
|
||||
fn HomePage() -> impl IntoView {
|
||||
let increment_counter = ServerAction::<IncrementCounter>::new();
|
||||
let counts = Resource::new(
|
||||
move || {
|
||||
(
|
||||
increment_counter.version().get(),
|
||||
)
|
||||
},
|
||||
move |_| load_counter()
|
||||
move || (increment_counter.version().get(),),
|
||||
move |_| load_counter(),
|
||||
);
|
||||
|
||||
let existing_counter = move || {
|
||||
Suspend::new(async move {
|
||||
let count = counts.await;
|
||||
view! { {count} }
|
||||
view! { {count} }
|
||||
})
|
||||
};
|
||||
|
||||
let onclick = move |ev| {
|
||||
increment_counter.dispatch(IncrementCounter{});
|
||||
let onclick = move |_| {
|
||||
increment_counter.dispatch(IncrementCounter {});
|
||||
};
|
||||
|
||||
view! {
|
||||
<h1>"Welcome to Leptos!"</h1>
|
||||
<h1>"Welcome to Wiseau movie picker"</h1>
|
||||
<Movies></Movies>
|
||||
<button on:click=onclick>"Click Me: "
|
||||
<Transition fallback=move || view! { <p>"Loading..."</p> }>
|
||||
{existing_counter}
|
||||
|
||||
52
src/app/movies.rs
Normal file
52
src/app/movies.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
use leptos::prelude::*;
|
||||
|
||||
use crate::model::Movie;
|
||||
|
||||
#[server]
|
||||
pub async fn load_movies() -> Result<Vec<Movie>, ServerFnError> {
|
||||
use crate::common::Context;
|
||||
let data = use_context::<Context>().unwrap();
|
||||
let movies = data.movies.lock().await.clone();
|
||||
Ok(movies)
|
||||
}
|
||||
|
||||
#[server]
|
||||
pub async fn add_movie(name: String) -> Result<(), ServerFnError> {
|
||||
use crate::common::Context;
|
||||
let data = use_context::<Context>().unwrap();
|
||||
let mut data = data.movies.lock().await;
|
||||
data.push(Movie::new(&name));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Renders the home page of your application.
|
||||
#[component]
|
||||
pub fn Movies() -> impl IntoView {
|
||||
let add_movie = ServerMultiAction::<AddMovie>::new();
|
||||
let movies_resource =
|
||||
Resource::new(move || (add_movie.version().get(),), move |_| load_movies());
|
||||
let movies = move || {
|
||||
Suspend::new(async move {
|
||||
let movies = movies_resource.await.unwrap();
|
||||
view! {
|
||||
<ul>
|
||||
{movies.into_iter().map(move |movie| {
|
||||
view! {
|
||||
<li>{movie.name}</li>
|
||||
}
|
||||
}).collect::<Vec<_>>()}
|
||||
</ul>
|
||||
}
|
||||
})
|
||||
};
|
||||
view! {
|
||||
<h2>"Movies"</h2>
|
||||
<MultiActionForm action=add_movie>
|
||||
<label>"Add a movie" <input type="text" name="name"/></label>
|
||||
<input type="submit" value="Add"/>
|
||||
</MultiActionForm>
|
||||
<Transition fallback=move || view! { <p>"Loading..."</p> }>
|
||||
{movies}
|
||||
</Transition>
|
||||
}
|
||||
}
|
||||
23
src/common.rs
Normal file
23
src/common.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::model::Movie;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Context {
|
||||
pub counter: Arc<Mutex<usize>>,
|
||||
pub movies: Arc<Mutex<Vec<Movie>>>,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn new() -> Self {
|
||||
let movies = vec![
|
||||
Movie::new("Hackers"),
|
||||
Movie::new("Princess Bridge"),
|
||||
];
|
||||
Self {
|
||||
counter: Arc::new(Mutex::new(0)),
|
||||
movies: Arc::new(Mutex::new(movies)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
pub mod app;
|
||||
pub mod model;
|
||||
#[cfg(feature = "ssr")]
|
||||
pub mod common;
|
||||
|
||||
#[cfg(feature = "hydrate")]
|
||||
#[wasm_bindgen::prelude::wasm_bindgen]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use wiseau::common;
|
||||
|
||||
//#[cfg(feature = "ssr")]
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::Mutex;
|
||||
use axum::Router;
|
||||
use leptos::logging::log;
|
||||
use leptos::prelude::*;
|
||||
@@ -15,13 +15,13 @@ async fn main() {
|
||||
// Generate the list of routes in your Leptos App
|
||||
let routes = generate_route_list(App);
|
||||
|
||||
let counter: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
|
||||
let context = common::Context::new();
|
||||
|
||||
let app = Router::new()
|
||||
.leptos_routes_with_context(
|
||||
&leptos_options,
|
||||
routes,
|
||||
move || provide_context(counter.clone()),
|
||||
move || provide_context(context.clone()),
|
||||
{
|
||||
let leptos_options = leptos_options.clone();
|
||||
move || shell(leptos_options.clone())
|
||||
|
||||
16
src/model.rs
Normal file
16
src/model.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct Movie {
|
||||
pub name: String,
|
||||
pub imdb_url: String,
|
||||
}
|
||||
|
||||
impl Movie {
|
||||
pub fn new(name: &str) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
imdb_url: String::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user