Commit d7844b8e4e
Verified · cmc
Layout: unified · split
Sources/OrgstarWidgets/AgendaTimeline.swift added +96
| @@ -0,0 +1,96 @@ | |||
| 1 | import OrgApp | ||
| 2 | import SwiftUI | ||
| 3 | import WidgetKit | ||
| 4 | |||
| 5 | struct AgendaEntry: TimelineEntry { | ||
| 6 | let date: Date | ||
| 7 | /// Nil until the app has written one. | ||
| 8 | let snapshot: AgendaSnapshot? | ||
| 9 | } | ||
| 10 | |||
| 11 | /// The app's agenda snapshot, with an entry for each time what's left of the day changes. | ||
| 12 | struct AgendaProvider: TimelineProvider { | ||
| 13 | func placeholder(in context: Context) -> AgendaEntry { | ||
| 14 | AgendaEntry(date: .now, snapshot: .sample(.now)) | ||
| 15 | } | ||
| 16 | |||
| 17 | func getSnapshot(in context: Context, completion: @escaping (AgendaEntry) -> Void) { | ||
| 18 | let snapshot = Self.load() | ||
| 19 | completion(AgendaEntry(date: .now, snapshot: snapshot ?? (context.isPreview ? .sample(.now) : nil))) | ||
| 20 | } | ||
| 21 | |||
| 22 | func getTimeline(in context: Context, completion: @escaping (Timeline<AgendaEntry>) -> Void) { | ||
| 23 | completion(Self.timeline(Self.load(), now: .now)) | ||
| 24 | } | ||
| 25 | |||
| 26 | static func load() -> AgendaSnapshot? { | ||
| 27 | AgendaSnapshot.file().flatMap(AgendaSnapshot.read) | ||
| 28 | } | ||
| 29 | |||
| 30 | static func timeline(_ snapshot: AgendaSnapshot?, now: Date, calendar: Calendar = .current) -> Timeline<AgendaEntry> { | ||
| 31 | let changes = snapshot?.changes(after: now, calendar: calendar) | ||
| 32 | ?? [calendar.date(byAdding: .day, value: 1, to: calendar.startOfDay(for: now))!] | ||
| 33 | let entries = ([now] + changes).map { AgendaEntry(date: $0, snapshot: snapshot) } | ||
| 34 | return Timeline(entries: entries, policy: .atEnd) | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | extension AgendaSnapshot.Hex { | ||
| 39 | func color(_ scheme: ColorScheme) -> Color { | ||
| 40 | Self.parse(scheme == .dark ? dark : light) ?? .primary | ||
| 41 | } | ||
| 42 | |||
| 43 | /// `#rrggbb` or `#rrggbbaa`. | ||
| 44 | static func parse(_ hex: String) -> Color? { | ||
| 45 | let digits = hex.dropFirst() | ||
| 46 | guard hex.first == "#", digits.count == 6 || digits.count == 8, let value = UInt64(digits, radix: 16) else { return nil } | ||
| 47 | let full = digits.count == 6 ? value << 8 | 0xFF : value | ||
| 48 | func part(_ shift: UInt64) -> Double { Double(full >> shift & 0xFF) / 255 } | ||
| 49 | return Color(.sRGB, red: part(24), green: part(16), blue: part(8), opacity: part(0)) | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | extension AgendaSnapshot { | ||
| 54 | func color(_ key: String, _ scheme: ColorScheme) -> Color? { | ||
| 55 | colors[key]?.color(scheme) | ||
| 56 | } | ||
| 57 | |||
| 58 | /// A day for the gallery and previews. | ||
| 59 | static func sample(_ now: Date, calendar: Calendar = .current) -> AgendaSnapshot { | ||
| 60 | let midnight = calendar.startOfDay(for: now) | ||
| 61 | func at(_ hour: Int, _ minute: Int = 0) -> Date { midnight.addingTimeInterval(Double(hour * 3600 + minute * 60)) } | ||
| 62 | let red = Hex(light: "#d70015", dark: "#ff6961") | ||
| 63 | let orange = Hex(light: "#c93400", dark: "#ff9f0a") | ||
| 64 | let gray = Hex(light: "#6c6c70", dark: "#98989d") | ||
| 65 | let blue = Hex(light: "#0a66d8", dark: "#409cff") | ||
| 66 | func row( | ||
| 67 | _ title: String, _ gutter: String, status: String = "normal", todo: String? = nil, todoColor: Hex? = nil, | ||
| 68 | priority: String? = nil, category: String = "work", start: Date? = nil, end: Date? = nil | ||
| 69 | ) -> Row { | ||
| 70 | Row( | ||
| 71 | id: title, gutter: gutter, status: status, title: title, category: category, todo: todo, priority: priority, isDone: false, | ||
| 72 | isEvent: false, start: start, end: end, path: nil, offset: nil, | ||
| 73 | statusColor: status == "overdue" ? red : status == "due-soon" ? orange : gray, todoColor: todoColor, | ||
| 74 | priorityColor: priority == nil ? nil : red, categoryColor: Hex(light: "#2e6b8f", dark: "#7fb8d9") | ||
| 75 | ) | ||
| 76 | } | ||
| 77 | let today = Day( | ||
| 78 | day: 0, date: midnight, header: "Today", | ||
| 79 | overdue: [row("Send the forms", "3d late", status: "overdue", todo: "TODO", todoColor: red, category: "home")], | ||
| 80 | rows: [ | ||
| 81 | row("Standup", "09:30", start: at(9, 30)), | ||
| 82 | row("Review the draft", "11:00–12:00", todo: "NEXT", todoColor: blue, priority: "A", start: at(11), end: at(12)), | ||
| 83 | row("Dentist", "14:00", category: "home", start: at(14)), | ||
| 84 | row("File expenses", "Due today", status: "due-soon", todo: "TODO", todoColor: red), | ||
| 85 | ] | ||
| 86 | ) | ||
| 87 | let tomorrow = Day( | ||
| 88 | day: 1, date: calendar.date(byAdding: .day, value: 1, to: midnight)!, header: "Tomorrow", overdue: [], | ||
| 89 | rows: [row("Plan the week", "Scheduled", todo: "TODO", todoColor: red)] | ||
| 90 | ) | ||
| 91 | return AgendaSnapshot( | ||
| 92 | generated: now, days: [today, tomorrow], | ||
| 93 | colors: ["agenda-today": Hex(light: "#007aff", dark: "#0a84ff"), "agenda-time": gray, "foreground": Hex(light: "#1f2328", dark: "#e6edf3")] | ||
| 94 | ) | ||
| 95 | } | ||
| 96 | } | ||
Sources/OrgstarWidgets/ClockActivityWidget.swift added +84
| @@ -0,0 +1,84 @@ | |||
| 1 | import ActivityKit | ||
| 2 | import AppIntents | ||
| 3 | import OrgApp | ||
| 4 | import SwiftUI | ||
| 5 | import WidgetKit | ||
| 6 | |||
| 7 | /// The running clock on the Lock Screen and in the Dynamic Island: the heading and the time | ||
| 8 | /// so far, which ticks by itself. | ||
| 9 | struct ClockActivityWidget: Widget { | ||
| 10 | var body: some WidgetConfiguration { | ||
| 11 | ActivityConfiguration(for: ClockActivityAttributes.self) { context in | ||
| 12 | HStack(spacing: 12) { | ||
| 13 | Image(systemName: "stopwatch").font(.title2).foregroundStyle(.orange) | ||
| 14 | VStack(alignment: .leading, spacing: 2) { | ||
| 15 | Text("Clocked in").font(.caption).foregroundStyle(.secondary) | ||
| 16 | Text(context.state.heading).font(.headline).lineLimit(2) | ||
| 17 | } | ||
| 18 | Spacer(minLength: 0) | ||
| 19 | VStack(alignment: .trailing, spacing: 6) { | ||
| 20 | ElapsedText(state: context.state).font(.title3.weight(.semibold)) | ||
| 21 | ClockOutButton() | ||
| 22 | } | ||
| 23 | } | ||
| 24 | .padding() | ||
| 25 | .widgetURL(AppLink.clock.url) | ||
| 26 | } dynamicIsland: { context in | ||
| 27 | DynamicIsland { | ||
| 28 | DynamicIslandExpandedRegion(.leading) { | ||
| 29 | Image(systemName: "stopwatch").font(.title2).foregroundStyle(.orange) | ||
| 30 | } | ||
| 31 | DynamicIslandExpandedRegion(.trailing) { | ||
| 32 | ElapsedText(state: context.state).font(.title3.weight(.semibold)).frame(width: 84, alignment: .trailing) | ||
| 33 | } | ||
| 34 | DynamicIslandExpandedRegion(.center) { | ||
| 35 | Text(context.state.heading).font(.headline).lineLimit(1) | ||
| 36 | } | ||
| 37 | DynamicIslandExpandedRegion(.bottom) { | ||
| 38 | ClockOutButton() | ||
| 39 | } | ||
| 40 | } compactLeading: { | ||
| 41 | Image(systemName: "stopwatch").foregroundStyle(.orange) | ||
| 42 | } compactTrailing: { | ||
| 43 | ElapsedText(state: context.state).frame(maxWidth: 56) | ||
| 44 | } minimal: { | ||
| 45 | Image(systemName: "stopwatch").foregroundStyle(.orange) | ||
| 46 | } | ||
| 47 | .widgetURL(AppLink.clock.url) | ||
| 48 | } | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | /// Time since the clock started, `1:05:09`. | ||
| 53 | struct ElapsedText: View { | ||
| 54 | let state: ClockActivityAttributes.ContentState | ||
| 55 | |||
| 56 | var body: some View { | ||
| 57 | Text(timerInterval: state.startedAt...Date.distantFuture, countsDown: false) | ||
| 58 | .monospacedDigit() | ||
| 59 | .lineLimit(1) | ||
| 60 | .minimumScaleFactor(0.7) | ||
| 61 | .multilineTextAlignment(.trailing) | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | struct ClockOutButton: View { | ||
| 66 | var body: some View { | ||
| 67 | Button(intent: ClockOutIntent()) { | ||
| 68 | Label("Clock Out", systemImage: "stop.fill").font(.caption.weight(.semibold)) | ||
| 69 | } | ||
| 70 | .tint(.orange) | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | #Preview("Lock Screen", as: .content, using: ClockActivityAttributes(path: "/notes/work.org", start: "2026-10-09 Fri 09:00")) { | ||
| 75 | ClockActivityWidget() | ||
| 76 | } contentStates: { | ||
| 77 | ClockActivityAttributes.ContentState(heading: "Review the draft", startedAt: .now.addingTimeInterval(-3725)) | ||
| 78 | } | ||
| 79 | |||
| 80 | #Preview("Expanded", as: .dynamicIsland(.expanded), using: ClockActivityAttributes(path: "/notes/work.org", start: "2026-10-09 Fri 09:00")) { | ||
| 81 | ClockActivityWidget() | ||
| 82 | } contentStates: { | ||
| 83 | ClockActivityAttributes.ContentState(heading: "Review the draft", startedAt: .now.addingTimeInterval(-3725)) | ||
| 84 | } | ||
Sources/OrgstarWidgets/OrgstarWidgets.swift added +19
| @@ -0,0 +1,19 @@ | |||
| 1 | import AppIntents | ||
| 2 | import OrgApp | ||
| 3 | import SwiftUI | ||
| 4 | import WidgetKit | ||
| 5 | |||
| 6 | /// The agenda on the Home Screen and the Lock Screen, and the running clock's Live Activity. | ||
| 7 | @main | ||
| 8 | struct OrgstarWidgets: WidgetBundle { | ||
| 9 | var body: some Widget { | ||
| 10 | TodayWidget() | ||
| 11 | UpNextWidget() | ||
| 12 | ClockActivityWidget() | ||
| 13 | } | ||
| 14 | } | ||
| 15 | |||
| 16 | /// The App Intents OrgApp declares: the Live Activity's Clock Out button. | ||
| 17 | struct OrgstarWidgetIntents: AppIntentsPackage { | ||
| 18 | static var includedPackages: [any AppIntentsPackage.Type] { [OrgAppIntents.self] } | ||
| 19 | } | ||
Sources/OrgstarWidgets/TodayWidget.swift added +168
| @@ -0,0 +1,168 @@ | |||
| 1 | import OrgApp | ||
| 2 | import SwiftUI | ||
| 3 | import WidgetKit | ||
| 4 | |||
| 5 | /// Today's agenda on the Home Screen: what's next (small), today's list (medium), today and | ||
| 6 | /// tomorrow (large). | ||
| 7 | struct TodayWidget: Widget { | ||
| 8 | var body: some WidgetConfiguration { | ||
| 9 | StaticConfiguration(kind: "sh.krz.orgstar.today", provider: AgendaProvider()) { entry in | ||
| 10 | TodayView(entry: entry) | ||
| 11 | } | ||
| 12 | .configurationDisplayName("Today") | ||
| 13 | .description("What's left of today's agenda.") | ||
| 14 | .supportedFamilies([.systemSmall, .systemMedium, .systemLarge]) | ||
| 15 | } | ||
| 16 | } | ||
| 17 | |||
| 18 | struct TodayView: View { | ||
| 19 | let entry: AgendaEntry | ||
| 20 | @Environment(\.widgetFamily) private var family | ||
| 21 | @Environment(\.colorScheme) private var scheme | ||
| 22 | |||
| 23 | var body: some View { | ||
| 24 | Group { | ||
| 25 | if let snapshot = entry.snapshot { | ||
| 26 | content(snapshot) | ||
| 27 | } else { | ||
| 28 | Text("Open Orgstar to show your agenda here.") | ||
| 29 | .font(.caption) | ||
| 30 | .foregroundStyle(.secondary) | ||
| 31 | .frame(maxWidth: .infinity, maxHeight: .infinity) | ||
| 32 | } | ||
| 33 | } | ||
| 34 | .widgetURL(AppLink.agenda.url) | ||
| 35 | .containerBackground(for: .widget) { | ||
| 36 | entry.snapshot?.color("agenda-background", scheme) ?? Color(uiColor: .systemBackground) | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | @ViewBuilder | ||
| 41 | private func content(_ snapshot: AgendaSnapshot) -> some View { | ||
| 42 | let upcoming = snapshot.upcoming(at: entry.date) | ||
| 43 | VStack(alignment: .leading, spacing: family == .systemSmall ? 4 : 6) { | ||
| 44 | header(snapshot) | ||
| 45 | switch family { | ||
| 46 | case .systemSmall: | ||
| 47 | rows(Array(upcoming.prefix(3)), snapshot, compact: true, empty: "Nothing left today") | ||
| 48 | case .systemLarge: | ||
| 49 | rows(Array(upcoming.prefix(6)), snapshot, compact: false, empty: "Nothing left today") | ||
| 50 | if let tomorrow = snapshot.day(after: entry.date) { | ||
| 51 | let next = (tomorrow.rows + tomorrow.overdue).filter { !$0.isDone } | ||
| 52 | Divider() | ||
| 53 | Text("Tomorrow").font(.caption.weight(.semibold)).foregroundStyle(.secondary) | ||
| 54 | rows(Array(next.prefix(max(2, 9 - min(upcoming.count, 6)))), snapshot, compact: false, empty: "Nothing scheduled") | ||
| 55 | } | ||
| 56 | default: | ||
| 57 | rows(Array(upcoming.prefix(4)), snapshot, compact: false, empty: "Nothing left today") | ||
| 58 | } | ||
| 59 | Spacer(minLength: 0) | ||
| 60 | } | ||
| 61 | .frame(maxWidth: .infinity, alignment: .leading) | ||
| 62 | } | ||
| 63 | |||
| 64 | private func header(_ snapshot: AgendaSnapshot) -> some View { | ||
| 65 | let open = snapshot.openCount(at: entry.date) | ||
| 66 | let overdue = snapshot.overdueCount(at: entry.date) | ||
| 67 | return HStack(alignment: .firstTextBaseline, spacing: 6) { | ||
| 68 | Text(entry.date, format: family == .systemSmall ? .dateTime.weekday(.abbreviated).day() : .dateTime.weekday(.wide).day().month()) | ||
| 69 | .font(.subheadline.weight(.semibold)) | ||
| 70 | .foregroundStyle(snapshot.color("agenda-today", scheme) ?? .accentColor) | ||
| 71 | Spacer(minLength: 0) | ||
| 72 | if overdue > 0, family != .systemSmall { | ||
| 73 | Text("\(overdue) overdue") | ||
| 74 | .font(.caption2.weight(.semibold)) | ||
| 75 | .foregroundStyle(snapshot.day(at: entry.date)?.overdue.first?.statusColor?.color(scheme) ?? .red) | ||
| 76 | } | ||
| 77 | Text(family == .systemSmall ? "\(open)" : "\(open) open") | ||
| 78 | .font(.caption2.weight(.semibold)) | ||
| 79 | .foregroundStyle(.secondary) | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | @ViewBuilder | ||
| 84 | private func rows(_ rows: [AgendaSnapshot.Row], _ snapshot: AgendaSnapshot, compact: Bool, empty: String) -> some View { | ||
| 85 | if rows.isEmpty { | ||
| 86 | Text(empty).font(.caption).foregroundStyle(.secondary) | ||
| 87 | } | ||
| 88 | ForEach(rows) { row in | ||
| 89 | if compact { | ||
| 90 | SmallRow(row: row) | ||
| 91 | } else if let link = row.link { | ||
| 92 | Link(destination: link.url) { WideRow(row: row) } | ||
| 93 | } else { | ||
| 94 | WideRow(row: row) | ||
| 95 | } | ||
| 96 | } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | /// The gutter over the title. | ||
| 101 | struct SmallRow: View { | ||
| 102 | let row: AgendaSnapshot.Row | ||
| 103 | @Environment(\.colorScheme) private var scheme | ||
| 104 | |||
| 105 | var body: some View { | ||
| 106 | VStack(alignment: .leading, spacing: 0) { | ||
| 107 | Text(row.gutter) | ||
| 108 | .font(.caption2.weight(.medium).monospacedDigit()) | ||
| 109 | .foregroundStyle(row.statusColor?.color(scheme) ?? .secondary) | ||
| 110 | Text(row.title).font(.caption).lineLimit(1) | ||
| 111 | } | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | /// The gutter, keyword and priority badges, the title and the category's dot. | ||
| 116 | struct WideRow: View { | ||
| 117 | let row: AgendaSnapshot.Row | ||
| 118 | @Environment(\.colorScheme) private var scheme | ||
| 119 | |||
| 120 | var body: some View { | ||
| 121 | HStack(spacing: 6) { | ||
| 122 | Text(row.gutter) | ||
| 123 | .font(.caption2.weight(.medium).monospacedDigit()) | ||
| 124 | .foregroundStyle(row.statusColor?.color(scheme) ?? .secondary) | ||
| 125 | .lineLimit(1) | ||
| 126 | .frame(width: 72, alignment: .leading) | ||
| 127 | if let todo = row.todo { | ||
| 128 | let color = row.todoColor?.color(scheme) ?? .secondary | ||
| 129 | Text(todo) | ||
| 130 | .font(.system(size: 9, weight: .bold)) | ||
| 131 | .foregroundStyle(color) | ||
| 132 | .padding(.horizontal, 4) | ||
| 133 | .padding(.vertical, 1) | ||
| 134 | .background(color.opacity(0.14), in: Capsule()) | ||
| 135 | } | ||
| 136 | if let priority = row.priority { | ||
| 137 | let color = row.priorityColor?.color(scheme) ?? .orange | ||
| 138 | Text(priority) | ||
| 139 | .font(.system(size: 9, weight: .bold)) | ||
| 140 | .foregroundStyle(color) | ||
| 141 | .frame(width: 14, height: 14) | ||
| 142 | .overlay(Circle().strokeBorder(color, lineWidth: 1)) | ||
| 143 | } | ||
| 144 | Text(row.title).font(.caption).lineLimit(1) | ||
| 145 | Spacer(minLength: 0) | ||
| 146 | Circle().fill(row.categoryColor?.color(scheme) ?? .secondary).frame(width: 6, height: 6) | ||
| 147 | } | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | #Preview("Small", as: .systemSmall) { | ||
| 152 | TodayWidget() | ||
| 153 | } timeline: { | ||
| 154 | AgendaEntry(date: .now, snapshot: .sample(.now)) | ||
| 155 | } | ||
| 156 | |||
| 157 | #Preview("Medium", as: .systemMedium) { | ||
| 158 | TodayWidget() | ||
| 159 | } timeline: { | ||
| 160 | AgendaEntry(date: .now, snapshot: .sample(.now)) | ||
| 161 | } | ||
| 162 | |||
| 163 | #Preview("Large", as: .systemLarge) { | ||
| 164 | TodayWidget() | ||
| 165 | } timeline: { | ||
| 166 | AgendaEntry(date: .now, snapshot: .sample(.now)) | ||
| 167 | AgendaEntry(date: .now, snapshot: nil) | ||
| 168 | } | ||
Sources/OrgstarWidgets/UpNextWidget.swift added +83
| @@ -0,0 +1,83 @@ | |||
| 1 | import OrgApp | ||
| 2 | import SwiftUI | ||
| 3 | import WidgetKit | ||
| 4 | |||
| 5 | /// The agenda on the Lock Screen: the next entry (rectangular), the next entry or the count | ||
| 6 | /// (inline), today's open entries (circular). | ||
| 7 | struct UpNextWidget: Widget { | ||
| 8 | var body: some WidgetConfiguration { | ||
| 9 | StaticConfiguration(kind: "sh.krz.orgstar.up-next", provider: AgendaProvider()) { entry in | ||
| 10 | UpNextView(entry: entry) | ||
| 11 | } | ||
| 12 | .configurationDisplayName("Up Next") | ||
| 13 | .description("The next agenda entry, or how many are open today.") | ||
| 14 | .supportedFamilies([.accessoryRectangular, .accessoryInline, .accessoryCircular]) | ||
| 15 | } | ||
| 16 | } | ||
| 17 | |||
| 18 | struct UpNextView: View { | ||
| 19 | let entry: AgendaEntry | ||
| 20 | @Environment(\.widgetFamily) private var family | ||
| 21 | |||
| 22 | private var next: AgendaSnapshot.Row? { entry.snapshot?.upcoming(at: entry.date).first } | ||
| 23 | private var open: Int { entry.snapshot?.openCount(at: entry.date) ?? 0 } | ||
| 24 | |||
| 25 | var body: some View { | ||
| 26 | content | ||
| 27 | .widgetURL((next?.link ?? .agenda).url) | ||
| 28 | .containerBackground(for: .widget) { Color.clear } | ||
| 29 | } | ||
| 30 | |||
| 31 | @ViewBuilder | ||
| 32 | private var content: some View { | ||
| 33 | switch family { | ||
| 34 | case .accessoryInline: | ||
| 35 | if let next { | ||
| 36 | Text("\(next.gutter) \(next.title)") | ||
| 37 | } else { | ||
| 38 | Text(open == 0 ? "Agenda clear" : "\(open) open today") | ||
| 39 | } | ||
| 40 | case .accessoryCircular: | ||
| 41 | ZStack { | ||
| 42 | AccessoryWidgetBackground() | ||
| 43 | VStack(spacing: -2) { | ||
| 44 | Text("\(open)").font(.title2.weight(.semibold)).widgetAccentable() | ||
| 45 | Text("open").font(.caption2) | ||
| 46 | } | ||
| 47 | } | ||
| 48 | .accessibilityLabel("\(open) open today") | ||
| 49 | default: | ||
| 50 | if let next { | ||
| 51 | VStack(alignment: .leading, spacing: 0) { | ||
| 52 | Text(next.gutter).font(.headline).widgetAccentable().lineLimit(1) | ||
| 53 | Text(next.title).font(.body).lineLimit(2) | ||
| 54 | } | ||
| 55 | .frame(maxWidth: .infinity, alignment: .leading) | ||
| 56 | } else { | ||
| 57 | VStack(alignment: .leading, spacing: 0) { | ||
| 58 | Text("Agenda").font(.headline).widgetAccentable() | ||
| 59 | Text(entry.snapshot == nil ? "Open Orgstar" : "Nothing left today").font(.body) | ||
| 60 | } | ||
| 61 | .frame(maxWidth: .infinity, alignment: .leading) | ||
| 62 | } | ||
| 63 | } | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | #Preview("Rectangular", as: .accessoryRectangular) { | ||
| 68 | UpNextWidget() | ||
| 69 | } timeline: { | ||
| 70 | AgendaEntry(date: .now, snapshot: .sample(.now)) | ||
| 71 | } | ||
| 72 | |||
| 73 | #Preview("Inline", as: .accessoryInline) { | ||
| 74 | UpNextWidget() | ||
| 75 | } timeline: { | ||
| 76 | AgendaEntry(date: .now, snapshot: .sample(.now)) | ||
| 77 | } | ||
| 78 | |||
| 79 | #Preview("Circular", as: .accessoryCircular) { | ||
| 80 | UpNextWidget() | ||
| 81 | } timeline: { | ||
| 82 | AgendaEntry(date: .now, snapshot: .sample(.now)) | ||
| 83 | } | ||
ios/Orgstar.xcodeproj/project.pbxproj +134
| @@ -9,6 +9,8 @@ | |||
| 9 | /* Begin PBXBuildFile section */ | 9 | /* Begin PBXBuildFile section */ |
| 10 | 1B78003BBCE8A4B809333342 /* OrgApp in Frameworks */ = {isa = PBXBuildFile; productRef = A2BE626BBE45EA52880B6169 /* OrgApp */; }; | 10 | 1B78003BBCE8A4B809333342 /* OrgApp in Frameworks */ = {isa = PBXBuildFile; productRef = A2BE626BBE45EA52880B6169 /* OrgApp */; }; |
| 11 | 1E5861C0EFE1D96CDC21A22F /* OrgApp in Frameworks */ = {isa = PBXBuildFile; productRef = BA239181876756F7732397EB /* OrgApp */; }; | 11 | 1E5861C0EFE1D96CDC21A22F /* OrgApp in Frameworks */ = {isa = PBXBuildFile; productRef = BA239181876756F7732397EB /* OrgApp */; }; |
| 12 | 2BE799BF03ED43EAA6849F53 /* OrgApp in Frameworks */ = {isa = PBXBuildFile; productRef = EDEF22C5B4F393296F1D17BB /* OrgApp */; }; | ||
| 13 | 76BC65EF4BE629390064AE36 /* OrgstarWidgets.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = B54C32C5D364C02EE21DB092 /* OrgstarWidgets.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; | ||
| 12 | 80E85E72A5B727A15D7123D4 /* OrgstarQuickLook.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 54F0339BC26341A6010C1386 /* OrgstarQuickLook.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; | 14 | 80E85E72A5B727A15D7123D4 /* OrgstarQuickLook.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 54F0339BC26341A6010C1386 /* OrgstarQuickLook.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; |
| 13 | 9BE045FD696469CA8D19F22C /* OrgHighlight in Frameworks */ = {isa = PBXBuildFile; productRef = 47D54A361A74FE9E2B0722BB /* OrgHighlight */; }; | 15 | 9BE045FD696469CA8D19F22C /* OrgHighlight in Frameworks */ = {isa = PBXBuildFile; productRef = 47D54A361A74FE9E2B0722BB /* OrgHighlight */; }; |
| 14 | A05D351FCD8FE36B6A58E035 /* OrgstarShare.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D128CD70D4E88FAA82D23FD9 /* OrgstarShare.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; | 16 | A05D351FCD8FE36B6A58E035 /* OrgstarShare.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D128CD70D4E88FAA82D23FD9 /* OrgstarShare.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; |
| @@ -16,6 +18,13 @@ | |||
| 16 | /* End PBXBuildFile section */ | 18 | /* End PBXBuildFile section */ |
| 17 | 19 | ||
| 18 | /* Begin PBXContainerItemProxy section */ | 20 | /* Begin PBXContainerItemProxy section */ |
| 21 | 21312AB4CA947625620BE69C /* PBXContainerItemProxy */ = { | ||
| 22 | isa = PBXContainerItemProxy; | ||
| 23 | containerPortal = 46F86FAA6BBF9AC94A7E4595 /* Project object */; | ||
| 24 | proxyType = 1; | ||
| 25 | remoteGlobalIDString = E87BE20AFDC99FD25E1A163F; | ||
| 26 | remoteInfo = OrgstarWidgets; | ||
| 27 | }; | ||
| 19 | 5932E50A667F73AEF6E5FB26 /* PBXContainerItemProxy */ = { | 28 | 5932E50A667F73AEF6E5FB26 /* PBXContainerItemProxy */ = { |
| 20 | isa = PBXContainerItemProxy; | 29 | isa = PBXContainerItemProxy; |
| 21 | containerPortal = 46F86FAA6BBF9AC94A7E4595 /* Project object */; | 30 | containerPortal = 46F86FAA6BBF9AC94A7E4595 /* Project object */; |
| @@ -41,6 +50,7 @@ | |||
| 41 | files = ( | 50 | files = ( |
| 42 | A05D351FCD8FE36B6A58E035 /* OrgstarShare.appex in Embed Foundation Extensions */, | 51 | A05D351FCD8FE36B6A58E035 /* OrgstarShare.appex in Embed Foundation Extensions */, |
| 43 | 80E85E72A5B727A15D7123D4 /* OrgstarQuickLook.appex in Embed Foundation Extensions */, | 52 | 80E85E72A5B727A15D7123D4 /* OrgstarQuickLook.appex in Embed Foundation Extensions */, |
| 53 | 76BC65EF4BE629390064AE36 /* OrgstarWidgets.appex in Embed Foundation Extensions */, | ||
| 44 | ); | 54 | ); |
| 45 | name = "Embed Foundation Extensions"; | 55 | name = "Embed Foundation Extensions"; |
| 46 | runOnlyForDeploymentPostprocessing = 0; | 56 | runOnlyForDeploymentPostprocessing = 0; |
| @@ -52,6 +62,9 @@ | |||
| 52 | 1025FACEDEC31014F0AFA230 /* OrgstarShare/OrgstarShare.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = OrgstarShare/OrgstarShare.entitlements; sourceTree = "<group>"; }; | 62 | 1025FACEDEC31014F0AFA230 /* OrgstarShare/OrgstarShare.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = OrgstarShare/OrgstarShare.entitlements; sourceTree = "<group>"; }; |
| 53 | 48A21BB1AB1E70D4429DCDE4 /* OrgstarQuickLook/Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = OrgstarQuickLook/Info.plist; sourceTree = "<group>"; }; | 63 | 48A21BB1AB1E70D4429DCDE4 /* OrgstarQuickLook/Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = OrgstarQuickLook/Info.plist; sourceTree = "<group>"; }; |
| 54 | 54F0339BC26341A6010C1386 /* OrgstarQuickLook.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OrgstarQuickLook.appex; sourceTree = BUILT_PRODUCTS_DIR; }; | 64 | 54F0339BC26341A6010C1386 /* OrgstarQuickLook.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OrgstarQuickLook.appex; sourceTree = BUILT_PRODUCTS_DIR; }; |
| 65 | 6C2E41672FBF640AB5554A2B /* OrgstarWidgets/Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = OrgstarWidgets/Info.plist; sourceTree = "<group>"; }; | ||
| 66 | B54C32C5D364C02EE21DB092 /* OrgstarWidgets.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OrgstarWidgets.appex; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 67 | C0AFAE84CB7F8B19772BF250 /* OrgstarWidgets/OrgstarWidgets.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = OrgstarWidgets/OrgstarWidgets.entitlements; sourceTree = "<group>"; }; | ||
| 55 | D128CD70D4E88FAA82D23FD9 /* OrgstarShare.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OrgstarShare.appex; sourceTree = BUILT_PRODUCTS_DIR; }; | 68 | D128CD70D4E88FAA82D23FD9 /* OrgstarShare.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OrgstarShare.appex; sourceTree = BUILT_PRODUCTS_DIR; }; |
| 56 | D72184D78ACF70837216BCBF /* OrgstarShare/Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = OrgstarShare/Info.plist; sourceTree = "<group>"; }; | 69 | D72184D78ACF70837216BCBF /* OrgstarShare/Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = OrgstarShare/Info.plist; sourceTree = "<group>"; }; |
| 57 | ECD4A6B56983444E4E07CE63 /* Orgstar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Orgstar.app; sourceTree = BUILT_PRODUCTS_DIR; }; | 70 | ECD4A6B56983444E4E07CE63 /* Orgstar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Orgstar.app; sourceTree = BUILT_PRODUCTS_DIR; }; |
| @@ -97,6 +110,11 @@ | |||
| 97 | path = ../Sources/OrgstarMobile; | 110 | path = ../Sources/OrgstarMobile; |
| 98 | sourceTree = "<group>"; | 111 | sourceTree = "<group>"; |
| 99 | }; | 112 | }; |
| 113 | DE99BDA1BB90EEDFA8FF4CC2 /* ../Sources/OrgstarWidgets */ = { | ||
| 114 | isa = PBXFileSystemSynchronizedRootGroup; | ||
| 115 | path = ../Sources/OrgstarWidgets; | ||
| 116 | sourceTree = "<group>"; | ||
| 117 | }; | ||
| 100 | /* End PBXFileSystemSynchronizedRootGroup section */ | 118 | /* End PBXFileSystemSynchronizedRootGroup section */ |
| 101 | 119 | ||
| 102 | /* Begin PBXFrameworksBuildPhase section */ | 120 | /* Begin PBXFrameworksBuildPhase section */ |
| @@ -125,6 +143,14 @@ | |||
| 125 | ); | 143 | ); |
| 126 | runOnlyForDeploymentPostprocessing = 0; | 144 | runOnlyForDeploymentPostprocessing = 0; |
| 127 | }; | 145 | }; |
| 146 | AE22603FB5DE3C5FFFBBC68E /* Frameworks */ = { | ||
| 147 | isa = PBXFrameworksBuildPhase; | ||
| 148 | buildActionMask = 2147483647; | ||
| 149 | files = ( | ||
| 150 | 2BE799BF03ED43EAA6849F53 /* OrgApp in Frameworks */, | ||
| 151 | ); | ||
| 152 | runOnlyForDeploymentPostprocessing = 0; | ||
| 153 | }; | ||
| 128 | /* End PBXFrameworksBuildPhase section */ | 154 | /* End PBXFrameworksBuildPhase section */ |
| 129 | 155 | ||
| 130 | /* Begin PBXGroup section */ | 156 | /* Begin PBXGroup section */ |
| @@ -134,6 +160,7 @@ | |||
| 134 | ECD4A6B56983444E4E07CE63 /* Orgstar.app */, | 160 | ECD4A6B56983444E4E07CE63 /* Orgstar.app */, |
| 135 | D128CD70D4E88FAA82D23FD9 /* OrgstarShare.appex */, | 161 | D128CD70D4E88FAA82D23FD9 /* OrgstarShare.appex */, |
| 136 | 54F0339BC26341A6010C1386 /* OrgstarQuickLook.appex */, | 162 | 54F0339BC26341A6010C1386 /* OrgstarQuickLook.appex */, |
| 163 | B54C32C5D364C02EE21DB092 /* OrgstarWidgets.appex */, | ||
| 137 | ); | 164 | ); |
| 138 | name = Products; | 165 | name = Products; |
| 139 | sourceTree = "<group>"; | 166 | sourceTree = "<group>"; |
| @@ -144,6 +171,7 @@ | |||
| 144 | 6425CB8F177EDFF8EE2BD447 /* ../Sources/OrgstarShare */, | 171 | 6425CB8F177EDFF8EE2BD447 /* ../Sources/OrgstarShare */, |
| 145 | 2412EC8ED6427B76498FCD18 /* ../Sources/OrgstarQuickLook */, | 172 | 2412EC8ED6427B76498FCD18 /* ../Sources/OrgstarQuickLook */, |
| 146 | 7E85FA5E5BA11D0F6891693E /* ../Sources/OrgstarMobile */, | 173 | 7E85FA5E5BA11D0F6891693E /* ../Sources/OrgstarMobile */, |
| 174 | DE99BDA1BB90EEDFA8FF4CC2 /* ../Sources/OrgstarWidgets */, | ||
| 147 | 40FCC6CF7BFC065FCDD48D4E /* Support */, | 175 | 40FCC6CF7BFC065FCDD48D4E /* Support */, |
| 148 | 0A2C978E52A76F0AA9F68BB5 /* Products */, | 176 | 0A2C978E52A76F0AA9F68BB5 /* Products */, |
| 149 | ); | 177 | ); |
| @@ -157,6 +185,8 @@ | |||
| 157 | D72184D78ACF70837216BCBF /* OrgstarShare/Info.plist */, | 185 | D72184D78ACF70837216BCBF /* OrgstarShare/Info.plist */, |
| 158 | 1025FACEDEC31014F0AFA230 /* OrgstarShare/OrgstarShare.entitlements */, | 186 | 1025FACEDEC31014F0AFA230 /* OrgstarShare/OrgstarShare.entitlements */, |
| 159 | 48A21BB1AB1E70D4429DCDE4 /* OrgstarQuickLook/Info.plist */, | 187 | 48A21BB1AB1E70D4429DCDE4 /* OrgstarQuickLook/Info.plist */, |
| 188 | 6C2E41672FBF640AB5554A2B /* OrgstarWidgets/Info.plist */, | ||
| 189 | C0AFAE84CB7F8B19772BF250 /* OrgstarWidgets/OrgstarWidgets.entitlements */, | ||
| 160 | ); | 190 | ); |
| 161 | name = Support; | 191 | name = Support; |
| 162 | sourceTree = "<group>"; | 192 | sourceTree = "<group>"; |
| @@ -178,6 +208,7 @@ | |||
| 178 | dependencies = ( | 208 | dependencies = ( |
| 179 | 7F4807D68646366ED2DCA5C2 /* PBXTargetDependency */, | 209 | 7F4807D68646366ED2DCA5C2 /* PBXTargetDependency */, |
| 180 | B35F6E044645C7D88B689DC1 /* PBXTargetDependency */, | 210 | B35F6E044645C7D88B689DC1 /* PBXTargetDependency */, |
| 211 | D82DF00DA5607ABDDF199065 /* PBXTargetDependency */, | ||
| 181 | ); | 212 | ); |
| 182 | fileSystemSynchronizedGroups = ( | 213 | fileSystemSynchronizedGroups = ( |
| 183 | 7E85FA5E5BA11D0F6891693E /* ../Sources/OrgstarMobile */, | 214 | 7E85FA5E5BA11D0F6891693E /* ../Sources/OrgstarMobile */, |
| @@ -237,6 +268,29 @@ | |||
| 237 | productReference = 54F0339BC26341A6010C1386 /* OrgstarQuickLook.appex */; | 268 | productReference = 54F0339BC26341A6010C1386 /* OrgstarQuickLook.appex */; |
| 238 | productType = "com.apple.product-type.app-extension"; | 269 | productType = "com.apple.product-type.app-extension"; |
| 239 | }; | 270 | }; |
| 271 | E87BE20AFDC99FD25E1A163F /* OrgstarWidgets */ = { | ||
| 272 | isa = PBXNativeTarget; | ||
| 273 | buildConfigurationList = 14080276016DB67528B057D6 /* Build configuration list for PBXNativeTarget "OrgstarWidgets" */; | ||
| 274 | buildPhases = ( | ||
| 275 | 296E85448BDDDD3245D3D432 /* Sources */, | ||
| 276 | AE22603FB5DE3C5FFFBBC68E /* Frameworks */, | ||
| 277 | EA6C64E8D42ADCFBC3B131FF /* Resources */, | ||
| 278 | ); | ||
| 279 | buildRules = ( | ||
| 280 | ); | ||
| 281 | dependencies = ( | ||
| 282 | ); | ||
| 283 | fileSystemSynchronizedGroups = ( | ||
| 284 | DE99BDA1BB90EEDFA8FF4CC2 /* ../Sources/OrgstarWidgets */, | ||
| 285 | ); | ||
| 286 | name = OrgstarWidgets; | ||
| 287 | packageProductDependencies = ( | ||
| 288 | EDEF22C5B4F393296F1D17BB /* OrgApp */, | ||
| 289 | ); | ||
| 290 | productName = OrgstarWidgets; | ||
| 291 | productReference = B54C32C5D364C02EE21DB092 /* OrgstarWidgets.appex */; | ||
| 292 | productType = "com.apple.product-type.app-extension"; | ||
| 293 | }; | ||
| 240 | /* End PBXNativeTarget section */ | 294 | /* End PBXNativeTarget section */ |
| 241 | 295 | ||
| 242 | /* Begin PBXProject section */ | 296 | /* Begin PBXProject section */ |
| @@ -267,6 +321,7 @@ | |||
| 267 | 4E815AD2268DF19F304A2880 /* Orgstar iOS */, | 321 | 4E815AD2268DF19F304A2880 /* Orgstar iOS */, |
| 268 | 92364A1473ECC9B162FEAE51 /* OrgstarShare */, | 322 | 92364A1473ECC9B162FEAE51 /* OrgstarShare */, |
| 269 | BBA37636EB6BBA564493899D /* OrgstarQuickLook */, | 323 | BBA37636EB6BBA564493899D /* OrgstarQuickLook */, |
| 324 | E87BE20AFDC99FD25E1A163F /* OrgstarWidgets */, | ||
| 270 | ); | 325 | ); |
| 271 | }; | 326 | }; |
| 272 | /* End PBXProject section */ | 327 | /* End PBXProject section */ |
| @@ -293,9 +348,23 @@ | |||
| 293 | ); | 348 | ); |
| 294 | runOnlyForDeploymentPostprocessing = 0; | 349 | runOnlyForDeploymentPostprocessing = 0; |
| 295 | }; | 350 | }; |
| 351 | EA6C64E8D42ADCFBC3B131FF /* Resources */ = { | ||
| 352 | isa = PBXResourcesBuildPhase; | ||
| 353 | buildActionMask = 2147483647; | ||
| 354 | files = ( | ||
| 355 | ); | ||
| 356 | runOnlyForDeploymentPostprocessing = 0; | ||
| 357 | }; | ||
| 296 | /* End PBXResourcesBuildPhase section */ | 358 | /* End PBXResourcesBuildPhase section */ |
| 297 | 359 | ||
| 298 | /* Begin PBXSourcesBuildPhase section */ | 360 | /* Begin PBXSourcesBuildPhase section */ |
| 361 | 296E85448BDDDD3245D3D432 /* Sources */ = { | ||
| 362 | isa = PBXSourcesBuildPhase; | ||
| 363 | buildActionMask = 2147483647; | ||
| 364 | files = ( | ||
| 365 | ); | ||
| 366 | runOnlyForDeploymentPostprocessing = 0; | ||
| 367 | }; | ||
| 299 | 347F295A9254F751A96C2737 /* Sources */ = { | 368 | 347F295A9254F751A96C2737 /* Sources */ = { |
| 300 | isa = PBXSourcesBuildPhase; | 369 | isa = PBXSourcesBuildPhase; |
| 301 | buildActionMask = 2147483647; | 370 | buildActionMask = 2147483647; |
| @@ -330,6 +399,11 @@ | |||
| 330 | target = BBA37636EB6BBA564493899D /* OrgstarQuickLook */; | 399 | target = BBA37636EB6BBA564493899D /* OrgstarQuickLook */; |
| 331 | targetProxy = D0655711FB3B470A356B2D36 /* PBXContainerItemProxy */; | 400 | targetProxy = D0655711FB3B470A356B2D36 /* PBXContainerItemProxy */; |
| 332 | }; | 401 | }; |
| 402 | D82DF00DA5607ABDDF199065 /* PBXTargetDependency */ = { | ||
| 403 | isa = PBXTargetDependency; | ||
| 404 | target = E87BE20AFDC99FD25E1A163F /* OrgstarWidgets */; | ||
| 405 | targetProxy = 21312AB4CA947625620BE69C /* PBXContainerItemProxy */; | ||
| 406 | }; | ||
| 333 | /* End PBXTargetDependency section */ | 407 | /* End PBXTargetDependency section */ |
| 334 | 408 | ||
| 335 | /* Begin XCBuildConfiguration section */ | 409 | /* Begin XCBuildConfiguration section */ |
| @@ -419,6 +493,29 @@ | |||
| 419 | }; | 493 | }; |
| 420 | name = Release; | 494 | name = Release; |
| 421 | }; | 495 | }; |
| 496 | 7BCEB4BC70BB3B62775CDCFB /* Debug */ = { | ||
| 497 | isa = XCBuildConfiguration; | ||
| 498 | buildSettings = { | ||
| 499 | CODE_SIGN_ENTITLEMENTS = OrgstarWidgets/OrgstarWidgets.entitlements; | ||
| 500 | CODE_SIGN_STYLE = Automatic; | ||
| 501 | CURRENT_PROJECT_VERSION = 1; | ||
| 502 | DEVELOPMENT_TEAM = ZCNAX3VL9D; | ||
| 503 | GENERATE_INFOPLIST_FILE = NO; | ||
| 504 | INFOPLIST_FILE = OrgstarWidgets/Info.plist; | ||
| 505 | IPHONEOS_DEPLOYMENT_TARGET = 26.0; | ||
| 506 | LD_RUNPATH_SEARCH_PATHS = ( | ||
| 507 | "$(inherited)", | ||
| 508 | "@executable_path/Frameworks", | ||
| 509 | "@executable_path/../../Frameworks", | ||
| 510 | ); | ||
| 511 | MARKETING_VERSION = 0.1.0; | ||
| 512 | PRODUCT_BUNDLE_IDENTIFIER = sh.krz.orgstar.widgets; | ||
| 513 | PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| 514 | SKIP_INSTALL = YES; | ||
| 515 | TARGETED_DEVICE_FAMILY = "1,2"; | ||
| 516 | }; | ||
| 517 | name = Debug; | ||
| 518 | }; | ||
| 422 | 942C95A5D90B164020736D83 /* Debug */ = { | 519 | 942C95A5D90B164020736D83 /* Debug */ = { |
| 423 | isa = XCBuildConfiguration; | 520 | isa = XCBuildConfiguration; |
| 424 | buildSettings = { | 521 | buildSettings = { |
| @@ -478,6 +575,29 @@ | |||
| 478 | }; | 575 | }; |
| 479 | name = Debug; | 576 | name = Debug; |
| 480 | }; | 577 | }; |
| 578 | E2365A4C43B017487EC51861 /* Release */ = { | ||
| 579 | isa = XCBuildConfiguration; | ||
| 580 | buildSettings = { | ||
| 581 | CODE_SIGN_ENTITLEMENTS = OrgstarWidgets/OrgstarWidgets.entitlements; | ||
| 582 | CODE_SIGN_STYLE = Automatic; | ||
| 583 | CURRENT_PROJECT_VERSION = 1; | ||
| 584 | DEVELOPMENT_TEAM = ZCNAX3VL9D; | ||
| 585 | GENERATE_INFOPLIST_FILE = NO; | ||
| 586 | INFOPLIST_FILE = OrgstarWidgets/Info.plist; | ||
| 587 | IPHONEOS_DEPLOYMENT_TARGET = 26.0; | ||
| 588 | LD_RUNPATH_SEARCH_PATHS = ( | ||
| 589 | "$(inherited)", | ||
| 590 | "@executable_path/Frameworks", | ||
| 591 | "@executable_path/../../Frameworks", | ||
| 592 | ); | ||
| 593 | MARKETING_VERSION = 0.1.0; | ||
| 594 | PRODUCT_BUNDLE_IDENTIFIER = sh.krz.orgstar.widgets; | ||
| 595 | PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| 596 | SKIP_INSTALL = YES; | ||
| 597 | TARGETED_DEVICE_FAMILY = "1,2"; | ||
| 598 | }; | ||
| 599 | name = Release; | ||
| 600 | }; | ||
| 481 | F25EF7827B5210B4D9103995 /* Debug */ = { | 601 | F25EF7827B5210B4D9103995 /* Debug */ = { |
| 482 | isa = XCBuildConfiguration; | 602 | isa = XCBuildConfiguration; |
| 483 | buildSettings = { | 603 | buildSettings = { |
| @@ -501,6 +621,15 @@ | |||
| 501 | /* End XCBuildConfiguration section */ | 621 | /* End XCBuildConfiguration section */ |
| 502 | 622 | ||
| 503 | /* Begin XCConfigurationList section */ | 623 | /* Begin XCConfigurationList section */ |
| 624 | 14080276016DB67528B057D6 /* Build configuration list for PBXNativeTarget "OrgstarWidgets" */ = { | ||
| 625 | isa = XCConfigurationList; | ||
| 626 | buildConfigurations = ( | ||
| 627 | 7BCEB4BC70BB3B62775CDCFB /* Debug */, | ||
| 628 | E2365A4C43B017487EC51861 /* Release */, | ||
| 629 | ); | ||
| 630 | defaultConfigurationIsVisible = 0; | ||
| 631 | defaultConfigurationName = Release; | ||
| 632 | }; | ||
| 504 | 30435AE6E633F256CC883684 /* Build configuration list for PBXProject "Orgstar" */ = { | 633 | 30435AE6E633F256CC883684 /* Build configuration list for PBXProject "Orgstar" */ = { |
| 505 | isa = XCConfigurationList; | 634 | isa = XCConfigurationList; |
| 506 | buildConfigurations = ( | 635 | buildConfigurations = ( |
| @@ -567,6 +696,11 @@ | |||
| 567 | package = A46A1BCE0B67C45BEC8F435B /* XCLocalSwiftPackageReference ".." */; | 696 | package = A46A1BCE0B67C45BEC8F435B /* XCLocalSwiftPackageReference ".." */; |
| 568 | productName = OrgApp; | 697 | productName = OrgApp; |
| 569 | }; | 698 | }; |
| 699 | EDEF22C5B4F393296F1D17BB /* OrgApp */ = { | ||
| 700 | isa = XCSwiftPackageProductDependency; | ||
| 701 | package = A46A1BCE0B67C45BEC8F435B /* XCLocalSwiftPackageReference ".." */; | ||
| 702 | productName = OrgApp; | ||
| 703 | }; | ||
| 570 | /* End XCSwiftPackageProductDependency section */ | 704 | /* End XCSwiftPackageProductDependency section */ |
| 571 | }; | 705 | }; |
| 572 | rootObject = 46F86FAA6BBF9AC94A7E4595 /* Project object */; | 706 | rootObject = 46F86FAA6BBF9AC94A7E4595 /* Project object */; |
ios/OrgstarWidgets/Info.plist added +25
| @@ -0,0 +1,25 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| 3 | <plist version="1.0"> | ||
| 4 | <dict> | ||
| 5 | <key>CFBundleIdentifier</key> | ||
| 6 | <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
| 7 | <key>CFBundleName</key> | ||
| 8 | <string>$(PRODUCT_NAME)</string> | ||
| 9 | <key>CFBundleDisplayName</key> | ||
| 10 | <string>Orgstar</string> | ||
| 11 | <key>CFBundleExecutable</key> | ||
| 12 | <string>$(EXECUTABLE_NAME)</string> | ||
| 13 | <key>CFBundlePackageType</key> | ||
| 14 | <string>XPC!</string> | ||
| 15 | <key>CFBundleShortVersionString</key> | ||
| 16 | <string>$(MARKETING_VERSION)</string> | ||
| 17 | <key>CFBundleVersion</key> | ||
| 18 | <string>$(CURRENT_PROJECT_VERSION)</string> | ||
| 19 | <key>NSExtension</key> | ||
| 20 | <dict> | ||
| 21 | <key>NSExtensionPointIdentifier</key> | ||
| 22 | <string>com.apple.widgetkit-extension</string> | ||
| 23 | </dict> | ||
| 24 | </dict> | ||
| 25 | </plist> | ||
ios/OrgstarWidgets/OrgstarWidgets.entitlements added +8
| @@ -0,0 +1,8 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| 3 | <plist version="1.0"> | ||
| 4 | <dict> | ||
| 5 | <key>com.apple.security.application-groups</key> | ||
| 6 | <array><string>group.sh.krz.orgstar</string></array> | ||
| 7 | </dict> | ||
| 8 | </plist> | ||