From 5cae71653fb3b973e61c61c109e2aac05a463cc1 Mon Sep 17 00:00:00 2001 From: Eli Ribble <eli@theribbles.org> Date: Wed, 4 Sep 2024 11:39:44 -0700 Subject: [PATCH] Space between when sent time, from, and subject in email summary This is the first time I'm creating some custom style. There's probably a way to do this with Bootstrap that I'm not expert enough to know about. For now I'm just scratching itches. --- src/EmailSummary.tsx | 23 +++++++++++++---------- src/client/Client.tsx | 2 +- src/client/types.tsx | 2 +- src/components/DateTime.tsx | 30 ++++++++++++++++++++++-------- src/components/EmailFrom.tsx | 20 ++++++++++++++++++++ src/style.scss | 12 ++++++++++++ 6 files changed, 69 insertions(+), 20 deletions(-) create mode 100644 src/components/EmailFrom.tsx diff --git a/src/EmailSummary.tsx b/src/EmailSummary.tsx index 66d3517..334231d 100644 --- a/src/EmailSummary.tsx +++ b/src/EmailSummary.tsx @@ -4,9 +4,11 @@ import ButtonGroup from "react-bootstrap/ButtonGroup"; import ButtonToolbar from "react-bootstrap/ButtonToolbar"; import Placeholder from "react-bootstrap/Placeholder"; import React from "react"; +import Stack from "react-bootstrap/Stack"; import Client from "./client/Client"; import DateTime from "./components/DateTime"; +import EmailFrom from "./components/EmailFrom"; import { IAccount, IEmailStub, IMailbox } from "./client/types"; type EmailSummaryProps = { @@ -49,17 +51,18 @@ class EmailSummary extends React.Component< return <Placeholder />; } return ( - <div className="p-2 border" key={this.props.emailId}> + <Stack + direction="horizontal" + className="email-summary" + key={this.props.emailId} + > + <DateTime className="received" d={stub.receivedAt} /> + <EmailFrom froms={stub.from} /> + <div>{stub.from == null ? "?" : stub.from[0].name}</div> <a className="btn" href={href}> - <DateTime d={stub.receivedAt} /> - <span> - {" - " + - (stub.from == null ? "?" : stub.from[0].name) + - " - " + - stub.subject} - </span> + <div>{stub.subject}</div> </a> - <ButtonToolbar> + <ButtonToolbar className="ms-auto"> <ButtonGroup className="me-2"> <Button onClick={() => { @@ -74,7 +77,7 @@ class EmailSummary extends React.Component< <Button>2</Button> </ButtonGroup> </ButtonToolbar> - </div> + </Stack> ); } } diff --git a/src/client/Client.tsx b/src/client/Client.tsx index 25eb9ab..bd3e460 100644 --- a/src/client/Client.tsx +++ b/src/client/Client.tsx @@ -241,7 +241,7 @@ export default class Client { ); } this.state.session.emailStubs[e.id] = { - from: e.from, + from: e.from === null ? [] : e.from, id: e.id, mailboxIds: e.mailboxIds, receivedAt: e.receivedAt, diff --git a/src/client/types.tsx b/src/client/types.tsx index e8fa48c..a251cd0 100644 --- a/src/client/types.tsx +++ b/src/client/types.tsx @@ -2,7 +2,7 @@ import * as client from "./jmap-client-ts/src/types"; export type MailboxIdMap = { [mailboxId: string]: boolean }; export interface IEmailStub { - from: Array<client.IEmailAddress> | null; + from: Array<client.IEmailAddress>; id: string; mailboxIds: MailboxIdMap; receivedAt: string; diff --git a/src/components/DateTime.tsx b/src/components/DateTime.tsx index 38c2148..91222cd 100644 --- a/src/components/DateTime.tsx +++ b/src/components/DateTime.tsx @@ -4,16 +4,30 @@ type DateTimeProps = { d: string; }; -const DateTime: React.FC<DateTimeProps> = ({ d }) => { - const datetime = Date.parse(d); +const DateTime: React.FC< + DateTimeProps & React.HTMLAttributes<HTMLSpanElement> +> = (props) => { + const datetime = Date.parse(props.d); const now = Date.now(); const diff = (now - datetime) / 1000; - if (diff < 30) return <span>moments ago</span>; - if (diff < 60) return <span>{diff}s</span>; - if (diff < 60 * 60) return <span>{Math.round(diff / 60)}m</span>; - if (diff < 60 * 60 * 48) return <span>{Math.round(diff / (60 * 60))}h</span>; + if (diff < 30) return <span className={props.className}>moments ago</span>; + if (diff < 60) return <span className={props.className}>{diff}s</span>; + if (diff < 60 * 60) + return <span className={props.className}>{Math.round(diff / 60)}m</span>; + if (diff < 60 * 60 * 48) + return ( + <span className={props.className}>{Math.round(diff / (60 * 60))}h</span> + ); if (diff < 60 * 60 * 24 * 365) - return <span>{Math.round(diff / (60 * 60 * 24))}d</span>; - return <span>{Math.round(diff / (60 * 60 * 24 * 365))}y</span>; + return ( + <span className={props.className}> + {Math.round(diff / (60 * 60 * 24))}d + </span> + ); + return ( + <span className={props.className}> + {Math.round(diff / (60 * 60 * 24 * 365))}y + </span> + ); }; export default DateTime; diff --git a/src/components/EmailFrom.tsx b/src/components/EmailFrom.tsx new file mode 100644 index 0000000..aa174a2 --- /dev/null +++ b/src/components/EmailFrom.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import * as client from "../client/jmap-client-ts/src/types"; + +type EmailFromProps = { + froms: Array<client.IEmailAddress>; +}; + +const EmailFrom: React.FC<EmailFromProps> = ({ froms }) => { + if (froms.length === 0) { + return <span className="email-from">None</span>; + } + if (froms.length > 1) { + return <span className="email-from">MANY?</span>; + } + if (froms[0].name) { + return <span className="email-from">{froms[0].name}</span>; + } + return <span className="email-from">{froms[0].email}</span>; +}; +export default EmailFrom; diff --git a/src/style.scss b/src/style.scss index 5de3350..e8cabd0 100644 --- a/src/style.scss +++ b/src/style.scss @@ -1 +1,13 @@ @import '~bootstrap/scss/bootstrap'; + +.email-summary { + .email-from { + overflow: hidden; + text-overflow: ellipsis; + width: 200px; + } + .received { + width: 50px; + } +} +