mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-06-24 20:28:16 +02:00
split inbox
This commit is contained in:
parent
83b54feb0c
commit
375d8bf2e0
2 changed files with 69 additions and 35 deletions
|
|
@ -215,6 +215,15 @@
|
||||||
letter-spacing: 0.08em;
|
letter-spacing: 0.08em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gmail-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gmail-section + .gmail-section {
|
||||||
|
margin-top: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
.gmail-row {
|
.gmail-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 12px minmax(140px, 0.22fr) minmax(0, 1fr) 60px;
|
grid-template-columns: 12px minmax(140px, 0.22fr) minmax(0, 1fr) 60px;
|
||||||
|
|
|
||||||
|
|
@ -558,34 +558,19 @@ export function EmailView() {
|
||||||
})
|
})
|
||||||
}, [query, threads])
|
}, [query, threads])
|
||||||
|
|
||||||
|
const { importantThreads, otherThreads } = useMemo(() => {
|
||||||
|
const important: GmailThread[] = []
|
||||||
|
const other: GmailThread[] = []
|
||||||
|
for (const thread of filteredThreads) {
|
||||||
|
if (thread.messages.length > 1) important.push(thread)
|
||||||
|
else other.push(thread)
|
||||||
|
}
|
||||||
|
return { importantThreads: important, otherThreads: other }
|
||||||
|
}, [filteredThreads])
|
||||||
|
|
||||||
const hasThreads = filteredThreads.length > 0
|
const hasThreads = filteredThreads.length > 0
|
||||||
|
|
||||||
return (
|
const renderRow = (thread: GmailThread) => {
|
||||||
<div className="gmail-shell">
|
|
||||||
<div className="gmail-main">
|
|
||||||
<div className="gmail-topbar">
|
|
||||||
<div className="gmail-search">
|
|
||||||
<Search size={18} />
|
|
||||||
<input
|
|
||||||
value={query}
|
|
||||||
onChange={(event) => setQuery(event.target.value)}
|
|
||||||
placeholder="Search mail"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<button type="button" className="gmail-icon-button" onClick={() => void loadThreads()} aria-label="Refresh">
|
|
||||||
{loading ? <LoaderIcon size={18} className="animate-spin" /> : <RefreshCw size={18} />}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{error ? (
|
|
||||||
<div className="gmail-empty-state">Could not load mail: {error}</div>
|
|
||||||
) : hasThreads ? (
|
|
||||||
<div className="gmail-list" aria-label="Recent emails">
|
|
||||||
<div className="gmail-list-header">
|
|
||||||
<span>Last 2 days</span>
|
|
||||||
<span>{filteredThreads.length} threads</span>
|
|
||||||
</div>
|
|
||||||
{filteredThreads.map((thread) => {
|
|
||||||
const latest = latestMessage(thread)
|
const latest = latestMessage(thread)
|
||||||
const isSelected = thread.threadId === selectedThreadId
|
const isSelected = thread.threadId === selectedThreadId
|
||||||
const isUnread = thread.unread === true
|
const isUnread = thread.unread === true
|
||||||
|
|
@ -616,7 +601,47 @@ export function EmailView() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="gmail-shell">
|
||||||
|
<div className="gmail-main">
|
||||||
|
<div className="gmail-topbar">
|
||||||
|
<div className="gmail-search">
|
||||||
|
<Search size={18} />
|
||||||
|
<input
|
||||||
|
value={query}
|
||||||
|
onChange={(event) => setQuery(event.target.value)}
|
||||||
|
placeholder="Search mail"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button type="button" className="gmail-icon-button" onClick={() => void loadThreads()} aria-label="Refresh">
|
||||||
|
{loading ? <LoaderIcon size={18} className="animate-spin" /> : <RefreshCw size={18} />}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{error ? (
|
||||||
|
<div className="gmail-empty-state">Could not load mail: {error}</div>
|
||||||
|
) : hasThreads ? (
|
||||||
|
<div className="gmail-list" aria-label="Recent emails">
|
||||||
|
{importantThreads.length > 0 && (
|
||||||
|
<section className="gmail-section">
|
||||||
|
<div className="gmail-list-header">
|
||||||
|
<span>Important</span>
|
||||||
|
<span>{importantThreads.length} thread{importantThreads.length === 1 ? '' : 's'}</span>
|
||||||
|
</div>
|
||||||
|
{importantThreads.map(renderRow)}
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
|
{otherThreads.length > 0 && (
|
||||||
|
<section className="gmail-section">
|
||||||
|
<div className="gmail-list-header">
|
||||||
|
<span>Everything else</span>
|
||||||
|
<span>{otherThreads.length} thread{otherThreads.length === 1 ? '' : 's'}</span>
|
||||||
|
</div>
|
||||||
|
{otherThreads.map(renderRow)}
|
||||||
|
</section>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="gmail-empty-state">
|
<div className="gmail-empty-state">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue