Align Mail UI with social.io design handoff
Rewrite the Mail feature to match the Apple-native look from the handoff spec: lane-split inbox, AI summary card, clean ThreadRow, Cc/From + format toolbar in Compose. Drop the gradient hero surfaces and blurred canvas backgrounds the spec calls out as anti-patterns, and introduce a token-backed design layer so the lane palette and SIO tint live in the asset catalog. - Add Assets.xcassets with SIOTint, LaneFeed, LanePaper, LanePeople (light + dark variants). - Add Sources/Core/Design/SIODesign.swift: SIO tokens, Lane enum, LaneChip, AvatarView, AISummaryCard, KeyboardHint, button styles, and a glass-chrome helper with iOS 26 / material fallback. - Extend MailThread with lane + summary; custom Codable keeps old payloads decodable. Seed mock threads with sensible lanes and hand-write summaries on launch-copy, investor-update, roadmap-notes. - Add lane filtering to AppViewModel (selectedLane, selectLane, laneUnreadCount, laneThreadCount). - Rewrite MailRootView end to end: sidebar with Inbox/lane rows, lane filter strip, Apple-native ThreadRow (avatar, unread dot, lane chip, summary chip), ThreadReadingView with AI summary + floating reply pill, ComposeView with To/Cc/From/Subject and a format toolbar. - Wire Assets.xcassets + SIODesign.swift into project.pbxproj. Accessibility identifiers preserved byte-identical; new ones (mailbox.lane.*, lane.chip.*) added only where new. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -82,7 +82,13 @@ struct MockMailService: MailServicing {
|
||||
],
|
||||
isUnread: true,
|
||||
isStarred: true,
|
||||
tags: ["Design", "Launch"]
|
||||
tags: ["Design", "Launch"],
|
||||
lane: .people,
|
||||
summary: [
|
||||
"Tanya tightened the onboarding copy and softened the empty-state tone.",
|
||||
"Phil signed off with a note to keep playful language on iPhone.",
|
||||
"Desktop first-run copy still needs a lighter pass before handoff."
|
||||
]
|
||||
),
|
||||
MailThread(
|
||||
routeID: "daily-sync-status",
|
||||
@@ -100,7 +106,8 @@ struct MockMailService: MailServicing {
|
||||
],
|
||||
isUnread: false,
|
||||
isStarred: false,
|
||||
tags: ["System"]
|
||||
tags: ["System"],
|
||||
lane: .feed
|
||||
),
|
||||
MailThread(
|
||||
routeID: "investor-update",
|
||||
@@ -118,7 +125,13 @@ struct MockMailService: MailServicing {
|
||||
],
|
||||
isUnread: true,
|
||||
isStarred: false,
|
||||
tags: ["External"]
|
||||
tags: ["External"],
|
||||
lane: .paper,
|
||||
summary: [
|
||||
"Mina wants a concise product update before Friday.",
|
||||
"She's specifically asking for screenshots of the new mail experience.",
|
||||
"Interested in how we differentiate from commodity inboxes."
|
||||
]
|
||||
),
|
||||
MailThread(
|
||||
routeID: "search-ranking-polish",
|
||||
@@ -143,7 +156,8 @@ struct MockMailService: MailServicing {
|
||||
],
|
||||
isUnread: false,
|
||||
isStarred: false,
|
||||
tags: ["Search"]
|
||||
tags: ["Search"],
|
||||
lane: .people
|
||||
),
|
||||
MailThread(
|
||||
routeID: "welcome-to-socialio",
|
||||
@@ -162,7 +176,8 @@ struct MockMailService: MailServicing {
|
||||
],
|
||||
isUnread: false,
|
||||
isStarred: false,
|
||||
tags: ["Draft"]
|
||||
tags: ["Draft"],
|
||||
lane: .people
|
||||
),
|
||||
MailThread(
|
||||
routeID: "roadmap-notes",
|
||||
@@ -180,7 +195,13 @@ struct MockMailService: MailServicing {
|
||||
],
|
||||
isUnread: false,
|
||||
isStarred: true,
|
||||
tags: ["Product"]
|
||||
tags: ["Product"],
|
||||
lane: .paper,
|
||||
summary: [
|
||||
"Three roadmap themes: faster triage, identity-rich threads, calmer notifications.",
|
||||
"Raw notes were cleaned up and archived by Nora.",
|
||||
"Owner split still needs to be reconciled with eng capacity."
|
||||
]
|
||||
)
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user