Local work on the social.io handoff before merging the claude worktree branch. Includes the full per-spec Sources/Core/Design module (8 files), watchOS target under WatchApp/, Live Activity + widget extension, entitlements, scheme, and asset catalog. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
83 lines
2.6 KiB
Swift
83 lines
2.6 KiB
Swift
import SwiftUI
|
|
import WidgetKit
|
|
|
|
struct WatchUnreadEntry: TimelineEntry {
|
|
let date: Date
|
|
let unreadCount: Int
|
|
}
|
|
|
|
struct WatchUnreadProvider: TimelineProvider {
|
|
func placeholder(in context: Context) -> WatchUnreadEntry {
|
|
WatchUnreadEntry(date: .now, unreadCount: 3)
|
|
}
|
|
|
|
func getSnapshot(in context: Context, completion: @escaping (WatchUnreadEntry) -> Void) {
|
|
completion(makeEntry())
|
|
}
|
|
|
|
func getTimeline(in context: Context, completion: @escaping (Timeline<WatchUnreadEntry>) -> Void) {
|
|
completion(Timeline(entries: [makeEntry()], policy: .after(.now.addingTimeInterval(900))))
|
|
}
|
|
|
|
private func makeEntry() -> WatchUnreadEntry {
|
|
let unreadCount = MockMailService().previewThreads().filter { $0.mailbox == .inbox && $0.isUnread }.count
|
|
return WatchUnreadEntry(date: .now, unreadCount: unreadCount)
|
|
}
|
|
}
|
|
|
|
struct WatchUnreadComplication: Widget {
|
|
let kind = "SocialIOWatchUnreadComplication"
|
|
|
|
var body: some WidgetConfiguration {
|
|
StaticConfiguration(kind: kind, provider: WatchUnreadProvider()) { entry in
|
|
WatchUnreadComplicationView(entry: entry)
|
|
}
|
|
.configurationDisplayName("social.io Inbox")
|
|
.description("Unread social.io mail at a glance.")
|
|
.supportedFamilies([.accessoryRectangular, .accessoryCircular, .accessoryCorner])
|
|
}
|
|
}
|
|
|
|
private struct WatchUnreadComplicationView: View {
|
|
let entry: WatchUnreadEntry
|
|
|
|
var body: some View {
|
|
switch widgetFamily {
|
|
case .accessoryCircular:
|
|
ZStack {
|
|
AccessoryWidgetBackground()
|
|
VStack(spacing: 2) {
|
|
Image(systemName: "envelope.fill")
|
|
Text(entry.unreadCount, format: .number)
|
|
.font(.caption2.weight(.bold))
|
|
}
|
|
}
|
|
.widgetURL(URL(string: "socialio://mailbox/inbox"))
|
|
|
|
case .accessoryCorner:
|
|
Text("\(entry.unreadCount)")
|
|
.font(.caption.weight(.bold))
|
|
.widgetURL(URL(string: "socialio://mailbox/inbox"))
|
|
|
|
default:
|
|
VStack(alignment: .leading, spacing: 4) {
|
|
Text("social.io")
|
|
.font(.caption2)
|
|
.foregroundStyle(.secondary)
|
|
Text("\(entry.unreadCount) unread")
|
|
.font(.caption.weight(.semibold))
|
|
}
|
|
.widgetURL(URL(string: "socialio://mailbox/inbox"))
|
|
}
|
|
}
|
|
|
|
@Environment(\.widgetFamily) private var widgetFamily
|
|
}
|
|
|
|
@main
|
|
struct SocialIOWatchWidgets: WidgetBundle {
|
|
var body: some Widget {
|
|
WatchUnreadComplication()
|
|
}
|
|
}
|