Allows for wrong answers, changed some names and added correct/wroung counters at the top

master
Wynd 2025-06-15 15:16:03 +03:00
parent 460b3e2790
commit 4d984cd2e3
2 changed files with 99 additions and 15 deletions

View File

@ -1,20 +1,47 @@
:root {
--text: white;
--correct: limegreen;
--correct-shadow: green;
--fail: crimson;
--fail-shadow: red;
--hover: gray;
--selection: goldenrod;
--selection-shadow: gold;
}
body {
background-color: #0f1116;
color: #ffffff;
color: var(--text);
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
margin: 0px;
overflow-x: hidden;
}
#counter {
margin: 10px;
font-size: 20px;
> div {
display: inline-block;
&.correct {
color: var(--correct);
text-shadow: var(--correct-shadow) 0px 0px 30px;
}
&.wrong {
color: var(--fail);
text-shadow: var(--fail-shadow) 0px 0px 30px;
}
&:not(:last-child)::after {
color: var(--text);
content: "/";
}
}
}
#result {
@ -25,8 +52,6 @@ body {
margin: auto;
text-align: center;
line-height: 1;
color: var(--correct);
text-shadow: var(--correct-shadow) 1px 1px 30px;
opacity: 0;
user-select: none;
@ -34,6 +59,16 @@ body {
display: block;
animation: 200ms fade-in forwards;
}
&.correct {
color: var(--correct);
text-shadow: var(--correct-shadow) 0px 0px 30px;
}
&.wrong {
color: var(--fail);
text-shadow: var(--fail-shadow) 0px 0px 30px;
}
}
@keyframes fade-in {
@ -56,8 +91,16 @@ form {
user-select: none;
h1 {
&.success {
text-wrap: balance;
&.correct {
color: var(--correct);
text-shadow: var(--correct-shadow) 0px 0px 30px;
}
&.wrong {
color: var(--fail);
text-shadow: var(--fail-shadow) 0px 0px 30px;
}
}
@ -70,9 +113,11 @@ form {
align-self: center;
box-sizing: border-box;
border: solid 2px unset;
text-wrap: balance;
&.selected {
border: solid 2px var(--selection);
box-shadow: 0px 0px 13px -5px var(--selection-shadow);
}
&:hover:not(.selected) {

View File

@ -85,22 +85,47 @@ pub fn QuestionForm() -> Element {
let total_questions = QUESTIONS.len();
let current_question = use_memo(move || questions().len());
let left_questions = use_memo(move || total_questions - current_question());
let mut correct_questions = use_signal(|| 0);
let mut wrong_questions = use_signal(|| 0);
let mut success_animation = use_signal(|| false);
let mut correct_animation = use_signal(|| false);
let mut wrong_animation = use_signal(|| false);
use_future(move || async move {
loop {
tokio::time::sleep(Duration::from_millis(400)).await;
if success_animation() {
let is_correct = correct_animation();
let is_wrong = wrong_animation();
if is_correct || is_wrong {
tokio::time::sleep(Duration::from_millis(600)).await;
success_animation.set(false);
// Uncheck all the answers
current().answers.iter_mut().for_each(|a| a.checked = false);
let mut correct_questions_lock = correct_questions.write();
let mut wrong_questions_lock = wrong_questions.write();
// Get a new question or reroll the list
if !questions().is_empty() {
current.set(questions.remove(0));
// Update the correct/wrong counters
if is_correct {
*correct_questions_lock += 1;
} else if is_wrong {
*wrong_questions_lock += 1;
}
} else {
questions.set(get_questions());
current.set(questions.remove(0));
*correct_questions_lock = 0;
*wrong_questions_lock = 0;
}
// Reset animation flags
correct_animation.set(false);
wrong_animation.set(false);
}
}
});
@ -116,24 +141,34 @@ pub fn QuestionForm() -> Element {
});
rsx! {
ResultPopup { is_visible: success_animation },
ResultPopup { is_correct: correct_animation, is_wrong: wrong_animation },
div {
id: "counter",
"{left_questions}/{total_questions}"
div { "{left_questions}" }
div {
class: "correct",
"{correct_questions}"
}
div {
class: "wrong",
"{wrong_questions}"
}
div { "{total_questions}" }
},
form {
id: "form",
onsubmit: move |_| {
if actual_correct() == total_correct() {
success_animation.set(true);
correct_animation.set(true);
}
else {
wrong_animation.set(true);
}
},
h1 {
class: if success_animation() { "success" },
class: if correct_animation() { "correct" },
class: if wrong_animation() { "wrong" },
"{current().message}"
}
{ answer_buttons }
@ -192,14 +227,18 @@ pub fn AnswerCheckbox(current: Signal<Question>, id: usize) -> Element {
}
#[component]
pub fn ResultPopup(is_visible: Signal<bool>) -> Element {
let is_visible = use_memo(move || is_visible());
pub fn ResultPopup(is_correct: Signal<bool>, is_wrong: Signal<bool>) -> Element {
let is_correct = use_memo(move || is_correct());
let is_wrong = use_memo(move || is_wrong());
let is_visible = use_memo(move || is_correct() || is_wrong());
rsx! {
div {
id: "result",
class: if is_visible() { "visible" },
""
class: if is_correct() { "correct" },
class: if is_wrong() { "wrong" },
if is_correct() { "" } else { "X" }
}
}
}