diff --git a/src/blog.rs b/src/blog.rs index 3a5bbd1..86d013d 100644 --- a/src/blog.rs +++ b/src/blog.rs @@ -9,10 +9,10 @@ use crate::utils::*; use js_sys::{JsString, RegExp}; use pulldown_cmark::*; use serde::{Serialize, Deserialize}; -use std::future::Future; use std::vec::Vec; use wasm_bindgen::JsCast; use wasm_bindgen::closure::Closure; +use wasm_bindgen_futures::spawn_local; // A list of the UUIDs of all published blog posts // This should be SORTED with the newest posts at lower indices (closer to 0) @@ -215,16 +215,25 @@ impl PostContentCache { Some(cache) } - async fn transform_tag<'a>(tag: &mut Tag<'a>) { + fn transform_tag<'a>(tag: &mut Tag<'a>) { match tag { Tag::Image(_, url, _) => { // Convert all external image to our cached URL // to protect users and speed up page loading let url_encoded: String = js_sys::encode_uri_component(url).into(); // Also write this URL to whitelist + // (just throw the task onto the JS ev loop, + // because to make this function async we MUST need to + // allocate Vec later in the render function) // we don't care about if this write succeeds or not, // because even if it breaks we still can recover by a simple refresh - let _ = store::put_str(&Self::url_to_cache_whitelist_key(url), "Y").await; + // and once it's written, it's permanent, so we expect the write + // to succeed as soon as the article is submitted + let url_cache_key = Self::url_to_cache_whitelist_key(url); + spawn_local(async move { + let _ = store::put_str(&url_cache_key, "Y").await; + () + }); // Now we can overwrite the tag URL *url = format!("{}{}", IMG_CACHE_PREFIX, url_encoded).into(); }, @@ -233,17 +242,15 @@ impl PostContentCache { } fn transform_tags<'ev>( - parser: impl 'ev + Iterator> - ) -> impl 'ev + Iterator>> { + parser: impl Iterator> + ) -> impl Iterator> { parser.map(|mut ev| { - async { - match ev { - Event::Start(ref mut tag) | Event::End(ref mut tag) => { - Self::transform_tag(tag).await; - ev - }, - _ => ev - } + match ev { + Event::Start(ref mut tag) | Event::End(ref mut tag) => { + Self::transform_tag(tag); + ev + }, + _ => ev } }) } @@ -329,17 +336,11 @@ impl PostContentCache { let parser = Parser::new_ext(&post.content, Options::all()); // Apply code highlighting via Highlight.js let parser = Self::transform_code_block_highlight(parser); - // Apply async tag transform (resulting in an iterator of Futures) + // Apply tag transform let parser = Self::transform_tags(parser); - // Await on every Future in the queue to convert them back as Events - let mut events: Vec = vec![]; - for ev in parser { - events.push(ev.await); - } - let mut html_output = String::new(); - html::push_html(&mut html_output, events.into_iter()); + html::push_html(&mut html_output, parser); html_output = Self::transform_html(html_output); PostContentCache { uuid: post.uuid.clone(),