mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-07-12 21:02:17 +02:00
feat(email): faster inbox load, Ctrl+Tab tab cycling, square preset buttons
- Inbox load: add an mtime-keyed in-memory cache to listInboxPage so it no longer re-reads and JSON.parses every cached thread (bodies included) on every call — only files whose mtime changed are re-parsed. Speeds up the Important→Everything-else handoff, live reloads during sync, and re-opening the inbox tab. - Add Ctrl+Tab / Ctrl+Shift+Tab to cycle to the next/previous tab (wraps around), alongside the existing Cmd+Shift+] / [ shortcuts. - Improve bar: make the tone preset buttons square (rounded-md), left-aligned, with a bit of vertical gap so wrapped rows aren't cramped.
This commit is contained in:
parent
824610f84f
commit
4a26bc9d80
3 changed files with 85 additions and 16 deletions
|
|
@ -4727,6 +4727,25 @@ function App() {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Ctrl+Tab — next tab, Ctrl+Shift+Tab — previous tab (browser-style).
|
||||
// Bound to Ctrl specifically (Cmd+Tab is the OS app switcher on macOS).
|
||||
if (e.ctrlKey && e.key === 'Tab') {
|
||||
e.preventDefault()
|
||||
const direction = e.shiftKey ? -1 : 1
|
||||
if (inFileView) {
|
||||
const currentIdx = fileTabs.findIndex(t => t.id === targetFileTabId)
|
||||
if (currentIdx === -1) return
|
||||
const nextIdx = (currentIdx + direction + fileTabs.length) % fileTabs.length
|
||||
switchFileTab(fileTabs[nextIdx].id)
|
||||
} else {
|
||||
const currentIdx = chatTabs.findIndex(t => t.id === activeChatTabId)
|
||||
if (currentIdx === -1) return
|
||||
const nextIdx = (currentIdx + direction + chatTabs.length) % chatTabs.length
|
||||
switchChatTab(chatTabs[nextIdx].id)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
document.addEventListener('keydown', handleTabKeyDown)
|
||||
return () => document.removeEventListener('keydown', handleTabKeyDown)
|
||||
|
|
|
|||
|
|
@ -1398,12 +1398,12 @@ const ComposeBox = memo(function ComposeBox({
|
|||
: (hasGenerated ? 'Edit' : 'Write')}
|
||||
</Button>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-1.5 border-b border-border px-3 pb-2.5">
|
||||
<div className="flex flex-wrap gap-x-1.5 gap-y-2 border-b border-border px-3 pb-2.5">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="xs"
|
||||
className="rounded-full"
|
||||
className="rounded-md"
|
||||
onClick={() => { void runAi('Improve the clarity, grammar, and flow of this email while preserving its meaning.', 'rewrite') }}
|
||||
disabled={generating}
|
||||
>Improve</Button>
|
||||
|
|
@ -1413,7 +1413,7 @@ const ComposeBox = memo(function ComposeBox({
|
|||
type="button"
|
||||
variant="outline"
|
||||
size="xs"
|
||||
className="rounded-full"
|
||||
className="rounded-md"
|
||||
onClick={() => { void runAi(preset.instruction, 'rewrite') }}
|
||||
disabled={generating}
|
||||
>{preset.label}</Button>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue