Version quasi-fonctionnelle
parent
f32d5b2bdb
commit
6d4e8462b8
|
|
@ -30,11 +30,11 @@ li.dernier_arrive {
|
|||
color: darkgrey;
|
||||
}
|
||||
|
||||
.courante {
|
||||
.active section.queue {
|
||||
background-color: lightgreen;
|
||||
}
|
||||
|
||||
.attente {
|
||||
.attente section.queue {
|
||||
background-color: pink;
|
||||
}
|
||||
|
||||
|
|
@ -45,3 +45,7 @@ section.queue {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
283
src/main.rs
283
src/main.rs
|
|
@ -1,69 +1,270 @@
|
|||
use sycamore::prelude::*;
|
||||
use sycamore::builder::prelude::*;
|
||||
use sycamore::rt::JsCast;
|
||||
use rand::prelude::*;
|
||||
use rand::distributions::Alphanumeric;
|
||||
|
||||
enum Queue {
|
||||
enum NomQueue {
|
||||
A, B
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
enum ModeQueue {
|
||||
Chrono,
|
||||
Aléatoire
|
||||
}
|
||||
|
||||
fn enqueue<A>(queue: &mut Vec<A>, s: A, mode: ModeQueue, rng: &mut ThreadRng) {
|
||||
//
|
||||
let n = queue.len();
|
||||
let k = match mode {
|
||||
ModeQueue::Chrono => 0,
|
||||
ModeQueue::Aléatoire => {
|
||||
// let mut rng = thread_rng();
|
||||
rng.gen_range(0, n + 1)
|
||||
impl ModeQueue {
|
||||
fn set_aléatoire(&mut self, b: bool) {
|
||||
match b {
|
||||
false => { *self = ModeQueue::Chrono},
|
||||
true => { *self = ModeQueue::Aléatoire},
|
||||
}
|
||||
};
|
||||
queue.insert(k, s)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ModeQueue {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
let s = match self {
|
||||
ModeQueue::Chrono => "Chrono",
|
||||
ModeQueue::Aléatoire => "Aléatoire"
|
||||
};
|
||||
write!(fmt, "{}", s)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ÉtatQueue<'a> {
|
||||
nom: String,
|
||||
mode: &'a Signal<ModeQueue>,
|
||||
contenu: &'a Signal<Vec<String>>,
|
||||
nouvelleau: &'a Signal<String>,
|
||||
priorité: &'a Signal<u8>,
|
||||
}
|
||||
|
||||
impl<'a> ÉtatQueue<'a> {
|
||||
fn new<'b>(cx: BoundedScope<'a, 'b>, nom: &str) -> Self {
|
||||
ÉtatQueue {
|
||||
nom: nom.into(),
|
||||
mode: create_signal(cx, ModeQueue::Aléatoire),
|
||||
contenu: create_signal(cx, vec![]),
|
||||
nouvelleau: create_signal(cx, "".into()),
|
||||
priorité: create_signal(cx, 1.into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
return self.contenu.get().len()
|
||||
}
|
||||
|
||||
fn enqueue(&mut self, rng: &mut ThreadRng) {
|
||||
//
|
||||
let s = &self.nouvelleau;
|
||||
let n = self.len();
|
||||
let k = match *self.mode.get() {
|
||||
ModeQueue::Chrono => n,
|
||||
ModeQueue::Aléatoire => {
|
||||
rng.gen_range(0, n + 1)
|
||||
}
|
||||
};
|
||||
self.contenu.modify().insert(k, s.to_string())
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn dequeue(&mut self) -> Option<String> {
|
||||
if self.len() > 0 {
|
||||
Some(self.contenu.modify().remove(0))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[derive(Prop)]
|
||||
struct QueueProp<'a>{
|
||||
q: ÉtatQueue<'a>
|
||||
}
|
||||
|
||||
fn validate_queue<'a>(mut queue: ÉtatQueue<'a>) -> impl FnMut(web_sys::Event) + 'a {
|
||||
move |ev: web_sys::Event| {
|
||||
let mut rng = thread_rng();
|
||||
let event : web_sys::KeyboardEvent = ev.unchecked_into();
|
||||
|
||||
if event.key_code() == 13 {
|
||||
queue.enqueue(&mut rng);
|
||||
queue.nouvelleau.set(String::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #[component]
|
||||
// fn Queue<'a, G: Html>(cx: Scope<'a>, queue: QueueProp<'a>) -> View<G> {
|
||||
// let queue_courante = use_context::<Signal<NomQueue>>(cx);
|
||||
|
||||
// }
|
||||
|
||||
|
||||
#[component]
|
||||
fn ConfigQueue<'a, G: Html>(cx: Scope<'a>, queue: QueueProp<'a>) -> View<G> {
|
||||
let prio_str = create_signal(cx, String::new());
|
||||
let est_aléatoire = create_signal(cx, true); //*queue.q.mode.get() == ModeQueue::Aléatoire);
|
||||
let nom = queue.q.nom;
|
||||
let suffix = rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(15)
|
||||
.map(char::from)
|
||||
.collect::<String>();
|
||||
create_effect(cx, ||
|
||||
if let Ok(p) = prio_str.get().parse::<u8>() {
|
||||
queue.q.priorité.set(p)
|
||||
});
|
||||
create_effect(cx, || prio_str.set(format!("{}", queue.q.priorité.get())));
|
||||
|
||||
create_effect(cx, ||
|
||||
queue.q.mode.modify().set_aléatoire(*est_aléatoire.get()));
|
||||
create_effect(cx, || est_aléatoire.set(*queue.q.mode.get() == ModeQueue::Aléatoire));
|
||||
|
||||
section()
|
||||
.c(h3().dyn_t(move || nom.clone()))
|
||||
.c(input()
|
||||
.attr("type", "checkbox")
|
||||
.dyn_attr("id", { let suffix = suffix.clone();
|
||||
move || Some(format!("mode_queue_{}", &suffix.clone()))
|
||||
})
|
||||
.bind_checked(est_aléatoire)
|
||||
)
|
||||
.c(label()
|
||||
.dyn_attr("for", {
|
||||
let suffix = suffix.clone();
|
||||
move || Some(format!("mode_queue_{}", &suffix.clone()))
|
||||
})
|
||||
.t("Entrée aléatoire")
|
||||
)
|
||||
.c(br())
|
||||
.c(input()
|
||||
.dyn_attr("id", { let suffix = suffix.clone();
|
||||
move || Some(format!("prio_queue_{}", &suffix.clone()))
|
||||
})
|
||||
.attr("type", "range")
|
||||
.attr("min", "1")
|
||||
.attr("max", "7")
|
||||
.bind_value(prio_str)
|
||||
)
|
||||
.c(
|
||||
label()
|
||||
.dyn_attr("for", { let suffix = suffix.clone();
|
||||
move || Some(format!("prio_queue_{}", &suffix.clone()))
|
||||
})
|
||||
.dyn_t(|| format!("Priorité: {}", queue.q.priorité.get()))
|
||||
)
|
||||
.view(cx)
|
||||
}
|
||||
|
||||
|
||||
#[component]
|
||||
fn Queue<'a, G: Html>(cx: Scope<'a>, queue: QueueProp<'a>) -> View<G> {
|
||||
let ok_queue = validate_queue(queue.q.clone());
|
||||
view! { cx,
|
||||
div {
|
||||
section(class="queue") {
|
||||
h3 {(queue.q.nom)}
|
||||
input(type="text", bind:value = queue.q.nouvelleau, on:keypress=ok_queue) {}
|
||||
ul {
|
||||
Keyed {
|
||||
iterable: queue.q.contenu,
|
||||
view: |cx, item: String| view! {cx, li { (item) }},
|
||||
key: |x| x.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
sycamore::render(|cx| {
|
||||
let prochainə = create_signal(cx, String::from("Camille"));
|
||||
let queue_A = create_signal(cx, vec![]);
|
||||
let nouvelleau_queue_A = create_signal(cx, "".into());
|
||||
let mode_queue_A = create_signal(cx, ModeQueue::Aléatoire);
|
||||
let mut do_enqueue = |_queue| {
|
||||
let mut rng = thread_rng();
|
||||
let val: std::rc::Rc<String> = nouvelleau_queue_A.get();
|
||||
enqueue(&mut queue_A.modify(), String::from(val.as_str()), *mode_queue_A.get(), &mut rng)
|
||||
let prochainə = create_signal(cx, String::from("personne encore"));
|
||||
let conf_visible = create_signal(cx, false);
|
||||
let queue_A = ÉtatQueue::new(cx, "Gauche");
|
||||
let queue_B = ÉtatQueue::new(cx, "Droite");
|
||||
let queue_courante = create_signal(cx, NomQueue::A);
|
||||
provide_context_ref(cx, queue_courante);
|
||||
let next = {
|
||||
let mut my_queue_A = queue_A.clone();
|
||||
let mut my_queue_B = queue_B.clone();
|
||||
move |_ev| {
|
||||
let (queue, next) = match *queue_courante.get() {
|
||||
NomQueue::A => (&mut my_queue_A, NomQueue::B),
|
||||
NomQueue::B => (&mut my_queue_B, NomQueue::A)
|
||||
};
|
||||
match queue.dequeue() {
|
||||
Some(p) => prochainə.set(p),
|
||||
None => ()
|
||||
}
|
||||
queue_courante.set(next);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
let queue_A_pour_aff = queue_A.clone();
|
||||
let queue_A_pour_conf = queue_A.clone();
|
||||
let queue_B_pour_aff = queue_B.clone();
|
||||
let queue_B_pour_conf = queue_B.clone();
|
||||
|
||||
|
||||
view! { cx,
|
||||
main {
|
||||
h1 { "Kikikoz" }
|
||||
p(class="orateurice") { (prochainə.get()) }
|
||||
p(class="orateurice") {
|
||||
"On écoute " (prochainə.get()) "."
|
||||
br {}
|
||||
button(on:click=next) { "Suivantə" }
|
||||
}
|
||||
section(id="les_queues") {
|
||||
section(id="queue_A", class="queue") {
|
||||
"Queue A"
|
||||
input(type="text", bind:value=nouvelleau_queue_A, on:keypress=move |ev: web_sys::Event| {
|
||||
let event : web_sys::KeyboardEvent = ev.unchecked_into();
|
||||
|
||||
if event.key_code() == 13 {
|
||||
do_enqueue(Queue::A);
|
||||
nouvelleau_queue_A.set(String::new())
|
||||
}
|
||||
})
|
||||
ul {
|
||||
Indexed {
|
||||
iterable: &queue_A,
|
||||
view: |cx, item: String| view! {cx,
|
||||
li { (item) }
|
||||
},
|
||||
}
|
||||
}
|
||||
div(class=(match *queue_courante.get(){NomQueue::A=> "active", NomQueue::B=>"attente"})) {
|
||||
Queue {
|
||||
q: queue_A_pour_aff
|
||||
}
|
||||
}
|
||||
|
||||
div(class=(match *queue_courante.get(){NomQueue::B=>"active", NomQueue::A=>"attente"})) {
|
||||
Queue {
|
||||
q: queue_B_pour_aff
|
||||
}
|
||||
}
|
||||
section(id="queue_B", class="queue") { "Queue B" }
|
||||
}
|
||||
}
|
||||
|
||||
aside {
|
||||
button(on:click=|_| conf_visible.set(! *conf_visible.get())) {
|
||||
(
|
||||
if *conf_visible.get() {
|
||||
"cacher"
|
||||
} else {
|
||||
"configuration"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
div(class=if *conf_visible.get() { "visible" } else { "hidden" }) {
|
||||
h2 { "Configuration" }
|
||||
ConfigQueue {
|
||||
q: queue_A_pour_conf
|
||||
}
|
||||
ConfigQueue {
|
||||
q: queue_B_pour_conf
|
||||
}
|
||||
// section {
|
||||
// h3 { "Queue B" }
|
||||
// input(type="checkbox", id="mélanger_queue_B") {}
|
||||
// label(for="enable_queue_B") {"Randomiser"}
|
||||
// br {}
|
||||
// input(type="range", id="prio_queue_B", min="1", max="7", bind:value=queue_B.priorité) {}
|
||||
// label(for="prio_queue_B") {"Priorité "} // (queue_B.priorité.get())}
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue