From 59fba4a13ceda2542526a60f8210f39889d869f0 Mon Sep 17 00:00:00 2001 From: Wynd Date: Mon, 16 Jun 2025 02:22:25 +0300 Subject: [PATCH] Platform specific cfgs and including all the questions in the build as to allow for mobile --- .gitignore | 2 +- Cargo.lock | 20 ++++++++++ Cargo.toml | 3 +- src/main.rs | 106 ++++++++++++++++++++++++++++++-------------------- src/models.rs | 2 +- 5 files changed, 87 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index 4411927..144242d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ # These are backup files generated by rustfmt **/*.rs.bk -questions*.toml +/questions diff --git a/Cargo.lock b/Cargo.lock index 81e5552..a36d3c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1405,6 +1405,7 @@ name = "flashcards" version = "0.1.0" dependencies = [ "dioxus", + "include_dir", "rand 0.9.1", "serde", "tokio", @@ -2207,6 +2208,25 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "include_dir" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "indexmap" version = "1.9.3" diff --git a/Cargo.toml b/Cargo.toml index 696766e..2d5977e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,11 +7,12 @@ edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -dioxus = { version = "0.6.3", features = [] } +dioxus = { version = "0.6", features = [] } toml = { version = "0.8" } serde = { version = "1.0", features = ["derive"] } rand = { version = "0.9" } tokio = { version = "1.45" } +include_dir = { version = "0.7" } [features] default = ["desktop"] diff --git a/src/main.rs b/src/main.rs index c983eed..88de015 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,17 @@ -use std::{env, sync::OnceLock, time::Duration}; +use std::{sync::OnceLock, time::Duration}; -use dioxus::{ - desktop::{Config, LogicalSize, WindowBuilder}, - prelude::*, -}; +#[cfg(feature = "desktop")] +use dioxus::desktop::{Config, LogicalSize, WindowBuilder}; +use dioxus::prelude::*; +use include_dir::{Dir, include_dir}; use models::{Question, Questions}; use rand::seq::SliceRandom; +#[cfg(feature = "desktop")] +use std::env; mod models; -const DEFAULT_FILE: &str = "questions.toml"; +const QUESTIONS_DIR: Dir = include_dir!("./questions"); const MAIN_CSS: Asset = asset!("/assets/main.css"); pub static QUESTIONS: OnceLock = OnceLock::new(); @@ -17,30 +19,36 @@ pub static QUESTIONS: OnceLock = OnceLock::new(); fn get_questions() -> Questions { QUESTIONS .get_or_init(|| { - let args: Vec = env::args().collect(); - let file_name = args.get(1).map(|x| x.as_str()).unwrap_or(DEFAULT_FILE); + let mut questions = Questions::default(); - let questions_str = std::fs::read_to_string(file_name) - .unwrap_or_else(|_| panic!("Could not read from file {file_name}")); - let mut questions: Questions = - toml::from_str(&questions_str).expect("Could not decode the given file as TOML"); + for entry in QUESTIONS_DIR.files() { + if let Some(content) = entry.contents_utf8() { + if let Ok(other_questions) = toml::from_str(content) { + questions += other_questions; + } + } + } - if args.len() > 2 { - for i in 2..args.len() { - let file_name = args.get(i).map(|x| x.as_str()); - let Some(file_name) = file_name else { - continue; - }; + #[cfg(feature = "desktop")] + { + let args: Vec = env::args().collect(); + if args.len() > 1 { + for i in 1..args.len() { + let file_name = args.get(i).map(|x| x.as_str()); + let Some(file_name) = file_name else { + continue; + }; - let Ok(questions_str) = std::fs::read_to_string(file_name) else { - continue; - }; + let Ok(questions_str) = std::fs::read_to_string(file_name) else { + continue; + }; - let Ok(other_questions) = toml::from_str(&questions_str) else { - continue; - }; + let Ok(other_questions) = toml::from_str(&questions_str) else { + continue; + }; - questions += other_questions; + questions += other_questions; + } } } @@ -65,29 +73,41 @@ fn get_rand_questions() -> Vec { } fn main() { - dioxus::LaunchBuilder::new() - .with_cfg( - Config::default().with_menu(None).with_window( - WindowBuilder::new() - .with_min_inner_size(LogicalSize::new(640, 540)) - .with_maximized(true) - .with_title("Flashcards"), - ), - ) - .launch(App) -} + #[cfg(feature = "desktop")] + { + dioxus::LaunchBuilder::new() + .with_cfg( + Config::default().with_menu(None).with_window( + WindowBuilder::new() + .with_min_inner_size(LogicalSize::new(640, 540)) + .with_maximized(true) + .with_title("Flashcards"), + ), + ) + .launch(App) + } -#[component] -fn App() -> Element { - rsx! { - document::Link { rel: "stylesheet", href: MAIN_CSS } - QuestionForm {} + #[cfg(feature = "mobile")] + { + dioxus::launch(App); } } #[component] -pub fn QuestionForm() -> Element { - let mut questions = use_signal(get_rand_questions); +fn App() -> Element { + let questions = get_rand_questions(); + + rsx! { + document::Link { rel: "stylesheet", href: MAIN_CSS } + if !questions.is_empty() { + QuestionForm { questions } + } + } +} + +#[component] +pub fn QuestionForm(questions: Vec) -> Element { + let mut questions = use_signal(|| questions); let mut current = use_signal(move || questions.remove(0)); let total_correct = use_memo(move || { diff --git a/src/models.rs b/src/models.rs index 127aec6..e6d5273 100644 --- a/src/models.rs +++ b/src/models.rs @@ -2,7 +2,7 @@ use std::ops::{AddAssign, Deref, DerefMut}; use serde::Deserialize; -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Default, Clone, Deserialize)] pub struct Questions { pub questions: Vec, }