Update dependencies
This commit is contained in:
708
Cargo.lock
generated
708
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
15
Cargo.toml
15
Cargo.toml
@ -5,12 +5,15 @@ authors = ["Joakim Hulthe <joakim@hulthe.net"]
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
seed = "0.8.0"
|
||||
#wasm-bindgen = "0.2.70"
|
||||
serde = { version = "1", features = ['derive'] }
|
||||
serde_json = "1"
|
||||
anyhow = "*"
|
||||
rand = "0.8.4"
|
||||
seed = "0.10.0"
|
||||
serde = { version = "1.0.0", features = ['derive'] }
|
||||
serde_json = "1.0.0"
|
||||
rand = "0.8.5"
|
||||
gloo-console = "0.3.0"
|
||||
gloo-net = "0.4.0"
|
||||
csv = "1.2.2"
|
||||
thiserror = "1.0.48"
|
||||
wasm-bindgen = "0.2.87"
|
||||
|
||||
[dependencies.css_typegen]
|
||||
git = "https://github.com/hulthe/css_typegen.git"
|
||||
|
||||
40
src/app.rs
40
src/app.rs
@ -1,15 +1,16 @@
|
||||
use crate::css::C;
|
||||
use crate::custom_list::{fetch_custom_song_list, fetch_custom_song_list_index, CustomLists};
|
||||
use crate::fetch::fetch_list_of;
|
||||
use crate::fuzzy::FuzzyScore;
|
||||
use crate::query::ParsedQuery;
|
||||
use crate::song::Song;
|
||||
use anyhow::anyhow;
|
||||
use gloo_console::error;
|
||||
use rand::seq::SliceRandom;
|
||||
use rand::thread_rng;
|
||||
use seed::app::cmds::timeout;
|
||||
use seed::browser::util::document;
|
||||
use seed::{attrs, button, div, empty, error, img, input, p, span, C, IF};
|
||||
use seed::{log, prelude::*};
|
||||
use seed::prelude::*;
|
||||
use seed::{attrs, button, div, empty, img, input, p, span, C, IF};
|
||||
use std::cmp::Reverse;
|
||||
use std::collections::HashSet;
|
||||
use web_sys::Element;
|
||||
@ -194,12 +195,9 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
autotype_song(model, orders);
|
||||
}
|
||||
Msg::Scroll => {
|
||||
let (scroll, max_scroll) = match get_scroll() {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!(e);
|
||||
return;
|
||||
}
|
||||
let Some((scroll, max_scroll)) = get_scroll() else {
|
||||
error!("Failed to get song list element by id:", SONG_LIST_ID);
|
||||
return;
|
||||
};
|
||||
|
||||
let scroll_left: i32 = max_scroll - scroll;
|
||||
@ -344,18 +342,10 @@ pub fn view(model: &Model) -> Vec<Node<Msg>> {
|
||||
}
|
||||
|
||||
async fn fetch_songs() -> Option<Msg> {
|
||||
let response = match fetch("/songs").await.and_then(|r| r.check_status()) {
|
||||
let mut songs: Vec<Song> = match fetch_list_of("/songs").await {
|
||||
Ok(response) => response,
|
||||
Err(e) => {
|
||||
log!("error fetching songs", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let mut songs: Vec<Song> = match response.json().await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log!("error parsing songs", e);
|
||||
error!("Error fetching songs:", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
@ -374,22 +364,20 @@ pub fn autotype_song(model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
|
||||
const SONG_LIST_ID: &str = "song_list";
|
||||
|
||||
fn get_song_list_element() -> anyhow::Result<Element> {
|
||||
document()
|
||||
.get_element_by_id(SONG_LIST_ID)
|
||||
.ok_or_else(|| anyhow!("Failed to access song list element"))
|
||||
fn get_song_list_element() -> Option<Element> {
|
||||
document().get_element_by_id(SONG_LIST_ID)
|
||||
}
|
||||
|
||||
fn scroll_to_top() {
|
||||
if let Ok(elem) = get_song_list_element() {
|
||||
if let Some(elem) = get_song_list_element() {
|
||||
elem.scroll_to_with_x_and_y(0.0, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_scroll() -> anyhow::Result<(i32, i32)> {
|
||||
fn get_scroll() -> Option<(i32, i32)> {
|
||||
let list = get_song_list_element()?;
|
||||
let scroll = list.scroll_top();
|
||||
let height = list.client_height();
|
||||
let max = (list.scroll_height() - height).max(0);
|
||||
Ok((scroll, max))
|
||||
Some((scroll, max))
|
||||
}
|
||||
|
||||
@ -1,24 +1,19 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use seed::{log, prelude::fetch};
|
||||
use gloo_console::error;
|
||||
|
||||
use crate::app::{Loading, Msg};
|
||||
use crate::{
|
||||
app::{Loading, Msg},
|
||||
fetch::fetch_list_of,
|
||||
};
|
||||
|
||||
pub type CustomLists = HashMap<String, Loading<HashSet<String>>>;
|
||||
|
||||
pub async fn fetch_custom_song_list_index() -> Option<Msg> {
|
||||
let response = match fetch("/custom/lists").await.and_then(|r| r.check_status()) {
|
||||
let custom_lists: Vec<String> = match fetch_list_of("/custom/lists").await {
|
||||
Ok(response) => response,
|
||||
Err(e) => {
|
||||
log!("error fetching custom song list index", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let custom_lists: Vec<String> = match response.json().await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log!("error parsing custom song list index", e);
|
||||
error!("Failed fetching custom song list index:", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
@ -27,21 +22,10 @@ pub async fn fetch_custom_song_list_index() -> Option<Msg> {
|
||||
}
|
||||
|
||||
pub async fn fetch_custom_song_list(list: String) -> Option<Msg> {
|
||||
let response = match fetch(format!("/custom/list/{list}"))
|
||||
.await
|
||||
.and_then(|r| r.check_status())
|
||||
{
|
||||
Ok(response) => response,
|
||||
let song_hashes: HashSet<String> = match fetch_list_of(format!("/custom/list/{list}")).await {
|
||||
Ok(response) => response.into_iter().collect(),
|
||||
Err(e) => {
|
||||
log!("error fetching custom song list", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let song_hashes: HashSet<String> = match response.json().await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
log!("error parsing custom song list", e);
|
||||
error!("Failed fetching custom song list:", e);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
70
src/fetch.rs
Normal file
70
src/fetch.rs
Normal file
@ -0,0 +1,70 @@
|
||||
use std::io::Cursor;
|
||||
|
||||
use gloo_net::http::{Request, Response};
|
||||
use serde::de::DeserializeOwned;
|
||||
use wasm_bindgen::{JsError, JsValue};
|
||||
|
||||
const HTTP_ACCEPT: &str = concat!("text/csv, ", "application/json;q=0.9");
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum FetchError {
|
||||
/// The request returned a non-2XX status code.
|
||||
#[error("server responded with {code} {text}")]
|
||||
Status { code: u16, text: String },
|
||||
|
||||
/// The response contained an unrecognized or missing content type.
|
||||
#[error("unknown content type {0:?}")]
|
||||
UnknownContentType(Option<String>),
|
||||
|
||||
/// Another error occured.
|
||||
#[error("{0}")]
|
||||
Other(#[from] gloo_net::Error),
|
||||
|
||||
#[error("error deserializing csv: {0}")]
|
||||
Csv(#[from] csv::Error),
|
||||
}
|
||||
|
||||
impl From<FetchError> for JsValue {
|
||||
fn from(e: FetchError) -> Self {
|
||||
JsError::new(&e.to_string()).into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform a GET request.
|
||||
pub async fn fetch(url: impl AsRef<str>) -> Result<Response, FetchError> {
|
||||
let response = Request::get(url.as_ref())
|
||||
.header("accept", HTTP_ACCEPT)
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
if !response.ok() {
|
||||
return Err(FetchError::Status {
|
||||
code: response.status(),
|
||||
text: response.status_text(),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
/// Perform a GET request and try to deserialize the response as a `Vec<T>`.
|
||||
pub async fn fetch_list_of<T: DeserializeOwned>(
|
||||
url: impl AsRef<str>,
|
||||
) -> Result<Vec<T>, FetchError> {
|
||||
let response = fetch(url.as_ref()).await?;
|
||||
let headers = response.headers();
|
||||
let content_type = headers.get("Content-Type").map(|s| s.to_lowercase());
|
||||
|
||||
match content_type.as_deref() {
|
||||
Some("text/csv") => {
|
||||
let text = response.text().await?;
|
||||
let reader = csv::Reader::from_reader(Cursor::new(text)).into_deserialize();
|
||||
let list = reader
|
||||
.map(|r| r.map_err(FetchError::from))
|
||||
.collect::<Result<_, _>>()?;
|
||||
Ok(list)
|
||||
}
|
||||
Some("application/json") => Ok(response.json().await?),
|
||||
_ => Err(FetchError::UnknownContentType(content_type)),
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
mod app;
|
||||
mod css;
|
||||
mod custom_list;
|
||||
mod fetch;
|
||||
mod fuzzy;
|
||||
mod query;
|
||||
mod song;
|
||||
|
||||
Reference in New Issue
Block a user