use eframe::{egui, egui::Context, Frame, Storage as EStorage};
use janki::{
dummy_storage::{DummyStorage, DynStorage},
game::{default_sag, AnkiGame, GiveFacts},
item::Fact,
storage::Storage as JStorage,
};
use std::time::Duration;
pub enum JankiState {
Testing {
current_text: String,
current_fact: Fact,
was_eligible: bool,
},
Tested {
fact: Fact,
was_correct: bool,
},
AddingNew {
term: String,
def: String,
},
Viewing {
show_defs: bool,
show_only_eligible: bool,
},
}
pub struct JankiApp {
app: AnkiGame<DummyStorage, GiveFacts>,
has_done_initial_read: bool,
state: JankiState,
}
impl JankiApp {
pub fn new() -> Self {
Self {
app: AnkiGame::new(DummyStorage::default(), default_sag()).unwrap(),
state: JankiState::Viewing {
show_defs: false,
show_only_eligible: true,
},
has_done_initial_read: false,
}
}
}
impl eframe::App for JankiApp {
fn update(&mut self, ctx: &Context, _frame: &mut Frame) {
if self.has_done_initial_read {
egui::SidePanel::left("left_side").show(ctx, |ui| {
if ui.button("New Test").clicked() {
if let Some((f, was_eligible)) = self.app.get_new_fact() {
self.state = JankiState::Testing {
current_text: String::default(),
current_fact: f,
was_eligible,
};
}
} else if ui.button("Add More").clicked() {
self.state = JankiState::AddingNew {
term: String::default(),
def: String::default(),
}
} else if ui.button("View").clicked() {
self.state = JankiState::Viewing {
show_defs: false,
show_only_eligible: true,
}
}
ui.separator();
if let JankiState::Viewing {
show_defs,
show_only_eligible,
} = &mut self.state
{
ui.checkbox(show_defs, "Show definitions: ");
ui.checkbox(show_only_eligible, "Show only eligible: ");
ui.separator();
}
ui.label(format!(
"Only {} Facts remaining this session!",
self.app.get_eligible_no(),
));
});
egui::CentralPanel::default().show(ctx, |ui| match &mut self.state {
JankiState::Testing {
current_fact,
current_text,
was_eligible,
} => {
if *was_eligible {
ui.label("Testing");
} else {
ui.label("EVEN MORE TESTING!");
}
ui.separator();
ui.label(format!("The term is: {}", current_fact.term));
ui.horizontal(|ui| {
ui.label("Please enter the definition: ");
ui.text_edit_singleline(current_text);
});
ui.separator();
if ui.button("Submit!").clicked() {
let was_correct = current_text.trim() == current_fact.definition;
self.app.finish_current_fact(was_correct);
self.app.set_new_fact();
self.state = JankiState::Tested {
fact: current_fact.clone(),
was_correct,
};
}
}
JankiState::Tested { fact, was_correct } => {
if *was_correct {
ui.label("Correct!");
} else {
ui.label(format!("Wrong - it should've been {:?}", fact.definition));
}
}
JankiState::AddingNew { term, def } => {
ui.label("Add New Stuff");
ui.separator();
ui.horizontal(|ui| {
ui.label("Enter a term: ");
ui.text_edit_singleline(term);
});
ui.horizontal(|ui| {
ui.label("Enter a definition: ");
ui.text_edit_singleline(def);
});
if ui.button("Submit").clicked() {
self.app
.add_card(Fact::new(term.to_string(), def.to_string()));
term.clear();
def.clear();
}
}
JankiState::Viewing {
show_defs,
show_only_eligible,
} => {
let mut list = if *show_only_eligible {
self.app.get_elgible()
} else {
self.app.get_all_facts()
};
ui.label("Viewing Facts!");
ui.separator();
ui.separator();
egui::ScrollArea::vertical().show(ui, |ui| {
let mut display_fact = |f: Fact, is_first: bool| {
if is_first {
ui.separator();
}
ui.label(format!("Term - {}", f.term));
if *show_defs {
ui.label(format!("Definition - {}", f.definition));
} else {
ui.label(format!("Definition Hidden!"));
}
};
let first = list.remove(0);
display_fact(first, false);
list.into_iter().for_each(|f| {
display_fact(f, true);
});
});
}
});
} else {
egui::CentralPanel::default().show(ctx, |ui| {
ui.label("Loading...");
ui.spinner();
});
}
}
fn save(&mut self, mut storage: &mut dyn EStorage) {
if !matches!(self.state, JankiState::Testing { .. }) {
if self.has_done_initial_read {
self.app
.write_custom(&mut storage as &mut dyn JStorage<ErrorType = serde_json::Error>)
.expect("Failure to write to EGUI storage");
} else {
self.has_done_initial_read = true;
self.app
.read_custom(&storage as &dyn JStorage<ErrorType = serde_json::Error>)
.expect("Failure to read from EGUI storage");
}
}
}
fn auto_save_interval(&self) -> Duration {
return Duration::from_millis(500);
}
}