87 Commits

Author SHA1 Message Date
neon443
b7ef7b4e19 add app type 2025-06-15 21:31:48 +01:00
neon443
7727f14ad4 Merge branch 'feat-mac' 2025-06-15 21:25:25 +01:00
neon443
e4107a2faa add success haptic and indentation 2025-06-15 21:24:15 +01:00
neon443
5ec16dd67a fix editing events on mac and ios
toolbar label()s instead of buton("label")s
fix event add/delete/tick animation
fix event complete progress on ios and mac and that it just spazzed out
browsing true for symbols browsing (not picking)
2025-06-15 21:18:58 +01:00
neon443
0cffe243eb completeevent button has a custo progress bar to work on ios aswell
extracted the com[lete button
2025-06-15 18:55:38 +01:00
neon443
6533fb85ed fix editing events 2025-06-15 15:41:37 +01:00
neon443
5c667679d5 fix "new edit event window" on mac not working
- it would save events with the same id and modify the previous one if u opened another one
add symbols to ios
date picker looks better mac
2025-06-15 15:34:08 +01:00
neon443
5dd25f1ede locked the freak in for this one -
can cancel events being completed!!!!!
added a cancel to symbolpicker
and made it dip after choosing
extracted completevent into viewmodel
eventlistview is pretty full rn -- need to cleana
added color picker ot addeventview wtf why wasnt it there
2025-06-14 21:32:11 +01:00
neon443
d80011ea27 remove my shitty uikit 2025-06-14 18:55:09 +01:00
neon443
a40d4f4300 ui cleanup 2025-06-14 18:53:34 +01:00
neon443
22af9fc060 hell nah fuck this 2025-06-14 18:27:13 +01:00
neon443
2dd2c51059 uikit shenanigans: collectionview for the symbol picker?? 2025-06-14 17:45:38 +01:00
neon443
4c9e72fad2 viewmodifier for backwards compat 2025-06-14 11:20:29 +01:00
neon443
cb26c69492 added a little help fow when nothing matches search 2025-06-14 11:17:41 +01:00
neon443
13ef94ea3e custom symbols picker 2025-06-14 10:59:48 +01:00
neon443
6e5b7adbc4 fix editing events on mac - they now reload on he fly
add search on mac
fix symbolspicker on mac
2025-06-14 10:24:03 +01:00
neon443
659f14d5a3 add events on mac 2025-06-13 22:00:28 +01:00
neon443
0663ba9e59 add settings on mac
add whats new on mac
clean up settings on ios
clean up whats new + liquid glass
2025-06-13 21:28:37 +01:00
neon443
6e7bc6c2d1 add viewmodifiers.siwft to conditionally do viewmodifiers
replaced all the .apply s everywhere
colorcodable into its own file
add icon changing for mac
2025-06-13 18:30:07 +01:00
neon443
3f21074091 moved icloud ui functions into viewModel
- idk why it was in the view
added settings for mac
fix addeventview
export view pasteboard for mac
move accent icon to new file
Archive view reversed - new to old
2025-06-13 17:15:23 +01:00
neon443
ee2e05c523 fix the cooked addeventview 2025-06-11 18:49:09 +01:00
neon443
e9e19e2659 Large rework:
Liquid Glass:
- remove ultrathinmaterial from all sheets
- button color change

remove the eventName eventDate etcs and replaced with an event var

Add addeventview for mac, cleanup #if s

clean up homeview
add .searchable
addeventview is horizontal i have no idea why
2025-06-11 18:34:17 +01:00
neon443
5ce48a4bc2 add new buttons 2025-06-10 15:09:10 +01:00
neon443
a7e09692f6 liquid glass update 1 2025-06-10 13:14:19 +01:00
neon443
559f891719 new liquid glass icon 2025-06-10 12:28:03 +01:00
neon443
2ef000458f minor concurrency improvements 2025-05-29 18:32:54 +01:00
Nihaal Sharma
d5580e52f5 Update README.md 2025-05-29 17:29:37 +01:00
Nihaal Sharma
84a7091e05 Update README.md 2025-05-29 17:22:53 +01:00
neon443
69047010d7 made it better 2025-05-28 15:47:55 +01:00
neon443
dfb1dae545 added a cancel button, extract logic 2025-05-28 14:52:43 +01:00
neon443
0f3b86fe8c New: custom alert for merge/replace imported events 2025-05-28 14:47:05 +01:00
neon443
1902c5102c can now edit events, need to make it apply on the fly
added about window
2025-05-28 13:42:53 +01:00
neon443
1179810ac2 move to contentview
add homeView
respect show completed events in home
archive view
move inot contentview
new mac icon
remove mac icons from the variants
2025-05-28 12:59:35 +01:00
neon443
dfc3a9290a mac icons for all the color variants 2025-05-28 11:47:37 +01:00
neon443
7236f0640e asset catalog: add mac &watchos icons 2025-05-28 11:32:08 +01:00
Nihaal Sharma
44b40894e4 Delete .github directory 2025-05-26 18:04:30 +01:00
Nihaal Sharma
e4842bd29a Update ios.yml 2025-05-26 18:02:37 +01:00
Nihaal Sharma
b378a831be Update ios.yml 2025-05-26 17:57:31 +01:00
Nihaal Sharma
2ff96a7093 Update ios.yml 2025-05-26 17:52:13 +01:00
Nihaal Sharma
4f5e31a6f3 Update ios.yml 2025-05-26 17:51:01 +01:00
Nihaal Sharma
266b27d817 Create ios.yml 2025-05-26 17:49:06 +01:00
neon443
d1c1144ad8 you asked for the haptics... 2025-05-21 21:43:47 +01:00
neon443
bcfe23a17e info plist shenanigans for ios 2025-05-21 20:53:35 +01:00
neon443
74ef5db2cf trying to impement a menu bar 2025-05-21 20:50:53 +01:00
neon443
389fdf6812 fix taget memberships and Settings -> NFSettings 2025-05-21 20:41:01 +01:00
neon443
b153d127a6 fix padding on the eventlistView extract settings to Settings.swift rename some files 2025-05-21 20:38:54 +01:00
neon443
62318c5ddc mac ui 2025-05-21 18:10:22 +01:00
neon443
773a083682 making mac ui 2025-05-21 17:21:04 +01:00
neon443
e051d73b7e declared types on all views, trying to make a nice mac app 2025-05-21 17:02:21 +01:00
neon443
4bf33d50d6 moved colours to tints.xcassets 2025-05-21 15:37:32 +01:00
neon443
74603cc588 fixed appkit and uikit conflicts 2025-05-21 15:28:35 +01:00
neon443
ed016217db added item and assets to macnearfuture 2025-05-21 14:52:55 +01:00
neon443
a64eb03cad add Mac target and delet tests 2025-05-21 14:45:04 +01:00
neon443
7c7f72a5d4 more reorgs 2025-05-21 14:40:50 +01:00
neon443
831305ba55 massive reorg: source and assets 2025-05-21 14:20:05 +01:00
neon443
69856e2857 fix concurrency warinings 2025-05-21 14:16:54 +01:00
neon443
7be2e3848a reorg 2025-05-21 14:14:40 +01:00
neon443
db05da3043 add haptic feedback, bump version, update whats new 2025-05-19 15:13:38 +01:00
neon443
940a8f4ebd haptic on tab selection, remove divider 2025-05-19 15:08:34 +01:00
neon443
48071c0791 remove th goof button 2025-05-19 15:03:49 +01:00
neon443
3a94dc7675 app intents make me wanna kms 2025-05-16 09:49:14 +01:00
neon443
08bf56ecbd ajsdlkfjkl;asdjfkl 2025-05-15 18:52:23 +01:00
neon443
008eecb52c ddfsdfsd 2025-05-15 18:41:03 +01:00
neon443
c640c77600 dskljfasdlkfjkl;asjfklajsdkl;fjaksd;jfgkladfjhghadfiughaipehroigjuoeirjgfioejroifjaoigjoiaejoirg 2025-05-15 18:30:02 +01:00
neon443
e9d49cc137 pls pls pls b fixed 2025-05-15 18:00:22 +01:00
neon443
565341c3d0 s 2025-05-15 17:32:04 +01:00
neon443
f9c50df47f s 2025-05-15 17:27:27 +01:00
neon443
bb598250a6 modified: Config.xcconfig 2025-05-15 17:22:25 +01:00
neon443
c7fddda601 ssfdafasfasdfaf 2025-05-15 17:06:58 +01:00
neon443
033a01463f fix icon setting fr this time 2025-05-15 12:31:53 +01:00
neon443
87209f38f3 jfdsa 2025-05-15 07:46:37 +01:00
neon443
7c852fc8ec fix the whats new appearing each settings save 2025-05-14 21:42:22 +01:00
neon443
73b3d9b234 update widget
to imporve readablity and add red for past
bump version
add whats new
2025-05-14 21:20:55 +01:00
neon443
0a17ec6292 bump version adn update whats new 2025-05-14 21:16:35 +01:00
neon443
bb67b0ce98 YESSSSSSSSS
ok now jsut have ot make this scalabel 😭
😭😭😭
2025-05-14 21:04:00 +01:00
neon443
82341f40ef ajkl;dfs;asfjl;laskdjf;ajsf 2025-05-14 20:51:02 +01:00
neon443
f9f030c8b3 app icon yayyyyy 2025-05-14 19:25:22 +01:00
neon443
3ca5017b61 remove basic ui color 2025-05-13 19:36:34 +01:00
neon443
0efcc9e183 bump version to 4.2.1(1) 2025-05-13 11:07:23 +01:00
neon443
595c2b74c5 fixed whatsnewview's horizontal layout 2025-05-13 11:07:03 +01:00
neon443
f252359eb1 bump version, update whats new 2025-05-13 11:00:31 +01:00
neon443
2b266e03ca fix whats new showing every time
prevAppVersoin wasnt being set lol
remove .searchable()
rename WhatsNew -> WhatsNewChunk
2025-05-13 10:59:22 +01:00
neon443
c935d4b1f0 improve whats new
added a global getdevice icon thingy
2025-05-12 21:07:51 +01:00
neon443
c82ce5fa17 Whats New!
add AboutView
move getVersion() and geBuildID()
reorg of presentaion related modifiers
2025-05-12 20:49:28 +01:00
neon443
7bef3bc4e6 animations make me wanna kms
animations!!!!!!!!! on add, delete and ticking yayy
sorts on load
extract contentview to HomeView, its got too indented loll
2025-05-12 19:24:34 +01:00
neon443
025dbf22cd tring to ad animations 2025-05-12 17:26:37 +01:00
neon443
da65c3ac69 asdkjlf 2025-05-09 14:14:15 +01:00
127 changed files with 2968 additions and 1749 deletions

View File

@@ -12,6 +12,6 @@ TEAM_ID = 8JGND254B7
BUNDLE_ID = com.neon443.NearFuture
BUNDLE_ID_WIDGETS = com.neon443.NearFuture.widgets
GROUP_ID = group.NearFuture
VERSION = 4.0.0
VERSION = 5
NAME = Near Future
BUILD_NUMBER = 0
BUILD_NUMBER = 1

View File

@@ -0,0 +1,40 @@
//
// AboutView.swift
// MacNearFuture
//
// Created by neon443 on 28/05/2025.
//
import SwiftUI
struct AboutView: View {
var body: some View {
VStack(alignment: .center) {
Image(nsImage: #imageLiteral(resourceName: "NearFutureIcon.png"))
.resizable()
.scaledToFit()
.frame(width: 100)
.clipShape(RoundedRectangle(cornerRadius: 25))
Text("Near Future")
.bold()
.monospaced()
.font(.title)
Text("Version " + getVersion() + " (\(getBuildID()))")
.padding(.bottom)
Text("© 2024-2025 neon443, Inc")
.padding(.bottom)
Link("Developer Website", destination: URL(string: "https://neon443.xyz")!)
}
.padding()
.padding()
.containerBackground(.ultraThinMaterial, for: .window)
.toolbar(removing: .title)
.toolbarBackground(.hidden, for: .windowToolbar)
.windowMinimizeBehavior(.disabled)
.windowFullScreenBehavior(.disabled)
}
}
#Preview {
AboutView()
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.icloud-container-identifiers</key>
<array/>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.NearFuture</string>
</array>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,72 @@
//
// MacNearFutureApp.swift
// MacNearFuture
//
// Created by neon443 on 21/05/2025.
//
import Foundation
import SwiftUI
@main
struct NearFutureApp: App {
@Environment(\.openWindow) var openWindow
@StateObject var viewModel: EventViewModel = EventViewModel()
@StateObject var settingsModel: SettingsViewModel = SettingsViewModel()
var body: some Scene {
WindowGroup {
ContentView(
viewModel: viewModel,
settingsModel: settingsModel
)
}
.defaultSize(width: 550, height: 650)
.commands {
CommandGroup(replacing: CommandGroupPlacement.appInfo) {
Button("About Near Future") {
openWindow(id: "about")
}
}
NearFutureCommands()
}
WindowGroup("Edit Event", for: Event.ID.self) { $eventID in
if viewModel.events.first(where: {$0.id == eventID}) == nil {
AddEventView(
viewModel: viewModel
)
} else {
EditEventView(
viewModel: viewModel,
event: Binding(
get: {
viewModel.events.first(where: {$0.id == eventID}) ?? viewModel.template
},
set: { newValue in
viewModel.editEvent(newValue)
}
)
)
}
}
.defaultSize(width: 480, height: 550)
.windowIdealSize(.fitToContent)
.restorationBehavior(.disabled)
Window("About Near Future", id: "about") {
AboutView()
}
.windowBackgroundDragBehavior(.enabled)
.windowResizability(.contentSize)
.restorationBehavior(.disabled)
.defaultPosition(UnitPoint.center)
Settings {
SettingsView(
viewModel: viewModel,
settingsModel: settingsModel
)
}
}
}

View File

@@ -0,0 +1,17 @@
//
// NFCommands.swift
// MacNearFuture
//
// Created by neon443 on 21/05/2025.
//
import Foundation
import SwiftUI
struct NearFutureCommands: Commands {
var body: some Commands {
CommandGroup(after: CommandGroupPlacement.appInfo) {
// Text("hi")
}
}
}

View File

@@ -0,0 +1,33 @@
//
// ArchiveView.swift
// MacNearFuture
//
// Created by neon443 on 28/05/2025.
//
import SwiftUI
struct ArchiveView: View {
@StateObject var viewModel: EventViewModel
@StateObject var settingsModel: SettingsViewModel
var filteredEvents: [Event] {
return viewModel.events.filter { $0.complete }
}
var body: some View {
ScrollView {
ForEach(filteredEvents) { event in
EventListView(viewModel: viewModel, event: event)
}
}
.scrollContentBackground(.hidden)
}
}
#Preview {
ArchiveView(
viewModel: dummyEventViewModel(),
settingsModel: dummySettingsViewModel()
)
}

View File

@@ -0,0 +1,88 @@
//
// ContentView.swift
// MacNearFuture
//
// Created by neon443 on 21/05/2025.
//
import SwiftUI
struct ContentView: View {
@StateObject var viewModel: EventViewModel
@StateObject var settingsModel: SettingsViewModel
@State private var showAddEventView: Bool = false
@State private var symbolSearchInput: String = ""
var body: some View {
NavigationSplitView {
List {
NavigationLink {
HomeView(
viewModel: viewModel,
settingsModel: settingsModel
)
} label: {
Image(systemName: "house")
Text("Home")
}
NavigationLink {
ArchiveView(
viewModel: viewModel,
settingsModel: settingsModel
)
} label: {
Image(systemName: "tray.full")
Text("Archive")
}
NavigationLink {
SymbolsPicker(
selection: .constant(""),
browsing: true
)
} label: {
Image(systemName: "star.circle")
Text("Symbols")
}
NavigationLink {
SettingsView(
viewModel: viewModel,
settingsModel: settingsModel
)
} label: {
Image(systemName: "gear")
Text("Settings")
}
}
} detail: {
Text("Welcome to Near Future")
}
.tint(settingsModel.settings.tint.color)
.frame(minWidth: 450, minHeight: 550)
.containerBackground(.regularMaterial, for: .window)
.sheet(isPresented: $settingsModel.settings.showWhatsNew) {
WhatsNewView(settingsModel: settingsModel)
.presentationSizing(.form)
}
.sheet(isPresented: $showAddEventView) {
AddEventView(
viewModel: viewModel
)
.presentationSizing(.page)
}
.toolbar {
Button() {
showAddEventView.toggle()
} label: {
Label("New", systemImage: "plus")
}
}
}
}
#Preview {
ContentView(
viewModel: dummyEventViewModel(),
settingsModel: dummySettingsViewModel()
)
}

View File

@@ -0,0 +1,50 @@
//
// HomeView.swift
// MacNearFuture
//
// Created by neon443 on 28/05/2025.
//
import SwiftUI
struct HomeView: View {
@StateObject var viewModel: EventViewModel
@StateObject var settingsModel: SettingsViewModel
@State private var searchInput: String = ""
var filteredEvents: [Event] {
if searchInput.isEmpty {
if settingsModel.settings.showCompletedInHome {
return viewModel.events
} else {
return viewModel.events.filter() { !$0.complete }
}
} else {
return viewModel.events.filter {
$0.name.localizedCaseInsensitiveContains(searchInput) ||
$0.notes.localizedCaseInsensitiveContains(searchInput)
}
}
}
var body: some View {
ScrollView {
ForEach(viewModel.events) { event in
if filteredEvents.contains(event) {
EventListView(viewModel: viewModel, event: event)
.id(event)
}
}
}
.searchable(text: $searchInput)
.scrollContentBackground(.hidden)
}
}
#Preview {
HomeView(
viewModel: dummyEventViewModel(),
settingsModel: dummySettingsViewModel()
)
}

View File

@@ -0,0 +1,155 @@
//
// SettingsView.swift
// NearFuture
//
// Created by neon443 on 13/06/2025.
//
import SwiftUI
struct SettingsView: View {
@ObservedObject var viewModel: EventViewModel
@ObservedObject var settingsModel: SettingsViewModel
@State private var importStr: String = ""
func changeIcon(to toIcon: String) {
if let nsimage = NSImage(named: toIcon) {
let nsImageView = NSImageView(image: nsimage)
nsImageView.frame = NSRect(x: 0, y: 0, width: 128, height: 128)
NSApplication.shared.dockTile.contentView = nsImageView
NSApplication.shared.dockTile.display()
}
}
var body: some View {
NavigationStack {
List {
ScrollView(.horizontal) {
HStack {
ForEach(settingsModel.accentChoices, id: \.self) { choice in
let color = Color(nsColor: NSColor(named: "uiColors/\(choice)")!)
ZStack {
Button() {
settingsModel.changeTint(to: choice)
changeIcon(to: choice)
} label: {
Circle()
.foregroundStyle(color)
.frame(width: 30)
}
.buttonStyle(.plain)
if ColorCodable(color) == settingsModel.settings.tint {
let needContrast: Bool = ColorCodable(color) == settingsModel.settings.tint
Circle()
.foregroundStyle(needContrast ? .two : .one)
.frame(width: 10)
}
}
}
}
}
Button("Show What's New") {
settingsModel.settings.showWhatsNew = true
}
Toggle("Show completed Events in Home", isOn: $settingsModel.settings.showCompletedInHome)
.onChange(of: settingsModel.settings.showCompletedInHome) { _ in
settingsModel.saveSettings()
}
NavigationLink() {
List {
if !settingsModel.notifsGranted {
Text("\(Image(systemName: "xmark")) Notifications disabled for Near Future")
.foregroundStyle(.red)
Button("Request Notifications") {
Task.detached {
let requestNotifsResult = await requestNotifs()
await MainActor.run {
settingsModel.notifsGranted = requestNotifsResult
}
}
}
} else {
Text("\(Image(systemName: "checkmark")) Notifications enabled for Near Future")
.foregroundStyle(.green)
}
}
} label: {
Image(systemName: "bell.badge.fill")
Text("Notifications")
}
NavigationLink() {
iCloudSettingsView(
viewModel: viewModel,
settingsModel: settingsModel
)
} label: {
HStack {
Image(systemName: "icloud.fill")
Text("iCloud")
Spacer()
Circle()
.frame(width: 20, height: 20)
.foregroundStyle(viewModel.iCloudStatusColor)
}
}
.onAppear {
viewModel.sync()
viewModel.updateiCStatus()
}
NavigationLink() {
ImportView(viewModel: viewModel, importStr: $importStr)
} label: {
Label("Import Events", systemImage: "tray.and.arrow.down.fill")
.foregroundStyle(.one)
}
NavigationLink() {
ExportView(viewModel: viewModel)
} label: {
Label("Export Events", systemImage: "square.and.arrow.up")
.foregroundStyle(.one)
}
Text("Tip")
.font(.subheadline)
Text("Near Future has Widgets!")
Text("Danger Zone")
.foregroundStyle(.red)
.font(.subheadline)
Button("Delete local data", role: .destructive) {
viewModel.dangerClearLocalData()
}
Button("Delete iCloud data", role: .destructive) {
viewModel.dangerCleariCloudData()
}
Button("Delete all data", role: .destructive) {
viewModel.dangerClearLocalData()
viewModel.dangerCleariCloudData()
}
Text("Debug")
.foregroundStyle(.red)
.font(.subheadline)
Button("Reset UserDefaults", role: .destructive) {
viewModel.dangerResetLocalData()
}
Button("Reset iCloud", role: .destructive) {
viewModel.dangerResetiCloud()
}
// AboutView()
.modifier(navigationInlineLarge())
.scrollContentBackground(.hidden)
}
}
}
}
#Preview {
SettingsView(
viewModel: dummyEventViewModel(),
settingsModel: dummySettingsViewModel()
)
}

View File

@@ -7,11 +7,44 @@
objects = {
/* Begin PBXBuildFile section */
A90D49382DDE0FAF00781124 /* ContentViewMac.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D49332DDE0FAF00781124 /* ContentViewMac.swift */; };
A90D493D2DDE10B200781124 /* NearFutureIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = A949F8312DCAAA8A0064DCA0 /* NearFutureIcon.png */; };
A90D493E2DDE10CF00781124 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A920C28D2D24011A00E4F9B1 /* Assets.xcassets */; };
A90D49422DDE114100781124 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Events.swift */; };
A90D49442DDE1C7600781124 /* Tints.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A90D49432DDE1C1100781124 /* Tints.xcassets */; };
A90D49452DDE1C7600781124 /* Tints.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A90D49432DDE1C1100781124 /* Tints.xcassets */; };
A90D49462DDE1C7A00781124 /* Tints.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A90D49432DDE1C1100781124 /* Tints.xcassets */; };
A90D49522DDE2D0000781124 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D49512DDE2D0000781124 /* Extensions.swift */; };
A90D49532DDE2D0000781124 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D49512DDE2D0000781124 /* Extensions.swift */; };
A90D495B2DDE2EDB00781124 /* MacNearFutureApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D495A2DDE2EDB00781124 /* MacNearFutureApp.swift */; };
A90D495E2DDE3C7400781124 /* NFCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D495D2DDE3C7400781124 /* NFCommands.swift */; };
A90D495F2DDE3C7400781124 /* NFCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D495D2DDE3C7400781124 /* NFCommands.swift */; };
A90D49612DDE626300781124 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D49602DDE626300781124 /* Settings.swift */; };
A90D49622DDE626300781124 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D49602DDE626300781124 /* Settings.swift */; };
A90D49632DDE626300781124 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D49602DDE626300781124 /* Settings.swift */; };
A914FA4B2DD26C6800856265 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914FA4A2DD26C0F00856265 /* HomeView.swift */; };
A914FA4D2DD2768900856265 /* WhatsNewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914FA4C2DD2768900856265 /* WhatsNewView.swift */; };
A914FA4F2DD276D200856265 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914FA4E2DD276D200856265 /* AboutView.swift */; };
A91EF8072DFC8B8B00B8463D /* ColorCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF8062DFC8B8B00B8463D /* ColorCodable.swift */; };
A91EF8082DFC8B8B00B8463D /* ColorCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF8062DFC8B8B00B8463D /* ColorCodable.swift */; };
A91EF8092DFC8B8B00B8463D /* ColorCodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF8062DFC8B8B00B8463D /* ColorCodable.swift */; };
A91EF80B2DFC910000B8463D /* ViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF80A2DFC910000B8463D /* ViewModifiers.swift */; };
A91EF80C2DFC910000B8463D /* ViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF80A2DFC910000B8463D /* ViewModifiers.swift */; };
A91EF80D2DFC910000B8463D /* ViewModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF80A2DFC910000B8463D /* ViewModifiers.swift */; };
A91EF80E2DFC9A0C00B8463D /* WhatsNewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914FA4C2DD2768900856265 /* WhatsNewView.swift */; };
A91EF8102DFCB66C00B8463D /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF80F2DFCB66C00B8463D /* SettingsView.swift */; };
A91EF8132DFCC87D00B8463D /* EditEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F83D2DCAABE00064DCA0 /* EditEventView.swift */; };
A91EF8142DFCC87D00B8463D /* AddEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F83C2DCAABE00064DCA0 /* AddEventView.swift */; };
A91EF8182DFD77BF00B8463D /* SymbolsLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF8172DFD77BF00B8463D /* SymbolsLoader.swift */; };
A91EF8192DFD77BF00B8463D /* SymbolsLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF8172DFD77BF00B8463D /* SymbolsLoader.swift */; };
A91EF81A2DFD77BF00B8463D /* SymbolsLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF8172DFD77BF00B8463D /* SymbolsLoader.swift */; };
A91EF81C2DFD796600B8463D /* SymbolsPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF81B2DFD796600B8463D /* SymbolsPicker.swift */; };
A91EF81D2DFD796600B8463D /* SymbolsPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF81B2DFD796600B8463D /* SymbolsPicker.swift */; };
A91EF81E2DFD796600B8463D /* SymbolsPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91EF81B2DFD796600B8463D /* SymbolsPicker.swift */; };
A920C2882D24011400E4F9B1 /* NearFutureApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C2872D24011400E4F9B1 /* NearFutureApp.swift */; };
A920C28C2D24011400E4F9B1 /* Item.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Item.swift */; };
A920C28C2D24011400E4F9B1 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Events.swift */; };
A920C28E2D24011A00E4F9B1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A920C28D2D24011A00E4F9B1 /* Assets.xcassets */; };
A920C2922D24011A00E4F9B1 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A920C2912D24011A00E4F9B1 /* Preview Assets.xcassets */; };
A920C2BE2D24021A00E4F9B1 /* SFSymbolsPicker in Frameworks */ = {isa = PBXBuildFile; productRef = A920C2BD2D24021A00E4F9B1 /* SFSymbolsPicker */; };
A949F8322DCAAA8A0064DCA0 /* NearFutureIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = A949F8312DCAAA8A0064DCA0 /* NearFutureIcon.png */; };
A949F84B2DCAABE00064DCA0 /* ArchiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F83A2DCAABE00064DCA0 /* ArchiveView.swift */; };
A949F84C2DCAABE00064DCA0 /* AddEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F83C2DCAABE00064DCA0 /* AddEventView.swift */; };
@@ -24,16 +57,25 @@
A949F8532DCAABE00064DCA0 /* ImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8452DCAABE00064DCA0 /* ImportView.swift */; };
A949F8542DCAABE00064DCA0 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8462DCAABE00064DCA0 /* SettingsView.swift */; };
A949F8552DCAABE00064DCA0 /* StatsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8482DCAABE00064DCA0 /* StatsView.swift */; };
A949F8562DCAABE00064DCA0 /* ExportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8432DCAABE00064DCA0 /* ExportView.swift */; };
A949F8592DCAAD670064DCA0 /* NearFutureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8572DCAAD670064DCA0 /* NearFutureTests.swift */; };
A949F85F2DCABB420064DCA0 /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F85D2DCABB420064DCA0 /* Buttons.swift */; };
A979F6052D270AF00094C0B3 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A979F6042D270AF00094C0B3 /* WidgetKit.framework */; };
A979F6072D270AF00094C0B3 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A979F6062D270AF00094C0B3 /* SwiftUI.framework */; };
A95E9ED32DFC703200ED655F /* iCloudSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8442DCAABE00064DCA0 /* iCloudSettingsView.swift */; };
A95E9ED82DFC742B00ED655F /* AccentIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95E9ED72DFC742B00ED655F /* AccentIcon.swift */; };
A95E9ED92DFC742B00ED655F /* AccentIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95E9ED72DFC742B00ED655F /* AccentIcon.swift */; };
A95E9EDA2DFC742B00ED655F /* AccentIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95E9ED72DFC742B00ED655F /* AccentIcon.swift */; };
A95E9EE42DFC77D400ED655F /* ImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8452DCAABE00064DCA0 /* ImportView.swift */; };
A95E9EE52DFC77E200ED655F /* ExportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8432DCAABE00064DCA0 /* ExportView.swift */; };
A96609E72DFD800000DBFA78 /* HelpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8412DCAABE00064DCA0 /* HelpView.swift */; };
A979F60A2D270AF00094C0B3 /* NearFutureWidgetsBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A979F6092D270AF00094C0B3 /* NearFutureWidgetsBundle.swift */; };
A979F60C2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A979F60B2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift */; };
A979F6102D270AF90094C0B3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A979F60F2D270AF80094C0B3 /* Assets.xcassets */; };
A979F6142D270AF90094C0B3 /* NearFutureWidgetsExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = A979F6022D270AF00094C0B3 /* NearFutureWidgetsExtension.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
A979F6182D2714310094C0B3 /* Item.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Item.swift */; };
A979F6182D2714310094C0B3 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Events.swift */; };
A98C20CE2DE7308E0008D61C /* ArchiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CD2DE7308E0008D61C /* ArchiveView.swift */; };
A98C20D02DE731BD0008D61C /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CF2DE731BD0008D61C /* HomeView.swift */; };
A98C20D42DE7339E0008D61C /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20D32DE7339E0008D61C /* AboutView.swift */; };
A9BAC6882DFF242300EC8E44 /* CompleteEventButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BAC6872DFF238100EC8E44 /* CompleteEventButton.swift */; };
A9BAC6892DFF242300EC8E44 /* CompleteEventButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9BAC6872DFF238100EC8E44 /* CompleteEventButton.swift */; };
A9D1C34D2DFE10FA00703C2D /* EventListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8402DCAABE00064DCA0 /* EventListView.swift */; };
A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */; };
/* End PBXBuildFile section */
@@ -45,12 +87,12 @@
remoteGlobalIDString = A979F6012D270AF00094C0B3;
remoteInfo = NearFutureWidgetsExtension;
};
A980FC3B2D93FB2B006A778F /* PBXContainerItemProxy */ = {
A98C20D12DE732B10008D61C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = A920C27C2D24011300E4F9B1 /* Project object */;
proxyType = 1;
remoteGlobalIDString = A920C2832D24011300E4F9B1;
remoteInfo = NearFuture;
remoteGlobalIDString = A979F6012D270AF00094C0B3;
remoteInfo = NearFutureWidgetsExtension;
};
/* End PBXContainerItemProxy section */
@@ -69,12 +111,29 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
A90D491F2DDE08E400781124 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
A90D49262DDE0FA400781124 /* Near Future.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Near Future.app"; sourceTree = BUILT_PRODUCTS_DIR; };
A90D49332DDE0FAF00781124 /* ContentViewMac.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentViewMac.swift; sourceTree = "<group>"; };
A90D49342DDE0FAF00781124 /* MacNearFuture.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MacNearFuture.entitlements; sourceTree = "<group>"; };
A90D49432DDE1C1100781124 /* Tints.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Tints.xcassets; sourceTree = "<group>"; };
A90D49512DDE2D0000781124 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
A90D495A2DDE2EDB00781124 /* MacNearFutureApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MacNearFutureApp.swift; path = MacNearFuture/MacNearFutureApp.swift; sourceTree = SOURCE_ROOT; };
A90D495D2DDE3C7400781124 /* NFCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NFCommands.swift; sourceTree = "<group>"; };
A90D49602DDE626300781124 /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
A90D49652DDE658100781124 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A90FDE222DC0D4310012790C /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
A914FA4A2DD26C0F00856265 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; };
A914FA4C2DD2768900856265 /* WhatsNewView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WhatsNewView.swift; path = NearFuture/Views/Settings/WhatsNewView.swift; sourceTree = SOURCE_ROOT; };
A914FA4E2DD276D200856265 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AboutView.swift; path = NearFuture/Views/Misc/AboutView.swift; sourceTree = SOURCE_ROOT; };
A91EF8062DFC8B8B00B8463D /* ColorCodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorCodable.swift; sourceTree = "<group>"; };
A91EF80A2DFC910000B8463D /* ViewModifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewModifiers.swift; sourceTree = "<group>"; };
A91EF80F2DFCB66C00B8463D /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
A91EF8172DFD77BF00B8463D /* SymbolsLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SymbolsLoader.swift; sourceTree = "<group>"; };
A91EF81B2DFD796600B8463D /* SymbolsPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SymbolsPicker.swift; sourceTree = "<group>"; };
A920C2842D24011400E4F9B1 /* NearFuture.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NearFuture.app; sourceTree = BUILT_PRODUCTS_DIR; };
A920C2872D24011400E4F9B1 /* NearFutureApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureApp.swift; sourceTree = "<group>"; };
A920C28B2D24011400E4F9B1 /* Item.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Item.swift; sourceTree = "<group>"; };
A920C28B2D24011400E4F9B1 /* Events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Events.swift; sourceTree = "<group>"; };
A920C28D2D24011A00E4F9B1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
A920C28F2D24011A00E4F9B1 /* NearFuture.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NearFuture.entitlements; sourceTree = "<group>"; };
A920C2912D24011A00E4F9B1 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
A949F82E2DCAAA640064DCA0 /* NearFutureIcon.pxd */ = {isa = PBXFileReference; lastKnownFileType = file; path = NearFutureIcon.pxd; sourceTree = "<group>"; };
A949F82F2DCAAA640064DCA0 /* NearFutureIconDark.pxd */ = {isa = PBXFileReference; lastKnownFileType = file; path = NearFutureIconDark.pxd; sourceTree = "<group>"; };
@@ -91,46 +150,35 @@
A949F8452DCAABE00064DCA0 /* ImportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportView.swift; sourceTree = "<group>"; };
A949F8462DCAABE00064DCA0 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
A949F8482DCAABE00064DCA0 /* StatsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsView.swift; sourceTree = "<group>"; };
A949F8572DCAAD670064DCA0 /* NearFutureTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureTests.swift; sourceTree = "<group>"; };
A949F85D2DCABB420064DCA0 /* Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Buttons.swift; sourceTree = "<group>"; };
A979F58B2D2700680094C0B3 /* NearFutureWidgetsBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgetsBundle.swift; sourceTree = "<group>"; };
A979F58D2D2700680094C0B3 /* NearFutureWidgetsLiveActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgetsLiveActivity.swift; sourceTree = "<group>"; };
A979F58F2D2700680094C0B3 /* NearFutureWidgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgets.swift; sourceTree = "<group>"; };
A979F5912D2700680094C0B3 /* AppIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIntent.swift; sourceTree = "<group>"; };
A979F5932D27006D0094C0B3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
A979F5952D27006D0094C0B3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A95E9ED72DFC742B00ED655F /* AccentIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccentIcon.swift; sourceTree = "<group>"; };
A979F6022D270AF00094C0B3 /* NearFutureWidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NearFutureWidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
A979F6042D270AF00094C0B3 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
A979F6062D270AF00094C0B3 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
A979F6092D270AF00094C0B3 /* NearFutureWidgetsBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgetsBundle.swift; sourceTree = "<group>"; };
A979F60B2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgetsLiveActivity.swift; sourceTree = "<group>"; };
A979F60F2D270AF80094C0B3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
A979F6112D270AF90094C0B3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A980FC302D920097006A778F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
A980FC372D93FB2B006A778F /* NearFutureTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NearFutureTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
A9C05E412D2805D7007DC497 /* NearFutureWidgetsExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NearFutureWidgetsExtension.entitlements; sourceTree = "<group>"; };
A98C20CD2DE7308E0008D61C /* ArchiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchiveView.swift; sourceTree = "<group>"; };
A98C20CF2DE731BD0008D61C /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; };
A98C20D32DE7339E0008D61C /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
A9BAC6872DFF238100EC8E44 /* CompleteEventButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompleteEventButton.swift; sourceTree = "<group>"; };
A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgets.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
A90D49232DDE0FA400781124 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
A920C2812D24011300E4F9B1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A920C2BE2D24021A00E4F9B1 /* SFSymbolsPicker in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
A979F5FF2D270AF00094C0B3 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
A979F6072D270AF00094C0B3 /* SwiftUI.framework in Frameworks */,
A979F6052D270AF00094C0B3 /* WidgetKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
A980FC342D93FB2B006A778F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -140,15 +188,80 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
A90D49202DDE0A3B00781124 /* Model */ = {
isa = PBXGroup;
children = (
A920C28B2D24011400E4F9B1 /* Events.swift */,
A90D49602DDE626300781124 /* Settings.swift */,
A91EF8062DFC8B8B00B8463D /* ColorCodable.swift */,
A95E9ED72DFC742B00ED655F /* AccentIcon.swift */,
A91EF8162DFD77A500B8463D /* SymbolsPicker */,
);
path = Model;
sourceTree = "<group>";
};
A90D49362DDE0FAF00781124 /* MacNearFuture */ = {
isa = PBXGroup;
children = (
A90D495A2DDE2EDB00781124 /* MacNearFutureApp.swift */,
A98C20D32DE7339E0008D61C /* AboutView.swift */,
A90D495D2DDE3C7400781124 /* NFCommands.swift */,
A90D493F2DDE10EC00781124 /* Views */,
A90D49342DDE0FAF00781124 /* MacNearFuture.entitlements */,
);
path = MacNearFuture;
sourceTree = "<group>";
};
A90D493F2DDE10EC00781124 /* Views */ = {
isa = PBXGroup;
children = (
A90D49332DDE0FAF00781124 /* ContentViewMac.swift */,
A98C20CF2DE731BD0008D61C /* HomeView.swift */,
A98C20CD2DE7308E0008D61C /* ArchiveView.swift */,
A91EF80F2DFCB66C00B8463D /* SettingsView.swift */,
);
path = Views;
sourceTree = "<group>";
};
A90D49412DDE112700781124 /* Shared */ = {
isa = PBXGroup;
children = (
A920C2872D24011400E4F9B1 /* NearFutureApp.swift */,
A90D49512DDE2D0000781124 /* Extensions.swift */,
A90D49202DDE0A3B00781124 /* Model */,
A91EF80A2DFC910000B8463D /* ViewModifiers.swift */,
A9BAC6872DFF238100EC8E44 /* CompleteEventButton.swift */,
);
path = Shared;
sourceTree = "<group>";
};
A90D49542DDE2D5800781124 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
A91EF8162DFD77A500B8463D /* SymbolsPicker */ = {
isa = PBXGroup;
children = (
A91EF8172DFD77BF00B8463D /* SymbolsLoader.swift */,
A91EF81B2DFD796600B8463D /* SymbolsPicker.swift */,
);
path = SymbolsPicker;
sourceTree = "<group>";
};
A920C27B2D24011300E4F9B1 = {
isa = PBXGroup;
children = (
A90D491F2DDE08E400781124 /* README.md */,
A90FDE222DC0D4310012790C /* Config.xcconfig */,
A949F8002DCAA0340064DCA0 /* Resources */,
A90D49412DDE112700781124 /* Shared */,
A920C2862D24011400E4F9B1 /* NearFuture */,
A90D49362DDE0FAF00781124 /* MacNearFuture */,
A949F8002DCAA0340064DCA0 /* Resources */,
A979F6082D270AF00094C0B3 /* NearFutureWidgets */,
A949F8582DCAAD670064DCA0 /* NearFutureTests */,
A979F6032D270AF00094C0B3 /* Frameworks */,
A90D49542DDE2D5800781124 /* Frameworks */,
A920C2852D24011400E4F9B1 /* Products */,
);
sourceTree = "<group>";
@@ -158,7 +271,7 @@
children = (
A920C2842D24011400E4F9B1 /* NearFuture.app */,
A979F6022D270AF00094C0B3 /* NearFutureWidgetsExtension.appex */,
A980FC372D93FB2B006A778F /* NearFutureTests.xctest */,
A90D49262DDE0FA400781124 /* Near Future.app */,
);
name = Products;
sourceTree = "<group>";
@@ -166,11 +279,7 @@
A920C2862D24011400E4F9B1 /* NearFuture */ = {
isa = PBXGroup;
children = (
A920C2872D24011400E4F9B1 /* NearFutureApp.swift */,
A920C28B2D24011400E4F9B1 /* Item.swift */,
A949F84A2DCAABE00064DCA0 /* Views */,
A980FC302D920097006A778F /* Info.plist */,
A920C28F2D24011A00E4F9B1 /* NearFuture.entitlements */,
A920C2902D24011A00E4F9B1 /* Preview Content */,
);
path = NearFuture;
@@ -179,7 +288,6 @@
A920C2902D24011A00E4F9B1 /* Preview Content */ = {
isa = PBXGroup;
children = (
A979F58A2D2700680094C0B3 /* NearFutureWidgets */,
A920C2912D24011A00E4F9B1 /* Preview Assets.xcassets */,
);
path = "Preview Content";
@@ -190,6 +298,7 @@
children = (
A949F8312DCAAA8A0064DCA0 /* NearFutureIcon.png */,
A920C28D2D24011A00E4F9B1 /* Assets.xcassets */,
A90D49432DDE1C1100781124 /* Tints.xcassets */,
A949F82E2DCAAA640064DCA0 /* NearFutureIcon.pxd */,
A949F82F2DCAAA640064DCA0 /* NearFutureIconDark.pxd */,
A949F8302DCAAA640064DCA0 /* NearFutureIconTint.pxd */,
@@ -217,7 +326,7 @@
A949F8422DCAABE00064DCA0 /* Home */ = {
isa = PBXGroup;
children = (
A949F83F2DCAABE00064DCA0 /* ContentView.swift */,
A914FA4A2DD26C0F00856265 /* HomeView.swift */,
A949F8402DCAABE00064DCA0 /* EventListView.swift */,
A949F8412DCAABE00064DCA0 /* HelpView.swift */,
);
@@ -227,10 +336,11 @@
A949F8472DCAABE00064DCA0 /* Settings */ = {
isa = PBXGroup;
children = (
A949F8432DCAABE00064DCA0 /* ExportView.swift */,
A949F8442DCAABE00064DCA0 /* iCloudSettingsView.swift */,
A949F8452DCAABE00064DCA0 /* ImportView.swift */,
A949F8462DCAABE00064DCA0 /* SettingsView.swift */,
A949F8442DCAABE00064DCA0 /* iCloudSettingsView.swift */,
A914FA4C2DD2768900856265 /* WhatsNewView.swift */,
A949F8452DCAABE00064DCA0 /* ImportView.swift */,
A949F8432DCAABE00064DCA0 /* ExportView.swift */,
);
path = Settings;
sourceTree = "<group>";
@@ -246,54 +356,26 @@
A949F84A2DCAABE00064DCA0 /* Views */ = {
isa = PBXGroup;
children = (
A949F83B2DCAABE00064DCA0 /* Archive */,
A949F83E2DCAABE00064DCA0 /* Events */,
A949F83F2DCAABE00064DCA0 /* ContentView.swift */,
A949F8422DCAABE00064DCA0 /* Home */,
A949F8472DCAABE00064DCA0 /* Settings */,
A949F8492DCAABE00064DCA0 /* Stats */,
A949F83E2DCAABE00064DCA0 /* Events */,
A949F83B2DCAABE00064DCA0 /* Archive */,
A949F85E2DCABB420064DCA0 /* Misc */,
A949F8492DCAABE00064DCA0 /* Stats */,
A949F8472DCAABE00064DCA0 /* Settings */,
);
path = Views;
sourceTree = "<group>";
};
A949F8582DCAAD670064DCA0 /* NearFutureTests */ = {
isa = PBXGroup;
children = (
A949F8572DCAAD670064DCA0 /* NearFutureTests.swift */,
);
path = NearFutureTests;
sourceTree = "<group>";
};
A949F85E2DCABB420064DCA0 /* Misc */ = {
isa = PBXGroup;
children = (
A949F85D2DCABB420064DCA0 /* Buttons.swift */,
A914FA4E2DD276D200856265 /* AboutView.swift */,
);
path = Misc;
sourceTree = "<group>";
};
A979F58A2D2700680094C0B3 /* NearFutureWidgets */ = {
isa = PBXGroup;
children = (
A979F58B2D2700680094C0B3 /* NearFutureWidgetsBundle.swift */,
A979F58D2D2700680094C0B3 /* NearFutureWidgetsLiveActivity.swift */,
A979F58F2D2700680094C0B3 /* NearFutureWidgets.swift */,
A979F5912D2700680094C0B3 /* AppIntent.swift */,
A979F5932D27006D0094C0B3 /* Assets.xcassets */,
A979F5952D27006D0094C0B3 /* Info.plist */,
);
path = NearFutureWidgets;
sourceTree = "<group>";
};
A979F6032D270AF00094C0B3 /* Frameworks */ = {
isa = PBXGroup;
children = (
A979F6042D270AF00094C0B3 /* WidgetKit.framework */,
A979F6062D270AF00094C0B3 /* SwiftUI.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
A979F6082D270AF00094C0B3 /* NearFutureWidgets */ = {
isa = PBXGroup;
children = (
@@ -301,8 +383,7 @@
A979F6092D270AF00094C0B3 /* NearFutureWidgetsBundle.swift */,
A979F60B2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift */,
A979F60F2D270AF80094C0B3 /* Assets.xcassets */,
A979F6112D270AF90094C0B3 /* Info.plist */,
A9C05E412D2805D7007DC497 /* NearFutureWidgetsExtension.entitlements */,
A90D49652DDE658100781124 /* Info.plist */,
);
path = NearFutureWidgets;
sourceTree = "<group>";
@@ -310,6 +391,26 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
A90D49252DDE0FA400781124 /* MacNearFuture */ = {
isa = PBXNativeTarget;
buildConfigurationList = A90D492F2DDE0FA600781124 /* Build configuration list for PBXNativeTarget "MacNearFuture" */;
buildPhases = (
A90D49222DDE0FA400781124 /* Sources */,
A90D49232DDE0FA400781124 /* Frameworks */,
A90D49242DDE0FA400781124 /* Resources */,
);
buildRules = (
);
dependencies = (
A98C20D22DE732B10008D61C /* PBXTargetDependency */,
);
name = MacNearFuture;
packageProductDependencies = (
);
productName = MacNearFuture;
productReference = A90D49262DDE0FA400781124 /* Near Future.app */;
productType = "com.apple.product-type.application";
};
A920C2832D24011300E4F9B1 /* NearFuture */ = {
isa = PBXNativeTarget;
buildConfigurationList = A920C2AB2D24011B00E4F9B1 /* Build configuration list for PBXNativeTarget "NearFuture" */;
@@ -326,7 +427,6 @@
);
name = NearFuture;
packageProductDependencies = (
A920C2BD2D24021A00E4F9B1 /* SFSymbolsPicker */,
);
productName = NearFuture;
productReference = A920C2842D24011400E4F9B1 /* NearFuture.app */;
@@ -349,26 +449,6 @@
productReference = A979F6022D270AF00094C0B3 /* NearFutureWidgetsExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
A980FC362D93FB2B006A778F /* NearFutureTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = A980FC3D2D93FB2B006A778F /* Build configuration list for PBXNativeTarget "NearFutureTests" */;
buildPhases = (
A980FC332D93FB2B006A778F /* Sources */,
A980FC342D93FB2B006A778F /* Frameworks */,
A980FC352D93FB2B006A778F /* Resources */,
);
buildRules = (
);
dependencies = (
A980FC3C2D93FB2B006A778F /* PBXTargetDependency */,
);
name = NearFutureTests;
packageProductDependencies = (
);
productName = NearFutureTests;
productReference = A980FC372D93FB2B006A778F /* NearFutureTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -376,19 +456,18 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1620;
LastSwiftUpdateCheck = 1640;
LastUpgradeCheck = 1630;
TargetAttributes = {
A90D49252DDE0FA400781124 = {
CreatedOnToolsVersion = 16.4;
};
A920C2832D24011300E4F9B1 = {
CreatedOnToolsVersion = 15.4;
};
A979F6012D270AF00094C0B3 = {
CreatedOnToolsVersion = 15.4;
};
A980FC362D93FB2B006A778F = {
CreatedOnToolsVersion = 16.2;
TestTargetID = A920C2832D24011300E4F9B1;
};
};
};
buildConfigurationList = A920C27F2D24011300E4F9B1 /* Build configuration list for PBXProject "NearFuture" */;
@@ -401,24 +480,34 @@
);
mainGroup = A920C27B2D24011300E4F9B1;
packageReferences = (
A920C2BC2D24021900E4F9B1 /* XCRemoteSwiftPackageReference "SFSymbolsPicker" */,
);
productRefGroup = A920C2852D24011400E4F9B1 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
A920C2832D24011300E4F9B1 /* NearFuture */,
A90D49252DDE0FA400781124 /* MacNearFuture */,
A979F6012D270AF00094C0B3 /* NearFutureWidgetsExtension */,
A980FC362D93FB2B006A778F /* NearFutureTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
A90D49242DDE0FA400781124 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A90D49452DDE1C7600781124 /* Tints.xcassets in Resources */,
A90D493E2DDE10CF00781124 /* Assets.xcassets in Resources */,
A90D493D2DDE10B200781124 /* NearFutureIcon.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
A920C2822D24011300E4F9B1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A90D49442DDE1C7600781124 /* Tints.xcassets in Resources */,
A920C2922D24011A00E4F9B1 /* Preview Assets.xcassets in Resources */,
A949F8322DCAAA8A0064DCA0 /* NearFutureIcon.png in Resources */,
A920C28E2D24011A00E4F9B1 /* Assets.xcassets in Resources */,
@@ -429,37 +518,74 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A90D49462DDE1C7A00781124 /* Tints.xcassets in Resources */,
A979F6102D270AF90094C0B3 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
A980FC352D93FB2B006A778F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
A90D49222DDE0FA400781124 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A91EF80E2DFC9A0C00B8463D /* WhatsNewView.swift in Sources */,
A91EF8192DFD77BF00B8463D /* SymbolsLoader.swift in Sources */,
A95E9EE42DFC77D400ED655F /* ImportView.swift in Sources */,
A9BAC6892DFF242300EC8E44 /* CompleteEventButton.swift in Sources */,
A91EF80C2DFC910000B8463D /* ViewModifiers.swift in Sources */,
A95E9ED92DFC742B00ED655F /* AccentIcon.swift in Sources */,
A91EF8102DFCB66C00B8463D /* SettingsView.swift in Sources */,
A90D495E2DDE3C7400781124 /* NFCommands.swift in Sources */,
A95E9EE52DFC77E200ED655F /* ExportView.swift in Sources */,
A91EF8132DFCC87D00B8463D /* EditEventView.swift in Sources */,
A91EF8142DFCC87D00B8463D /* AddEventView.swift in Sources */,
A9D1C34D2DFE10FA00703C2D /* EventListView.swift in Sources */,
A98C20D42DE7339E0008D61C /* AboutView.swift in Sources */,
A98C20CE2DE7308E0008D61C /* ArchiveView.swift in Sources */,
A98C20D02DE731BD0008D61C /* HomeView.swift in Sources */,
A90D495B2DDE2EDB00781124 /* MacNearFutureApp.swift in Sources */,
A91EF8082DFC8B8B00B8463D /* ColorCodable.swift in Sources */,
A90D49522DDE2D0000781124 /* Extensions.swift in Sources */,
A91EF81D2DFD796600B8463D /* SymbolsPicker.swift in Sources */,
A90D49422DDE114100781124 /* Events.swift in Sources */,
A90D49382DDE0FAF00781124 /* ContentViewMac.swift in Sources */,
A90D49622DDE626300781124 /* Settings.swift in Sources */,
A95E9ED32DFC703200ED655F /* iCloudSettingsView.swift in Sources */,
A96609E72DFD800000DBFA78 /* HelpView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
A920C2802D24011300E4F9B1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A920C28C2D24011400E4F9B1 /* Item.swift in Sources */,
A920C28C2D24011400E4F9B1 /* Events.swift in Sources */,
A949F84B2DCAABE00064DCA0 /* ArchiveView.swift in Sources */,
A914FA4F2DD276D200856265 /* AboutView.swift in Sources */,
A949F84C2DCAABE00064DCA0 /* AddEventView.swift in Sources */,
A914FA4B2DD26C6800856265 /* HomeView.swift in Sources */,
A949F84D2DCAABE00064DCA0 /* EditEventView.swift in Sources */,
A949F84E2DCAABE00064DCA0 /* ContentView.swift in Sources */,
A90D49612DDE626300781124 /* Settings.swift in Sources */,
A90D495F2DDE3C7400781124 /* NFCommands.swift in Sources */,
A949F84F2DCAABE00064DCA0 /* EventListView.swift in Sources */,
A91EF8092DFC8B8B00B8463D /* ColorCodable.swift in Sources */,
A949F8502DCAABE00064DCA0 /* HelpView.swift in Sources */,
A949F85F2DCABB420064DCA0 /* Buttons.swift in Sources */,
A914FA4D2DD2768900856265 /* WhatsNewView.swift in Sources */,
A91EF80B2DFC910000B8463D /* ViewModifiers.swift in Sources */,
A949F8512DCAABE00064DCA0 /* ExportView.swift in Sources */,
A95E9ED82DFC742B00ED655F /* AccentIcon.swift in Sources */,
A90D49532DDE2D0000781124 /* Extensions.swift in Sources */,
A949F8522DCAABE00064DCA0 /* iCloudSettingsView.swift in Sources */,
A9BAC6882DFF242300EC8E44 /* CompleteEventButton.swift in Sources */,
A949F8532DCAABE00064DCA0 /* ImportView.swift in Sources */,
A949F8542DCAABE00064DCA0 /* SettingsView.swift in Sources */,
A91EF81E2DFD796600B8463D /* SymbolsPicker.swift in Sources */,
A949F8552DCAABE00064DCA0 /* StatsView.swift in Sources */,
A91EF81A2DFD77BF00B8463D /* SymbolsLoader.swift in Sources */,
A920C2882D24011400E4F9B1 /* NearFutureApp.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -468,19 +594,16 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A979F6182D2714310094C0B3 /* Item.swift in Sources */,
A979F6182D2714310094C0B3 /* Events.swift in Sources */,
A91EF81C2DFD796600B8463D /* SymbolsPicker.swift in Sources */,
A979F60A2D270AF00094C0B3 /* NearFutureWidgetsBundle.swift in Sources */,
A95E9EDA2DFC742B00ED655F /* AccentIcon.swift in Sources */,
A91EF80D2DFC910000B8463D /* ViewModifiers.swift in Sources */,
A91EF8182DFD77BF00B8463D /* SymbolsLoader.swift in Sources */,
A91EF8072DFC8B8B00B8463D /* ColorCodable.swift in Sources */,
A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */,
A979F60C2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
A980FC332D93FB2B006A778F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A949F8592DCAAD670064DCA0 /* NearFutureTests.swift in Sources */,
A949F8562DCAABE00064DCA0 /* ExportView.swift in Sources */,
A90D49632DDE626300781124 /* Settings.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -493,19 +616,86 @@
target = A979F6012D270AF00094C0B3 /* NearFutureWidgetsExtension */;
targetProxy = A979F6122D270AF90094C0B3 /* PBXContainerItemProxy */;
};
A980FC3C2D93FB2B006A778F /* PBXTargetDependency */ = {
A98C20D22DE732B10008D61C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = A920C2832D24011300E4F9B1 /* NearFuture */;
targetProxy = A980FC3B2D93FB2B006A778F /* PBXContainerItemProxy */;
target = A979F6012D270AF00094C0B3 /* NearFutureWidgetsExtension */;
targetProxy = A98C20D12DE732B10008D61C /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
A90D49302DDE0FA600781124 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = A90FDE222DC0D4310012790C /* Config.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "bloo blue green pink purple red yellow";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = MacNearFuture/MacNearFuture.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = "$(BUILD_NUMBER)";
DEVELOPMENT_TEAM = 8JGND254B7;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15;
MARKETING_VERSION = "$(VERSION)";
PRODUCT_BUNDLE_IDENTIFIER = com.neon443.NearFuture;
PRODUCT_NAME = "Near Future";
REGISTER_APP_GROUPS = YES;
SDKROOT = macosx;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
A90D49312DDE0FA600781124 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = A90FDE222DC0D4310012790C /* Config.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "bloo blue green pink purple red yellow";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = MacNearFuture/MacNearFuture.entitlements;
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = "$(BUILD_NUMBER)";
DEVELOPMENT_TEAM = 8JGND254B7;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 15;
MARKETING_VERSION = "$(VERSION)";
PRODUCT_BUNDLE_IDENTIFIER = com.neon443.NearFuture;
PRODUCT_NAME = "Near Future";
REGISTER_APP_GROUPS = YES;
SDKROOT = macosx;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
};
name = Release;
};
A920C2A92D24011B00E4F9B1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "Bloo Blue Green Pink Purple Red Yellow";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
@@ -565,7 +755,7 @@
);
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 6.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -573,7 +763,10 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "Bloo Blue Green Pink Purple Red Yellow";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
@@ -621,7 +814,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_VERSION = 6.0;
SWIFT_VERSION = 5.0;
};
name = Release;
};
@@ -629,8 +822,10 @@
isa = XCBuildConfiguration;
baseConfigurationReference = A90FDE222DC0D4310012790C /* Config.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "bloo blue green pink purple red yellow";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_USE_OPTIMIZATION_PROFILE = YES;
CODE_SIGN_ENTITLEMENTS = NearFuture/NearFuture.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(BUILD_NUMBER)";
@@ -640,9 +835,9 @@
ENABLE_HARDENED_RUNTIME = NO;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = NearFuture/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "$(NAME)";
INFOPLIST_KEY_CFBundleDisplayName = "Near Future";
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
@@ -667,8 +862,8 @@
REGISTER_APP_GROUPS = YES;
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = YES;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
@@ -680,8 +875,10 @@
isa = XCBuildConfiguration;
baseConfigurationReference = A90FDE222DC0D4310012790C /* Config.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "bloo blue green pink purple red yellow";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_USE_OPTIMIZATION_PROFILE = YES;
CODE_SIGN_ENTITLEMENTS = NearFuture/NearFuture.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(BUILD_NUMBER)";
@@ -691,9 +888,9 @@
ENABLE_HARDENED_RUNTIME = NO;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = NearFuture/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "$(NAME)";
INFOPLIST_KEY_CFBundleDisplayName = "Near Future";
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
@@ -715,8 +912,8 @@
REGISTER_APP_GROUPS = YES;
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = YES;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
@@ -730,12 +927,13 @@
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_USE_OPTIMIZATION_PROFILE = YES;
CODE_SIGN_ENTITLEMENTS = NearFutureWidgets/NearFutureWidgetsExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(BUILD_NUMBER)";
DEVELOPMENT_TEAM = "$(TEAM_ID)";
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = NearFutureWidgets/Info.plist;
INFOPLIST_FILE = "$(SRCROOT)/NearFutureWidgets/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = NearFutureWidgets;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 17;
@@ -755,8 +953,9 @@
REGISTER_APP_GROUPS = YES;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = YES;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -770,12 +969,13 @@
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
CLANG_USE_OPTIMIZATION_PROFILE = YES;
CODE_SIGN_ENTITLEMENTS = NearFutureWidgets/NearFutureWidgetsExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(BUILD_NUMBER)";
DEVELOPMENT_TEAM = "$(TEAM_ID)";
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = NearFutureWidgets/Info.plist;
INFOPLIST_FILE = "$(SRCROOT)/NearFutureWidgets/Info.plist";
INFOPLIST_KEY_CFBundleDisplayName = NearFutureWidgets;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
IPHONEOS_DEPLOYMENT_TARGET = 17;
@@ -791,8 +991,9 @@
REGISTER_APP_GROUPS = YES;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = YES;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -801,61 +1002,18 @@
};
name = Release;
};
A980FC3E2D93FB2B006A778F /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = A90FDE222DC0D4310012790C /* Config.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16;
MACOSX_DEPLOYMENT_TARGET = 13;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.neon443.NearFutureTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NearFuture.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/NearFuture";
XROS_DEPLOYMENT_TARGET = 1;
};
name = Debug;
};
A980FC3F2D93FB2B006A778F /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = A90FDE222DC0D4310012790C /* Config.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16;
MACOSX_DEPLOYMENT_TARGET = 13;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = dev.neon443.NearFutureTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = YES;
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NearFuture.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/NearFuture";
XROS_DEPLOYMENT_TARGET = 1;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
A90D492F2DDE0FA600781124 /* Build configuration list for PBXNativeTarget "MacNearFuture" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A90D49302DDE0FA600781124 /* Debug */,
A90D49312DDE0FA600781124 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
A920C27F2D24011300E4F9B1 /* Build configuration list for PBXProject "NearFuture" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@@ -883,35 +1041,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
A980FC3D2D93FB2B006A778F /* Build configuration list for PBXNativeTarget "NearFutureTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A980FC3E2D93FB2B006A778F /* Debug */,
A980FC3F2D93FB2B006A778F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
A920C2BC2D24021900E4F9B1 /* XCRemoteSwiftPackageReference "SFSymbolsPicker" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/alessiorubicini/SFSymbolsPicker";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.0.6;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
A920C2BD2D24021A00E4F9B1 /* SFSymbolsPicker */ = {
isa = XCSwiftPackageProductDependency;
package = A920C2BC2D24021900E4F9B1 /* XCRemoteSwiftPackageReference "SFSymbolsPicker" */;
productName = SFSymbolsPicker;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = A920C27C2D24011300E4F9B1 /* Project object */;
}

View File

@@ -1,15 +0,0 @@
{
"originHash" : "19df39f99b22f4ef95b73ed292ffb0c8d7694dd4c9db2b96ea73b091b7b1a026",
"pins" : [
{
"identity" : "sfsymbolspicker",
"kind" : "remoteSourceControl",
"location" : "https://github.com/alessiorubicini/SFSymbolsPicker",
"state" : {
"revision" : "73c909b8a7fc77a30dd04208e33f759f8b52c4c8",
"version" : "1.0.6"
}
}
],
"version" : 3
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1630"
LastUpgradeVersion = "1640"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
@@ -15,9 +15,9 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A920C2832D24011300E4F9B1"
BuildableName = "NearFuture.app"
BlueprintName = "NearFuture"
BlueprintIdentifier = "A90D49252DDE0FA400781124"
BuildableName = "Near Future.app"
BlueprintName = "MacNearFuture"
ReferencedContainer = "container:NearFuture.xcodeproj">
</BuildableReference>
</BuildActionEntry>
@@ -32,8 +32,8 @@
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@@ -44,9 +44,9 @@
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A920C2832D24011300E4F9B1"
BuildableName = "NearFuture.app"
BlueprintName = "NearFuture"
BlueprintIdentifier = "A90D49252DDE0FA400781124"
BuildableName = "Near Future.app"
BlueprintName = "MacNearFuture"
ReferencedContainer = "container:NearFuture.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
@@ -61,9 +61,9 @@
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "A920C2832D24011300E4F9B1"
BuildableName = "NearFuture.app"
BlueprintName = "NearFuture"
BlueprintIdentifier = "A90D49252DDE0FA400781124"
BuildableName = "Near Future.app"
BlueprintName = "MacNearFuture"
ReferencedContainer = "container:NearFuture.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>

View File

@@ -4,24 +4,29 @@
<dict>
<key>SchemeUserState</key>
<dict>
<key>NearFuture nodebug.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>NearFuture.xcscheme_^#shared#^_</key>
<key>MacNearFuture.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
<key>NearFutureWidgetsExtension.xcscheme_^#shared#^_</key>
<key>NearFuture.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>NearFutureWidgetsExtension.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>A90D49252DDE0FA400781124</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>A920C2832D24011300E4F9B1</key>
<dict>
<key>primary</key>

View File

@@ -1,169 +0,0 @@
//
// EventListView.swift
// NearFuture
//
// Created by neon443 on 18/04/2025.
//
import SwiftUI
import SwiftData
struct EventListView: View {
@ObservedObject var viewModel: EventViewModel
@State var event: Event
var body: some View {
NavigationLink() {
EditEventView(
viewModel: viewModel,
event: $event
)
} label: {
ZStack {
HStack {
RoundedRectangle(cornerRadius: 5)
.frame(width: 7)
.foregroundStyle(
event.color.color.opacity(
event.complete ? 0.5 : 1
)
)
VStack(alignment: .leading) {
HStack {
Image(systemName: event.symbol)
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.shadow(radius: 5)
.foregroundStyle(
.one.opacity(
event.complete ? 0.5 : 1
)
)
Text("\(event.name)")
.font(.headline)
.foregroundStyle(.one)
.strikethrough(event.complete)
.multilineTextAlignment(.leading)
}
if !event.notes.isEmpty {
Text(event.notes)
.font(.subheadline)
.foregroundStyle(.one.opacity(0.8))
.multilineTextAlignment(.leading)
}
Text(
event.date.formatted(
date: .long,
time: .shortened
)
)
.font(.subheadline)
.foregroundStyle(
.one.opacity(
event.complete ? 0.5 : 1
)
)
if event.recurrence != .none {
Text("Occurs \(event.recurrence.rawValue)")
.font(.subheadline)
.foregroundStyle(
.one.opacity(event.complete ? 0.5 : 1))
}
}
Spacer()
VStack {
Text("\(daysUntilEvent(event.date).long)")
.font(.subheadline)
.foregroundStyle(.one)
}
Button() {
withAnimation {
event.complete.toggle()
}
let eventToModify = viewModel.events.firstIndex() { currEvent in
currEvent.id == event.id
}
if let eventToModify = eventToModify {
viewModel.events[eventToModify] = event
viewModel.saveEvents()
}
} label: {
if event.complete {
ZStack {
Circle()
.foregroundStyle(.green)
Image(systemName: "checkmark")
.resizable()
.foregroundStyle(.white)
.scaledToFit()
.bold()
.frame(width: 15)
}
} else {
Image(systemName: "circle")
.resizable()
.scaledToFit()
.foregroundStyle(event.color.color)
}
}
.buttonStyle(.borderless)
.frame(maxWidth: 25, maxHeight: 25)
.shadow(radius: 5)
.padding(.trailing, 5)
}
.padding(.vertical, 5)
.background(.ultraThinMaterial)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(
.one.opacity(appearance == .dark ? 0.5 : 1),
lineWidth: 1
)
)
.clipShape(
RoundedRectangle(cornerRadius: 10)
)
.fixedSize(horizontal: false, vertical: true)
}
.contextMenu() {
Button(role: .destructive) {
let eventToModify = viewModel.events.firstIndex() { currEvent in
currEvent.id == event.id
}
if let eventToModify = eventToModify {
viewModel.events.remove(at: eventToModify)
viewModel.saveEvents()
}
} label: {
Label("Delete", systemImage: "trash")
}
}
}
}
}
#Preview("EventListView") {
let vm = dummyEventViewModel()
ZStack {
Color.black
VStack {
ForEach(0..<50) { _ in
Rectangle()
.foregroundStyle(randomColor().opacity(0.5))
.padding(-10)
}
.ignoresSafeArea(.all)
.blur(radius: 5)
}
VStack {
ForEach(vm.events) { event in
EventListView(
viewModel: vm,
event: event
)
}
}
.padding(.horizontal, 10)
}
}

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

View File

@@ -1,112 +0,0 @@
//
// ArchiveHelp.swift
// NearFuture
//
// Created by neon443 on 26/04/2025.
//
import SwiftUI
enum HelpType {
case Search
case Archive
}
struct HelpView: View {
/// initialises a Search HelpView
///
init(searchInput: Binding<String>, focusedField: Field?) {
_searchInput = searchInput
self.helpType = .Search
_showAddEvent = .constant(false)
}
/// initialises an Archive HelpView
///
init(showAddEvent: Binding<Bool>) {
_showAddEvent = showAddEvent
self.helpType = .Archive
_searchInput = .constant("")
self.focusedField = nil
}
@Binding var searchInput: String
@FocusState var focusedField: Field?
@Binding var showAddEvent: Bool
var helpType: HelpType
var details: (
symbol: String,
title: String,
body: String,
buttonAction: () -> (),
buttonSymbol: String,
buttonText: String
) {
switch helpType {
case .Search:
return (
symbol: "questionmark.app.dashed",
title: "Looking for something?",
body: "Tip: The Search bar searches event names and notes.",
buttonAction: {
searchInput = ""
focusedField = nil
},
buttonSymbol: "xmark",
buttonText: "Clear Filters"
)
case .Archive:
return (
symbol: "eyes",
title: "Nothing to see here...",
body: "The Archive contains events that have been marked as complete.",
buttonAction: {
showAddEvent.toggle()
},
buttonSymbol: "plus",
buttonText: "Create an event"
)
}
}
var body: some View {
List {
ZStack {
Color(.tintColor)
.opacity(0.4)
.padding(.horizontal, -15)
.blur(radius: 5)
HStack {
Image(systemName: details.symbol)
.resizable()
.scaledToFit()
.frame(width: 30, height: 30)
.padding(.trailing)
Text(details.title)
.bold()
.font(.title2)
}
}
.listRowSeparator(.hidden)
Text(details.body)
Button() {
details.buttonAction()
} label: {
HStack {
Image(systemName: details.buttonSymbol)
.bold()
Text(details.buttonText)
}
.foregroundStyle(Color.accentColor)
}
}
.scrollContentBackground(.hidden)
}
}
#Preview {
HelpView(searchInput: .constant(""), focusedField: nil)
HelpView(showAddEvent: .constant(false))
}

View File

@@ -2,10 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array/>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>

View File

@@ -1,36 +0,0 @@
//
// NearFutureApp.swift
// NearFuture
//
// Created by Nihaal Sharma on 24/12/2024.
//
import SwiftUI
import SwiftData
@main
struct NearFutureApp: App {
// var sharedModelContainer: ModelContainer = {
// let schema = Schema([
// Item.self,
// ])
// let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
//
// do {
// return try ModelContainer(for: schema, configurations: [modelConfiguration])
// } catch {
// fatalError("Could not create ModelContainer: \(error)")
// }
// }()
@StateObject var settingsModel: SettingsViewModel = SettingsViewModel()
var body: some Scene {
WindowGroup {
ContentView(
viewModel: EventViewModel(),
settingsModel: settingsModel
)
.tint(settingsModel.settings.tint.color)
}
// .modelContainer(sharedModelContainer)
}
}

View File

@@ -1,18 +0,0 @@
//
// AppIntent.swift
// NearFutureWidgets
//
// Created by Nihaal Sharma on 02/01/2025.
//
import WidgetKit
import AppIntents
struct ConfigurationAppIntent: WidgetConfigurationIntent {
static var title: LocalizedStringResource = "Configuration"
static var description = IntentDescription("This is an example widget.")
// An example configurable parameter.
@Parameter(title: "Favorite Emoji", default: "😃")
var favoriteEmoji: String
}

View File

@@ -1,11 +0,0 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,13 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,11 +0,0 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.widgetkit-extension</string>
</dict>
</dict>
</plist>

View File

@@ -1,84 +0,0 @@
//
// NearFutureWidgets.swift
// NearFutureWidgets
//
// Created by Nihaal Sharma on 02/01/2025.
//
import WidgetKit
import SwiftUI
struct Provider: AppIntentTimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), configuration: ConfigurationAppIntent())
}
func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
SimpleEntry(date: Date(), configuration: configuration)
}
func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate, configuration: configuration)
entries.append(entry)
}
return Timeline(entries: entries, policy: .atEnd)
}
}
struct SimpleEntry: TimelineEntry {
let date: Date
let configuration: ConfigurationAppIntent
}
struct NearFutureWidgetsEntryView : View {
var entry: Provider.Entry
var body: some View {
VStack {
Text("Time:")
Text(entry.date, style: .time)
Text("Favorite Emoji:")
Text(entry.configuration.favoriteEmoji)
}
}
}
struct NearFutureWidgets: Widget {
let kind: String = "NearFutureWidgets"
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
NearFutureWidgetsEntryView(entry: entry)
.containerBackground(.fill.tertiary, for: .widget)
}
}
}
extension ConfigurationAppIntent {
fileprivate static var smiley: ConfigurationAppIntent {
let intent = ConfigurationAppIntent()
intent.favoriteEmoji = "😀"
return intent
}
fileprivate static var starEyes: ConfigurationAppIntent {
let intent = ConfigurationAppIntent()
intent.favoriteEmoji = "🤩"
return intent
}
}
#Preview(as: .systemSmall) {
NearFutureWidgets()
} timeline: {
SimpleEntry(date: .now, configuration: .smiley)
SimpleEntry(date: .now, configuration: .starEyes)
}

View File

@@ -1,17 +0,0 @@
//
// NearFutureWidgetsBundle.swift
// NearFutureWidgets
//
// Created by Nihaal Sharma on 02/01/2025.
//
import WidgetKit
import SwiftUI
@main
struct NearFutureWidgetsBundle: WidgetBundle {
var body: some Widget {
NearFutureWidgets()
NearFutureWidgetsLiveActivity()
}
}

View File

@@ -1,80 +0,0 @@
//
// NearFutureWidgetsLiveActivity.swift
// NearFutureWidgets
//
// Created by Nihaal Sharma on 02/01/2025.
//
import ActivityKit
import WidgetKit
import SwiftUI
struct NearFutureWidgetsAttributes: ActivityAttributes {
public struct ContentState: Codable, Hashable {
// Dynamic stateful properties about your activity go here!
var emoji: String
}
// Fixed non-changing properties about your activity go here!
var name: String
}
struct NearFutureWidgetsLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: NearFutureWidgetsAttributes.self) { context in
// Lock screen/banner UI goes here
VStack {
Text("Hello \(context.state.emoji)")
}
.activityBackgroundTint(Color.cyan)
.activitySystemActionForegroundColor(Color.black)
} dynamicIsland: { context in
DynamicIsland {
// Expanded UI goes here. Compose the expanded UI through
// various regions, like leading/trailing/center/bottom
DynamicIslandExpandedRegion(.leading) {
Text("Leading")
}
DynamicIslandExpandedRegion(.trailing) {
Text("Trailing")
}
DynamicIslandExpandedRegion(.bottom) {
Text("Bottom \(context.state.emoji)")
// more content
}
} compactLeading: {
Text("L")
} compactTrailing: {
Text("T \(context.state.emoji)")
} minimal: {
Text(context.state.emoji)
}
.widgetURL(URL(string: "http://www.apple.com"))
.keylineTint(Color.red)
}
}
}
extension NearFutureWidgetsAttributes {
fileprivate static var preview: NearFutureWidgetsAttributes {
NearFutureWidgetsAttributes(name: "World")
}
}
extension NearFutureWidgetsAttributes.ContentState {
fileprivate static var smiley: NearFutureWidgetsAttributes.ContentState {
NearFutureWidgetsAttributes.ContentState(emoji: "😀")
}
fileprivate static var starEyes: NearFutureWidgetsAttributes.ContentState {
NearFutureWidgetsAttributes.ContentState(emoji: "🤩")
}
}
#Preview("Notification", as: .content, using: NearFutureWidgetsAttributes.preview) {
NearFutureWidgetsLiveActivity()
} contentStates: {
NearFutureWidgetsAttributes.ContentState.smiley
NearFutureWidgetsAttributes.ContentState.starEyes
}

View File

@@ -10,7 +10,10 @@ import SwiftUI
struct ArchiveView: View {
@ObservedObject var viewModel: EventViewModel
@State var showAddEvent: Bool = false
@State var hey: UUID = UUID()
var filteredEvents: [Event] {
let filteredEvents = viewModel.events.filter({$0.complete})
return filteredEvents.reversed()
}
var body: some View {
NavigationStack {
ZStack {
@@ -19,51 +22,42 @@ struct ArchiveView: View {
HelpView(showAddEvent: $showAddEvent)
} else {
ScrollView {
ForEach(viewModel.events.filter({$0.complete})) { event in
EventListView(viewModel: viewModel, event: event)
ForEach(filteredEvents) { event in
NavigationLink() {
EditEventView(
viewModel: viewModel,
event: Binding(
get: { event },
set: { newValue in
viewModel.editEvent(newValue)
}
)
)
} label: {
EventListView(viewModel: viewModel, event: event)
.id(event.complete)
}
.transition(.moveAndFadeReversed)
}
.padding(.horizontal)
.id(hey)
.onReceive(viewModel.objectWillChange) {
hey = UUID()
}
}
.animation(.default, value: filteredEvents)
}
}
.transition(.opacity)
.scrollContentBackground(.hidden)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
ToolbarItem(placement: .primaryAction) {
AddEventButton(showingAddEventView: $showAddEvent)
}
}
.navigationTitle("Archive")
.apply {
if #available(iOS 17, *) {
$0.toolbarTitleDisplayMode(.inlineLarge)
} else {
$0.navigationBarTitleDisplayMode(.inline)
}
}
.modifier(navigationInlineLarge())
}
.sheet(isPresented: $showAddEvent) {
AddEventView(
viewModel: viewModel,
eventName: $viewModel.editableTemplate.name,
eventComplete: $viewModel.editableTemplate.complete,
eventCompleteDesc: $viewModel.editableTemplate.completeDesc,
eventSymbol: $viewModel.editableTemplate.symbol,
eventColor: $viewModel.editableTemplate.color.colorBind,
eventNotes: $viewModel.editableTemplate.notes,
eventDate: $viewModel.editableTemplate.date,
eventRecurrence: $viewModel.editableTemplate.recurrence,
adding: true
viewModel: viewModel
)
.presentationDragIndicator(.visible)
.apply {
if #available(iOS 16.4, *) {
$0.presentationBackground(.ultraThinMaterial)
}
}
}
}
}
@@ -71,5 +65,3 @@ struct ArchiveView: View {
#Preview {
ArchiveView(viewModel: dummyEventViewModel())
}

View File

@@ -0,0 +1,69 @@
//
// ContentView.swift
// NearFuture
//
// Created by neon443 on 24/12/2024.
//
import SwiftUI
import UserNotifications
import SwiftData
enum Tab {
case home
case archive
case symbols
case stats
case settings
}
struct ContentView: View {
@StateObject var viewModel: EventViewModel
@StateObject var settingsModel: SettingsViewModel
@State var tabSelection: Tab = .home
var body: some View {
TabView(selection: $tabSelection) {
HomeView(viewModel: viewModel, settingsModel: settingsModel)
.tabItem {
Label("Home", systemImage: "house")
}
.tag(Tab.home)
ArchiveView(viewModel: viewModel)
.tabItem() {
Label("Archive", systemImage: "tray.full")
}
.tag(Tab.archive)
SymbolsPicker(
selection: .constant(""),
browsing: true
)
.tabItem {
Label("Symbols", systemImage: "star.circle")
}
.tag(Tab.symbols)
StatsView(viewModel: viewModel)
// SymbolsPickerStoryboardUIViewRepresentable()
.tabItem {
Label("Statistics", systemImage: "chart.pie")
}
.tag(Tab.stats)
SettingsView(viewModel: viewModel, settingsModel: settingsModel)
.tabItem {
Label("Settings", systemImage: "gear")
}
.tag(Tab.settings)
}
.modifier(hapticHeavy(trigger: tabSelection))
.sheet(isPresented: $settingsModel.settings.showWhatsNew) {
WhatsNewView(settingsModel: settingsModel)
}
}
}
#Preview {
ContentView(
viewModel: dummyEventViewModel(),
settingsModel: dummySettingsViewModel()
)
}

View File

@@ -2,27 +2,21 @@
// AddEventView.swift
// NearFuture
//
// Created by Nihaal Sharma on 25/12/2024.
// Created by neon443 on 25/12/2024.
//
import SwiftUI
import SFSymbolsPicker
struct AddEventView: View {
@ObservedObject var viewModel: EventViewModel
@Binding var eventName: String
@Binding var eventComplete: Bool
@Binding var eventCompleteDesc: String
@Binding var eventSymbol: String
@Binding var eventColor: Color
@Binding var eventNotes: String
@Binding var eventDate: Date
@Binding var eventRecurrence: Event.RecurrenceType
@State var event: Event = dummyEventViewModel().template
@State var adding: Bool
@State var adding: Bool = true
@State var showNeedsNameAlert: Bool = false
@State var isSymbolPickerPresented = false
@State var isSymbolPickerPresented: Bool = false
@State private var bye: Bool = false
@FocusState private var focusedField: Field?
private enum Field {
@@ -31,186 +25,177 @@ struct AddEventView: View {
@Environment(\.dismiss) var dismiss
var isMac: Bool {
if #available(iOS 1, *) {
return false
} else {
return true
}
}
var body: some View {
NavigationStack {
Form {
Section(
header:
Text("Event Details")
.font(.headline)
.foregroundColor(.accentColor)
) {
// name & symbol
HStack(spacing: 5) {
Button() {
isSymbolPickerPresented.toggle()
} label: {
Image(systemName: eventSymbol)
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.foregroundStyle(eventColor)
}
.frame(width: 20)
.buttonStyle(.borderless)
.sheet(isPresented: $isSymbolPickerPresented) {
SymbolsPicker(
selection: $eventSymbol,
title: "Choose a Symbol",
searchLabel: "Search...",
autoDismiss: true)
.presentationDetents([.medium])
.apply {
if #available(iOS 16.4, *) {
$0.presentationBackground(.ultraThinMaterial)
}
ZStack {
if !adding {
backgroundGradient
}
NavigationStack {
List {
Section(
header:
Text("Event Details")
.font(.headline)
.foregroundColor(.accentColor)
) {
// name & symbol
HStack(spacing: 5) {
Button() {
isSymbolPickerPresented.toggle()
} label: {
Image(systemName: event.symbol)
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.foregroundStyle(event.color.color)
}
.frame(width: 20)
.buttonStyle(.borderless)
.sheet(isPresented: $isSymbolPickerPresented) {
SymbolsPicker(
selection: $event.symbol
)
.presentationDetents([.medium])
.modifier(presentationSizeForm())
}
TextField("Event Name", text: $event.name)
.textFieldStyle(.roundedBorder)
}
ColorPicker("", selection: $eventColor, supportsOpacity: false)
.fixedSize()
// dscription
ZStack {
TextField("Event Name", text: $eventName)
TextField("Event Notes", text: $event.notes)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.trailing, eventName.isEmpty ? 0 : 30)
.animation(.spring, value: eventName)
.focused($focusedField, equals: Field.Name)
.submitLabel(.next)
.padding(.trailing, event.notes.isEmpty ? 0 : 30)
.animation(.spring, value: event.notes)
.focused($focusedField, equals: Field.Notes)
.submitLabel(.done)
.onSubmit {
focusedField = .Notes
focusedField = nil
}
MagicClearButton(text: $eventName)
}
}
// dscription
ZStack {
TextField("Event Notes", text: $eventNotes)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.trailing, eventNotes.isEmpty ? 0 : 30)
.animation(.spring, value: eventNotes)
.focused($focusedField, equals: Field.Notes)
.submitLabel(.done)
.onSubmit {
focusedField = nil
ColorPicker("Event Color", selection: $event.color.colorBind)
// date picker
HStack {
Spacer()
DatePicker("", selection: $event.date, displayedComponents: .date)
#if os(iOS)
.datePickerStyle(.wheel)
#else
.datePickerStyle(.graphical)
#endif
Spacer()
Button() {
event.date = Date()
} label: {
Image(systemName: "arrow.uturn.left")
.resizable()
.scaledToFit()
}
MagicClearButton(text: $eventNotes)
}
// date picker
HStack {
Spacer()
DatePicker("", selection: $eventDate, displayedComponents: .date)
.datePickerStyle(WheelDatePickerStyle())
Spacer()
Button() {
eventDate = Date()
} label: {
Image(systemName: "arrow.uturn.left")
.resizable()
.scaledToFit()
.buttonStyle(BorderlessButtonStyle())
.frame(width: 20)
}
.buttonStyle(BorderlessButtonStyle())
.frame(width: 20)
}
DatePicker(
"",
selection: $eventDate,
selection: $event.date,
displayedComponents: .hourAndMinute
)
// re-ocurrence Picker
Picker("Recurrence", selection: $eventRecurrence) {
ForEach(Event.RecurrenceType.allCases, id: \.self) { recurrence in
Text(recurrence.rawValue.capitalized)
#if os(macOS)
.datePickerStyle(.stepperField)
#endif
// re-ocurrence Picker
Picker("Recurrence", selection: $event.recurrence) {
ForEach(Event.RecurrenceType.allCases, id: \.self) { recurrence in
Text(recurrence.rawValue.capitalized)
}
}
}
.pickerStyle(SegmentedPickerStyle())
Text(
describeOccurrence(
date: eventDate,
recurrence: eventRecurrence
)
)
}
}
.scrollContentBackground(.hidden)
.navigationTitle("\(adding ? "Add Event" : "")")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .topBarLeading) {
if adding {
Button() {
resetAddEventView()
dismiss()
} label: {
Image(systemName: "xmark.circle.fill")
.symbolRenderingMode(.hierarchical)
.resizable()
.scaledToFit()
.frame(width: 30)
}
}
}
ToolbarItem(placement: .topBarTrailing) {
if adding {
Button {
viewModel.addEvent(
newEvent: Event(
name: eventName,
complete: eventComplete,
completeDesc: eventCompleteDesc,
symbol: eventSymbol,
color: ColorCodable(eventColor),
notes: eventNotes,
date: eventDate,
recurrence: eventRecurrence
)
.pickerStyle(SegmentedPickerStyle())
Text(
describeOccurrence(
date: event.date,
recurrence: event.recurrence
)
resetAddEventView()
} label: {
Text("Save")
.font(.headline)
.cornerRadius(10)
.buttonStyle(BorderedProminentButtonStyle())
}
.disabled(eventName.isEmpty)
.onTapGesture {
if eventName.isEmpty {
showNeedsNameAlert.toggle()
}
}
.alert("Missing Name", isPresented: $showNeedsNameAlert) {
Button("OK", role: .cancel) {
showNeedsNameAlert.toggle()
focusedField = .Name
}
} message: {
Text("Give your Event a name before saving.")
}
if eventName.isEmpty {
HStack {
Image(systemName: "exclamationmark")
.foregroundStyle(.red)
Text("Give your event a name.")
)
}
}
.navigationTitle("\(adding ? "Add Event" : "")")
.modifier(navigationInlineLarge())
.toolbar {
ToolbarItem(placement: .cancellationAction) {
if adding {
Button() {
resetAddEventView()
dismiss()
} label: {
Image(systemName: "xmark")
.resizable()
.scaledToFit()
.tint(.one)
}
}
}
ToolbarItem() {
if adding {
Button {
viewModel.addEvent(
newEvent: event
)
bye.toggle()
resetAddEventView()
} label: {
Label("Save", systemImage: "checkmark")
}
.tint(.accent)
.modifier(hapticSuccess(trigger: bye))
.disabled(event.name.isEmpty)
.onTapGesture {
if event.name.isEmpty {
showNeedsNameAlert.toggle()
}
}
.alert("Missing Name", isPresented: $showNeedsNameAlert) {
Button("OK", role: .cancel) {
showNeedsNameAlert.toggle()
focusedField = .Name
}
} message: {
Text("Give your Event a name before saving.")
}
}
}
ToolbarItem(placement: .confirmationAction) {
if !adding {
Button() {
viewModel.editEvent(event)
dismiss()
} label: {
Label("Done", systemImage: "checkmark")
}
.disabled(event.name == "")
}
}
}
.navigationTitle("Editing \(event.name) - Ne")
}
.scrollContentBackground(isMac ? .automatic : .hidden)
.presentationDragIndicator(.visible)
}
}
func resetAddEventView() {
//reset addeventView
eventName = viewModel.template.name
eventComplete = viewModel.template.complete
eventCompleteDesc = viewModel.template.completeDesc
eventSymbol = viewModel.template.symbol
eventColor = randomColor()
eventNotes = viewModel.template.notes
eventDate = viewModel.template.date
eventRecurrence = viewModel.template.recurrence
event = viewModel.template
dismiss()
}
@@ -223,21 +208,7 @@ struct AddEventView: View {
.sheet(isPresented: .constant(true)) {
AddEventView(
viewModel: vm,
eventName: .constant(vm.template.notes),
eventComplete: .constant(vm.template.complete),
eventCompleteDesc: .constant(vm.template.completeDesc),
eventSymbol: .constant(vm.template.symbol),
eventColor: .constant(vm.template.color.color),
eventNotes: .constant(vm.template.notes),
eventDate: .constant(vm.template.date),
eventRecurrence: .constant(vm.template.recurrence),
adding: true
)
.presentationDragIndicator(.visible)
.apply {
if #available(iOS 16.4, *) {
$0.presentationBackground(.ultraThinMaterial)
}
}
}
}

View File

@@ -2,7 +2,7 @@
// EditEventView.swift
// NearFuture
//
// Created by Nihaal Sharma on 02/01/2025.
// Created by neon443 on 02/01/2025.
//
import SwiftUI
@@ -12,44 +12,13 @@ struct EditEventView: View {
@ObservedObject var viewModel: EventViewModel
@Binding var event: Event
fileprivate func saveEdits() {
//if there is an event in vM.events with the id of the event we r editing,
//firstindex - loops through the arr and finds first element where that events id matches editing event's id
if let index = viewModel.events.firstIndex(where: { xEvent in
xEvent.id == event.id
}) {
viewModel.events[index] = event
}
viewModel.saveEvents()
dismiss()
}
var body: some View {
AddEventView(
viewModel: viewModel,
eventName: $event.name,
eventComplete: $event.complete,
eventCompleteDesc: $event.completeDesc,
eventSymbol: $event.symbol,
eventColor: $event.color.colorBind,
eventNotes: $event.notes,
eventDate: $event.date,
eventRecurrence: $event.recurrence,
event: event,
adding: false //bc we editing existing event
)
.navigationTitle("Edit Event")
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button() {
saveEdits()
} label: {
Text("Done")
.bold()
}
.disabled(event.name == "")
}
}
}
}

View File

@@ -1,189 +0,0 @@
//
// ContentView.swift
// NearFuture
//
// Created by Nihaal Sharma on 24/12/2024.
//
import SwiftUI
import UserNotifications
import SwiftData
enum Field {
case Search
}
enum Tab {
case Home
case Archive
case Statistics
case Settings
case Gradient
}
struct ContentView: View {
@StateObject var viewModel: EventViewModel
@StateObject var settingsModel: SettingsViewModel
@State private var eventName = ""
@State private var eventComplete = false
@State private var eventCompleteDesc = ""
@State private var eventSymbol = "star"
@State private var eventColor: Color = randomColor()
@State private var eventNotes = ""
@State private var eventDate = Date()
@State private var eventRecurrence: Event.RecurrenceType = .none
@State var hey: UUID = UUID()
@State private var showingAddEventView = false
@State private var searchInput: String = ""
var filteredEvents: [Event] {
if searchInput.isEmpty {
return viewModel.events.filter() {!$0.complete}
} else {
return viewModel.events.filter {
$0.name.localizedCaseInsensitiveContains(searchInput) ||
$0.notes.localizedCaseInsensitiveContains(searchInput)
}
}
}
var noEvents: Bool {
if viewModel.events.count == 0 {
return true
} else {
return false
}
}
@FocusState private var focusedField: Field?
@FocusState private var focusedTab: Tab?
var body: some View {
TabView {
NavigationStack {
ZStack {
backgroundGradient
VStack {
ZStack {
TextField(
"\(Image(systemName: "magnifyingglass")) Search",
text: $searchInput
)
.padding(.trailing, searchInput.isEmpty ? 0 : 30)
.animation(.spring, value: searchInput)
.textFieldStyle(RoundedBorderTextFieldStyle())
.submitLabel(.done)
.focused($focusedField, equals: Field.Search)
.onSubmit {
focusedField = nil
}
MagicClearButton(text: $searchInput)
.onTapGesture {
focusedField = nil
}
}
.padding(.horizontal)
if filteredEvents.isEmpty && !searchInput.isEmpty {
HelpView(searchInput: $searchInput, focusedField: focusedField)
} else {
ScrollView {
ForEach(filteredEvents) { event in
EventListView(viewModel: viewModel, event: event)
}
.onDelete(perform: viewModel.removeEvent)
.id(hey)
.onReceive(viewModel.objectWillChange) {
hey = UUID()
}
.padding(.horizontal)
if /*!searchInput.isEmpty && */filteredEvents.isEmpty {
HelpView(
searchInput: $searchInput,
focusedField: focusedField
)
}
Spacer()
}
}
}
.navigationTitle("Near Future")
.apply {
if #available(iOS 17, *) {
$0.toolbarTitleDisplayMode(.inlineLarge)
} else {
$0.navigationBarTitleDisplayMode(.inline)
}
}
.sheet(isPresented: $showingAddEventView) {
AddEventView(
viewModel: viewModel,
eventName: $eventName,
eventComplete: $eventComplete,
eventCompleteDesc: $eventCompleteDesc,
eventSymbol: $eventSymbol,
eventColor: $eventColor,
eventNotes: $eventNotes,
eventDate: $eventDate,
eventRecurrence: $eventRecurrence,
adding: true //adding event
)
.presentationDragIndicator(.visible)
.apply {
if #available(iOS 16.4, *) {
$0.presentationBackground(.ultraThinMaterial)
}
}
}
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
AddEventButton(showingAddEventView: $showingAddEventView)
}
}
}
}
.tabItem {
Label("Home", systemImage: "house")
}
.focused($focusedTab, equals: Tab.Home)
ArchiveView(viewModel: viewModel)
.tabItem() {
Label("Archive", systemImage: "tray.full")
}
.focused($focusedTab, equals: Tab.Archive)
StatsView(viewModel: viewModel)
.tabItem {
Label("Statistics", systemImage: "chart.pie")
}
.focused($focusedTab, equals: Tab.Statistics)
SettingsView(viewModel: viewModel, settingsModel: settingsModel)
.tabItem {
Label("Settings", systemImage: "gear")
}
.focused($focusedTab, equals: Tab.Settings)
}
}
}
#Preview {
ContentView(
viewModel: dummyEventViewModel(),
settingsModel: dummySettingsViewModel()
)
}
extension View {
var appearance: ColorScheme {
return UITraitCollection.current.userInterfaceStyle == .dark ? .dark : .light
}
var backgroundGradient: some View {
return LinearGradient(
gradient: Gradient(colors: [.bgTop, .two]),
startPoint: .top,
endPoint: .bottom
)
.ignoresSafeArea(.all)
}
}
extension View {
func apply<V: View>(@ViewBuilder _ block: (Self) -> V) -> V { block(self) }
}

View File

@@ -12,135 +12,185 @@ struct EventListView: View {
@ObservedObject var viewModel: EventViewModel
@State var event: Event
@Environment(\.openWindow) var openWindow
@State var hovering: Bool = false
#if canImport(AppKit)
var body: some View {
NavigationLink() {
EditEventView(
viewModel: viewModel,
event: $event
)
} label: {
ZStack {
HStack {
RoundedRectangle(cornerRadius: 5)
.frame(width: 7)
.foregroundStyle(
event.color.color.opacity(
event.complete ? 0.5 : 1
)
ZStack {
Color.black.opacity(hovering ? 0.5 : 0.0)
HStack {
RoundedRectangle(cornerRadius: 5)
.frame(width: 7)
.foregroundStyle(
event.color.color.opacity(
event.complete ? 0.5 : 1
)
VStack(alignment: .leading) {
HStack {
Image(systemName: event.symbol)
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.shadow(radius: 5)
.foregroundStyle(
.one.opacity(
event.complete ? 0.5 : 1
)
)
VStack(alignment: .leading) {
HStack {
Image(systemName: event.symbol)
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.shadow(radius: 5)
.foregroundStyle(
.one.opacity(
event.complete ? 0.5 : 1
)
Text("\(event.name)")
.font(.headline)
.foregroundStyle(.one)
.strikethrough(event.complete)
.multilineTextAlignment(.leading)
}
if !event.notes.isEmpty {
Text(event.notes)
.font(.subheadline)
.foregroundStyle(.one.opacity(0.8))
.multilineTextAlignment(.leading)
}
Text(
event.date.formatted(
date: .long,
time: .shortened
)
Text("\(event.name)")
.bold()
.foregroundStyle(.one)
.strikethrough(event.complete)
.multilineTextAlignment(.leading)
}
if !event.notes.isEmpty {
Text(event.notes)
.foregroundStyle(.one.opacity(0.8))
.multilineTextAlignment(.leading)
}
Text(
event.date.formatted(
date: .long,
time: .shortened
)
.font(.subheadline)
)
.foregroundStyle(
.one.opacity(
event.complete ? 0.5 : 1
)
)
if event.recurrence != .none {
Text("Occurs \(event.recurrence.rawValue)")
.font(.subheadline)
.foregroundStyle(
.one.opacity(event.complete ? 0.5 : 1))
}
}
Spacer()
VStack {
Text("\(daysUntilEvent(event.date).long)")
.multilineTextAlignment(.trailing)
.foregroundStyle(event.date.timeIntervalSinceNow < 0 ? .red : .one)
}
CompleteEventButton(
viewModel: viewModel,
event: $event
)
}
.fixedSize(horizontal: false, vertical: true)
}
.onHover { isHovering in
withAnimation {
hovering.toggle()
}
}
.onTapGesture {
openWindow(value: event.id)
}
.contextMenu() {
Button(role: .destructive) {
let eventToModify = viewModel.events.firstIndex() { currEvent in
currEvent.id == event.id
}
if let eventToModify = eventToModify {
viewModel.events.remove(at: eventToModify)
viewModel.saveEvents()
}
} label: {
Label("Delete", systemImage: "trash")
}
}
}
#else
var body: some View {
HStack {
RoundedRectangle(cornerRadius: 5)
.frame(width: 7)
.foregroundStyle(
event.color.color.opacity(
event.complete ? 0.5 : 1
)
)
VStack(alignment: .leading) {
HStack {
Image(systemName: event.symbol)
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.shadow(radius: 5)
.foregroundStyle(
.one.opacity(
event.complete ? 0.5 : 1
)
)
if event.recurrence != .none {
Text("Occurs \(event.recurrence.rawValue)")
.font(.subheadline)
.foregroundStyle(
.one.opacity(event.complete ? 0.5 : 1))
}
}
Spacer()
VStack {
Text("\(daysUntilEvent(event.date).long)")
.font(.subheadline)
.foregroundStyle(.one)
}
Button() {
withAnimation {
event.complete.toggle()
}
let eventToModify = viewModel.events.firstIndex() { currEvent in
currEvent.id == event.id
}
if let eventToModify = eventToModify {
viewModel.events[eventToModify] = event
viewModel.saveEvents()
}
} label: {
if event.complete {
ZStack {
Circle()
.foregroundStyle(.green)
Image(systemName: "checkmark")
.resizable()
.foregroundStyle(.white)
.scaledToFit()
.bold()
.frame(width: 15)
}
} else {
Image(systemName: "circle")
.resizable()
.scaledToFit()
.foregroundStyle(event.color.color)
}
}
.buttonStyle(.borderless)
.frame(maxWidth: 25, maxHeight: 25)
.shadow(radius: 5)
.padding(.trailing, 5)
Text("\(event.name)")
.font(.headline)
.foregroundStyle(.one)
.strikethrough(event.complete)
.multilineTextAlignment(.leading)
}
.padding(.vertical, 5)
.background(.ultraThinMaterial)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(
.one.opacity(appearance == .dark ? 0.5 : 1),
lineWidth: 1
)
if !event.notes.isEmpty {
Text(event.notes)
.font(.subheadline)
.foregroundStyle(.one.opacity(0.8))
.multilineTextAlignment(.leading)
}
Text(
event.date.formatted(
date: .long,
time: .shortened
)
)
.clipShape(
RoundedRectangle(cornerRadius: 10)
.font(.subheadline)
.foregroundStyle(
.one.opacity(
event.complete ? 0.5 : 1
)
)
.fixedSize(horizontal: false, vertical: true)
if event.recurrence != .none {
Text("Occurs \(event.recurrence.rawValue)")
.font(.subheadline)
.foregroundStyle(
.one.opacity(event.complete ? 0.5 : 1))
}
}
.contextMenu() {
Button(role: .destructive) {
let eventToModify = viewModel.events.firstIndex() { currEvent in
currEvent.id == event.id
}
if let eventToModify = eventToModify {
viewModel.events.remove(at: eventToModify)
viewModel.saveEvents()
}
} label: {
Label("Delete", systemImage: "trash")
Spacer()
VStack {
Text("\(daysUntilEvent(event.date).long)")
.font(.subheadline)
.foregroundStyle(event.date.timeIntervalSinceNow < 0 ? .red : .one)
.multilineTextAlignment(.trailing)
}
CompleteEventButton(
viewModel: viewModel,
event: $event
)
}
.padding(.vertical, 5)
.overlay(
RoundedRectangle(cornerRadius: 15)
.stroke(.one.opacity(0.5), lineWidth: 1)
)
.clipShape(RoundedRectangle(cornerRadius: 15))
.fixedSize(horizontal: false, vertical: true)
.contextMenu() {
Button(role: .destructive) {
let eventToModify = viewModel.events.firstIndex() { currEvent in
currEvent.id == event.id
}
if let eventToModify = eventToModify {
viewModel.events.remove(at: eventToModify)
viewModel.saveEvents()
}
} label: {
Label("Delete", systemImage: "trash")
}
}
}
#endif
}
#Preview("EventListView") {

View File

@@ -13,6 +13,10 @@ enum HelpType {
case Archive
}
enum Field {
case Search
}
struct HelpView: View {
/// initialises a Search HelpView
///
@@ -74,7 +78,7 @@ struct HelpView: View {
var body: some View {
List {
ZStack {
Color(.tintColor)
Color(.accent)
.opacity(0.4)
.padding(.horizontal, -15)
.blur(radius: 5)

View File

@@ -0,0 +1,103 @@
//
// HomeView.swift
// NearFuture
//
// Created by neon443 on 12/05/2025.
//
import SwiftUI
import AppIntents
struct HomeView: View {
@ObservedObject var viewModel: EventViewModel
@ObservedObject var settingsModel: SettingsViewModel
@State private var showingAddEventView: Bool = false
@State private var searchInput: String = ""
@Environment(\.colorScheme) var appearance
var darkMode: Bool {
return appearance == .dark
}
var filteredEvents: [Event] {
if searchInput.isEmpty {
if settingsModel.settings.showCompletedInHome {
return viewModel.events
} else {
return viewModel.events.filter() {!$0.complete}
}
} else {
return viewModel.events.filter {
$0.name.localizedCaseInsensitiveContains(searchInput) ||
$0.notes.localizedCaseInsensitiveContains(searchInput)
}
}
}
@State private var focusedTab: Tab = .home
@FocusState private var focusedField: Field?
var body: some View {
NavigationStack {
ZStack {
backgroundGradient
VStack {
if filteredEvents.isEmpty && !searchInput.isEmpty {
HelpView(searchInput: $searchInput, focusedField: focusedField)
} else {
ScrollView {
// LazyVStack {
ForEach(filteredEvents) { event in
NavigationLink() {
EditEventView(
viewModel: viewModel,
event: Binding(
get: { event },
set: { newValue in
viewModel.editEvent(newValue)
}
)
)
} label: {
EventListView(viewModel: viewModel, event: event)
.id(event.complete)
}
.transition(.moveAndFade)
}
.padding(.horizontal)
// }
if filteredEvents.isEmpty {
HelpView(
searchInput: $searchInput,
focusedField: focusedField
)
}
Spacer()
}
.animation(.default, value: filteredEvents)
}
}
.searchable(text: $searchInput)
.navigationTitle("Near Future")
.modifier(navigationInlineLarge())
.sheet(isPresented: $showingAddEventView) {
AddEventView(
viewModel: viewModel
)
}
.toolbar {
ToolbarItem(placement: .primaryAction) {
AddEventButton(showingAddEventView: $showingAddEventView)
}
}
}
}
}
}
#Preview {
HomeView(
viewModel: dummyEventViewModel(),
settingsModel: dummySettingsViewModel()
)
}

View File

@@ -0,0 +1,31 @@
//
// AboutView.swift
// NearFuture
//
// Created by neon443 on 12/05/2025.
//
import SwiftUI
struct AboutView: View {
var body: some View {
VStack {
Image(uiImage: #imageLiteral(resourceName: "NearFutureIcon.png"))
.resizable()
.scaledToFit()
.frame(width: 100)
.clipShape(RoundedRectangle(cornerRadius: 25))
Text("Near Future")
.bold()
.monospaced()
.font(.title)
.frame(maxWidth: .infinity)
Text("Version " + getVersion() + " (\(getBuildID()))")
.frame(maxWidth: .infinity)
}
}
}
#Preview {
AboutView()
}

View File

@@ -34,17 +34,12 @@ struct AddEventButton: View {
Button() {
showingAddEventView.toggle()
} label: {
ZStack {
Circle()
.frame(width: 33)
.foregroundStyle(.one)
Image(systemName: "plus")
.resizable()
.scaledToFit()
.frame(width: 15)
.bold()
.foregroundStyle(.two)
}
Image(systemName: "plus")
.resizable()
.scaledToFit()
.frame(width: 15)
.bold()
.foregroundStyle(.one)
}
}
}

View File

@@ -12,7 +12,11 @@ struct ExportView: View {
var body: some View {
List {
Button() {
#if canImport(UIKit)
UIPasteboard.general.string = viewModel.exportEvents()
#else
NSPasteboard.general.setString(viewModel.exportEvents(), forType: .string)
#endif
} label: {
Label("Copy Events", systemImage: "document.on.clipboard")
}

View File

@@ -15,47 +15,117 @@ struct ImportView: View {
@State private var text: String = "Ready..."
@State private var fgColor: Color = .yellow
var body: some View {
List {
Section("Status") {
Label(text, systemImage: image)
.contentTransition(.numericText())
.foregroundStyle(fgColor)
@State private var showAlert: Bool = false
@State private var replaceCurrentEvents: Bool = false
fileprivate func importEvents() {
do throws {
try viewModel.importEvents(importStr, replace: replaceCurrentEvents)
withAnimation {
image = "checkmark.circle.fill"
text = "Complete"
fgColor = .green
}
TextField("", text: $importStr)
Button() {
do throws {
try viewModel.importEvents(importStr)
withAnimation {
image = "checkmark.circle.fill"
text = "Complete"
fgColor = .green
}
} catch importError.invalidB64 {
withAnimation {
image = "xmark.app.fill"
text = "Invalid base64 input."
fgColor = .red
}
} catch {
withAnimation {
image = "xmark.app.fill"
text = error.localizedDescription
fgColor = .red
}
}
} label: {
Label("Import", systemImage: "tray.and.arrow.down.fill")
} catch importError.invalidB64 {
withAnimation {
image = "xmark.app.fill"
text = "Invalid base64 input."
fgColor = .red
}
.disabled(importStr.isEmpty)
.onAppear() {
importStr = ""
image = "clock.fill"
text = "Ready..."
fgColor = .yellow
} catch {
withAnimation {
image = "xmark.app.fill"
text = error.localizedDescription
fgColor = .red
}
}
}
var body: some View {
ZStack(alignment: .center) {
List {
Section("Status") {
Label(text, systemImage: image)
.contentTransition(.numericText())
.foregroundStyle(fgColor)
}
TextField("", text: $importStr)
Button() {
withAnimation {
showAlert.toggle()
}
} label: {
Label("Import", systemImage: "tray.and.arrow.down.fill")
}
.disabled(importStr.isEmpty)
.onAppear() {
importStr = ""
image = "clock.fill"
text = "Ready..."
fgColor = .yellow
}
}
.blur(radius: showAlert ? 2 : 0)
Group {
Rectangle()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.foregroundStyle(replaceCurrentEvents ? .red.opacity(0.25) : .black.opacity(0.2))
.animation(.default, value: replaceCurrentEvents)
.ignoresSafeArea()
ZStack {
Rectangle()
.clipShape(RoundedRectangle(cornerRadius: 25))
VStack(alignment: .center) {
Text("Are you sure?")
.font(.largeTitle)
.bold()
.foregroundStyle(replaceCurrentEvents ? .red : .two)
.animation(.default, value: replaceCurrentEvents)
Text("This will replace your current events!")
.lineLimit(nil)
.multilineTextAlignment(.center)
.opacity(replaceCurrentEvents ? 1 : 0)
.animation(.default, value: replaceCurrentEvents)
.foregroundStyle(.two)
Toggle("Replace Events", isOn: $replaceCurrentEvents)
.foregroundStyle(.two)
Spacer()
HStack {
Button() {
withAnimation {
showAlert.toggle()
}
importEvents()
} label: {
Text("cancel")
.font(.title2)
.bold()
}
.buttonStyle(BorderedProminentButtonStyle())
Spacer()
Button() {
withAnimation {
showAlert.toggle()
}
importEvents()
} label: {
Text("yes")
.font(.title2)
.bold()
}
.buttonStyle(BorderedProminentButtonStyle())
}
.padding()
}
.padding()
}
.frame(maxWidth: 250, maxHeight: 250)
}
.opacity(showAlert ? 1 : 0)
}
}
}

View File

@@ -2,7 +2,7 @@
// SettingsView.swift
// NearFuture
//
// Created by Nihaal Sharma on 29/12/2024.
// Created by neon443 on 29/12/2024.
//
import SwiftUI
@@ -10,33 +10,22 @@ import SwiftUI
struct SettingsView: View {
@ObservedObject var viewModel: EventViewModel
@ObservedObject var settingsModel: SettingsViewModel
@State private var hasUbiquitous: Bool = false
@State private var lastSyncWasSuccessful: Bool = false
@State private var lastSyncWasNormalAgo: Bool = false
@State private var localCountEqualToiCloud: Bool = false
@State private var icloudCountEqualToLocal: Bool = false
@State private var importStr: String = ""
func updateStatus() {
let vm = viewModel
hasUbiquitous = vm.hasUbiquitousKeyValueStore()
lastSyncWasSuccessful = vm.syncStatus.contains("Success")
lastSyncWasNormalAgo = vm.lastSync?.timeIntervalSinceNow.isNormal ?? false
localCountEqualToiCloud = vm.localEventCount == vm.icloudEventCount
icloudCountEqualToLocal = vm.icloudEventCount == vm.localEventCount
}
var iCloudStatusColor: Color {
let allTrue = hasUbiquitous && lastSyncWasSuccessful && lastSyncWasNormalAgo && localCountEqualToiCloud && icloudCountEqualToLocal
let someTrue = hasUbiquitous || lastSyncWasSuccessful || lastSyncWasNormalAgo || localCountEqualToiCloud || icloudCountEqualToLocal
if allTrue {
return .green
} else if someTrue {
return .orange
} else {
return .red
func changeIcon(to toIcon: String) {
guard UIApplication.shared.supportsAlternateIcons else {
print("doesnt tsupport alternate icons")
return
}
guard toIcon != "orange" else {
UIApplication.shared.setAlternateIconName(nil) { error in
print(error as Any)
}
return
}
UIApplication.shared.setAlternateIconName(toIcon) { error in
print(error as Any)
}
}
@@ -47,16 +36,18 @@ struct SettingsView: View {
List {
ScrollView(.horizontal) {
HStack {
ForEach(settingsModel.accentChoices, id: \.self) { color in
ForEach(settingsModel.accentChoices, id: \.self) { choice in
let color = Color(uiColor: UIColor(named: "uiColors/\(choice)")!)
ZStack {
Button() {
settingsModel.settings.tint.colorBind = color
settingsModel.saveSettings()
settingsModel.changeTint(to: choice)
changeIcon(to: choice)
} label: {
Circle()
.foregroundStyle(color)
.frame(width: 30)
}
.buttonStyle(.plain)
if ColorCodable(color) == settingsModel.settings.tint {
let needContrast: Bool = ColorCodable(color) == settingsModel.settings.tint
Circle()
@@ -67,16 +58,26 @@ struct SettingsView: View {
}
}
}
Button("Show What's New") {
settingsModel.settings.showWhatsNew = true
}
Toggle("Show completed Events in Home", isOn: $settingsModel.settings.showCompletedInHome)
.onChange(of: settingsModel.settings.showCompletedInHome) { _ in
settingsModel.saveSettings()
}
NavigationLink() {
List {
if !settingsModel.notifsGranted {
Button("Request Notifications") {
Task {
settingsModel.notifsGranted = await requestNotifs()
}
}
Text("\(Image(systemName: "xmark")) Notifications disabled for Near Future")
.foregroundStyle(.red)
Button("Request Notifications") {
Task.detached {
let requestNotifsResult = await requestNotifs()
await MainActor.run {
settingsModel.notifsGranted = requestNotifsResult
}
}
}
} else {
Text("\(Image(systemName: "checkmark")) Notifications enabled for Near Future")
.foregroundStyle(.green)
@@ -89,12 +90,7 @@ struct SettingsView: View {
NavigationLink() {
iCloudSettingsView(
viewModel: viewModel,
hasUbiquitous: $hasUbiquitous,
lastSyncWasSuccessful: $lastSyncWasSuccessful,
lastSyncWasNormalAgo: $lastSyncWasNormalAgo,
localCountEqualToiCloud: $localCountEqualToiCloud,
icloudCountEqualToLocal: $icloudCountEqualToLocal,
updateStatus: updateStatus
settingsModel: settingsModel
)
} label: {
HStack {
@@ -103,12 +99,12 @@ struct SettingsView: View {
Spacer()
Circle()
.frame(width: 20, height: 20)
.foregroundStyle(iCloudStatusColor)
.foregroundStyle(viewModel.iCloudStatusColor)
}
}
.onAppear {
viewModel.sync()
updateStatus()
viewModel.updateiCStatus()
}
NavigationLink() {
ImportView(viewModel: viewModel, importStr: $importStr)
@@ -148,32 +144,13 @@ struct SettingsView: View {
}
}
Section("About") {
VStack {
Image(uiImage: #imageLiteral(resourceName: "NearFutureIcon.png"))
.resizable()
.scaledToFit()
.frame(width: 100)
.clipShape(RoundedRectangle(cornerRadius: 25))
Text("Near Future")
.bold()
.monospaced()
.font(.title)
.frame(maxWidth: .infinity)
Text("Version " + getVersion() + " (\(getBuildID()))")
.frame(maxWidth: .infinity)
}
AboutView()
}
}
}
.scrollContentBackground(.hidden)
.navigationTitle("Settings")
.apply {
if #available(iOS 17, *) {
$0.toolbarTitleDisplayMode(.inlineLarge)
} else {
$0.navigationBarTitleDisplayMode(.inline)
}
}
.modifier(navigationInlineLarge())
.scrollContentBackground(.hidden)
}
}
}
@@ -184,17 +161,3 @@ struct SettingsView: View {
settingsModel: dummySettingsViewModel()
)
}
func getVersion() -> String {
guard let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] else {
fatalError("no bundle id wtf lol")
}
return "\(version)"
}
func getBuildID() -> String {
guard let build = Bundle.main.infoDictionary?["CFBundleVersion"] else {
fatalError("wtf did u do w the build number")
}
return "\(build)"
}

View File

@@ -0,0 +1,132 @@
//
// WhatsNewView.swift
// NearFuture
//
// Created by neon443 on 12/05/2025.
//
import SwiftUI
struct WhatsNewView: View {
@ObservedObject var settingsModel: SettingsViewModel
@Environment(\.dismiss) var dismiss
struct WhatsNewChunk: Identifiable {
var id: UUID = UUID()
var symbol: String
var title: String
var subtitle: String
}
@State var bye: Bool = false
var whatsNewChunks: [WhatsNewChunk] {
return [
WhatsNewChunk(
symbol: "desktopcomputer",
title: "Mac Native App",
subtitle: "New Mac native app (Intel too!)"
),
WhatsNewChunk(
symbol: "iphone.radiowaves.left.and.right",
title: "Haptic Feedback",
subtitle: "Lovely haptic feedback when completing and adding events, and selecting tabs"
),
WhatsNewChunk(
symbol: "app",
title: "App Icons",
subtitle: "You now get a special app icon that matches the color you choose in settings!"
),
WhatsNewChunk(
symbol: "apps.iphone",
title: "Widgets Day Count Fix",
subtitle: "The day count for widgets are now red for overdue events, just like the app, and are now more readable"
),
WhatsNewChunk(
symbol: settingsModel.device.sf,
title: "This Screen",
subtitle: "This update add a Whats New page that will tell you (suprise!) What's New"
),
WhatsNewChunk(
symbol: "bell.badge.fill",
title: "Notifications",
subtitle: "Events now have notifications, reminding you to complete them!"
),
WhatsNewChunk(
symbol: "list.bullet.indent",
title: "Animations!",
subtitle: "I added animations for adding, removing and ticking events - animations are definitely the most important change"
)
]
}
var body: some View {
NavigationStack {
ScrollView {
Text("What's New")
.font(.largeTitle)
.bold()
.padding(.vertical)
VStack(alignment: .leading) {
ForEach(whatsNewChunks) { new in
WhatsNewChunkView(
symbol: new.symbol,
title: new.title,
subtitle: new.subtitle
)
}
Spacer()
}
.padding(.horizontal, 10)
}
Button() {
bye.toggle()
dismiss()
} label: {
Text("Continue")
.font(.headline)
.frame(height: 40)
.bold()
// .frame(maxWidth: .infinity)
}
.foregroundStyle(.orange)
.modifier(glassButton())
.modifier(hapticHeavy(trigger: bye))
}
.scrollContentBackground(.hidden)
.presentationDragIndicator(.visible)
.onDisappear {
settingsModel.settings.prevAppVersion = getVersion()+getBuildID()
settingsModel.saveSettings()
}
}
}
#Preview {
Color.accent
.ignoresSafeArea(.all)
.sheet(isPresented: .constant(true)) {
WhatsNewView(settingsModel: dummySettingsViewModel())
}
}
struct WhatsNewChunkView: View {
@State var symbol: String
@State var title: String
@State var subtitle: String
var body: some View {
HStack {
Image(systemName: symbol)
.resizable()
.scaledToFit()
.frame(width: 30, height: 30)
.foregroundStyle(Color.orange)
.padding(.trailing, 15)
VStack(alignment: .leading) {
Text(title)
.font(.headline)
.bold()
Text(subtitle)
.foregroundStyle(.gray)
.font(.subheadline)
.fixedSize(horizontal: false, vertical: true)
}
}
}
}

View File

@@ -8,30 +8,18 @@
import SwiftUI
struct iCloudSettingsView: View {
@State var viewModel: EventViewModel
@ObservedObject var viewModel: EventViewModel
@ObservedObject var settingsModel: SettingsViewModel
@State var showPushAlert: Bool = false
@State var showPullAlert: Bool = false
@Binding var hasUbiquitous: Bool
@Binding var lastSyncWasSuccessful: Bool
@Binding var lastSyncWasNormalAgo: Bool
@Binding var localCountEqualToiCloud: Bool
@Binding var icloudCountEqualToLocal: Bool
let asi = ProcessInfo().isiOSAppOnMac
let model = UIDevice().model
var device: (sf: String, label: String) {
if asi {
return (sf: "laptopcomputer", label: "Computer")
} else if model == "iPhone" {
return (sf: model.lowercased(), label: model)
} else if model == "iPad" {
return (sf: model.lowercased(), label: model)
}
return (sf: "iphone", label: "iPhone")
}
var updateStatus: () -> Void
// @Binding var hasUbiquitous: Bool
// @Binding var lastSyncWasSuccessful: Bool
// @Binding var lastSyncWasNormalAgo: Bool
// @Binding var localCountEqualToiCloud: Bool
// @Binding var icloudCountEqualToLocal: Bool
//
// var updateStatus: () -> Void
var body: some View {
ZStack {
@@ -67,7 +55,7 @@ struct iCloudSettingsView: View {
Button("OK", role: .destructive) {
viewModel.replaceiCloudWithLocalData()
viewModel.sync()
updateStatus()
viewModel.updateiCStatus()
}
Button("Cancel", role: .cancel) {}
} message: {
@@ -76,7 +64,7 @@ struct iCloudSettingsView: View {
Button() {
viewModel.sync()
updateStatus()
viewModel.updateiCStatus()
} label: {
Image(systemName: "arrow.triangle.2.circlepath")
.resizable()
@@ -99,7 +87,7 @@ struct iCloudSettingsView: View {
Button("OK", role: .destructive) {
viewModel.replaceLocalWithiCloudData()
viewModel.sync()
updateStatus()
viewModel.updateiCStatus()
}
Button("Cancel", role: .cancel) {}
} message: {
@@ -107,7 +95,7 @@ struct iCloudSettingsView: View {
}
}
ZStack {
Image(systemName: device.sf)
Image(systemName: settingsModel.device.sf)
.resizable()
.scaledToFit()
.frame(width: 75, height: 75)
@@ -117,30 +105,30 @@ struct iCloudSettingsView: View {
.monospaced()
.bold()
}
Text(device.label)
Text(settingsModel.device.label)
}
Spacer()
}
.listRowSeparator(.hidden)
.onAppear {
viewModel.sync()
updateStatus()
viewModel.updateiCStatus()
}
HStack {
Circle()
.frame(width: 20, height: 20)
.foregroundStyle(hasUbiquitous ? .green : .red)
.foregroundStyle(viewModel.hasUbiquitous ? .green : .red)
Text("iCloud")
Spacer()
Text("\(hasUbiquitous ? "" : "Not ")Working")
Text("\(viewModel.hasUbiquitous ? "" : "Not ")Working")
.bold()
}
HStack {
Circle()
.frame(width: 20, height: 20)
.foregroundStyle(lastSyncWasSuccessful ? .green : .red)
.foregroundStyle(viewModel.lastSyncWasSuccessful ? .green : .red)
Text("Sync Status")
Spacer()
Text("\(viewModel.syncStatus)")
@@ -150,7 +138,7 @@ struct iCloudSettingsView: View {
HStack {
Circle()
.frame(width: 20, height: 20)
.foregroundStyle(lastSyncWasNormalAgo ? .green : .red)
.foregroundStyle(viewModel.lastSyncWasNormalAgo ? .green : .red)
Text("Last Sync")
Spacer()
Text("\(viewModel.lastSync?.formatted(date: .long, time: .standard) ?? "Never")")
@@ -160,7 +148,7 @@ struct iCloudSettingsView: View {
HStack {
Circle()
.frame(width: 20, height: 20)
.foregroundStyle(localCountEqualToiCloud ? .green : .red)
.foregroundStyle(viewModel.localCountEqualToiCloud ? .green : .red)
Text("Local Events")
Spacer()
Text("\(viewModel.localEventCount)")
@@ -170,7 +158,7 @@ struct iCloudSettingsView: View {
HStack {
Circle()
.frame(width: 20, height: 20)
.foregroundStyle(icloudCountEqualToLocal ? .green : .red)
.foregroundStyle(viewModel.icloudCountEqualToLocal ? .green : .red)
Text("Events in iCloud")
Spacer()
Text("\(viewModel.icloudEventCount)")
@@ -184,11 +172,10 @@ struct iCloudSettingsView: View {
}
.refreshable {
viewModel.sync()
updateStatus()
viewModel.updateiCStatus()
}
.scrollContentBackground(.hidden)
.navigationTitle("iCloud")
.navigationBarTitleDisplayMode(.inline)
}
}
}
@@ -196,11 +183,6 @@ struct iCloudSettingsView: View {
#Preview("iCloudSettingsView") {
iCloudSettingsView(
viewModel: dummyEventViewModel(),
hasUbiquitous: .constant(true),
lastSyncWasSuccessful: .constant(true),
lastSyncWasNormalAgo: .constant(true),
localCountEqualToiCloud: .constant(true),
icloudCountEqualToLocal: .constant(true),
updateStatus: {}
settingsModel: dummySettingsViewModel()
)
}

View File

@@ -2,7 +2,7 @@
// StatsView.swift
// NearFuture
//
// Created by Nihaal Sharma on 05/01/2025.
// Created by neon443 on 05/01/2025.
//
import SwiftUI
@@ -58,13 +58,7 @@ struct StatsView: View {
}
.scrollContentBackground(.hidden)
.navigationTitle("Statistics")
.apply {
if #available(iOS 17, *) {
$0.toolbarTitleDisplayMode(.inlineLarge)
} else {
$0.navigationBarTitleDisplayMode(.inline)
}
}
.modifier(navigationInlineLarge())
}
}
}

View File

@@ -1,16 +0,0 @@
//
// NearFutureTests.swift
// NearFutureTests
//
// Created by neon443 on 26/03/2025.
//
import Testing
struct NearFutureTests {
@Test func example() async throws {
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
}
}

View File

@@ -2,11 +2,12 @@
// NearFutureWidgets.swift
// NearFutureWidgets
//
// Created by Nihaal Sharma on 02/01/2025.
// Created by neon443 on 02/01/2025.
//
import WidgetKit
import SwiftUI
import AppIntents
// Timeline Entry for Widget
struct EventWidgetEntry: TimelineEntry {
@@ -46,6 +47,24 @@ struct EventWidgetProvider: TimelineProvider {
}
}
// Event Widget View
struct EventWidgetView: View {
var entry: EventWidgetEntry
@@ -128,17 +147,36 @@ struct EventWidgetView: View {
Spacer()
//short days till if not large widget
if isLarge {
Text(daysUntilEvent(event.date).long)
.font(.caption)
.multilineTextAlignment(.trailing)
.foregroundColor(event.color.color)
.padding(.trailing, -12)
} else {
if !isLarge {
Text(daysUntilEvent(event.date).short)
.font(.caption)
.multilineTextAlignment(.trailing)
.foregroundColor(event.color.color)
.foregroundColor(event.date < Date() ? .red : .primary)
.padding(.trailing, -12)
} else {
Button(
intent: CompleteEvent(
eventID: IntentParameter(
title: LocalizedStringResource(
stringLiteral: event.id.uuidString
)
)
)
) {
if event.complete {
Circle()
.frame(width: 10)
.foregroundStyle(.green)
} else {
Circle()
.frame(width: 10)
.foregroundStyle(.gray)
}
}
Text(daysUntilEvent(event.date).long)
.font(.caption)
.multilineTextAlignment(.trailing)
.foregroundColor(event.date < Date() ? .red : .primary)
.padding(.trailing, -12)
}
}

View File

@@ -2,7 +2,7 @@
// NearFutureWidgetsBundle.swift
// NearFutureWidgets
//
// Created by Nihaal Sharma on 02/01/2025.
// Created by neon443 on 02/01/2025.
//
import WidgetKit

View File

@@ -2,7 +2,7 @@
// NearFutureWidgetsLiveActivity.swift
// NearFutureWidgets
//
// Created by Nihaal Sharma on 02/01/2025.
// Created by neon443 on 02/01/2025.
//
//import ActivityKit

View File

@@ -1,6 +1,24 @@
# NearFuture
[App Store](https://apps.apple.com/us/app/near-future-event-tracker/id6744963429)
<div align="center">
<br/>
<p>
<img src="https://github.com/neon443/NearFuture/blob/main/Resources/Assets.xcassets/AppIcon.appiconset/NearFutureIcon.png?raw=true" title="dockphobia" alt="dockphobia icon" width="100" />
</p>
<h3>Near Future</h3>
<p>
<a href="https://apps.apple.com/us/app/near-future-event-tracker/id6744963429">
download
<img alt="GitHub Release" src="https://img.shields.io/itunes/v/6744963429">
</a>
</p>
<p>
make your Dock scared of the mouse
<br/>
<a href="https://neon443.github.io">
made by neon443
</a>
</p>
<br/>
</div>
**Near Future** is a SwiftUI App to help people track upcoming events - Holidays, Trips, Birthdays, Weddings, Anniversaries.
@@ -11,17 +29,18 @@
- [x] Event colors
- [x] Recurrence
- [x] Search
- [ ] Notifications
- [x] Notifications
- [ ] Mac App
- [ ] Apple Watch App
- [x] Home Screen Widgets
- [ ] Lock Screen Widgets
- [ ] Later Box
- [ ] Sort by
- [ ] Reorder Events
- [ ] Archive
- [x] Archive
- [ ] Collaboration
- [ ] Autocomplete tasks
- [ ] Settings
- [x] Settings
## Features
- **Event Creation**: Create events with a name, description, date, recurrence, and an icon
@@ -53,4 +72,4 @@ Contributions are welcome! Just follow these steps:
## Used Tools/Frameworks
- Swift & SwiftUI by Apple
- **SFSymbolsPicker** by [alessiorubicini/SFSymbolsPickerForSwiftUI].
- **SFSymbolsPicker** by [alessiorubicini/SFSymbolsPickerForSwiftUI].

View File

@@ -31,54 +31,70 @@
"size" : "1024x1024"
},
{
"filename" : "MacNearFutureIcon16.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "MacNearFutureIcon32.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "MacNearFutureIcon32.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "MacNearFutureIcon64.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "MacNearFutureIcon128.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "MacNearFutureIcon256.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "MacNearFutureIcon256.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "MacNearFutureIcon512.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "MacNearFutureIcon512.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "MacNearFutureIcon.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
},
{
"filename" : "NearFutureIcon.png",
"idiom" : "universal",
"platform" : "watchos",
"size" : "1024x1024"
}
],
"info" : {

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 893 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -0,0 +1,44 @@
{
"images" : [
{
"filename" : "bloo.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "blooDark.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"filename" : "NearFutureIconTint.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"filename" : "bloo.png",
"idiom" : "universal",
"platform" : "watchos",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 KiB

View File

@@ -0,0 +1,44 @@
{
"images" : [
{
"filename" : "blue.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "blueDark.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"filename" : "NearFutureIconTint.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"filename" : "blue.png",
"idiom" : "universal",
"platform" : "watchos",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 KiB

View File

@@ -0,0 +1,44 @@
{
"images" : [
{
"filename" : "green.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "greenDark.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"filename" : "NearFutureIconTint.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"filename" : "green.png",
"idiom" : "universal",
"platform" : "watchos",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 KiB

View File

@@ -0,0 +1,44 @@
{
"images" : [
{
"filename" : "pink.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "pinkDark.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"filename" : "NearFutureIconTint.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"filename" : "pink.png",
"idiom" : "universal",
"platform" : "watchos",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 KiB

View File

@@ -0,0 +1,44 @@
{
"images" : [
{
"filename" : "purple.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "purpleDark.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"filename" : "NearFutureIconTint.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"filename" : "purple.png",
"idiom" : "universal",
"platform" : "watchos",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

View File

@@ -0,0 +1,44 @@
{
"images" : [
{
"filename" : "red.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "redDark.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"filename" : "NearFutureIconTint.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"filename" : "red.png",
"idiom" : "universal",
"platform" : "watchos",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 KiB

View File

@@ -1,38 +0,0 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.000",
"green" : "0.000",
"red" : "0.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,44 @@
{
"images" : [
{
"filename" : "yellow.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "yellowDark.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "tinted"
}
],
"filename" : "NearFutureIconTint.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"filename" : "yellow.png",
"idiom" : "universal",
"platform" : "watchos",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 KiB

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

BIN
Resources/Grue.pxd Normal file
View File

Binary file not shown.

BIN
Resources/GrueDark.pxd Normal file
View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

View File

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More