mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-07-06 20:42:15 +02:00
move to accordian
This commit is contained in:
parent
21148d02b9
commit
ec1420fcf5
2 changed files with 82 additions and 57 deletions
|
|
@ -124,22 +124,26 @@
|
||||||
background: rgba(60, 64, 67, 0.08);
|
background: rgba(60, 64, 67, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.gmail-layout {
|
.gmail-list {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: minmax(420px, 0.45fr) minmax(480px, 0.55fr);
|
flex-direction: column;
|
||||||
|
min-width: 0;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: auto;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border: 1px solid #e4e7ee;
|
border: 1px solid #e4e7ee;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gmail-list {
|
.gmail-row-group {
|
||||||
min-width: 0;
|
display: flex;
|
||||||
min-height: 0;
|
flex-direction: column;
|
||||||
overflow: auto;
|
border-bottom: 1px solid #f1f3f4;
|
||||||
border-right: 1px solid #e4e7ee;
|
}
|
||||||
|
|
||||||
|
.gmail-row-group:last-child {
|
||||||
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gmail-list-header {
|
.gmail-list-header {
|
||||||
|
|
@ -165,7 +169,6 @@
|
||||||
min-height: 44px;
|
min-height: 44px;
|
||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
border: none;
|
border: none;
|
||||||
border-bottom: 1px solid #f1f3f4;
|
|
||||||
background: #f6f8fc;
|
background: #f6f8fc;
|
||||||
color: #5f6368;
|
color: #5f6368;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
@ -248,28 +251,52 @@
|
||||||
.gmail-detail {
|
.gmail-detail {
|
||||||
display: flex;
|
display: flex;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
min-height: 0;
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gmail-detail-inline {
|
||||||
|
background: #f6f8fc;
|
||||||
|
border-top: 1px solid #e4e7ee;
|
||||||
|
box-shadow: inset 3px 0 0 #1a73e8;
|
||||||
|
}
|
||||||
|
|
||||||
.gmail-detail-toolbar {
|
.gmail-detail-toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
justify-content: space-between;
|
||||||
height: 44px;
|
gap: 12px;
|
||||||
padding: 0 12px;
|
height: 48px;
|
||||||
|
padding: 0 16px;
|
||||||
border-bottom: 1px solid #e8eaed;
|
border-bottom: 1px solid #e8eaed;
|
||||||
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gmail-back-button {
|
.gmail-thread-subject-inline {
|
||||||
display: none;
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
color: #202124;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gmail-thread-scroll {
|
.gmail-detail-toolbar-actions {
|
||||||
min-height: 0;
|
display: flex;
|
||||||
overflow: auto;
|
align-items: center;
|
||||||
padding: 24px 32px 40px;
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gmail-detail-toolbar-actions .gmail-icon-button span {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gmail-thread-body {
|
||||||
|
padding: 20px 28px 32px;
|
||||||
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gmail-thread-subject-row {
|
.gmail-thread-subject-row {
|
||||||
|
|
|
||||||
|
|
@ -247,29 +247,27 @@ function ComposeBox({
|
||||||
|
|
||||||
function ThreadDetail({
|
function ThreadDetail({
|
||||||
thread,
|
thread,
|
||||||
onBack,
|
onClose,
|
||||||
}: {
|
}: {
|
||||||
thread: GmailThread
|
thread: GmailThread
|
||||||
onBack: () => void
|
onClose: () => void
|
||||||
}) {
|
}) {
|
||||||
const [composeMode, setComposeMode] = useState<ComposeMode | null>(null)
|
const [composeMode, setComposeMode] = useState<ComposeMode | null>(null)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="gmail-detail">
|
<div className="gmail-detail gmail-detail-inline">
|
||||||
<div className="gmail-detail-toolbar">
|
<div className="gmail-detail-toolbar">
|
||||||
<button type="button" className="gmail-icon-button gmail-back-button" onClick={onBack} aria-label="Back to inbox">
|
<div className="gmail-thread-subject-inline">{thread.subject || '(No subject)'}</div>
|
||||||
<span>←</span>
|
<div className="gmail-detail-toolbar-actions">
|
||||||
</button>
|
<button type="button" className="gmail-icon-button" aria-label="Archive"><Archive size={18} /></button>
|
||||||
<button type="button" className="gmail-icon-button" aria-label="Archive"><Archive size={18} /></button>
|
<button type="button" className="gmail-icon-button" aria-label="More"><MoreVertical size={18} /></button>
|
||||||
<button type="button" className="gmail-icon-button" aria-label="More"><MoreVertical size={18} /></button>
|
<button type="button" className="gmail-icon-button" onClick={onClose} aria-label="Close thread">
|
||||||
|
<span>×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="gmail-thread-scroll">
|
<div className="gmail-thread-body">
|
||||||
<div className="gmail-thread-subject-row">
|
|
||||||
<h1>{thread.subject || '(No subject)'}</h1>
|
|
||||||
<span>Inbox</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="gmail-message-stack">
|
<div className="gmail-message-stack">
|
||||||
{thread.messages.map((message, index) => {
|
{thread.messages.map((message, index) => {
|
||||||
const isLast = index === thread.messages.length - 1
|
const isLast = index === thread.messages.length - 1
|
||||||
|
|
@ -399,7 +397,7 @@ export function EmailView() {
|
||||||
})
|
})
|
||||||
}, [query, threads])
|
}, [query, threads])
|
||||||
|
|
||||||
const selectedThread = filteredThreads.find(thread => thread.threadId === selectedThreadId) ?? filteredThreads[0] ?? null
|
const hasThreads = filteredThreads.length > 0
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="gmail-shell">
|
<div className="gmail-shell">
|
||||||
|
|
@ -420,23 +418,22 @@ export function EmailView() {
|
||||||
|
|
||||||
{error ? (
|
{error ? (
|
||||||
<div className="gmail-empty-state">Could not load mail: {error}</div>
|
<div className="gmail-empty-state">Could not load mail: {error}</div>
|
||||||
) : selectedThread ? (
|
) : hasThreads ? (
|
||||||
<div className="gmail-layout">
|
<div className="gmail-list" aria-label="Recent emails">
|
||||||
<div className="gmail-list" aria-label="Recent emails">
|
<div className="gmail-list-header">
|
||||||
<div className="gmail-list-header">
|
<span>Last 2 days</span>
|
||||||
<span>Last 2 days</span>
|
<span>{filteredThreads.length} threads</span>
|
||||||
<span>{filteredThreads.length} threads</span>
|
</div>
|
||||||
</div>
|
{filteredThreads.map((thread) => {
|
||||||
{filteredThreads.map((thread) => {
|
const latest = latestMessage(thread)
|
||||||
const latest = latestMessage(thread)
|
const isSelected = thread.threadId === selectedThreadId
|
||||||
const isSelected = thread.threadId === selectedThread.threadId
|
const isUnread = thread.unread === true
|
||||||
const isUnread = thread.unread === true
|
return (
|
||||||
return (
|
<div key={thread.threadId} className="gmail-row-group">
|
||||||
<button
|
<button
|
||||||
key={thread.threadId}
|
|
||||||
type="button"
|
type="button"
|
||||||
className={cn('gmail-row', isSelected && 'gmail-row-selected', isUnread && 'gmail-row-unread')}
|
className={cn('gmail-row', isSelected && 'gmail-row-selected', isUnread && 'gmail-row-unread')}
|
||||||
onClick={() => setSelectedThreadId(thread.threadId)}
|
onClick={() => setSelectedThreadId(isSelected ? null : thread.threadId)}
|
||||||
>
|
>
|
||||||
<span className="gmail-row-check" />
|
<span className="gmail-row-check" />
|
||||||
<span className="gmail-row-star"><Star size={16} /></span>
|
<span className="gmail-row-star"><Star size={16} /></span>
|
||||||
|
|
@ -447,14 +444,15 @@ export function EmailView() {
|
||||||
</span>
|
</span>
|
||||||
<span className="gmail-row-date">{formatInboxTime(latest?.date || thread.date)}</span>
|
<span className="gmail-row-date">{formatInboxTime(latest?.date || thread.date)}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
{isSelected && (
|
||||||
})}
|
<ThreadDetail
|
||||||
</div>
|
thread={thread}
|
||||||
|
onClose={() => setSelectedThreadId(null)}
|
||||||
<ThreadDetail
|
/>
|
||||||
thread={selectedThread}
|
)}
|
||||||
onBack={() => setSelectedThreadId(null)}
|
</div>
|
||||||
/>
|
)
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="gmail-empty-state">
|
<div className="gmail-empty-state">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue