Implement searching based on URL state.
This commit is contained in:
parent
576973c6e6
commit
de2b79fa2a
@ -16,9 +16,13 @@
|
||||
.error {
|
||||
background-color: red;
|
||||
}
|
||||
.text_plain {
|
||||
.view-part-text-plain {
|
||||
white-space: pre-line;
|
||||
}
|
||||
iframe {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
||||
112
web/src/lib.rs
112
web/src/lib.rs
@ -3,8 +3,8 @@
|
||||
// but some rules are too "annoying" or are not applicable for your case.)
|
||||
#![allow(clippy::wildcard_imports)]
|
||||
|
||||
use log::{debug, error, info, Level};
|
||||
use notmuch::{Content, Part, SearchSummary, ThreadNode, ThreadSet};
|
||||
use log::{debug, error, info, warn, Level};
|
||||
use notmuch::{Content, Part, SearchSummary, Thread, ThreadNode, ThreadSet};
|
||||
use seed::{prelude::*, *};
|
||||
|
||||
// ------ ------
|
||||
@ -13,14 +13,34 @@ use seed::{prelude::*, *};
|
||||
|
||||
// `init` describes what should happen when your app started.
|
||||
fn init(url: Url, orders: &mut impl Orders<Msg>) -> Model {
|
||||
warn!("init called");
|
||||
log!(url);
|
||||
orders.subscribe(|_: subs::UrlChanged| info!("url changed!"));
|
||||
orders
|
||||
.skip()
|
||||
.perform_cmd(async { Msg::SearchResult(search_request("*").await) });
|
||||
let mut url = url.clone();
|
||||
let mut query = "".to_string();
|
||||
let hpp = url.next_hash_path_part();
|
||||
log!(hpp);
|
||||
match hpp {
|
||||
Some("t") => {
|
||||
let tid = url.next_hash_path_part().unwrap_or("").to_string();
|
||||
orders.send_msg(Msg::ShowRequest(tid));
|
||||
}
|
||||
Some("s") => {
|
||||
query = url.next_hash_path_part().unwrap_or("").to_string();
|
||||
orders.send_msg(Msg::SearchRequest(query.clone()));
|
||||
}
|
||||
p => {
|
||||
log!(p);
|
||||
orders.send_msg(Msg::SearchRequest("".to_string()));
|
||||
}
|
||||
};
|
||||
orders.subscribe(|uc: subs::UrlChanged| {
|
||||
info!("uc {:#?}", uc);
|
||||
});
|
||||
|
||||
info!("init query '{}'", query);
|
||||
Model {
|
||||
context: Context::None,
|
||||
query: "".to_string(),
|
||||
query,
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,32 +77,34 @@ enum Msg {
|
||||
fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
match msg {
|
||||
Msg::Noop => {}
|
||||
|
||||
Msg::SearchRequest(query) => {
|
||||
model.query = query.clone();
|
||||
let url = Url::new().set_hash_path(["s", &query]);
|
||||
orders.request_url(url);
|
||||
orders
|
||||
.skip()
|
||||
.perform_cmd(async move { Msg::SearchResult(search_request(&query).await) });
|
||||
}
|
||||
|
||||
Msg::SearchResult(Ok(response_data)) => {
|
||||
debug!("fetch ok {:#?}", response_data);
|
||||
model.context = Context::Search(response_data);
|
||||
}
|
||||
|
||||
Msg::SearchResult(Err(fetch_error)) => {
|
||||
error!("fetch failed {:?}", fetch_error);
|
||||
}
|
||||
Msg::ShowRequest(query) => {
|
||||
|
||||
Msg::ShowRequest(tid) => {
|
||||
let url = Url::new().set_hash_path(["t", &tid]);
|
||||
orders.request_url(url);
|
||||
orders
|
||||
.skip()
|
||||
.perform_cmd(async move { Msg::ShowResult(show_request(&query).await) });
|
||||
.perform_cmd(async move { Msg::ShowResult(show_request(&tid).await) });
|
||||
}
|
||||
|
||||
Msg::ShowResult(Ok(response_data)) => {
|
||||
debug!("fetch ok {:#?}", response_data);
|
||||
model.context = Context::Thread(response_data);
|
||||
}
|
||||
|
||||
Msg::ShowResult(Err(fetch_error)) => {
|
||||
error!("fetch failed {:?}", fetch_error);
|
||||
}
|
||||
@ -90,6 +112,7 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
|
||||
}
|
||||
|
||||
async fn search_request(query: &str) -> fetch::Result<SearchSummary> {
|
||||
info!("making search request for '{}'", query);
|
||||
Request::new(api::search(query))
|
||||
.method(Method::Get)
|
||||
.fetch()
|
||||
@ -100,20 +123,20 @@ async fn search_request(query: &str) -> fetch::Result<SearchSummary> {
|
||||
}
|
||||
|
||||
mod api {
|
||||
const BASE_URL: &str = "http://nixos-07:9345";
|
||||
const BASE_URL: &str = "/api";
|
||||
pub fn search(query: &str) -> String {
|
||||
format!("{}/search/{}", BASE_URL, query)
|
||||
}
|
||||
pub fn show(query: &str) -> String {
|
||||
format!("{}/show/{}", BASE_URL, query)
|
||||
pub fn show(tid: &str) -> String {
|
||||
format!("{}/show/{}", BASE_URL, tid)
|
||||
}
|
||||
pub fn original(message_id: &str) -> String {
|
||||
format!("{}/original/{}", BASE_URL, message_id)
|
||||
}
|
||||
}
|
||||
|
||||
async fn show_request(query: &str) -> fetch::Result<ThreadSet> {
|
||||
Request::new(api::show(query))
|
||||
async fn show_request(tid: &str) -> fetch::Result<ThreadSet> {
|
||||
Request::new(api::show(tid))
|
||||
.method(Method::Get)
|
||||
.fetch()
|
||||
.await?
|
||||
@ -180,11 +203,7 @@ fn view_part(part: &Part) -> Node<Msg> {
|
||||
"text/plain" => view_text_plain(&part.content),
|
||||
"text/html" => {
|
||||
if let Some(Content::String(html)) = &part.content {
|
||||
return div![
|
||||
C!["view-part-text-html"],
|
||||
div!["TEST"],
|
||||
iframe![Node::from_html(None, &html)]
|
||||
];
|
||||
return div![C!["view-part-text-html"], div!["TEST"], raw![&html]];
|
||||
} else {
|
||||
div![
|
||||
C!["error"],
|
||||
@ -244,10 +263,12 @@ fn first_subject(thread: &ThreadNode) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
fn view_search_results(search_results: &SearchSummary) -> Node<Msg> {
|
||||
fn view_search_results(query: &str, search_results: &SearchSummary) -> Node<Msg> {
|
||||
seed::document().set_title(&format!("lb: {}", query));
|
||||
let rows = search_results.0.iter().map(|r| {
|
||||
let tid = r.thread.clone();
|
||||
tr![
|
||||
td![],
|
||||
td![
|
||||
&r.authors,
|
||||
IF!(r.total>1 => small![" ", r.total.to_string()]),
|
||||
@ -258,7 +279,10 @@ fn view_search_results(search_results: &SearchSummary) -> Node<Msg> {
|
||||
ev(Ev::Click, move |_| Msg::ShowRequest(tid)),
|
||||
]
|
||||
});
|
||||
div![table![tr![th!["From"], th!["Subject"], th!["Date"]], rows]]
|
||||
div![table![
|
||||
tr![th!["tid"], th!["From"], th!["Subject"], th!["Date"]],
|
||||
rows
|
||||
]]
|
||||
}
|
||||
|
||||
fn view_thread(thread_set: &ThreadSet) -> Node<Msg> {
|
||||
@ -266,14 +290,46 @@ fn view_thread(thread_set: &ThreadSet) -> Node<Msg> {
|
||||
let thread = &thread_set.0[0];
|
||||
assert_eq!(thread.0.len(), 1);
|
||||
let thread_node = &thread.0[0];
|
||||
let subject = first_subject(&thread_node).unwrap_or("<No subject>".to_string());
|
||||
seed::document().set_title(&subject);
|
||||
div![
|
||||
h1![first_subject(&thread_node)],
|
||||
h1![subject],
|
||||
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(" ", " ")] */
|
||||
pre![
|
||||
"Add zippy for debug dump",
|
||||
view_debug_thread_set(thread_set)
|
||||
] /* pre![format!("Thread: {:#?}", thread_set).replace(" ", " ")] */
|
||||
]
|
||||
}
|
||||
|
||||
fn view_debug_thread_set(thread_set: &ThreadSet) -> Node<Msg> {
|
||||
ul![thread_set
|
||||
.0
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, t)| { li!["t", i, ": ", view_debug_thread(t),] })]
|
||||
}
|
||||
fn view_debug_thread(thread: &Thread) -> Node<Msg> {
|
||||
ul![thread
|
||||
.0
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, tn)| { li!["tn", i, ": ", view_debug_thread_node(tn),] })]
|
||||
}
|
||||
|
||||
fn view_debug_thread_node(thread_node: &ThreadNode) -> Node<Msg> {
|
||||
ul![
|
||||
IF!(thread_node.0.is_some()=>li!["tn id:", &thread_node.0.as_ref().unwrap().id]),
|
||||
thread_node.1.iter().enumerate().map(|(i, tn)| li![
|
||||
"tn",
|
||||
i,
|
||||
": ",
|
||||
view_debug_thread_node(tn)
|
||||
])
|
||||
]
|
||||
}
|
||||
|
||||
@ -307,7 +363,7 @@ 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),
|
||||
Context::Search(search_results) => view_search_results(&model.query, search_results),
|
||||
};
|
||||
div![view_header(&model.query), content]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user