From a68ffc4bb740cb433bbe52c90fb23925d0a33417 Mon Sep 17 00:00:00 2001
From: Charles
Date: Sat, 3 May 2025 22:28:19 -0700
Subject: [PATCH] add: movie input, refactor things, and fix vscode config
---
.vscode/settings.json | 3 +++
Cargo.toml | 1 +
src/app.rs | 37 ++++++++++++++----------------
src/app/movies.rs | 52 +++++++++++++++++++++++++++++++++++++++++++
src/common.rs | 23 +++++++++++++++++++
src/lib.rs | 3 +++
src/main.rs | 8 +++----
src/model.rs | 16 +++++++++++++
8 files changed, 119 insertions(+), 24 deletions(-)
create mode 100644 .vscode/settings.json
create mode 100644 src/app/movies.rs
create mode 100644 src/common.rs
create mode 100644 src/model.rs
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..43307f0
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "rust-analyzer.cargo.features": ["ssr"]
+}
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 9beb937..3326466 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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 = [
diff --git a/src/app.rs b/src/app.rs
index 7e07242..849adc9 100644
--- a/src/app.rs
+++ b/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 {
- use tokio::sync::Mutex;
- use std::sync::Arc;
- let data = use_context::>>().unwrap();
- let mut data = data.lock().await;
+ use crate::common::Context;
+ let data = use_context::().unwrap();
+ let data = data.counter.lock().await;
Ok(*data)
}
#[server]
pub async fn increment_counter() -> Result {
- use tokio::sync::Mutex;
- use std::sync::Arc;
- let data = use_context::>>().unwrap();
- let mut data = data.lock().await;
+ use crate::common::Context;
+ let data = use_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::::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! {
- "Welcome to Leptos!"
+ "Welcome to Wiseau movie picker"
+
}>
{existing_counter}
diff --git a/src/app/movies.rs b/src/app/movies.rs
new file mode 100644
index 0000000..3d81ae5
--- /dev/null
+++ b/src/app/movies.rs
@@ -0,0 +1,52 @@
+use leptos::prelude::*;
+
+use crate::model::Movie;
+
+#[server]
+pub async fn load_movies() -> Result, ServerFnError> {
+ use crate::common::Context;
+ let data = use_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::().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::::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! {
+
+ {movies.into_iter().map(move |movie| {
+ view! {
+ - {movie.name}
+ }
+ }).collect::>()}
+
+ }
+ })
+ };
+ view! {
+ "Movies"
+
+
+
+
+ "Loading..." }>
+ {movies}
+
+ }
+}
diff --git a/src/common.rs b/src/common.rs
new file mode 100644
index 0000000..a3a6de7
--- /dev/null
+++ b/src/common.rs
@@ -0,0 +1,23 @@
+use std::sync::Arc;
+use tokio::sync::Mutex;
+
+use crate::model::Movie;
+
+#[derive(Clone)]
+pub struct Context {
+ pub counter: Arc>,
+ pub movies: Arc>>,
+}
+
+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)),
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index 151489d..f581f38 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,7 @@
pub mod app;
+pub mod model;
+#[cfg(feature = "ssr")]
+pub mod common;
#[cfg(feature = "hydrate")]
#[wasm_bindgen::prelude::wasm_bindgen]
diff --git a/src/main.rs b/src/main.rs
index f4f0cc0..9f4dae2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -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> = 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())
diff --git a/src/model.rs b/src/model.rs
new file mode 100644
index 0000000..a912bd9
--- /dev/null
+++ b/src/model.rs
@@ -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(),
+ }
+ }
+}
\ No newline at end of file