1//! The toasts every open page is shown when something happens elsewhere, 2//! pushed by the archive over `/live`. Pure: what happened in, markup out. 3 4use archive::{Answer, Fetch}; 5use maud::{Markup, html}; 6 7use super::url_encode; 8 9/// Someone asked a question. `shown` is the question and Jev's answers if 10/// the feed may show it; otherwise the toast says only that someone asked. 11/// `data-q` lets the page that asked it skip its own toast. 12pub fn asked(shown: Option<(&str, &[Answer])>) -> Markup { 13 html! { 14 @match shown { 15 Some((input, answers)) => { 16 div .toast data-q=(input) { 17 "Someone asked " 18 a href={ "/?q=" (url_encode(input)) } { "“" (input) "”" } 19 @if !answers.is_empty() { 20 " · Jev: " 21 b { (answers.iter().map(|answer| answer.headline.as_str()).collect::<Vec<_>>().join(" ")) } 22 } 23 } 24 } 25 None => div .toast { "Someone asked Jev something." }, 26 } 27 } 28} 29 30/// What a deploy changed, told to a page from before it. 31pub fn note(note: &str) -> Markup { 32 html! { div .toast .note { b { "New: " } (note) } } 33} 34 35/// Someone cloned or pulled a repository (`lmjtfy.git`): this site's is 36/// "the code", any other is named. 37pub fn fetched(fetch: Fetch, served: &str) -> Markup { 38 let what = match fetch { 39 Fetch::Clone => "cloned", 40 Fetch::Pull => "pulled", 41 }; 42 html! { 43 div .toast { 44 "Someone " (what) " " 45 a href={ "/" (served) } { @if served == "lmjtfy.git" { "the code" } @else { (served) } } 46 "." 47 } 48 } 49} 50 51#[cfg(test)] 52mod tests { 53 use super::*; 54 use archive::Detail; 55 56 #[test] 57 fn an_unlisted_question_is_not_shown() { 58 let html = asked(None).into_string(); 59 assert_eq!(html, r#"<div class="toast">Someone asked Jev something.</div>"#); 60 } 61 62 #[test] 63 fn a_listed_question_is_shown_escaped_with_its_answer() { 64 let answers = [Answer { headline: "No.".into(), detail: Detail::Noul { p_yes: 0.03 } }]; 65 let html = asked(Some(("is <b>this</b> ok?", &answers))).into_string(); 66 assert!(html.contains("<b>this</b>"), "{html}"); 67 assert!(html.contains("<b>No.</b>"), "{html}"); 68 assert!(html.contains(r#"href="/?q=is+%3Cb%3Ethis%3C%2Fb%3E+ok%3F""#), "{html}"); 69 } 70 71 #[test] 72 fn a_release_note_is_text() { 73 assert_eq!(note("a <b> c").into_string(), r#"<div class="toast note"><b>New: </b>a <b> c</div>"#); 74 } 75 76 #[test] 77 fn a_clone_links_to_the_code() { 78 assert!(fetched(Fetch::Pull, "lmjtfy.git").into_string().contains(r#"Someone pulled <a href="/lmjtfy.git">the code</a>."#)); 79 assert!(fetched(Fetch::Clone, "jevsnes.git").into_string().contains(r#"Someone cloned <a href="/jevsnes.git">jevsnes.git</a>."#)); 80 } 81}