web & server: plumb debugging info for content type hierarchy.

Also cleanup Email trait.
This commit is contained in:
2023-11-27 13:47:02 -08:00
parent 87dfe4ace7
commit 48466808d3
4 changed files with 128 additions and 43 deletions

View File

@@ -159,6 +159,22 @@
"ofType": null
}
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "contentTree",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
}
],
"inputFields": null,
@@ -400,6 +416,22 @@
"ofType": null
}
}
},
{
"args": [],
"deprecationReason": null,
"description": null,
"isDeprecated": false,
"name": "contentTree",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
}
}
],
"inputFields": null,

View File

@@ -23,9 +23,11 @@ query ShowThreadQuery($threadId: String!) {
}
... on PlainText {
contents
contentTree
}
... on Html {
contents
contentTree
}
}
path

View File

@@ -985,58 +985,57 @@ fn view_search_pager_legacy(start: usize, count: usize, total: usize) -> Node<Ms
}
trait Email {
fn name(&self) -> &Option<String>;
fn addr(&self) -> &Option<String>;
fn name(&self) -> Option<&str>;
fn addr(&self) -> Option<&str>;
}
impl<T: Email> Email for &'_ T {
fn name(&self) -> &Option<String> {
fn name(&self) -> Option<&str> {
return (*self).name();
}
fn addr(&self) -> &Option<String> {
fn addr(&self) -> Option<&str> {
return (*self).addr();
}
}
impl Email for ShowThreadQueryThreadMessagesCc {
fn name(&self) -> &Option<String> {
return &self.name;
fn name(&self) -> Option<&str> {
self.name.as_deref()
}
fn addr(&self) -> &Option<String> {
return &self.addr;
fn addr(&self) -> Option<&str> {
self.addr.as_deref()
}
}
impl Email for ShowThreadQueryThreadMessagesFrom {
fn name(&self) -> &Option<String> {
return &self.name;
fn name(&self) -> Option<&str> {
self.name.as_deref()
}
fn addr(&self) -> &Option<String> {
return &self.addr;
fn addr(&self) -> Option<&str> {
self.addr.as_deref()
}
}
impl Email for ShowThreadQueryThreadMessagesTo {
fn name(&self) -> &Option<String> {
return &self.name;
fn name(&self) -> Option<&str> {
self.name.as_deref()
}
fn addr(&self) -> &Option<String> {
return &self.addr;
fn addr(&self) -> Option<&str> {
self.addr.as_deref()
}
}
fn view_addresses<E: Email>(addrs: &[E]) -> Vec<Node<Msg>> {
addrs
.into_iter()
.map(|address| {
span![
C!["tag", "is-black"],
address.addr().as_ref().map(|a| attrs! {At::Title=>a}),
address
.name()
.as_ref()
.unwrap_or(address.addr().as_ref().unwrap_or(&"(UNKNOWN)".to_string()))
]
})
.collect::<Vec<_>>()
fn view_address(email: impl Email) -> Node<Msg> {
span![
C!["tag", "is-black"],
email.addr().as_ref().map(|a| attrs! {At::Title=>a}),
email
.name()
.as_ref()
.unwrap_or(&email.addr().unwrap_or("(UNKNOWN)"))
]
}
fn view_addresses(addrs: &[impl Email]) -> Vec<Node<Msg>> {
addrs.into_iter().map(view_address).collect::<Vec<_>>()
}
fn view_thread(thread: &ShowThreadQueryThread) -> Node<Msg> {
@@ -1061,11 +1060,21 @@ fn view_thread(thread: &ShowThreadQueryThread) -> Node<Msg> {
ShowThreadQueryThreadMessagesBodyOnUnhandledContentType { contents },
) => pre![C!["error"], contents],
ShowThreadQueryThreadMessagesBody::PlainText(
ShowThreadQueryThreadMessagesBodyOnPlainText { contents },
) => div![C!["view-part-text-plain"], contents],
ShowThreadQueryThreadMessagesBodyOnPlainText {
contents,
content_tree,
},
) => div![C!["view-part-text-plain"], contents, pre![content_tree]],
ShowThreadQueryThreadMessagesBody::Html(
ShowThreadQueryThreadMessagesBodyOnHtml { contents },
) => div![C!["view-part-text-html"], raw![contents]],
ShowThreadQueryThreadMessagesBodyOnHtml {
contents,
content_tree,
},
) => div![
C!["view-part-text-html"],
raw![contents],
pre![content_tree]
],
}
],
]