From b008cadecd8e68269610cd8acb64ad63f47e42a7 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Thu, 17 Nov 2022 18:56:00 -0800 Subject: [PATCH] Refactor model into a single context enum. --- web/src/lib.rs | 130 ++++++++++++++++++++----------------------------- 1 file changed, 53 insertions(+), 77 deletions(-) diff --git a/web/src/lib.rs b/web/src/lib.rs index cb2022f..b8d0ede 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -19,8 +19,7 @@ fn init(url: Url, orders: &mut impl Orders) -> Model { .skip() .perform_cmd(async { Msg::SearchResult(search_request("*").await) }); Model { - search_results: None, - show_results: None, + context: Context::None, query: "".to_string(), } } @@ -28,12 +27,16 @@ fn init(url: Url, orders: &mut impl Orders) -> Model { // ------ ------ // Model // ------ ------ +enum Context { + None, + Search(SearchSummary), + Thread(ThreadSet), +} // `Model` describes our app state. struct Model { - search_results: Option, - show_results: Option, query: String, + context: Context, } // ------ ------ @@ -55,7 +58,6 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders) { match msg { Msg::Noop => {} Msg::SearchRequest(query) => { - model.show_results = None; model.query = query.clone(); orders .skip() @@ -64,14 +66,13 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders) { Msg::SearchResult(Ok(response_data)) => { debug!("fetch ok {:#?}", response_data); - model.search_results = Some(response_data); + model.context = Context::Search(response_data); } Msg::SearchResult(Err(fetch_error)) => { error!("fetch failed {:?}", fetch_error); } Msg::ShowRequest(query) => { - model.show_results = None; orders .skip() .perform_cmd(async move { Msg::ShowResult(show_request(&query).await) }); @@ -79,7 +80,7 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders) { Msg::ShowResult(Ok(response_data)) => { debug!("fetch ok {:#?}", response_data); - model.show_results = Some(response_data); + model.context = Context::Thread(response_data); } Msg::ShowResult(Err(fetch_error)) => { @@ -242,76 +243,42 @@ fn first_subject(thread: &ThreadNode) -> Option { } None } -/* -let msg = thread.0.as_ref(); -if let Some(msg) = msg { -div![ -a![attrs! {At::Href=>api::original(&msg.id)}, "Original"], -table![ -tr![th!["Subject"], td![&msg.headers.subject],], -tr![th!["From"], td![&msg.headers.from],], -tr![th!["To"], td![&msg.headers.to],], -tr![th!["CC"], td![&msg.headers.cc],], -tr![th!["BCC"], td![&msg.headers.bcc],], -tr![th!["Reply-To"], td![&msg.headers.reply_to],], -tr![th!["Date"], td![&msg.headers.date],], -], -table![ -tr![th!["MessageId"], td![&msg.id],], -tr![ -th!["Match"], -td![if msg.r#match { "true" } else { "false" }], -], -tr![ -th!["Excluded"], -td![if msg.excluded { "true" } else { "false" }], -], -tr![th!["Filename"], td![&msg.filename],], -tr![th!["Timestamp"], td![msg.timestamp.to_string()],], -tr![th!["Date"], td![&msg.date_relative],], -tr![th!["Tags"], td![format!("{:?}", msg.tags)],], -], -] -} else { -div![h2!["No message"]] -} -*/ -// `view` describes what to display. -fn view(model: &Model) -> Node { - let content = if let Some(show_results) = &model.show_results { - assert_eq!(show_results.0.len(), 1); - let thread = &show_results.0[0]; - assert_eq!(thread.0.len(), 1); - let thread_node = &thread.0[0]; - div![ - h1![first_subject(&thread_node)], - a![ - attrs! {At::Href=>api::original(&thread_node.0.as_ref().expect("message missing").id)}, - "Original" +fn view_search_results(search_results: &SearchSummary) -> Node { + let rows = search_results.0.iter().map(|r| { + let tid = r.thread.clone(); + tr![ + td![ + &r.authors, + IF!(r.total>1 => small![" ", r.total.to_string()]), + IF!(r.tags.contains(&"attachment".to_string()) => "📎"), ], - view_message(&thread_node), - pre!["Add zippy for debug dump"] /* pre![format!("Thread: {:#?}", show_results).replace(" ", " ")] */ + td![&r.subject], + td![&r.date_relative], + ev(Ev::Click, move |_| Msg::ShowRequest(tid)), ] - } else if let Some(search_results) = &model.search_results { - let rows = search_results.0.iter().map(|r| { - let tid = r.thread.clone(); - tr![ - td![ - &r.authors, - IF!(r.total>1 => small![" ", r.total.to_string()]), - IF!(r.tags.contains(&"attachment".to_string()) => "📎"), - ], - td![&r.subject], - td![&r.date_relative], - ev(Ev::Click, move |_| Msg::ShowRequest(tid)), - ] - }); - div![table![tr![th!["From"], th!["Subject"], th!["Date"]], rows]] - } else { - div![h1!["Loading"]] - }; - let query = model.query.clone(); + }); + div![table![tr![th!["From"], th!["Subject"], th!["Date"]], rows]] +} + +fn view_thread(thread_set: &ThreadSet) -> Node { + assert_eq!(thread_set.0.len(), 1); + let thread = &thread_set.0[0]; + assert_eq!(thread.0.len(), 1); + let thread_node = &thread.0[0]; + div![ + h1![first_subject(&thread_node)], + a![ + attrs! {At::Href=>api::original(&thread_node.0.as_ref().expect("message missing").id)}, + "Original" + ], + view_message(&thread_node), + pre!["Add zippy for debug dump"] /* pre![format!("Thread: {:#?}", thread_set).replace(" ", " ")] */ + ] +} + +fn view_header(query: &str) -> Node { + let query = query.to_string(); div![ button![ "Unread", @@ -326,16 +293,25 @@ fn view(model: &Model) -> Node { }, input_ev(Ev::Input, Msg::SearchRequest), // Resend search on enter. - keyboard_ev(Ev::KeyUp, |e| if e.key_code() == 0x0d { + keyboard_ev(Ev::KeyUp, move |e| if e.key_code() == 0x0d { Msg::SearchRequest(query) } else { Msg::Noop }), ], - content ] } +// `view` describes what to display. +fn view(model: &Model) -> Node { + let content = match &model.context { + Context::None => div![h1!["Loading"]], + Context::Thread(thread_set) => view_thread(thread_set), + Context::Search(search_results) => view_search_results(search_results), + }; + div![view_header(&model.query), content] +} + // ------ ------ // Start // ------ ------