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 soundclips;
|
||||||
|
pub mod state;
|
||||||
pub mod vbplay;
|
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::{routing, Router};
|
||||||
use axum_template::{engine::Engine, Key, RenderHtml};
|
use axum_template::{engine::Engine, Key, RenderHtml};
|
||||||
use minijinja::{path_loader, Environment};
|
use minijinja::{path_loader, Environment};
|
||||||
|
use state::{AppState, TemplateEngine};
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@ -10,23 +11,9 @@ use std::sync::{Arc, Mutex};
|
|||||||
use vbplay::AudioThread;
|
use vbplay::AudioThread;
|
||||||
|
|
||||||
mod soundclips;
|
mod soundclips;
|
||||||
|
mod state;
|
||||||
mod vbplay;
|
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]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let mut jinja = Environment::new();
|
let mut jinja = Environment::new();
|
||||||
@ -36,7 +23,7 @@ async fn main() {
|
|||||||
let audio = vbplay::audio_thread();
|
let audio = vbplay::audio_thread();
|
||||||
let audio: Arc<Mutex<AudioThread>> = Arc::new(Mutex::new(audio));
|
let audio: Arc<Mutex<AudioThread>> = Arc::new(Mutex::new(audio));
|
||||||
|
|
||||||
let state = AppState {
|
let app_state = AppState {
|
||||||
engine: template_engine,
|
engine: template_engine,
|
||||||
clips: soundclips::scan_directory_for_clips("E:/sounds/soundboard", &["mp3"])
|
clips: soundclips::scan_directory_for_clips("E:/sounds/soundboard", &["mp3"])
|
||||||
.expect("No Soundclips found."),
|
.expect("No Soundclips found."),
|
||||||
@ -51,7 +38,7 @@ async fn main() {
|
|||||||
.route("/", routing::get(home))
|
.route("/", routing::get(home))
|
||||||
.route("/play/:hash", routing::get(play_handler))
|
.route("/play/:hash", routing::get(play_handler))
|
||||||
.route("/stop", routing::get(stop_handler))
|
.route("/stop", routing::get(stop_handler))
|
||||||
.with_state(state);
|
.with_state(app_state);
|
||||||
|
|
||||||
println!("listening on {}", addr);
|
println!("listening on {}", addr);
|
||||||
|
|
||||||
@ -67,7 +54,7 @@ struct TemplateContext {
|
|||||||
clips: Vec<soundclips::SoundClip>,
|
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 clips = state.0.clone().clips; // this is not ideal.
|
||||||
let context = TemplateContext { clips: clips };
|
let context = TemplateContext { clips: clips };
|
||||||
RenderHtml(Key("index.html".to_owned()), engine, context)
|
RenderHtml(Key("index.html".to_owned()), engine, context)
|
||||||
|
@ -58,18 +58,20 @@ pub fn scan_directory_for_clips(directory: &str, extensions: &[&str]) -> Option<
|
|||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
if let Some(ext) = path.extension() {
|
if let Some(ext) = path.extension() {
|
||||||
if extensions.iter().any(|&e| ext == OsStr::new(e)) {
|
if extensions.iter().any(|&e| ext == OsStr::new(e)) {
|
||||||
let file_name = path.file_name().unwrap().to_str().unwrap().to_string();
|
if let Some(file_name) = path.file_name().unwrap().to_str() {
|
||||||
/*
|
/*
|
||||||
the calls to unwrap() are more or less "safe" because:
|
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.
|
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.
|
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());
|
let sound_clip =
|
||||||
|
SoundClip::new(file_name.to_string(), directory.to_owned());
|
||||||
sound_clips.push(sound_clip);
|
sound_clips.push(sound_clip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("Failed to read directory entry: {}", entry.unwrap_err());
|
println!("Failed to read directory entry: {}", entry.unwrap_err());
|
||||||
}
|
}
|
||||||
|
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>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<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 %}
|
{% for clip in clips %}
|
||||||
<button onclick="play('{{clip.hash}}')">{{clip.file_name}}</button><br />
|
<button onclick="play('{{clip.hash}}')">{{clip.file_name}}</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<div class="player">
|
||||||
<button onclick="stop()">Stop.</button>
|
<button onclick="stop()">Stop.</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user