import WidgetKit import SwiftUI struct RandomBookmarkEntry: TimelineEntry { let date: Date let bookmark: WidgetBookmark? static let placeholder = RandomBookmarkEntry( date: .now, bookmark: WidgetBookmark(url: "https://example.com", title: "A Saved Article Worth Revisiting", domain: "example.com", faviconUrl: nil) ) } struct RandomBookmarkProvider: TimelineProvider { func placeholder(in context: Context) -> RandomBookmarkEntry { .placeholder } func getSnapshot(in context: Context, completion: @escaping (RandomBookmarkEntry) -> Void) { let bookmarks = WidgetDataStore.loadBookmarks() completion(RandomBookmarkEntry(date: .now, bookmark: bookmarks.randomElement())) } func getTimeline(in context: Context, completion: @escaping (Timeline) -> Void) { let bookmarks = WidgetDataStore.loadBookmarks() let entry = RandomBookmarkEntry(date: .now, bookmark: bookmarks.randomElement()) let next = Calendar.current.date(byAdding: .hour, value: 1, to: .now)! completion(Timeline(entries: [entry], policy: .after(next))) } } struct RandomBookmarkWidgetView: View { let entry: RandomBookmarkEntry var body: some View { Group { if let bookmark = entry.bookmark { VStack(alignment: .leading, spacing: 0) { HStack { Text("Rediscover") .font(.system(size: 12, weight: .semibold)) .foregroundStyle(.secondary) Spacer() Image(systemName: "sparkles") .font(.system(size: 11)) .foregroundStyle(.blue) } Spacer() RoundedRectangle(cornerRadius: 7) .fill(Color.blue.opacity(0.1)) .frame(width: 38, height: 38) .overlay { Image(systemName: "bookmark.fill") .font(.system(size: 15)) .foregroundStyle(.blue) } Spacer().frame(height: 10) Text(bookmark.title) .font(.system(size: 14, weight: .semibold)) .foregroundStyle(.primary) .lineLimit(3) .fixedSize(horizontal: false, vertical: true) Text(bookmark.domain) .font(.system(size: 12)) .foregroundStyle(.secondary) .padding(.top, 2) } .padding(14) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading) .widgetURL(.marksBookmark(bookmark.url)) } else { VStack(spacing: 8) { Image(systemName: "bookmark") .font(.system(size: 28)) .foregroundStyle(.secondary) Text("Open Marks to\nload bookmarks.") .font(.system(size: 12)) .foregroundStyle(.secondary) .multilineTextAlignment(.center) } .frame(maxWidth: .infinity, maxHeight: .infinity) } } .containerBackground(.fill.tertiary, for: .widget) } } struct RandomBookmarkWidget: Widget { var body: some WidgetConfiguration { StaticConfiguration( kind: "com.magicive.marks.RandomBookmark", provider: RandomBookmarkProvider() ) { entry in RandomBookmarkWidgetView(entry: entry) } .configurationDisplayName("Rediscover") .description("A random saved bookmark to revisit.") .supportedFamilies([.systemSmall]) } }