diff --git a/NearFuture.xcodeproj/project.pbxproj b/NearFuture.xcodeproj/project.pbxproj index 1deb3ec..b3345db 100644 --- a/NearFuture.xcodeproj/project.pbxproj +++ b/NearFuture.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + A914FA4B2DD26C6800856265 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A914FA4A2DD26C0F00856265 /* HomeView.swift */; }; A920C2882D24011400E4F9B1 /* NearFutureApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C2872D24011400E4F9B1 /* NearFutureApp.swift */; }; A920C28C2D24011400E4F9B1 /* Item.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Item.swift */; }; A920C28E2D24011A00E4F9B1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A920C28D2D24011A00E4F9B1 /* Assets.xcassets */; }; @@ -70,6 +71,7 @@ /* Begin PBXFileReference section */ A90FDE222DC0D4310012790C /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; + A914FA4A2DD26C0F00856265 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; 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 = ""; }; A920C28B2D24011400E4F9B1 /* Item.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Item.swift; sourceTree = ""; }; @@ -220,6 +222,7 @@ A949F83F2DCAABE00064DCA0 /* ContentView.swift */, A949F8402DCAABE00064DCA0 /* EventListView.swift */, A949F8412DCAABE00064DCA0 /* HelpView.swift */, + A914FA4A2DD26C0F00856265 /* HomeView.swift */, ); path = Home; sourceTree = ""; @@ -450,6 +453,7 @@ A920C28C2D24011400E4F9B1 /* Item.swift in Sources */, A949F84B2DCAABE00064DCA0 /* ArchiveView.swift in Sources */, A949F84C2DCAABE00064DCA0 /* AddEventView.swift in Sources */, + A914FA4B2DD26C6800856265 /* HomeView.swift in Sources */, A949F84D2DCAABE00064DCA0 /* EditEventView.swift in Sources */, A949F84E2DCAABE00064DCA0 /* ContentView.swift in Sources */, A949F84F2DCAABE00064DCA0 /* EventListView.swift in Sources */, diff --git a/NearFuture/Item.swift b/NearFuture/Item.swift index 4e2fc48..b7245fd 100644 --- a/NearFuture/Item.swift +++ b/NearFuture/Item.swift @@ -2,7 +2,7 @@ // Item.swift // NearFuture // -// Created by Nihaal Sharma on 24/12/2024. +// Created by neon443 on 24/12/2024. // import Foundation @@ -20,7 +20,7 @@ import UserNotifications // } //} -struct Event: Identifiable, Codable, Equatable { +struct Event: Identifiable, Codable, Equatable, Animatable { var id = UUID() var name: String var complete: Bool @@ -227,6 +227,7 @@ class EventViewModel: ObservableObject { } } updateSyncStatus() + self.events.sort() {$0.date < $1.date} } func getNotifs() async -> [UNNotificationRequest] { diff --git a/NearFuture/NearFutureApp.swift b/NearFuture/NearFutureApp.swift index 50fa06e..96ae80f 100644 --- a/NearFuture/NearFutureApp.swift +++ b/NearFuture/NearFutureApp.swift @@ -2,7 +2,7 @@ // NearFutureApp.swift // NearFuture // -// Created by Nihaal Sharma on 24/12/2024. +// Created by neon443 on 24/12/2024. // import SwiftUI diff --git a/NearFuture/Preview Content/NearFutureWidgets/AppIntent.swift b/NearFuture/Preview Content/NearFutureWidgets/AppIntent.swift index c48db3f..21e1c5b 100644 --- a/NearFuture/Preview Content/NearFutureWidgets/AppIntent.swift +++ b/NearFuture/Preview Content/NearFutureWidgets/AppIntent.swift @@ -2,7 +2,7 @@ // AppIntent.swift // NearFutureWidgets // -// Created by Nihaal Sharma on 02/01/2025. +// Created by neon443 on 02/01/2025. // import WidgetKit diff --git a/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgets.swift b/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgets.swift index 1bc2e8c..9bb45d4 100644 --- a/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgets.swift +++ b/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgets.swift @@ -2,7 +2,7 @@ // NearFutureWidgets.swift // NearFutureWidgets // -// Created by Nihaal Sharma on 02/01/2025. +// Created by neon443 on 02/01/2025. // import WidgetKit diff --git a/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgetsBundle.swift b/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgetsBundle.swift index 53d8f79..31a0562 100644 --- a/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgetsBundle.swift +++ b/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgetsBundle.swift @@ -2,7 +2,7 @@ // NearFutureWidgetsBundle.swift // NearFutureWidgets // -// Created by Nihaal Sharma on 02/01/2025. +// Created by neon443 on 02/01/2025. // import WidgetKit diff --git a/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgetsLiveActivity.swift b/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgetsLiveActivity.swift index 21c5d09..3eef6ad 100644 --- a/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgetsLiveActivity.swift +++ b/NearFuture/Preview Content/NearFutureWidgets/NearFutureWidgetsLiveActivity.swift @@ -2,7 +2,7 @@ // NearFutureWidgetsLiveActivity.swift // NearFutureWidgets // -// Created by Nihaal Sharma on 02/01/2025. +// Created by neon443 on 02/01/2025. // import ActivityKit diff --git a/NearFuture/Views/Archive/ArchiveView.swift b/NearFuture/Views/Archive/ArchiveView.swift index 0ec074f..6a53feb 100644 --- a/NearFuture/Views/Archive/ArchiveView.swift +++ b/NearFuture/Views/Archive/ArchiveView.swift @@ -10,7 +10,9 @@ import SwiftUI struct ArchiveView: View { @ObservedObject var viewModel: EventViewModel @State var showAddEvent: Bool = false - @State var hey: UUID = UUID() + var filteredEvents: [Event] { + return viewModel.events.filter() {$0.complete} + } var body: some View { NavigationStack { ZStack { @@ -19,16 +21,14 @@ struct ArchiveView: View { HelpView(showAddEvent: $showAddEvent) } else { ScrollView { - ForEach(viewModel.events.filter({$0.complete})) { event in + ForEach(filteredEvents) { event in EventListView(viewModel: viewModel, event: event) + .transition(.moveAndFadeReversed) + .id(event.complete) } } - .transition(.opacity) + .animation(.default, value: filteredEvents) .padding(.horizontal) - .id(hey) - .onReceive(viewModel.objectWillChange) { - hey = UUID() - } } } .scrollContentBackground(.hidden) @@ -72,5 +72,3 @@ struct ArchiveView: View { #Preview { ArchiveView(viewModel: dummyEventViewModel()) } - - diff --git a/NearFuture/Views/Events/AddEventView.swift b/NearFuture/Views/Events/AddEventView.swift index b69ea54..c9a7fd1 100644 --- a/NearFuture/Views/Events/AddEventView.swift +++ b/NearFuture/Views/Events/AddEventView.swift @@ -2,7 +2,7 @@ // AddEventView.swift // NearFuture // -// Created by Nihaal Sharma on 25/12/2024. +// Created by neon443 on 25/12/2024. // import SwiftUI diff --git a/NearFuture/Views/Events/EditEventView.swift b/NearFuture/Views/Events/EditEventView.swift index 07be060..0cea627 100644 --- a/NearFuture/Views/Events/EditEventView.swift +++ b/NearFuture/Views/Events/EditEventView.swift @@ -2,7 +2,7 @@ // EditEventView.swift // NearFuture // -// Created by Nihaal Sharma on 02/01/2025. +// Created by neon443 on 02/01/2025. // import SwiftUI diff --git a/NearFuture/Views/Home/ContentView.swift b/NearFuture/Views/Home/ContentView.swift index 1affb75..6ee814c 100644 --- a/NearFuture/Views/Home/ContentView.swift +++ b/NearFuture/Views/Home/ContentView.swift @@ -2,7 +2,7 @@ // ContentView.swift // NearFuture // -// Created by Nihaal Sharma on 24/12/2024. +// Created by neon443 on 24/12/2024. // import SwiftUI @@ -18,140 +18,14 @@ enum Tab { case stats case settings } -enum FilterCategory { - case Future - case Past - case Complete - case Incomplete -} 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 { - 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 { 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 { - Button("hiiiiiiiiiiiiiii") { - withAnimation() { - settingsModel.settings.showCompletedInHome.toggle() - } - } - Button("sort") { - withAnimation() { - viewModel.events.sort() { $0.date < $1.date } - } - } - ScrollView { - ForEach(filteredEvents) { event in - EventListView(viewModel: viewModel, event: event) - } - .animation(.default, value: filteredEvents) - .transition(.opacity) - .id(hey) - .onReceive(viewModel.objectWillChange) { - hey = UUID() - } - .padding(.horizontal) - if 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) - } - } - } - } + HomeView(viewModel: viewModel, settingsModel: settingsModel) .tabItem { Label("Home", systemImage: "house") } @@ -194,8 +68,23 @@ extension View { ) .ignoresSafeArea(.all) } -} - -extension View { + func apply(@ViewBuilder _ block: (Self) -> V) -> V { block(self) } } + +extension AnyTransition { + static var moveAndFade: AnyTransition { + .asymmetric( + insertion: .move(edge: .leading), + removal: .move(edge: .trailing) + ) + .combined(with: .opacity) + } + static var moveAndFadeReversed: AnyTransition { + .asymmetric( + insertion: .move(edge: .trailing), + removal: .move(edge: .leading) + ) + .combined(with: .opacity) + } +} diff --git a/NearFuture/Views/Home/HomeView.swift b/NearFuture/Views/Home/HomeView.swift new file mode 100644 index 0000000..170dc58 --- /dev/null +++ b/NearFuture/Views/Home/HomeView.swift @@ -0,0 +1,137 @@ +// +// HomeView.swift +// NearFuture +// +// Created by neon443 on 12/05/2025. +// + +import SwiftUI + +struct HomeView: View { + @ObservedObject var viewModel: EventViewModel + @ObservedObject 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 private var showingAddEventView = false + @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) + } + } + } + @State private var focusedTab: Tab = .home + + @FocusState private var focusedField: Field? + + var body: some View { + 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 { + Button("hiiiiiiiiiiiiiii") { + withAnimation() { + settingsModel.settings.showCompletedInHome.toggle() + } + } + ScrollView { + ForEach(filteredEvents) { event in + EventListView(viewModel: viewModel, event: event) + .transition(.moveAndFade) + .id(event.complete) + } + .padding(.horizontal) + if filteredEvents.isEmpty { + HelpView( + searchInput: $searchInput, + focusedField: focusedField + ) + } + Spacer() + } + .animation(.default, value: filteredEvents) + .searchable(text: $searchInput) + } + } + .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) + } + } + } + } + } +} + + +#Preview { + HomeView( + viewModel: dummyEventViewModel(), + settingsModel: dummySettingsViewModel() + ) +} diff --git a/NearFuture/Views/Settings/SettingsView.swift b/NearFuture/Views/Settings/SettingsView.swift index d22584c..d88d865 100644 --- a/NearFuture/Views/Settings/SettingsView.swift +++ b/NearFuture/Views/Settings/SettingsView.swift @@ -2,7 +2,7 @@ // SettingsView.swift // NearFuture // -// Created by Nihaal Sharma on 29/12/2024. +// Created by neon443 on 29/12/2024. // import SwiftUI diff --git a/NearFuture/Views/Stats/StatsView.swift b/NearFuture/Views/Stats/StatsView.swift index fce5cc3..588e121 100644 --- a/NearFuture/Views/Stats/StatsView.swift +++ b/NearFuture/Views/Stats/StatsView.swift @@ -2,7 +2,7 @@ // StatsView.swift // NearFuture // -// Created by Nihaal Sharma on 05/01/2025. +// Created by neon443 on 05/01/2025. // import SwiftUI diff --git a/NearFutureWidgets/NearFutureWidgets.swift b/NearFutureWidgets/NearFutureWidgets.swift index 402063f..e4c4eb3 100644 --- a/NearFutureWidgets/NearFutureWidgets.swift +++ b/NearFutureWidgets/NearFutureWidgets.swift @@ -2,7 +2,7 @@ // NearFutureWidgets.swift // NearFutureWidgets // -// Created by Nihaal Sharma on 02/01/2025. +// Created by neon443 on 02/01/2025. // import WidgetKit diff --git a/NearFutureWidgets/NearFutureWidgetsBundle.swift b/NearFutureWidgets/NearFutureWidgetsBundle.swift index 654f90b..8faa300 100644 --- a/NearFutureWidgets/NearFutureWidgetsBundle.swift +++ b/NearFutureWidgets/NearFutureWidgetsBundle.swift @@ -2,7 +2,7 @@ // NearFutureWidgetsBundle.swift // NearFutureWidgets // -// Created by Nihaal Sharma on 02/01/2025. +// Created by neon443 on 02/01/2025. // import WidgetKit diff --git a/NearFutureWidgets/NearFutureWidgetsLiveActivity.swift b/NearFutureWidgets/NearFutureWidgetsLiveActivity.swift index d4f25c6..663351b 100644 --- a/NearFutureWidgets/NearFutureWidgetsLiveActivity.swift +++ b/NearFutureWidgets/NearFutureWidgetsLiveActivity.swift @@ -2,7 +2,7 @@ // NearFutureWidgetsLiveActivity.swift // NearFutureWidgets // -// Created by Nihaal Sharma on 02/01/2025. +// Created by neon443 on 02/01/2025. // //import ActivityKit