| 23 |
23 |
|
//! - `GET /emails` — the list, under `?folder=`, `?label=`, `?archived=`,
|
| 24 |
24 |
|
//! `?shown=`.
|
| 25 |
25 |
|
//! - `GET /emails/list` — the list alone, which is what a filter swaps.
|
|
26 |
+ |
//! - `POST /emails/read-all` — every message read, whatever the view.
|
| 26 |
27 |
|
//! - `GET /emails/{id}` — the thread, read.
|
| 27 |
28 |
|
//! - `POST /emails/{id}/read` — read or unread, under `read`.
|
| 28 |
29 |
|
//! - `POST /emails/{id}/archive` — archive or unarchive, under `on`.
|
| 52 |
53 |
|
//! Sharing hit on the settings screen.
|
| 53 |
54 |
|
//! - **Search.** `search.js` is its own screen and its own port. The box on this
|
| 54 |
55 |
|
//! screen calls into it.
|
| 55 |
|
- |
//!
|
| 56 |
|
- |
//! One omission is not ours: `mark_all_emails_read` is a command with a
|
| 57 |
|
- |
//! `GoingsOn.emails.markAllRead` binding and **no control anywhere in the
|
| 58 |
|
- |
//! markup**. Nothing described here reaches it because nothing shipped reaches
|
| 59 |
|
- |
//! it either. Recorded rather than quietly given a button, which would make the
|
| 60 |
|
- |
//! described screen offer something the screen it stands in for does not.
|
| 61 |
56 |
|
|
| 62 |
57 |
|
// Handlers take their request by value because `quasi_router::Handler` is a
|
| 63 |
58 |
|
// plain `fn(&S, Request)` pointer, so the signature is the router's and not a
|
| 543 |
538 |
|
]));
|
| 544 |
539 |
|
}
|
| 545 |
540 |
|
band = band.extend(filters(state, view)?);
|
|
541 |
+ |
// Offered whatever the count says, which is what the filter row does. The
|
|
542 |
+ |
// gate the rest of this file applies — say it rather than offer it when the
|
|
543 |
+ |
// control leads nowhere — does not catch here: marking an already-read
|
|
544 |
+ |
// mailbox read is a write that succeeds and changes nothing, not a button
|
|
545 |
+ |
// that calls something the described screen cannot reach.
|
|
546 |
+ |
band = band.with(Node::act(
|
|
547 |
+ |
"Mark all read",
|
|
548 |
+ |
view.carry(Action::post("/emails/read-all")),
|
|
549 |
+ |
));
|
| 546 |
550 |
|
|
| 547 |
551 |
|
let thread_pane = match open {
|
| 548 |
552 |
|
Some(id) => thread_slot(state, id, view)?,
|
| 890 |
894 |
|
wrote(state, &view, read.then_some(id))
|
| 891 |
895 |
|
}
|
| 892 |
896 |
|
|
|
897 |
+ |
/// Every message read, whatever is being looked at.
|
|
898 |
+ |
///
|
|
899 |
+ |
/// The one write on this screen that ignores the view it was sent from.
|
|
900 |
+ |
/// `mark_all_read` takes a user and nothing else, and the shipped control is the
|
|
901 |
+ |
/// same: `emails.js:markAllRead` calls the command and then clears unread across
|
|
902 |
+ |
/// the streamed threads without consulting a filter. Reading only the filtered
|
|
903 |
+ |
/// set would be a different feature, and inventing it here would make the
|
|
904 |
+ |
/// described screen do something the screen it stands in for does not. The view
|
|
905 |
+ |
/// is still carried, because the answer is the same page the user was on.
|
|
906 |
+ |
fn read_all(state: &AppState, request: quasi_router::Request) -> Result<Response, RouteError> {
|
|
907 |
+ |
let view = View::of(&request);
|
|
908 |
+ |
let marked = state
|
|
909 |
+ |
.emails
|
|
910 |
+ |
.mark_all_read(DESKTOP_USER_ID)
|
|
911 |
+ |
.map_err(|error| RouteError::internal(error.to_string()))?;
|
|
912 |
+ |
|
|
913 |
+ |
// The count, because it is the only thing that distinguishes a mailbox that
|
|
914 |
+ |
// had unread mail from one that did not. The JS says "All emails marked as
|
|
915 |
+ |
// read!" either way, which tells a user who clicked it twice nothing.
|
|
916 |
+ |
Ok(wrote(state, &view, None)?.toast(
|
|
917 |
+ |
makeover_layout::Tone::Success,
|
|
918 |
+ |
match marked {
|
|
919 |
+ |
0 => "Nothing was unread".to_owned(),
|
|
920 |
+ |
1 => "1 email marked read".to_owned(),
|
|
921 |
+ |
many => format!("{many} emails marked read"),
|
|
922 |
+ |
},
|
|
923 |
+ |
))
|
|
924 |
+ |
}
|
|
925 |
+ |
|
| 893 |
926 |
|
/// Archive, or bring it back.
|
| 894 |
927 |
|
///
|
| 895 |
928 |
|
/// # The fifth finding
|
| 1162 |
1195 |
|
// not have to know that to be sure `list` never arrives as an id.
|
| 1163 |
1196 |
|
.get("/emails/list", list_only)
|
| 1164 |
1197 |
|
.get("/emails", index)
|
|
1198 |
+ |
.post("/emails/read-all", read_all)
|
| 1165 |
1199 |
|
.get("/emails/{id}", thread)
|
| 1166 |
1200 |
|
.post("/emails/{id}/read", set_read)
|
| 1167 |
1201 |
|
.post("/emails/{id}/archive", set_archived)
|