Refactor model into a single context enum.

This commit is contained in:
Bill Thiede 2022-11-17 18:56:00 -08:00
parent ce3c027e9a
commit b008cadecd

View File

@ -19,8 +19,7 @@ fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
.skip() .skip()
.perform_cmd(async { Msg::SearchResult(search_request("*").await) }); .perform_cmd(async { Msg::SearchResult(search_request("*").await) });
Model { Model {
search_results: None, context: Context::None,
show_results: None,
query: "".to_string(), query: "".to_string(),
} }
} }
@ -28,12 +27,16 @@ fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
// ------ ------ // ------ ------
// Model // Model
// ------ ------ // ------ ------
enum Context {
None,
Search(SearchSummary),
Thread(ThreadSet),
}
// `Model` describes our app state. // `Model` describes our app state.
struct Model { struct Model {
search_results: Option<SearchSummary>,
show_results: Option<ThreadSet>,
query: String, query: String,
context: Context,
} }
// ------ ------ // ------ ------
@ -55,7 +58,6 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
match msg { match msg {
Msg::Noop => {} Msg::Noop => {}
Msg::SearchRequest(query) => { Msg::SearchRequest(query) => {
model.show_results = None;
model.query = query.clone(); model.query = query.clone();
orders orders
.skip() .skip()
@ -64,14 +66,13 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
Msg::SearchResult(Ok(response_data)) => { Msg::SearchResult(Ok(response_data)) => {
debug!("fetch 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)) => { Msg::SearchResult(Err(fetch_error)) => {
error!("fetch failed {:?}", fetch_error); error!("fetch failed {:?}", fetch_error);
} }
Msg::ShowRequest(query) => { Msg::ShowRequest(query) => {
model.show_results = None;
orders orders
.skip() .skip()
.perform_cmd(async move { Msg::ShowResult(show_request(&query).await) }); .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>) {
Msg::ShowResult(Ok(response_data)) => { Msg::ShowResult(Ok(response_data)) => {
debug!("fetch 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)) => { Msg::ShowResult(Err(fetch_error)) => {
@ -242,76 +243,42 @@ fn first_subject(thread: &ThreadNode) -> Option<String> {
} }
None 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_search_results(search_results: &SearchSummary) -> Node<Msg> {
fn view(model: &Model) -> Node<Msg> { let rows = search_results.0.iter().map(|r| {
let content = if let Some(show_results) = &model.show_results { let tid = r.thread.clone();
assert_eq!(show_results.0.len(), 1); tr![
let thread = &show_results.0[0]; td![
assert_eq!(thread.0.len(), 1); &r.authors,
let thread_node = &thread.0[0]; IF!(r.total>1 => small![" ", r.total.to_string()]),
div![ IF!(r.tags.contains(&"attachment".to_string()) => "📎"),
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), td![&r.subject],
pre!["Add zippy for debug dump"] /* pre![format!("Thread: {:#?}", show_results).replace(" ", " ")] */ 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| { div![table![tr![th!["From"], th!["Subject"], th!["Date"]], rows]]
let tid = r.thread.clone(); }
tr![
td![ fn view_thread(thread_set: &ThreadSet) -> Node<Msg> {
&r.authors, assert_eq!(thread_set.0.len(), 1);
IF!(r.total>1 => small![" ", r.total.to_string()]), let thread = &thread_set.0[0];
IF!(r.tags.contains(&"attachment".to_string()) => "📎"), assert_eq!(thread.0.len(), 1);
], let thread_node = &thread.0[0];
td![&r.subject], div![
td![&r.date_relative], h1![first_subject(&thread_node)],
ev(Ev::Click, move |_| Msg::ShowRequest(tid)), a![
] attrs! {At::Href=>api::original(&thread_node.0.as_ref().expect("message missing").id)},
}); "Original"
div![table![tr![th!["From"], th!["Subject"], th!["Date"]], rows]] ],
} else { view_message(&thread_node),
div![h1!["Loading"]] pre!["Add zippy for debug dump"] /* pre![format!("Thread: {:#?}", thread_set).replace(" ", " ")] */
}; ]
let query = model.query.clone(); }
fn view_header(query: &str) -> Node<Msg> {
let query = query.to_string();
div![ div![
button![ button![
"Unread", "Unread",
@ -326,16 +293,25 @@ fn view(model: &Model) -> Node<Msg> {
}, },
input_ev(Ev::Input, Msg::SearchRequest), input_ev(Ev::Input, Msg::SearchRequest),
// Resend search on enter. // 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) Msg::SearchRequest(query)
} else { } else {
Msg::Noop Msg::Noop
}), }),
], ],
content
] ]
} }
// `view` describes what to display.
fn view(model: &Model) -> Node<Msg> {
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 // Start
// ------ ------ // ------ ------