default to Inbox perspective, show GTD item detail, reduce toolbar
- default to Inbox perspective (not INBOX mailbox) after first sync - selectItemForDetail bridges GTD item selection to detail pane by creating a synthetic ThreadSummary for email items - reduce GTD toolbar from 5 to 3 buttons (defer, complete, discard), someday/project remain accessible via keyboard shortcuts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -194,6 +194,27 @@ final class MailViewModel {
|
|||||||
startObservingThreads(accountId: accountConfig.id, mailboxId: mailbox.id)
|
startObservingThreads(accountId: accountConfig.id, mailboxId: mailbox.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func selectItemForDetail(_ item: ItemSummary?) {
|
||||||
|
guard let item else {
|
||||||
|
selectedThread = nil
|
||||||
|
messages = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch item {
|
||||||
|
case .email(let msg):
|
||||||
|
// Show the message directly in the detail pane
|
||||||
|
selectedThread = ThreadSummary(
|
||||||
|
id: msg.id, accountId: accountConfig?.id ?? "", subject: msg.subject,
|
||||||
|
lastDate: msg.date, messageCount: 1, unreadCount: 0,
|
||||||
|
senders: msg.from?.displayName ?? "", snippet: msg.snippet
|
||||||
|
)
|
||||||
|
messages = [msg]
|
||||||
|
case .task:
|
||||||
|
selectedThread = nil
|
||||||
|
messages = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func selectPerspective(_ perspective: Perspective) {
|
func selectPerspective(_ perspective: Perspective) {
|
||||||
selectedMailbox = nil
|
selectedMailbox = nil
|
||||||
selectedThread = nil
|
selectedThread = nil
|
||||||
@@ -238,6 +259,7 @@ final class MailViewModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var isSyncing = false
|
private var isSyncing = false
|
||||||
|
private var hasLoadedInitialPerspective = false
|
||||||
|
|
||||||
func syncNow() async {
|
func syncNow() async {
|
||||||
guard let coordinator, !isSyncing else { return }
|
guard let coordinator, !isSyncing else { return }
|
||||||
@@ -249,9 +271,10 @@ final class MailViewModel {
|
|||||||
// Reload mailboxes after sync (they may have been created on first sync)
|
// Reload mailboxes after sync (they may have been created on first sync)
|
||||||
if let accountConfig {
|
if let accountConfig {
|
||||||
await loadMailboxes(accountId: accountConfig.id)
|
await loadMailboxes(accountId: accountConfig.id)
|
||||||
// On first sync, default to INBOX view
|
// On first sync, load Inbox perspective
|
||||||
if selectedMailbox == nil, let inbox = mailboxes.first(where: { $0.name.lowercased() == "inbox" }) {
|
if !hasLoadedInitialPerspective {
|
||||||
selectMailbox(inbox)
|
hasLoadedInitialPerspective = true
|
||||||
|
selectPerspective(.inbox)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ struct ThreadListView: View {
|
|||||||
get: { viewModel.selectedItem?.id },
|
get: { viewModel.selectedItem?.id },
|
||||||
set: { newId in
|
set: { newId in
|
||||||
viewModel.selectedItem = viewModel.items.first { $0.id == newId }
|
viewModel.selectedItem = viewModel.items.first { $0.id == newId }
|
||||||
|
viewModel.selectItemForDetail(viewModel.selectedItem)
|
||||||
}
|
}
|
||||||
)) { item in
|
)) { item in
|
||||||
ItemRow(item: item)
|
ItemRow(item: item)
|
||||||
@@ -176,24 +177,6 @@ struct ThreadListView: View {
|
|||||||
.keyboardShortcut("d", modifiers: [])
|
.keyboardShortcut("d", modifiers: [])
|
||||||
.help("Defer (d)")
|
.help("Defer (d)")
|
||||||
|
|
||||||
Button {
|
|
||||||
if let item = selectedItemSummary {
|
|
||||||
viewModel.deferItem(item, until: nil)
|
|
||||||
}
|
|
||||||
} label: {
|
|
||||||
Label("Someday", systemImage: "moon.zzz")
|
|
||||||
}
|
|
||||||
.keyboardShortcut("d", modifiers: [.shift])
|
|
||||||
.help("Someday (⇧D)")
|
|
||||||
|
|
||||||
Button {
|
|
||||||
showLabelPicker = true
|
|
||||||
} label: {
|
|
||||||
Label("Project", systemImage: "folder.badge.plus")
|
|
||||||
}
|
|
||||||
.keyboardShortcut("p", modifiers: [])
|
|
||||||
.help("File to Project (p)")
|
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
if let item = selectedItemSummary {
|
if let item = selectedItemSummary {
|
||||||
viewModel.completeItem(item)
|
viewModel.completeItem(item)
|
||||||
|
|||||||
Reference in New Issue
Block a user