refactor: state
This commit is contained in:
parent
cb0272b790
commit
fa22be6e0e
11
Justfile
Normal file
11
Justfile
Normal file
@ -0,0 +1,11 @@
|
||||
default:
|
||||
@just hello
|
||||
|
||||
run:
|
||||
@cargo run main
|
||||
|
||||
bin args='':
|
||||
@cargo run --bin {{args}}
|
||||
|
||||
hello:
|
||||
@echo "Hello, world!"
|
@ -1,2 +1,3 @@
|
||||
pub mod soundclips;
|
||||
pub mod state;
|
||||
pub mod vbplay;
|
||||
|
25
src/main.rs
25
src/main.rs
@ -1,7 +1,8 @@
|
||||
use axum::extract::{FromRef, State};
|
||||
use axum::extract::State;
|
||||
use axum::{routing, Router};
|
||||
use axum_template::{engine::Engine, Key, RenderHtml};
|
||||
use minijinja::{path_loader, Environment};
|
||||
use state::{AppState, TemplateEngine};
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use serde::Serialize;
|
||||
@ -10,23 +11,9 @@ use std::sync::{Arc, Mutex};
|
||||
use vbplay::AudioThread;
|
||||
|
||||
mod soundclips;
|
||||
mod state;
|
||||
mod vbplay;
|
||||
|
||||
type AppEngine = Engine<Environment<'static>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub engine: AppEngine,
|
||||
pub clips: Vec<soundclips::SoundClip>,
|
||||
pub player: Arc<Mutex<AudioThread>>,
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for AppEngine {
|
||||
fn from_ref(state: &AppState) -> Self {
|
||||
state.engine.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let mut jinja = Environment::new();
|
||||
@ -36,7 +23,7 @@ async fn main() {
|
||||
let audio = vbplay::audio_thread();
|
||||
let audio: Arc<Mutex<AudioThread>> = Arc::new(Mutex::new(audio));
|
||||
|
||||
let state = AppState {
|
||||
let app_state = AppState {
|
||||
engine: template_engine,
|
||||
clips: soundclips::scan_directory_for_clips("E:/sounds/soundboard", &["mp3"])
|
||||
.expect("No Soundclips found."),
|
||||
@ -51,7 +38,7 @@ async fn main() {
|
||||
.route("/", routing::get(home))
|
||||
.route("/play/:hash", routing::get(play_handler))
|
||||
.route("/stop", routing::get(stop_handler))
|
||||
.with_state(state);
|
||||
.with_state(app_state);
|
||||
|
||||
println!("listening on {}", addr);
|
||||
|
||||
@ -67,7 +54,7 @@ struct TemplateContext {
|
||||
clips: Vec<soundclips::SoundClip>,
|
||||
}
|
||||
|
||||
async fn home(engine: AppEngine, state: State<AppState>) -> impl axum::response::IntoResponse {
|
||||
async fn home(engine: TemplateEngine, state: State<AppState>) -> impl axum::response::IntoResponse {
|
||||
let clips = state.0.clone().clips; // this is not ideal.
|
||||
let context = TemplateContext { clips: clips };
|
||||
RenderHtml(Key("index.html".to_owned()), engine, context)
|
||||
|
@ -58,15 +58,17 @@ pub fn scan_directory_for_clips(directory: &str, extensions: &[&str]) -> Option<
|
||||
if path.is_file() {
|
||||
if let Some(ext) = path.extension() {
|
||||
if extensions.iter().any(|&e| ext == OsStr::new(e)) {
|
||||
let file_name = path.file_name().unwrap().to_str().unwrap().to_string();
|
||||
/*
|
||||
the calls to unwrap() are more or less "safe" because:
|
||||
if let Some(file_name) = path.file_name().unwrap().to_str() {
|
||||
/*
|
||||
the calls to unwrap() are more or less "safe" because:
|
||||
|
||||
file_name() only returns None if the path ends in "..", which won't be the case for paths returned by read_dir.
|
||||
to_str() only returns None if the file name isn't valid Unicode, which is quite rare on most modern file systems.
|
||||
*/
|
||||
let sound_clip = SoundClip::new(file_name, directory.to_owned());
|
||||
sound_clips.push(sound_clip);
|
||||
file_name() only returns None if the path ends in "..", which won't be the case for paths returned by read_dir.
|
||||
to_str() only returns None if the file name isn't valid Unicode, which is quite rare on most modern file systems.
|
||||
*/
|
||||
let sound_clip =
|
||||
SoundClip::new(file_name.to_string(), directory.to_owned());
|
||||
sound_clips.push(sound_clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
src/state.rs
Normal file
21
src/state.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use crate::soundclips::SoundClip;
|
||||
use crate::vbplay::AudioThread;
|
||||
use axum::extract::FromRef;
|
||||
use axum_template::engine::Engine;
|
||||
use minijinja::Environment;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
pub type TemplateEngine = Engine<Environment<'static>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub engine: TemplateEngine,
|
||||
pub clips: Vec<SoundClip>,
|
||||
pub player: Arc<Mutex<AudioThread>>,
|
||||
}
|
||||
|
||||
impl FromRef<AppState> for TemplateEngine {
|
||||
fn from_ref(state: &AppState) -> Self {
|
||||
state.engine.clone()
|
||||
}
|
||||
}
|
@ -13,10 +13,20 @@
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
{% for clip in clips %}
|
||||
<button onclick="play('{{clip.hash}}')">{{clip.file_name}}</button><br />
|
||||
{% endfor %}
|
||||
|
||||
<button onclick="stop()">Stop.</button>
|
||||
<div class="container">
|
||||
<div class="categories">
|
||||
<span class="category">Category 1</span>
|
||||
<!-- More categories -->
|
||||
<button class="more">More</button>
|
||||
</div>
|
||||
<div class="soundclips">
|
||||
{% for clip in clips %}
|
||||
<button onclick="play('{{clip.hash}}')">{{clip.file_name}}</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="player">
|
||||
<button onclick="stop()">Stop.</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user