10 Commits

Author SHA1 Message Date
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
29 changed files with 776 additions and 507 deletions

View File

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

View File

@@ -24,14 +24,14 @@ struct NearFutureApp: App {
.defaultSize(width: 550, height: 650) .defaultSize(width: 550, height: 650)
.commands { .commands {
CommandGroup(replacing: CommandGroupPlacement.appInfo) { CommandGroup(replacing: CommandGroupPlacement.appInfo) {
Button("about nf") { Button("About Near Future") {
openWindow(id: "about") openWindow(id: "about")
} }
} }
NearFutureCommands() NearFutureCommands()
} }
WindowGroup("edit Event", for: Event.ID.self) { $eventID in WindowGroup("Edit Event", for: Event.ID.self) { $eventID in
EditEventView( EditEventView(
viewModel: viewModel, viewModel: viewModel,
event: Binding( event: Binding(
@@ -60,7 +60,10 @@ struct NearFutureApp: App {
.defaultPosition(UnitPoint.center) .defaultPosition(UnitPoint.center)
Settings { Settings {
Text("wip") SettingsView(
viewModel: viewModel,
settingsModel: settingsModel
)
} }
} }
} }

View File

@@ -11,7 +11,7 @@ import SwiftUI
struct NearFutureCommands: Commands { struct NearFutureCommands: Commands {
var body: some Commands { var body: some Commands {
CommandGroup(after: CommandGroupPlacement.appInfo) { CommandGroup(after: CommandGroupPlacement.appInfo) {
Text("hi") // Text("hi")
} }
} }
} }

View File

@@ -11,8 +11,11 @@ struct ContentView: View {
@StateObject var viewModel: EventViewModel @StateObject var viewModel: EventViewModel
@StateObject var settingsModel: SettingsViewModel @StateObject var settingsModel: SettingsViewModel
@State private var showAddEventView: Bool = false
@State private var symbolSearchInput: String = ""
var body: some View { var body: some View {
NavigationSplitView(preferredCompactColumn: .constant(.sidebar)) { NavigationSplitView {
List { List {
NavigationLink { NavigationLink {
HomeView( HomeView(
@@ -32,6 +35,14 @@ struct ContentView: View {
Image(systemName: "tray.full") Image(systemName: "tray.full")
Text("Archive") Text("Archive")
} }
NavigationLink {
SymbolsPicker(
selection: $symbolSearchInput
)
} label: {
Image(systemName: "star.circle")
Text("Symbols")
}
NavigationLink { NavigationLink {
SettingsView( SettingsView(
viewModel: viewModel, viewModel: viewModel,
@@ -43,11 +54,31 @@ struct ContentView: View {
} }
} }
} detail: { } detail: {
Text("Welcome to Near Future")
} }
.tint(settingsModel.settings.tint.color) .tint(settingsModel.settings.tint.color)
.frame(minWidth: 450, minHeight: 550) .frame(minWidth: 450, minHeight: 550)
.containerBackground(.ultraThinMaterial, for: .window) .containerBackground(.regularMaterial, for: .window)
.sheet(isPresented: $settingsModel.settings.showWhatsNew) {
WhatsNewView(settingsModel: settingsModel)
.presentationSizing(.form)
}
.sheet(isPresented: $showAddEventView) {
AddEventView(
viewModel: viewModel,
event: $viewModel.editableTemplate,
adding: true
)
.presentationSizing(.page)
}
.toolbar {
Button() {
showAddEventView.toggle()
} label: {
Image(systemName: "plus")
Text("New")
}
}
} }
} }

View File

@@ -118,11 +118,6 @@ struct EventListView: View {
.spring(response: 0.2, dampingFraction: 0.75, blendDuration: 2), .spring(response: 0.2, dampingFraction: 0.75, blendDuration: 2),
value: largeTick value: largeTick
) )
.apply {
if #available(iOS 17, *) {
$0.sensoryFeedback(.success, trigger: event.complete)
}
}
} }
.transition(.opacity) .transition(.opacity)
.fixedSize(horizontal: false, vertical: true) .fixedSize(horizontal: false, vertical: true)

View File

@@ -1,199 +0,0 @@
//
// AddEventView.swift
// MacNearFuture
//
// Created by neon443 on 11/06/2025.
//
import SwiftUI
import SFSymbolsPicker
struct AddEventView: View {
@ObservedObject var viewModel: EventViewModel
@Binding var event: Event
@State var adding: Bool
@State var showNeedsNameAlert: Bool = false
@State var isSymbolPickerPresented: Bool = false
@State private var bye: Bool = false
@FocusState private var focusedField: Field?
private enum Field {
case Name, Notes
}
@Environment(\.dismiss) var dismiss
var body: some View {
ZStack {
if !adding {
backgroundGradient
}
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,
title: "Choose a Symbol",
searchLabel: "Search...",
autoDismiss: true)
.presentationDetents([.medium])
}
// dscription
ZStack {
TextField("Event Notes", text: $event.notes)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.trailing, event.notes.isEmpty ? 0 : 30)
.animation(.spring, value: event.notes)
.focused($focusedField, equals: Field.Notes)
.submitLabel(.done)
.onSubmit {
focusedField = nil
}
// MagicClearButton(text: $eventNotes)
}
// date picker
HStack {
Spacer()
DatePicker("", selection: $event.date, displayedComponents: .date)
Spacer()
Button() {
event.date = Date()
} label: {
Image(systemName: "arrow.uturn.left")
.resizable()
.scaledToFit()
}
.buttonStyle(BorderlessButtonStyle())
.frame(width: 20)
}
DatePicker(
"",
selection: $event.date,
displayedComponents: .hourAndMinute
)
// 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: event.date,
recurrence: event.recurrence
)
)
}
}
.scrollContentBackground(.hidden)
.navigationTitle("\(adding ? "Add Event" : "")")
.toolbar {
ToolbarItem() {
if adding {
Button() {
resetAddEventView()
dismiss()
} label: {
Image(systemName: "xmark")
.resizable()
.scaledToFit()
.frame(width: 30)
}
}
}
ToolbarItem/*(placement: .topBarTrailing)*/ {
if adding {
Button {
viewModel.addEvent(
newEvent: event
)
bye.toggle()
resetAddEventView()
} label: {
Text("Save")
.font(.headline)
.cornerRadius(10)
.buttonStyle(BorderedProminentButtonStyle())
}
.tint(.accent)
.apply {
if #available(iOS 17, *) {
$0.sensoryFeedback(.success, 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.")
}
if event.name.isEmpty {
HStack {
Image(systemName: "exclamationmark")
.foregroundStyle(.red)
Text("Give your event a name.")
}
}
}
}
}
}
.scrollContentBackground(.hidden)
.presentationDragIndicator(.visible)
}
}
func resetAddEventView() {
//reset addeventView
event = viewModel.template
dismiss()
}
}
#Preview {
let vm = dummyEventViewModel()
Color.orange
.ignoresSafeArea(.all)
.sheet(isPresented: .constant(true)) {
AddEventView(
viewModel: vm,
event: .constant(vm.template),
adding: true
)
}
}

View File

@@ -1,41 +0,0 @@
//
// EditEventView.swift
// NearFuture
//
// Created by neon443 on 21/05/2025.
//
import SwiftUI
struct EditEventView: View {
@Environment(\.dismiss) var dismiss
@ObservedObject var viewModel: EventViewModel
@Binding var event: Event
var body: some View {
AddEventView(
viewModel: viewModel,
event: $event,
adding: false //bc we editing existing event
)
.navigationTitle("Edit Event")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button() {
dismiss()
} label: {
Text("Done")
.bold()
}
.disabled(event.name == "")
}
}
}
}
#Preview {
EditEventView(
viewModel: dummyEventViewModel(),
event: .constant(dummyEventViewModel().template)
)
}

View File

@@ -11,20 +11,33 @@ struct HomeView: View {
@StateObject var viewModel: EventViewModel @StateObject var viewModel: EventViewModel
@StateObject var settingsModel: SettingsViewModel @StateObject var settingsModel: SettingsViewModel
@State private var searchInput: String = ""
var filteredEvents: [Event] { var filteredEvents: [Event] {
switch settingsModel.settings.showCompletedInHome { if searchInput.isEmpty {
case true: if settingsModel.settings.showCompletedInHome {
return viewModel.events return viewModel.events
case false: } else {
return viewModel.events.filter { !$0.complete } return viewModel.events.filter() { !$0.complete }
} }
} } else {
var body: some View { return viewModel.events.filter {
ScrollView { $0.name.localizedCaseInsensitiveContains(searchInput) ||
ForEach(filteredEvents) { event in $0.notes.localizedCaseInsensitiveContains(searchInput)
EventListView(viewModel: viewModel, event: event)
} }
} }
}
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) .scrollContentBackground(.hidden)
} }
} }

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

@@ -16,7 +16,6 @@
A90D49462DDE1C7A00781124 /* 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 */; }; A90D49522DDE2D0000781124 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D49512DDE2D0000781124 /* Extensions.swift */; };
A90D49532DDE2D0000781124 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D49512DDE2D0000781124 /* Extensions.swift */; }; A90D49532DDE2D0000781124 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D49512DDE2D0000781124 /* Extensions.swift */; };
A90D49562DDE2D5800781124 /* SFSymbolsPicker in Frameworks */ = {isa = PBXBuildFile; productRef = A90D49552DDE2D5800781124 /* SFSymbolsPicker */; };
A90D495B2DDE2EDB00781124 /* MacNearFutureApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D495A2DDE2EDB00781124 /* MacNearFutureApp.swift */; }; A90D495B2DDE2EDB00781124 /* MacNearFutureApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D495A2DDE2EDB00781124 /* MacNearFutureApp.swift */; };
A90D495E2DDE3C7400781124 /* NFCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D495D2DDE3C7400781124 /* NFCommands.swift */; }; A90D495E2DDE3C7400781124 /* NFCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D495D2DDE3C7400781124 /* NFCommands.swift */; };
A90D495F2DDE3C7400781124 /* NFCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D495D2DDE3C7400781124 /* NFCommands.swift */; }; A90D495F2DDE3C7400781124 /* NFCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90D495D2DDE3C7400781124 /* NFCommands.swift */; };
@@ -26,11 +25,26 @@
A914FA4B2DD26C6800856265 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914FA4A2DD26C0F00856265 /* HomeView.swift */; }; A914FA4B2DD26C6800856265 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914FA4A2DD26C0F00856265 /* HomeView.swift */; };
A914FA4D2DD2768900856265 /* WhatsNewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914FA4C2DD2768900856265 /* WhatsNewView.swift */; }; A914FA4D2DD2768900856265 /* WhatsNewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914FA4C2DD2768900856265 /* WhatsNewView.swift */; };
A914FA4F2DD276D200856265 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914FA4E2DD276D200856265 /* AboutView.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 */; }; A920C2882D24011400E4F9B1 /* NearFutureApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C2872D24011400E4F9B1 /* NearFutureApp.swift */; };
A920C28C2D24011400E4F9B1 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Events.swift */; }; A920C28C2D24011400E4F9B1 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Events.swift */; };
A920C28E2D24011A00E4F9B1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A920C28D2D24011A00E4F9B1 /* Assets.xcassets */; }; A920C28E2D24011A00E4F9B1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A920C28D2D24011A00E4F9B1 /* Assets.xcassets */; };
A920C2922D24011A00E4F9B1 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A920C2912D24011A00E4F9B1 /* Preview 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 */; }; A949F8322DCAAA8A0064DCA0 /* NearFutureIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = A949F8312DCAAA8A0064DCA0 /* NearFutureIcon.png */; };
A949F84B2DCAABE00064DCA0 /* ArchiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F83A2DCAABE00064DCA0 /* ArchiveView.swift */; }; A949F84B2DCAABE00064DCA0 /* ArchiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F83A2DCAABE00064DCA0 /* ArchiveView.swift */; };
A949F84C2DCAABE00064DCA0 /* AddEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F83C2DCAABE00064DCA0 /* AddEventView.swift */; }; A949F84C2DCAABE00064DCA0 /* AddEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F83C2DCAABE00064DCA0 /* AddEventView.swift */; };
@@ -48,20 +62,23 @@
A95E9ED82DFC742B00ED655F /* AccentIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95E9ED72DFC742B00ED655F /* AccentIcon.swift */; }; A95E9ED82DFC742B00ED655F /* AccentIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95E9ED72DFC742B00ED655F /* AccentIcon.swift */; };
A95E9ED92DFC742B00ED655F /* 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 */; }; A95E9EDA2DFC742B00ED655F /* AccentIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = A95E9ED72DFC742B00ED655F /* AccentIcon.swift */; };
A95E9EE32DFC775300ED655F /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8462DCAABE00064DCA0 /* SettingsView.swift */; };
A95E9EE42DFC77D400ED655F /* ImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8452DCAABE00064DCA0 /* ImportView.swift */; }; A95E9EE42DFC77D400ED655F /* ImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8452DCAABE00064DCA0 /* ImportView.swift */; };
A95E9EE52DFC77E200ED655F /* ExportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A949F8432DCAABE00064DCA0 /* ExportView.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 */; }; A979F60A2D270AF00094C0B3 /* NearFutureWidgetsBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = A979F6092D270AF00094C0B3 /* NearFutureWidgetsBundle.swift */; };
A979F60C2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A979F60B2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift */; }; A979F60C2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = A979F60B2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift */; };
A979F6102D270AF90094C0B3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A979F60F2D270AF80094C0B3 /* Assets.xcassets */; }; 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, ); }; }; A979F6142D270AF90094C0B3 /* NearFutureWidgetsExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = A979F6022D270AF00094C0B3 /* NearFutureWidgetsExtension.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
A979F6182D2714310094C0B3 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Events.swift */; }; A979F6182D2714310094C0B3 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Events.swift */; };
A98C20CB2DE730740008D61C /* EventListViewMac.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CA2DE730740008D61C /* EventListViewMac.swift */; }; A98C20CB2DE730740008D61C /* EventListViewMac.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CA2DE730740008D61C /* EventListViewMac.swift */; };
A98C20CC2DE730740008D61C /* EditEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20C92DE730740008D61C /* EditEventView.swift */; };
A98C20CE2DE7308E0008D61C /* ArchiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CD2DE7308E0008D61C /* ArchiveView.swift */; }; A98C20CE2DE7308E0008D61C /* ArchiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CD2DE7308E0008D61C /* ArchiveView.swift */; };
A98C20D02DE731BD0008D61C /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CF2DE731BD0008D61C /* HomeView.swift */; }; A98C20D02DE731BD0008D61C /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CF2DE731BD0008D61C /* HomeView.swift */; };
A98C20D42DE7339E0008D61C /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20D32DE7339E0008D61C /* AboutView.swift */; }; A98C20D42DE7339E0008D61C /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20D32DE7339E0008D61C /* AboutView.swift */; };
A9B78B942DF9F3CF00647399 /* AddEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9B78B932DF9F3CF00647399 /* AddEventView.swift */; }; A9C769A22DFDD1FC00082FFF /* SymbolsPicker.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A9C769A02DFDD1FC00082FFF /* SymbolsPicker.storyboard */; };
A9C769A32DFDD1FC00082FFF /* SymbolsPicker.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A9C769A02DFDD1FC00082FFF /* SymbolsPicker.storyboard */; };
A9C769A52DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C769A42DFDD27500082FFF /* SymbolsPickerStoryboard.swift */; };
A9C769A62DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C769A42DFDD27500082FFF /* SymbolsPickerStoryboard.swift */; };
A9C769A72DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9C769A42DFDD27500082FFF /* SymbolsPickerStoryboard.swift */; };
A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */; }; A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@@ -111,6 +128,11 @@
A914FA4A2DD26C0F00856265 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; 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; }; 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; }; 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; }; 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>"; }; A920C2872D24011400E4F9B1 /* NearFutureApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureApp.swift; sourceTree = "<group>"; };
A920C28B2D24011400E4F9B1 /* Events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Events.swift; sourceTree = "<group>"; }; A920C28B2D24011400E4F9B1 /* Events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Events.swift; sourceTree = "<group>"; };
@@ -137,12 +159,12 @@
A979F6092D270AF00094C0B3 /* NearFutureWidgetsBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgetsBundle.swift; sourceTree = "<group>"; }; 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>"; }; 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>"; }; A979F60F2D270AF80094C0B3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
A98C20C92DE730740008D61C /* EditEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditEventView.swift; sourceTree = "<group>"; };
A98C20CA2DE730740008D61C /* EventListViewMac.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventListViewMac.swift; sourceTree = "<group>"; }; A98C20CA2DE730740008D61C /* EventListViewMac.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventListViewMac.swift; sourceTree = "<group>"; };
A98C20CD2DE7308E0008D61C /* ArchiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchiveView.swift; 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>"; }; 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>"; }; A98C20D32DE7339E0008D61C /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
A9B78B932DF9F3CF00647399 /* AddEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEventView.swift; sourceTree = "<group>"; }; A9C769A02DFDD1FC00082FFF /* SymbolsPicker.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SymbolsPicker.storyboard; sourceTree = "<group>"; };
A9C769A42DFDD27500082FFF /* SymbolsPickerStoryboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SymbolsPickerStoryboard.swift; sourceTree = "<group>"; };
A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgets.swift; sourceTree = "<group>"; }; A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgets.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@@ -151,7 +173,6 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A90D49562DDE2D5800781124 /* SFSymbolsPicker in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -159,7 +180,6 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A920C2BE2D24021A00E4F9B1 /* SFSymbolsPicker in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -178,7 +198,9 @@
children = ( children = (
A920C28B2D24011400E4F9B1 /* Events.swift */, A920C28B2D24011400E4F9B1 /* Events.swift */,
A90D49602DDE626300781124 /* Settings.swift */, A90D49602DDE626300781124 /* Settings.swift */,
A91EF8062DFC8B8B00B8463D /* ColorCodable.swift */,
A95E9ED72DFC742B00ED655F /* AccentIcon.swift */, A95E9ED72DFC742B00ED655F /* AccentIcon.swift */,
A91EF8162DFD77A500B8463D /* SymbolsPicker */,
); );
path = Model; path = Model;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -202,7 +224,7 @@
A98C20CF2DE731BD0008D61C /* HomeView.swift */, A98C20CF2DE731BD0008D61C /* HomeView.swift */,
A98C20CA2DE730740008D61C /* EventListViewMac.swift */, A98C20CA2DE730740008D61C /* EventListViewMac.swift */,
A98C20CD2DE7308E0008D61C /* ArchiveView.swift */, A98C20CD2DE7308E0008D61C /* ArchiveView.swift */,
A98C20C82DE730420008D61C /* Events */, A91EF80F2DFCB66C00B8463D /* SettingsView.swift */,
); );
path = Views; path = Views;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -213,6 +235,7 @@
A920C2872D24011400E4F9B1 /* NearFutureApp.swift */, A920C2872D24011400E4F9B1 /* NearFutureApp.swift */,
A90D49512DDE2D0000781124 /* Extensions.swift */, A90D49512DDE2D0000781124 /* Extensions.swift */,
A90D49202DDE0A3B00781124 /* Model */, A90D49202DDE0A3B00781124 /* Model */,
A91EF80A2DFC910000B8463D /* ViewModifiers.swift */,
); );
path = Shared; path = Shared;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -224,6 +247,17 @@
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
A91EF8162DFD77A500B8463D /* SymbolsPicker */ = {
isa = PBXGroup;
children = (
A91EF8172DFD77BF00B8463D /* SymbolsLoader.swift */,
A91EF81B2DFD796600B8463D /* SymbolsPicker.swift */,
A9C769A02DFDD1FC00082FFF /* SymbolsPicker.storyboard */,
A9C769A42DFDD27500082FFF /* SymbolsPickerStoryboard.swift */,
);
path = SymbolsPicker;
sourceTree = "<group>";
};
A920C27B2D24011300E4F9B1 = { A920C27B2D24011300E4F9B1 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -361,15 +395,6 @@
path = NearFutureWidgets; path = NearFutureWidgets;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
A98C20C82DE730420008D61C /* Events */ = {
isa = PBXGroup;
children = (
A9B78B932DF9F3CF00647399 /* AddEventView.swift */,
A98C20C92DE730740008D61C /* EditEventView.swift */,
);
path = Events;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@@ -385,11 +410,9 @@
); );
dependencies = ( dependencies = (
A98C20D22DE732B10008D61C /* PBXTargetDependency */, A98C20D22DE732B10008D61C /* PBXTargetDependency */,
A90D494D2DDE2C6000781124 /* PBXTargetDependency */,
); );
name = MacNearFuture; name = MacNearFuture;
packageProductDependencies = ( packageProductDependencies = (
A90D49552DDE2D5800781124 /* SFSymbolsPicker */,
); );
productName = MacNearFuture; productName = MacNearFuture;
productReference = A90D49262DDE0FA400781124 /* Near Future.app */; productReference = A90D49262DDE0FA400781124 /* Near Future.app */;
@@ -411,7 +434,6 @@
); );
name = NearFuture; name = NearFuture;
packageProductDependencies = ( packageProductDependencies = (
A920C2BD2D24021A00E4F9B1 /* SFSymbolsPicker */,
); );
productName = NearFuture; productName = NearFuture;
productReference = A920C2842D24011400E4F9B1 /* NearFuture.app */; productReference = A920C2842D24011400E4F9B1 /* NearFuture.app */;
@@ -465,7 +487,6 @@
); );
mainGroup = A920C27B2D24011300E4F9B1; mainGroup = A920C27B2D24011300E4F9B1;
packageReferences = ( packageReferences = (
A920C2BC2D24021900E4F9B1 /* XCRemoteSwiftPackageReference "SFSymbolsPicker" */,
); );
productRefGroup = A920C2852D24011400E4F9B1 /* Products */; productRefGroup = A920C2852D24011400E4F9B1 /* Products */;
projectDirPath = ""; projectDirPath = "";
@@ -495,6 +516,7 @@
files = ( files = (
A90D49442DDE1C7600781124 /* Tints.xcassets in Resources */, A90D49442DDE1C7600781124 /* Tints.xcassets in Resources */,
A920C2922D24011A00E4F9B1 /* Preview Assets.xcassets in Resources */, A920C2922D24011A00E4F9B1 /* Preview Assets.xcassets in Resources */,
A9C769A22DFDD1FC00082FFF /* SymbolsPicker.storyboard in Resources */,
A949F8322DCAAA8A0064DCA0 /* NearFutureIcon.png in Resources */, A949F8322DCAAA8A0064DCA0 /* NearFutureIcon.png in Resources */,
A920C28E2D24011A00E4F9B1 /* Assets.xcassets in Resources */, A920C28E2D24011A00E4F9B1 /* Assets.xcassets in Resources */,
); );
@@ -505,6 +527,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A90D49462DDE1C7A00781124 /* Tints.xcassets in Resources */, A90D49462DDE1C7A00781124 /* Tints.xcassets in Resources */,
A9C769A32DFDD1FC00082FFF /* SymbolsPicker.storyboard in Resources */,
A979F6102D270AF90094C0B3 /* Assets.xcassets in Resources */, A979F6102D270AF90094C0B3 /* Assets.xcassets in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -516,23 +539,30 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A95E9EE32DFC775300ED655F /* SettingsView.swift in Sources */, A9C769A52DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */,
A91EF80E2DFC9A0C00B8463D /* WhatsNewView.swift in Sources */,
A91EF8192DFD77BF00B8463D /* SymbolsLoader.swift in Sources */,
A95E9EE42DFC77D400ED655F /* ImportView.swift in Sources */, A95E9EE42DFC77D400ED655F /* ImportView.swift in Sources */,
A98C20CB2DE730740008D61C /* EventListViewMac.swift in Sources */, A98C20CB2DE730740008D61C /* EventListViewMac.swift in Sources */,
A91EF80C2DFC910000B8463D /* ViewModifiers.swift in Sources */,
A95E9ED92DFC742B00ED655F /* AccentIcon.swift in Sources */, A95E9ED92DFC742B00ED655F /* AccentIcon.swift in Sources */,
A98C20CC2DE730740008D61C /* EditEventView.swift in Sources */, A91EF8102DFCB66C00B8463D /* SettingsView.swift in Sources */,
A90D495E2DDE3C7400781124 /* NFCommands.swift in Sources */, A90D495E2DDE3C7400781124 /* NFCommands.swift in Sources */,
A95E9EE52DFC77E200ED655F /* ExportView.swift in Sources */, A95E9EE52DFC77E200ED655F /* ExportView.swift in Sources */,
A91EF8132DFCC87D00B8463D /* EditEventView.swift in Sources */,
A91EF8142DFCC87D00B8463D /* AddEventView.swift in Sources */,
A98C20D42DE7339E0008D61C /* AboutView.swift in Sources */, A98C20D42DE7339E0008D61C /* AboutView.swift in Sources */,
A98C20CE2DE7308E0008D61C /* ArchiveView.swift in Sources */, A98C20CE2DE7308E0008D61C /* ArchiveView.swift in Sources */,
A98C20D02DE731BD0008D61C /* HomeView.swift in Sources */, A98C20D02DE731BD0008D61C /* HomeView.swift in Sources */,
A90D495B2DDE2EDB00781124 /* MacNearFutureApp.swift in Sources */, A90D495B2DDE2EDB00781124 /* MacNearFutureApp.swift in Sources */,
A9B78B942DF9F3CF00647399 /* AddEventView.swift in Sources */, A91EF8082DFC8B8B00B8463D /* ColorCodable.swift in Sources */,
A90D49522DDE2D0000781124 /* Extensions.swift in Sources */, A90D49522DDE2D0000781124 /* Extensions.swift in Sources */,
A91EF81D2DFD796600B8463D /* SymbolsPicker.swift in Sources */,
A90D49422DDE114100781124 /* Events.swift in Sources */, A90D49422DDE114100781124 /* Events.swift in Sources */,
A90D49382DDE0FAF00781124 /* ContentViewMac.swift in Sources */, A90D49382DDE0FAF00781124 /* ContentViewMac.swift in Sources */,
A90D49622DDE626300781124 /* Settings.swift in Sources */, A90D49622DDE626300781124 /* Settings.swift in Sources */,
A95E9ED32DFC703200ED655F /* iCloudSettingsView.swift in Sources */, A95E9ED32DFC703200ED655F /* iCloudSettingsView.swift in Sources */,
A96609E72DFD800000DBFA78 /* HelpView.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -550,16 +580,21 @@
A90D49612DDE626300781124 /* Settings.swift in Sources */, A90D49612DDE626300781124 /* Settings.swift in Sources */,
A90D495F2DDE3C7400781124 /* NFCommands.swift in Sources */, A90D495F2DDE3C7400781124 /* NFCommands.swift in Sources */,
A949F84F2DCAABE00064DCA0 /* EventListView.swift in Sources */, A949F84F2DCAABE00064DCA0 /* EventListView.swift in Sources */,
A91EF8092DFC8B8B00B8463D /* ColorCodable.swift in Sources */,
A949F8502DCAABE00064DCA0 /* HelpView.swift in Sources */, A949F8502DCAABE00064DCA0 /* HelpView.swift in Sources */,
A949F85F2DCABB420064DCA0 /* Buttons.swift in Sources */, A949F85F2DCABB420064DCA0 /* Buttons.swift in Sources */,
A914FA4D2DD2768900856265 /* WhatsNewView.swift in Sources */, A914FA4D2DD2768900856265 /* WhatsNewView.swift in Sources */,
A91EF80B2DFC910000B8463D /* ViewModifiers.swift in Sources */,
A949F8512DCAABE00064DCA0 /* ExportView.swift in Sources */, A949F8512DCAABE00064DCA0 /* ExportView.swift in Sources */,
A95E9ED82DFC742B00ED655F /* AccentIcon.swift in Sources */, A95E9ED82DFC742B00ED655F /* AccentIcon.swift in Sources */,
A90D49532DDE2D0000781124 /* Extensions.swift in Sources */, A90D49532DDE2D0000781124 /* Extensions.swift in Sources */,
A9C769A62DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */,
A949F8522DCAABE00064DCA0 /* iCloudSettingsView.swift in Sources */, A949F8522DCAABE00064DCA0 /* iCloudSettingsView.swift in Sources */,
A949F8532DCAABE00064DCA0 /* ImportView.swift in Sources */, A949F8532DCAABE00064DCA0 /* ImportView.swift in Sources */,
A949F8542DCAABE00064DCA0 /* SettingsView.swift in Sources */, A949F8542DCAABE00064DCA0 /* SettingsView.swift in Sources */,
A91EF81E2DFD796600B8463D /* SymbolsPicker.swift in Sources */,
A949F8552DCAABE00064DCA0 /* StatsView.swift in Sources */, A949F8552DCAABE00064DCA0 /* StatsView.swift in Sources */,
A91EF81A2DFD77BF00B8463D /* SymbolsLoader.swift in Sources */,
A920C2882D24011400E4F9B1 /* NearFutureApp.swift in Sources */, A920C2882D24011400E4F9B1 /* NearFutureApp.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -569,8 +604,13 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A979F6182D2714310094C0B3 /* Events.swift in Sources */, A979F6182D2714310094C0B3 /* Events.swift in Sources */,
A91EF81C2DFD796600B8463D /* SymbolsPicker.swift in Sources */,
A979F60A2D270AF00094C0B3 /* NearFutureWidgetsBundle.swift in Sources */, A979F60A2D270AF00094C0B3 /* NearFutureWidgetsBundle.swift in Sources */,
A95E9EDA2DFC742B00ED655F /* AccentIcon.swift in Sources */, A95E9EDA2DFC742B00ED655F /* AccentIcon.swift in Sources */,
A91EF80D2DFC910000B8463D /* ViewModifiers.swift in Sources */,
A91EF8182DFD77BF00B8463D /* SymbolsLoader.swift in Sources */,
A9C769A72DFDD27500082FFF /* SymbolsPickerStoryboard.swift in Sources */,
A91EF8072DFC8B8B00B8463D /* ColorCodable.swift in Sources */,
A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */, A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */,
A979F60C2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift in Sources */, A979F60C2D270AF00094C0B3 /* NearFutureWidgetsLiveActivity.swift in Sources */,
A90D49632DDE626300781124 /* Settings.swift in Sources */, A90D49632DDE626300781124 /* Settings.swift in Sources */,
@@ -580,10 +620,6 @@
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */ /* Begin PBXTargetDependency section */
A90D494D2DDE2C6000781124 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
productRef = A90D494C2DDE2C6000781124 /* SFSymbolsPicker */;
};
A979F6132D270AF90094C0B3 /* PBXTargetDependency */ = { A979F6132D270AF90094C0B3 /* PBXTargetDependency */ = {
isa = PBXTargetDependency; isa = PBXTargetDependency;
platformFilter = ios; platformFilter = ios;
@@ -1012,35 +1048,6 @@
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
/* End XCConfigurationList section */ /* 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 */
A90D494C2DDE2C6000781124 /* SFSymbolsPicker */ = {
isa = XCSwiftPackageProductDependency;
package = A920C2BC2D24021900E4F9B1 /* XCRemoteSwiftPackageReference "SFSymbolsPicker" */;
productName = SFSymbolsPicker;
};
A90D49552DDE2D5800781124 /* SFSymbolsPicker */ = {
isa = XCSwiftPackageProductDependency;
package = A920C2BC2D24021900E4F9B1 /* XCRemoteSwiftPackageReference "SFSymbolsPicker" */;
productName = SFSymbolsPicker;
};
A920C2BD2D24021A00E4F9B1 /* SFSymbolsPicker */ = {
isa = XCSwiftPackageProductDependency;
package = A920C2BC2D24021900E4F9B1 /* XCRemoteSwiftPackageReference "SFSymbolsPicker" */;
productName = SFSymbolsPicker;
};
/* End XCSwiftPackageProductDependency section */
}; };
rootObject = A920C27C2D24011300E4F9B1 /* Project object */; 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

@@ -39,13 +39,7 @@ struct ArchiveView: View {
} }
} }
.navigationTitle("Archive") .navigationTitle("Archive")
.apply { .modifier(navigationInlineLarge())
if #available(iOS 17, *) {
$0.toolbarTitleDisplayMode(.inlineLarge)
} else {
$0.navigationBarTitleDisplayMode(.inline)
}
}
} }
.sheet(isPresented: $showAddEvent) { .sheet(isPresented: $showAddEvent) {
AddEventView( AddEventView(

View File

@@ -9,9 +9,6 @@ import SwiftUI
import UserNotifications import UserNotifications
import SwiftData import SwiftData
enum Field {
case Search
}
enum Tab { enum Tab {
case home case home
case archive case archive
@@ -22,10 +19,10 @@ enum Tab {
struct ContentView: View { struct ContentView: View {
@StateObject var viewModel: EventViewModel @StateObject var viewModel: EventViewModel
@StateObject var settingsModel: SettingsViewModel @StateObject var settingsModel: SettingsViewModel
@State var selection: Tab = .home @State var tabSelection: Tab = .home
var body: some View { var body: some View {
TabView(selection: $selection) { TabView(selection: $tabSelection) {
HomeView(viewModel: viewModel, settingsModel: settingsModel) HomeView(viewModel: viewModel, settingsModel: settingsModel)
.tabItem { .tabItem {
Label("Home", systemImage: "house") Label("Home", systemImage: "house")
@@ -37,6 +34,7 @@ struct ContentView: View {
} }
.tag(Tab.archive) .tag(Tab.archive)
StatsView(viewModel: viewModel) StatsView(viewModel: viewModel)
// SymbolsPickerStoryboardUIViewRepresentable()
.tabItem { .tabItem {
Label("Statistics", systemImage: "chart.pie") Label("Statistics", systemImage: "chart.pie")
} }
@@ -47,11 +45,7 @@ struct ContentView: View {
} }
.tag(Tab.settings) .tag(Tab.settings)
} }
.apply { .modifier(hapticHeavy(trigger: tabSelection))
if #available(iOS 17, *) {
$0.sensoryFeedback(.impact(weight: .heavy, intensity: 1), trigger: selection)
}
}
.sheet(isPresented: $settingsModel.settings.showWhatsNew) { .sheet(isPresented: $settingsModel.settings.showWhatsNew) {
WhatsNewView(settingsModel: settingsModel) WhatsNewView(settingsModel: settingsModel)
} }

View File

@@ -6,7 +6,6 @@
// //
import SwiftUI import SwiftUI
import SFSymbolsPicker
struct AddEventView: View { struct AddEventView: View {
@ObservedObject var viewModel: EventViewModel @ObservedObject var viewModel: EventViewModel
@@ -54,11 +53,10 @@ struct AddEventView: View {
.buttonStyle(.borderless) .buttonStyle(.borderless)
.sheet(isPresented: $isSymbolPickerPresented) { .sheet(isPresented: $isSymbolPickerPresented) {
SymbolsPicker( SymbolsPicker(
selection: $event.symbol, selection: $event.symbol
title: "Choose a Symbol", )
searchLabel: "Search...",
autoDismiss: true)
.presentationDetents([.medium]) .presentationDetents([.medium])
.modifier(presentationSizeForm())
} }
TextField("Event Name", text: $event.name) TextField("Event Name", text: $event.name)
.textFieldStyle(.roundedBorder) .textFieldStyle(.roundedBorder)
@@ -75,7 +73,6 @@ struct AddEventView: View {
.onSubmit { .onSubmit {
focusedField = nil focusedField = nil
} }
// MagicClearButton(text: $eventNotes)
} }
@@ -83,7 +80,9 @@ struct AddEventView: View {
HStack { HStack {
Spacer() Spacer()
DatePicker("", selection: $event.date, displayedComponents: .date) DatePicker("", selection: $event.date, displayedComponents: .date)
#if os(iOS)
.datePickerStyle(.wheel) .datePickerStyle(.wheel)
#endif
Spacer() Spacer()
Button() { Button() {
event.date = Date() event.date = Date()
@@ -118,9 +117,9 @@ struct AddEventView: View {
} }
} }
.navigationTitle("\(adding ? "Add Event" : "")") .navigationTitle("\(adding ? "Add Event" : "")")
.navigationBarTitleDisplayMode(.inline) .modifier(navigationInlineLarge())
.toolbar { .toolbar {
ToolbarItem(placement: .topBarLeading) { ToolbarItem(placement: .cancellationAction) {
if adding { if adding {
Button() { Button() {
resetAddEventView() resetAddEventView()
@@ -129,7 +128,6 @@ struct AddEventView: View {
Image(systemName: "xmark") Image(systemName: "xmark")
.resizable() .resizable()
.scaledToFit() .scaledToFit()
.frame(width: 30)
.tint(.one) .tint(.one)
} }
} }
@@ -149,11 +147,7 @@ struct AddEventView: View {
.buttonStyle(BorderedProminentButtonStyle()) .buttonStyle(BorderedProminentButtonStyle())
} }
.tint(.accent) .tint(.accent)
.apply { .modifier(hapticSuccess(trigger: bye))
if #available(iOS 17, *) {
$0.sensoryFeedback(.success, trigger: bye)
}
}
.disabled(event.name.isEmpty) .disabled(event.name.isEmpty)
.onTapGesture { .onTapGesture {
if event.name.isEmpty { if event.name.isEmpty {
@@ -173,7 +167,6 @@ struct AddEventView: View {
} }
} }
.scrollContentBackground(.hidden) .scrollContentBackground(.hidden)
.scrollContentBackground(.hidden)
.presentationDragIndicator(.visible) .presentationDragIndicator(.visible)
} }
} }

View File

@@ -33,7 +33,7 @@ struct EditEventView: View {
) )
.navigationTitle("Edit Event") .navigationTitle("Edit Event")
.toolbar { .toolbar {
ToolbarItem(placement: .topBarTrailing) { ToolbarItem(/*placement: .topBarTrailing*/) {
Button() { Button() {
saveEdits() saveEdits()
} label: { } label: {

View File

@@ -112,11 +112,7 @@ struct EventListView: View {
.frame(maxWidth: 25, maxHeight: 25) .frame(maxWidth: 25, maxHeight: 25)
.shadow(radius: 5) .shadow(radius: 5)
.padding(.trailing, 5) .padding(.trailing, 5)
.apply { .modifier(hapticSuccess(trigger: event.complete))
if #available(iOS 17, *) {
$0.sensoryFeedback(.success, trigger: event.complete)
}
}
} }
.transition(.opacity) .transition(.opacity)
.padding(.vertical, 5) .padding(.vertical, 5)

View File

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

View File

@@ -67,13 +67,7 @@ struct HomeView: View {
} }
.searchable(text: $searchInput) .searchable(text: $searchInput)
.navigationTitle("Near Future") .navigationTitle("Near Future")
.apply { .modifier(navigationInlineLarge())
if #available(iOS 17, *) {
$0.toolbarTitleDisplayMode(.inlineLarge)
} else {
$0.navigationBarTitleDisplayMode(.inline)
}
}
.sheet(isPresented: $showingAddEventView) { .sheet(isPresented: $showingAddEventView) {
AddEventView( AddEventView(
viewModel: viewModel, viewModel: viewModel,

View File

@@ -13,22 +13,20 @@ struct SettingsView: View {
@State private var importStr: String = "" @State private var importStr: String = ""
func changeIcon(to: String) { func changeIcon(to toIcon: String) {
#if canImport(UIKit)
guard UIApplication.shared.supportsAlternateIcons else { guard UIApplication.shared.supportsAlternateIcons else {
print("doesnt tsupport alternate icons") print("doesnt tsupport alternate icons")
return return
} }
guard to != "orange" else { guard toIcon != "orange" else {
UIApplication.shared.setAlternateIconName(nil) { error in UIApplication.shared.setAlternateIconName(nil) { error in
print(error as Any) print(error as Any)
} }
return return
} }
UIApplication.shared.setAlternateIconName(to) { error in UIApplication.shared.setAlternateIconName(toIcon) { error in
print(error as Any) print(error as Any)
} }
#endif
} }
var body: some View { var body: some View {
@@ -39,11 +37,7 @@ struct SettingsView: View {
ScrollView(.horizontal) { ScrollView(.horizontal) {
HStack { HStack {
ForEach(settingsModel.accentChoices, id: \.self) { choice in ForEach(settingsModel.accentChoices, id: \.self) { choice in
#if canImport(UIKit)
let color = Color(uiColor: UIColor(named: "uiColors/\(choice)")!) let color = Color(uiColor: UIColor(named: "uiColors/\(choice)")!)
#else
let color = Color(nsColor: NSColor(named: "uiColors/\(choice)")!)
#endif
ZStack { ZStack {
Button() { Button() {
settingsModel.changeTint(to: choice) settingsModel.changeTint(to: choice)
@@ -53,6 +47,7 @@ struct SettingsView: View {
.foregroundStyle(color) .foregroundStyle(color)
.frame(width: 30) .frame(width: 30)
} }
.buttonStyle(.plain)
if ColorCodable(color) == settingsModel.settings.tint { if ColorCodable(color) == settingsModel.settings.tint {
let needContrast: Bool = ColorCodable(color) == settingsModel.settings.tint let needContrast: Bool = ColorCodable(color) == settingsModel.settings.tint
Circle() Circle()
@@ -153,17 +148,9 @@ struct SettingsView: View {
} }
} }
} }
.scrollContentBackground(.hidden)
.navigationTitle("Settings") .navigationTitle("Settings")
.apply { .modifier(navigationInlineLarge())
#if canImport(UIKit) .scrollContentBackground(.hidden)
if #available(iOS 17, *) {
$0.toolbarTitleDisplayMode(.inlineLarge)
} else {
$0.navigationBarTitleDisplayMode(.inline)
}
#endif
}
} }
} }
} }

View File

@@ -19,6 +19,11 @@ struct WhatsNewView: View {
@State var bye: Bool = false @State var bye: Bool = false
var whatsNewChunks: [WhatsNewChunk] { var whatsNewChunks: [WhatsNewChunk] {
return [ return [
WhatsNewChunk(
symbol: "desktopcomputer",
title: "Mac Native App",
subtitle: "New Mac native app (Intel too!)"
),
WhatsNewChunk( WhatsNewChunk(
symbol: "iphone.radiowaves.left.and.right", symbol: "iphone.radiowaves.left.and.right",
title: "Haptic Feedback", title: "Haptic Feedback",
@@ -53,23 +58,22 @@ struct WhatsNewView: View {
} }
var body: some View { var body: some View {
NavigationStack { NavigationStack {
List { ScrollView {
VStack { Text("What's New")
Text("What's New") .font(.largeTitle)
.font(.largeTitle) .bold()
.bold() .padding(.vertical)
AboutView() VStack(alignment: .leading) {
Divider() ForEach(whatsNewChunks) { new in
VStack(alignment: .leading) { WhatsNewChunkView(
ForEach(whatsNewChunks) { new in symbol: new.symbol,
WhatsNewChunkView( title: new.title,
symbol: new.symbol, subtitle: new.subtitle
title: new.title, )
subtitle: new.subtitle
)
}
} }
Spacer()
} }
.padding(.horizontal, 10)
} }
Button() { Button() {
bye.toggle() bye.toggle()
@@ -79,16 +83,11 @@ struct WhatsNewView: View {
.font(.headline) .font(.headline)
.frame(height: 40) .frame(height: 40)
.bold() .bold()
.frame(maxWidth: .infinity) // .frame(maxWidth: .infinity)
}
.buttonStyle(BorderedProminentButtonStyle())
.clipShape(RoundedRectangle(cornerRadius: 15))
.padding().padding()
.apply {
if #available(iOS 17, *) {
$0.sensoryFeedback(.impact(weight: .heavy, intensity: 1), trigger: bye)
}
} }
.foregroundStyle(.orange)
.modifier(glassButton())
.modifier(hapticHeavy(trigger: bye))
} }
.scrollContentBackground(.hidden) .scrollContentBackground(.hidden)
.presentationDragIndicator(.visible) .presentationDragIndicator(.visible)
@@ -117,7 +116,7 @@ struct WhatsNewChunkView: View {
.resizable() .resizable()
.scaledToFit() .scaledToFit()
.frame(width: 30, height: 30) .frame(width: 30, height: 30)
.foregroundStyle(Color.accentColor) .foregroundStyle(Color.orange)
.padding(.trailing, 15) .padding(.trailing, 15)
VStack(alignment: .leading) { VStack(alignment: .leading) {
Text(title) Text(title)

View File

@@ -58,13 +58,7 @@ struct StatsView: View {
} }
.scrollContentBackground(.hidden) .scrollContentBackground(.hidden)
.navigationTitle("Statistics") .navigationTitle("Statistics")
.apply { .modifier(navigationInlineLarge())
if #available(iOS 17, *) {
$0.toolbarTitleDisplayMode(.inlineLarge)
} else {
$0.navigationBarTitleDisplayMode(.inline)
}
}
} }
} }
} }

View File

@@ -17,8 +17,6 @@ extension View {
) )
.ignoresSafeArea(.all) .ignoresSafeArea(.all)
} }
func apply<V: View>(@ViewBuilder _ block: (Self) -> V) -> V { block(self) }
} }
extension AnyTransition { extension AnyTransition {

View File

@@ -0,0 +1,83 @@
//
// ColorCodable.swift
// NearFuture
//
// Created by neon443 on 13/06/2025.
//
import Foundation
import SwiftUI
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
struct ColorCodable: Codable, Equatable, Hashable {
init(_ color: Color) {
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 1
#if canImport(UIKit)
let uiColor = UIColor(color)
uiColor.getRed(&r, green: &g, blue: &b, alpha: &a)
#elseif canImport(AppKit)
let nscolor = NSColor(color).usingColorSpace(.deviceRGB)
nscolor!.getRed(&r, green: &g, blue: &b, alpha: &a)
#endif
self = ColorCodable(
red: r,
green: g,
blue: b
)
}
#if canImport(UIKit)
init(uiColor: UIColor) {
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 1.0
uiColor.getRed(&r, green: &g, blue: &b, alpha: &a)
self = ColorCodable(
red: r,
green: g,
blue: b
)
}
#elseif canImport(AppKit)
init(nsColor: NSColor) {
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 1.0
let nsColor = nsColor.usingColorSpace(.deviceRGB)
nsColor!.getRed(&r, green: &g, blue: &b, alpha: &a)
self = ColorCodable(
red: r,
green: g,
blue: b
)
}
#endif
init(red: Double, green: Double, blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
var red: Double
var green: Double
var blue: Double
var color: Color {
Color(red: red, green: green, blue: blue)
}
var colorBind: Color {
get {
return Color(
red: red,
green: green,
blue: blue
)
} set {
let cc = ColorCodable(newValue)
self.red = cc.red
self.green = cc.green
self.blue = cc.blue
}
}
}

View File

@@ -24,7 +24,7 @@ import AppKit
// } // }
//} //}
struct Event: Identifiable, Codable, Equatable, Animatable { struct Event: Identifiable, Codable, Equatable, Animatable, Hashable {
var id = UUID() var id = UUID()
var name: String var name: String
var complete: Bool var complete: Bool
@@ -40,75 +40,6 @@ struct Event: Identifiable, Codable, Equatable, Animatable {
} }
} }
struct ColorCodable: Codable, Equatable {
init(_ color: Color) {
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 1
#if canImport(UIKit)
let uiColor = UIColor(color)
uiColor.getRed(&r, green: &g, blue: &b, alpha: &a)
#elseif canImport(AppKit)
let nscolor = NSColor(color).usingColorSpace(.deviceRGB)
nscolor!.getRed(&r, green: &g, blue: &b, alpha: &a)
#endif
self = ColorCodable(
red: r,
green: g,
blue: b
)
}
#if canImport(UIKit)
init(uiColor: UIColor) {
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 1.0
uiColor.getRed(&r, green: &g, blue: &b, alpha: &a)
self = ColorCodable(
red: r,
green: g,
blue: b
)
}
#elseif canImport(AppKit)
init(nsColor: NSColor) {
var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 1.0
let nsColor = nsColor.usingColorSpace(.deviceRGB)
nsColor!.getRed(&r, green: &g, blue: &b, alpha: &a)
self = ColorCodable(
red: r,
green: g,
blue: b
)
}
#endif
init(red: Double, green: Double, blue: Double) {
self.red = red
self.green = green
self.blue = blue
}
var red: Double
var green: Double
var blue: Double
var color: Color {
Color(red: red, green: green, blue: blue)
}
var colorBind: Color {
get {
return Color(
red: red,
green: green,
blue: blue
)
} set {
let cc = ColorCodable(newValue)
self.red = cc.red
self.green = cc.green
self.blue = cc.blue
}
}
}
func daysUntilEvent(_ eventDate: Date) -> (long: String, short: String) { func daysUntilEvent(_ eventDate: Date) -> (long: String, short: String) {
let calendar = Calendar.current let calendar = Calendar.current
let startOfDayNow = calendar.startOfDay(for: Date()) let startOfDayNow = calendar.startOfDay(for: Date())

View File

@@ -0,0 +1,36 @@
//
// SymbolsLoader.swift
// NearFuture
//
// Created by neon443 on 14/06/2025.
//
import Foundation
class SymbolsLoader: ObservableObject {
@Published var allSymbols: [String] = []
init() {
self.allSymbols = getAllSymbols()
}
func getSymbols(_ searched: String) -> [String] {
if searched.isEmpty {
return allSymbols
} else {
return allSymbols.filter() { $0.localizedCaseInsensitiveContains(searched) }
}
}
func getAllSymbols() -> [String] {
var allSymbols = [String]()
if let bundle = Bundle(identifier: "com.apple.CoreGlyphs"),
let resPath = bundle.path(forResource: "name_availability", ofType: "plist"),
let plist = try? NSDictionary(contentsOf: URL(fileURLWithPath: resPath), error: ()),
let plistSymbols = plist["symbols"] as? [String: String]
{
allSymbols = Array(plistSymbols.keys)
}
return allSymbols
}
}

View File

@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="24093.7" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="24053.1"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="collection view cell content view" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="s0d-6b-0kx">
<objects>
<viewController storyboardIdentifier="ViewController" id="Y6W-OH-hqX" customClass="ViewController" customModule="NearFuture" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" fixedFrame="YES" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="xBf-3w-4Ao">
<rect key="frame" x="0.0" y="63" width="393" height="666"/>
<autoresizingMask key="autoresizingMask"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<collectionViewFlowLayout key="collectionViewLayout" automaticEstimatedItemSize="YES" minimumLineSpacing="10" minimumInteritemSpacing="10" id="d2N-B5-D5N">
<size key="itemSize" width="100" height="100"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="symbolCell" id="nKx-2O-Nq5" customClass="SymbolCell" customModule="NearFuture" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="100" height="100"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<collectionViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="3DG-aV-ZH4">
<rect key="frame" x="0.0" y="0.0" width="100" height="100"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="AaY-Po-OoS">
<rect key="frame" x="0.0" y="0.0" width="100" height="100"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gGM-kQ-cA7">
<rect key="frame" x="29" y="79" width="42" height="21"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</collectionViewCellContentView>
<connections>
<outlet property="imageView" destination="AaY-Po-OoS" id="Swa-vO-Mtz"/>
<outlet property="textLabel" destination="gGM-kQ-cA7" id="Qei-Qd-rn5"/>
</connections>
</collectionViewCell>
</cells>
</collectionView>
</subviews>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<connections>
<outlet property="collectionView" destination="xBf-3w-4Ao" id="c9h-Ew-aOX"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="139.69465648854961" y="65.492957746478879"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View File

@@ -0,0 +1,73 @@
//
// SymbolsPicker.swift
// NearFuture
//
// Created by neon443 on 14/06/2025.
//
import SwiftUI
struct SymbolsPicker: View {
@StateObject private var symbolsLoader = SymbolsLoader()
@Binding var selection: String
@FocusState var searchfocuesd: Bool
@State var searchInput: String = ""
var symbols: [String] {
return symbolsLoader.getSymbols(searchInput)
}
private func gridLayout(forWidth geoSizeWidth: CGFloat) -> [GridItem] {
let gridItem = GridItem(.fixed(80), spacing: 20, alignment: .center)
let columns = Int(geoSizeWidth/100.rounded(.up))
return Array(repeating: gridItem, count: columns)
}
var body: some View {
NavigationStack {
GeometryReader { geo in
ScrollView {
if symbols.isEmpty {
HStack {
Image(systemName: "magnifyingglass")
.resizable().scaledToFit()
.frame(width: 30)
Text("You look lost")
.font(.title)
.bold()
}
.padding()
Text("The symbol picker search only works with exact matches, try a different search term.")
}
LazyVGrid(columns: gridLayout(forWidth: geo.size.width)) {
ForEach(symbols, id: \.self) { symbol in
Button() {
selection = symbol
} label: {
VStack {
Image(systemName: symbol)
.resizable()
.scaledToFit()
.symbolRenderingMode(.palette)
.foregroundStyle(.blue, .gray, .black)
Text(symbol)
.truncationMode(.middle)
.font(.footnote)
}
}
.frame(maxWidth: 80, maxHeight: 80)
.buttonStyle(.plain)
}
}
}
.searchable(text: $searchInput)
}
}
}
}
#Preview {
SymbolsPicker(selection: .constant(""))
}

View File

@@ -0,0 +1,92 @@
//
// SymbolsPickerStoryboard.swift
// NearFuture
//
// Created by neon443 on 14/06/2025.
//
import Foundation
import SwiftUI
#if canImport(UIKit)
import UIKit
#else
import AppKit
#endif
class ViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
var symbolLoader: SymbolsLoader = SymbolsLoader()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.itemSize = CGSize(
width: 100,
height: 100
)
}
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
}
}
extension ViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
symbolLoader.allSymbols.count
}
func collectionView(
_ collectionView: UICollectionView,
numberOfItemsInSection section: Int
) -> Int {
section
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "symbolCell", for: indexPath) as! SymbolCell
let imageView = cell.imageView
imageView?.image = UIImage(systemName: symbolLoader.allSymbols[indexPath.item])!
cell.textLabel?.text = "hi\(indexPath.row)"
return cell
}
}
extension ViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(indexPath.item)
}
}
class SymbolCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var textLabel: UILabel!
}
struct SymbolsPickerStoryboardUIViewRepresentable: UIViewRepresentable {
class Coordinator {
var viewController: ViewController?
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
func makeUIView(context: Context) -> some UIView {
let storyboard = UIStoryboard(name: "SymbolsPicker", bundle: nil)
let viewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
context.coordinator.viewController = viewController
return viewController.view
}
func updateUIView(_ uiView: UIViewType, context: Context) {
print()
}
}

View File

@@ -0,0 +1,76 @@
//
// ViewModifiers.swift
// NearFuture
//
// Created by neon443 on 13/06/2025.
//
import Foundation
import SwiftUI
struct hapticHeavy: ViewModifier {
var trigger: any Equatable
init(trigger: any Equatable) {
self.trigger = trigger
}
func body(content: Content) -> some View {
if #available(iOS 17, *) {
content
.sensoryFeedback(.impact(weight: .heavy, intensity: 1), trigger: trigger)
} else {
content
}
}
}
struct glassButton: ViewModifier {
func body(content: Content) -> some View {
if #available(iOS 19, macOS 16, *) {
content.buttonStyle(.glass)
} else {
content.buttonStyle(.borderedProminent)
.clipShape(RoundedRectangle(cornerRadius: 15))
.tint(.two)
}
}
}
struct hapticSuccess: ViewModifier {
var trigger: any Equatable
init(trigger: any Equatable) {
self.trigger = trigger
}
func body(content: Content) -> some View {
if #available(iOS 17, *) {
content.sensoryFeedback(.success, trigger: trigger)
} else {
content
}
}
}
struct navigationInlineLarge: ViewModifier {
func body(content: Content) -> some View {
#if os(macOS)
content
.toolbarTitleDisplayMode(.inlineLarge)
#else
content
.navigationBarTitleDisplayMode(.inline)
#endif
}
}
struct presentationSizeForm: ViewModifier {
func body(content: Content) -> some View {
if #available(iOS 18, macOS 15, *) {
content.presentationSizing(.form)
} else {
content
}
}
}