This works I guess

This commit is contained in:
Daan Vanoverloop 2022-09-10 20:03:15 +02:00
parent 30d96df00a
commit 004885e6e7
Signed by: Danacus
GPG Key ID: F2272B50E129FC5C
3 changed files with 108 additions and 27 deletions

6
web/dist/index.html vendored
View File

@ -6,7 +6,7 @@
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" rel="stylesheet"> <link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.9.96/css/materialdesignicons.min.css" rel="stylesheet">
<title>LAN Party</title> <title>LAN Party</title>
<link rel="preload" href="/index-a2c5ffc914f34da_bg.wasm" as="fetch" type="application/wasm" crossorigin=""> <link rel="preload" href="/index-ca59edff96de869_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
<link rel="modulepreload" href="/index-a2c5ffc914f34da.js"></head> <link rel="modulepreload" href="/index-ca59edff96de869.js"></head>
<body> <body>
<script type="module">import init from '/index-a2c5ffc914f34da.js';init('/index-a2c5ffc914f34da_bg.wasm');</script></body></html> <script type="module">import init from '/index-ca59edff96de869.js';init('/index-ca59edff96de869_bg.wasm');</script></body></html>

View File

@ -1,4 +1,9 @@
use std::{marker::PhantomData, str::FromStr}; use std::{
collections::{HashMap, HashSet},
hash::Hash,
marker::PhantomData,
str::FromStr,
};
use crate::components::Block; use crate::components::Block;
use lan_party_core::event::{ use lan_party_core::event::{
@ -7,7 +12,9 @@ use lan_party_core::event::{
}; };
use log::debug; use log::debug;
use paste::paste; use paste::paste;
use sycamore::prelude::*; use sycamore::{builder::prelude::*, prelude::*};
use super::{BlockProps, Button, ButtonProps};
macro_rules! editable { macro_rules! editable {
($type:ty => $editor:ty) => { ($type:ty => $editor:ty) => {
@ -174,8 +181,8 @@ edit_enum!(EventTypeSpec => selected =>
); );
edit_struct!(TestSpec => ("Number of players", num_players)); edit_struct!(TestSpec => ("Number of players", num_players));
edit_struct!(TeamGameSpec => ("Win rewards", win_rewards)); edit_struct!(TeamGameSpec => ("Teams", teams), ("Win rewards", win_rewards), ("Lose rewards", lose_rewards));
edit_struct!(FreeForAllGameSpec => ); edit_struct!(FreeForAllGameSpec => ("Participants", participants), ("Win rewards", win_rewards), ("Lose rewards", lose_rewards));
pub struct StringEdit; pub struct StringEdit;
@ -251,7 +258,7 @@ pub struct VecEdit;
impl<'a, G, T, I> Editor<'a, G, I> for VecEdit impl<'a, G, T, I> Editor<'a, G, I> for VecEdit
where where
G: Html, G: Html,
T: Editable<'a, G> + Clone + PartialEq + 'a, T: Editable<'a, G> + Clone + PartialEq + Default + 'a,
I: IntoIterator<Item = T> + FromIterator<T> + Clone, I: IntoIterator<Item = T> + FromIterator<T> + Clone,
{ {
fn edit(cx: Scope<'a>, props: EditProps<'a, I>) -> View<G> { fn edit(cx: Scope<'a>, props: EditProps<'a, I>) -> View<G> {
@ -266,9 +273,6 @@ where
.map(|x| create_signal(cx, x)) .map(|x| create_signal(cx, x))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
); );
//let signal = create_signal(cx, 0);
//let vec2 = vec.get().as_ref().clone();
//let signal = create_ref(cx, vec.get(0).unwrap());
create_effect(cx, || { create_effect(cx, || {
props.state.set( props.state.set(
@ -281,30 +285,107 @@ where
) )
}); });
/* let onadd = move |_| vec.modify().push(create_signal(cx, T::default()));
view! { cx,
Indexed( Block(
iterable=vec, cx,
view=|cx: BoundedScope<'_, 'a>, x| { BlockProps {
let signal = create_ref(cx, x); title: "List".into(),
view! { cx, children: Children::new(cx, move |_| {
(T::edit(cx, x.into())) div()
} .dyn_c(move || {
}, View::new_fragment(
) vec.get()
} .as_ref()
*/ .clone()
.into_iter()
.map(|x| div().c(x.edit(cx)).c(br()).view(cx))
.collect(),
)
})
.c(Button(
cx,
ButtonProps {
onclick: onadd,
text: "Add new".into(),
icon: "mdi-plus".into(),
},
))
.view(cx)
}),
},
)
} }
} }
impl<'a, G, T> Editable<'a, G> for Vec<T> impl<'a, G, T> Editable<'a, G> for Vec<T>
where where
G: Html, G: Html,
T: Editable<'a, G> + Clone + PartialEq + 'a, T: Editable<'a, G> + Clone + PartialEq + Default + 'a,
{ {
type Editor = VecEdit; type Editor = VecEdit;
} }
impl<'a, G, T> Editable<'a, G> for HashSet<T>
where
G: Html,
T: Editable<'a, G> + Clone + PartialEq + Default + Hash + Eq + 'a,
{
type Editor = VecEdit;
}
impl<'a, G, K, V> Editable<'a, G> for HashMap<K, V>
where
G: Html,
K: Clone + Hash + Eq,
V: Clone,
(K, V): Editable<'a, G> + Clone + PartialEq + Default + Hash + Eq + 'a,
{
type Editor = VecEdit;
}
pub struct TupleEdit;
impl<'a, 'b, G: Html, A: Editable<'a, G> + Clone, B: Editable<'a, G> + Clone> Editor<'a, G, (A, B)>
for TupleEdit
{
fn edit(cx: Scope<'a>, props: EditProps<'a, (A, B)>) -> View<G> {
let state = props.state;
let (a, b) = state.get_untracked().as_ref().clone();
let a = create_signal(cx, a.clone());
let b = create_signal(cx, b.clone());
create_effect(cx, || {
props
.state
.set((a.get().as_ref().clone(), b.get().as_ref().clone()))
});
Block(
cx,
BlockProps {
title: "Tuple".into(),
children: Children::new(cx, move |_| {
div()
.dyn_c(move || a.edit(cx))
.dyn_c(move || b.edit(cx))
.view(cx)
}),
},
)
}
}
impl<'a, G, A, B> Editable<'a, G> for (A, B)
where
G: Html,
A: Editable<'a, G> + Clone,
B: Editable<'a, G> + Clone,
{
type Editor = TupleEdit;
}
#[derive(Default, Clone, Debug)] #[derive(Default, Clone, Debug)]
pub struct Test { pub struct Test {
inner: TestInner, inner: TestInner,

View File

@ -6,7 +6,7 @@ use web_sys::Event;
use yew::use_effect; use yew::use_effect;
#[derive(Prop)] #[derive(Prop)]
pub struct Props<F: FnMut(Event)> { pub struct ButtonProps<F: FnMut(Event)> {
pub onclick: F, pub onclick: F,
#[builder(default)] #[builder(default)]
pub text: String, pub text: String,
@ -15,7 +15,7 @@ pub struct Props<F: FnMut(Event)> {
} }
#[component] #[component]
pub fn Button<'a, G: Html, F: 'a + FnMut(Event)>(cx: Scope<'a>, props: Props<F>) -> View<G> { pub fn Button<'a, G: Html, F: 'a + FnMut(Event)>(cx: Scope<'a>, props: ButtonProps<F>) -> View<G> {
let mut icon_class = String::from("mdi "); let mut icon_class = String::from("mdi ");
if !props.icon.is_empty() { if !props.icon.is_empty() {