Add dictionary and dictionary quiz pages

This commit is contained in:
2026-02-22 11:07:57 +03:00
parent 170ccfc0fb
commit 6268b0ab33
8 changed files with 568 additions and 27 deletions
+148
View File
@@ -0,0 +1,148 @@
use crate::dictionary::DictionaryElement;
use crate::quiz::Score;
use crate::Page::PreviousPage;
use crate::RootMessage;
use crate::{NavigatedPage, Page};
use iced::widget::{button, container, row, text, text_input};
use iced::{alignment, Fill, Task};
use rand::prelude::SliceRandom;
#[derive(Debug, Clone)]
pub struct DictionaryQuizState {
words: Vec<DictionaryElement>,
current_set: Vec<DictionaryElement>,
answer: String,
view: String,
correct: String,
score: Score,
is_help: bool,
reverse: bool,
}
#[derive(Debug, Clone)]
pub enum DictionaryQuizMessage {
Next,
Back,
AnswerChanged(String),
SubmitAnswer,
}
impl NavigatedPage<DictionaryQuizMessage> for DictionaryQuizState {
fn navigate(&self, message: &DictionaryQuizMessage) -> Option<Page> {
match message {
DictionaryQuizMessage::Back => Some(PreviousPage),
_ => None,
}
}
}
impl DictionaryQuizState {
pub fn new(words: Vec<DictionaryElement>, reverse: bool) -> DictionaryQuizState {
DictionaryQuizState {
words,
current_set: Vec::new(),
answer: "".to_string(),
view: "---".to_string(),
correct: "".to_string(),
score: Default::default(),
is_help: false,
reverse: reverse,
}
}
pub fn update(&mut self, message: DictionaryQuizMessage) -> Task<RootMessage> {
match message {
DictionaryQuizMessage::Next => {
self.next();
}
DictionaryQuizMessage::Back => {}
DictionaryQuizMessage::AnswerChanged(c) => self.answer = c.clone(),
DictionaryQuizMessage::SubmitAnswer => self.submit(),
}
Task::none()
}
pub fn view(&self) -> iced::Element<'_, DictionaryQuizMessage> {
container(
iced::widget::column![
row![
text!("{}", self.view).size(54),
text!(
"{}",
if self.is_help {
self.correct.clone()
} else {
String::new()
}
),
]
.align_y(alignment::Vertical::Center)
.spacing(20),
text_input("Перевод", &self.answer)
.size(28)
.width(150)
.on_input(DictionaryQuizMessage::AnswerChanged)
.on_submit(DictionaryQuizMessage::SubmitAnswer),
row![
text!("{}", self.score.total.to_string()).size(25),
text!("{}", self.score.correct.to_string())
.size(25)
.color(iced::Color::from_rgb8(60, 170, 60)),
text!("{}", self.score.fail.to_string())
.color(iced::Color::from_rgb8(255, 79, 0))
.size(25),
]
.spacing(10),
button("Закончить").on_press(DictionaryQuizMessage::Back),
]
.spacing(10)
.align_x(alignment::Horizontal::Center),
)
.center_y(Fill)
.center_x(Fill)
.into()
}
fn next(&mut self) {}
fn submit(&mut self) {
if self.view == "---" {
self.show_next();
return;
}
if !self.is_help {
self.score.total += 1;
}
if self.answer == self.correct {
if self.is_help == false {
self.score.correct += 1;
}
self.show_next()
} else {
self.score.fail += 1;
self.is_help = true;
}
}
fn update_set(&mut self) {
self.current_set.append(&mut self.words.clone());
self.current_set.shuffle(&mut rand::rng())
}
fn show_next(&mut self) {
self.is_help = false;
self.answer = String::new();
if self.current_set.is_empty() {
self.update_set();
}
let next = self.current_set.pop().unwrap();
if self.reverse {
self.view = next.value.clone();
self.correct = next.key.clone();
} else {
self.view = next.key.clone();
self.correct = next.value.clone();
}
}
}