Mail · Reading: a message reader, a conversation, and quoted text
MailReader opens a message under its subject: the sender's picture, name and address, who it went to, when it came, and Reply, Reply all when it went to more than one, and Forward, each only with a handler; then its words and its files, each downloadable. MailThreadView lays a conversation oldest first: the newest stands open, the others fold to a line of the sender, their first words and when, which a press, Enter or Space opens. QuotedText folds words quoted from before behind a small mark; open, they sit behind a rule. Long names give way at the label width. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0a281d91ab
commit
f946af6216
12 files changed
+920
-4
No files matched your search
@@ -8,6 +8,8 @@ use ely_gpui_component::{
|
||||
use gpui::{AnyElement, App, IntoElement, ParentElement, SharedString, Styled, Window, div, px};
|
||||
use jiff::{SignedDuration, Timestamp};
|
||||
|
||||
mod read;
|
||||
|
||||
use super::Page;
|
||||
use crate::{
|
||||
probe::probe,
|
||||
@@ -33,6 +35,14 @@ const SCRIPT: &[Step] = &[
|
||||
Step::UpAt("mail-list", 417.0, 112.0),
|
||||
Step::Wait(200),
|
||||
Step::Shot("starred"),
|
||||
Step::DownAt("mail-reader", 12.0, 227.0),
|
||||
Step::UpAt("mail-reader", 12.0, 227.0),
|
||||
Step::Wait(300),
|
||||
Step::Shot("quoted-open"),
|
||||
Step::DownAt("mail-thread", 200.0, 120.0),
|
||||
Step::UpAt("mail-thread", 200.0, 120.0),
|
||||
Step::Wait(300),
|
||||
Step::Shot("thread-opened"),
|
||||
];
|
||||
|
||||
fn boxes(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
@@ -200,5 +210,7 @@ fn render(window: &mut Window, cx: &mut App) -> AnyElement {
|
||||
.child(boxes(window, cx))
|
||||
.child(list(window, cx))
|
||||
.child(zero(cx))
|
||||
.child(read::reader(cx))
|
||||
.child(read::thread(cx))
|
||||
.into_any_element()
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
use ely_gpui_component::mail::{Contact, MailReader, MailThreadView, Message, QuotedText};
|
||||
use gpui::{App, IntoElement, ParentElement, Styled, div, px};
|
||||
use jiff::{SignedDuration, Timestamp};
|
||||
|
||||
use crate::{probe::probe, ui::section};
|
||||
|
||||
fn ana() -> Contact {
|
||||
Contact::new("Ana Lima", "ana@atrium.studio")
|
||||
}
|
||||
|
||||
fn ben() -> Contact {
|
||||
Contact::new("Ben Ito", "ben@atrium.studio")
|
||||
}
|
||||
|
||||
fn you() -> Contact {
|
||||
Contact::new("You", "you@atrium.studio")
|
||||
}
|
||||
|
||||
fn ago(minutes: i64) -> Timestamp {
|
||||
Timestamp::now() - SignedDuration::from_mins(minutes)
|
||||
}
|
||||
|
||||
fn paragraph(text: &'static str) -> impl IntoElement {
|
||||
div().child(text)
|
||||
}
|
||||
|
||||
pub fn reader(cx: &mut App) -> impl IntoElement + use<> {
|
||||
let message = Message::new("review", ana(), ago(12))
|
||||
.to([you(), ben()])
|
||||
.cc([Contact::new("Dev Rao", "dev@atrium.studio")])
|
||||
.file("atrium-plan.pdf", 2_400_000)
|
||||
.file("stair-hall.jpg", 3_100_000);
|
||||
section(
|
||||
"MailReader / QuotedText",
|
||||
"A message open for reading: the subject, who wrote to whom and when, replies, the words and the files. Words quoted from before fold behind a small mark until pressed.",
|
||||
cx,
|
||||
)
|
||||
.child(probe(
|
||||
"mail-reader",
|
||||
div().w(px(640.)).child(
|
||||
MailReader::new("mail-reader", "Friday's review moves to 10:00", message)
|
||||
.on_reply(|key, _, _| log::info!("gallery: reply {key}"))
|
||||
.on_reply_all(|key, _, _| log::info!("gallery: reply all {key}"))
|
||||
.on_forward(|key, _, _| log::info!("gallery: forward {key}"))
|
||||
.on_download(|key, file, _, _| log::info!("gallery: download {key} {file}"))
|
||||
.child(paragraph("Morning both,"))
|
||||
.child(paragraph(
|
||||
"Friday's review moves to 10:00, in the model room. The client wants to see the stair at the scale we'll build it, so please bring the plaster samples if they've dried.",
|
||||
))
|
||||
.child(paragraph("The plan and a photo of the stair hall are attached. — Ana"))
|
||||
.child(
|
||||
QuotedText::new("mail-quoted")
|
||||
.child(paragraph("On Thursday, Ben Ito wrote:"))
|
||||
.child(paragraph(
|
||||
"The samples are in the stair hall: lime, tadelakt and a sanded gypsum. The tadelakt needs another day.",
|
||||
)),
|
||||
),
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn thread(cx: &mut App) -> impl IntoElement + use<> {
|
||||
let message = |key: &'static str, from: Contact, minutes: i64, snippet: &'static str| {
|
||||
Message::new(key, from, ago(minutes))
|
||||
.to([you()])
|
||||
.snippet(snippet)
|
||||
};
|
||||
section(
|
||||
"MailThreadView",
|
||||
"A conversation, oldest first: the newest stands open, and the others fold to a line of who, their first words and when, which a press, Enter or Space opens.",
|
||||
cx,
|
||||
)
|
||||
.child(probe(
|
||||
"mail-thread",
|
||||
div().w(px(640.)).child(
|
||||
MailThreadView::new("mail-thread", "Plaster samples")
|
||||
.on_reply(|key, _, _| log::info!("gallery: reply {key}"))
|
||||
.on_forward(|key, _, _| log::info!("gallery: forward {key}"))
|
||||
.message(
|
||||
message("s1", ben(), 60 * 30, "Three finishes are in the stair hall: lime, tadelakt and a sanded gypsum."),
|
||||
paragraph("Three finishes are in the stair hall: lime, tadelakt and a sanded gypsum. Leave notes on the backs."),
|
||||
)
|
||||
.message(
|
||||
message("s2", ana(), 60 * 26, "The lime reads warmest by the windows. Can we see it at dusk?"),
|
||||
paragraph("The lime reads warmest by the windows. Can we see it at dusk?"),
|
||||
)
|
||||
.message(
|
||||
message("s3", Contact::new("Chloé Martin", "chloe@atrium.studio"), 60 * 5, "Dusk works. I'll bring the lamp we use for the model."),
|
||||
paragraph("Dusk works. I'll bring the lamp we use for the model."),
|
||||
)
|
||||
.message(
|
||||
message("s4", ben(), 40, "The tadelakt is sealed. All three are ready for Friday."),
|
||||
paragraph("The tadelakt is sealed. All three are ready for Friday."),
|
||||
),
|
||||
),
|
||||
))
|
||||
}
|
||||
Reference in new issue
Block a user