add events on mac

This commit is contained in:
neon443
2025-06-13 22:00:28 +01:00
parent 0663ba9e59
commit 659f14d5a3
6 changed files with 27 additions and 256 deletions

View File

@@ -11,6 +11,8 @@ struct ContentView: View {
@StateObject var viewModel: EventViewModel
@StateObject var settingsModel: SettingsViewModel
@State private var showAddEventView: Bool = false
var body: some View {
NavigationSplitView {
List {
@@ -52,6 +54,22 @@ struct ContentView: View {
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

@@ -1,195 +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)
.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.")
}
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

@@ -34,6 +34,8 @@
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 */; };
A920C2882D24011400E4F9B1 /* NearFutureApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C2872D24011400E4F9B1 /* NearFutureApp.swift */; };
A920C28C2D24011400E4F9B1 /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = A920C28B2D24011400E4F9B1 /* Events.swift */; };
A920C28E2D24011A00E4F9B1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A920C28D2D24011A00E4F9B1 /* Assets.xcassets */; };
@@ -64,11 +66,9 @@
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 */; };
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 */; };
A98C20D02DE731BD0008D61C /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20CF2DE731BD0008D61C /* HomeView.swift */; };
A98C20D42DE7339E0008D61C /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20D32DE7339E0008D61C /* AboutView.swift */; };
A9B78B942DF9F3CF00647399 /* AddEventView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9B78B932DF9F3CF00647399 /* AddEventView.swift */; };
A9FC7EEA2D2823920020D75B /* NearFutureWidgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */; };
/* End PBXBuildFile section */
@@ -147,12 +147,10 @@
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>"; };
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>"; };
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>"; };
A9B78B932DF9F3CF00647399 /* AddEventView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEventView.swift; sourceTree = "<group>"; };
A9FC7EE92D28238A0020D75B /* NearFutureWidgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearFutureWidgets.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -213,7 +211,6 @@
A98C20CF2DE731BD0008D61C /* HomeView.swift */,
A98C20CA2DE730740008D61C /* EventListViewMac.swift */,
A98C20CD2DE7308E0008D61C /* ArchiveView.swift */,
A98C20C82DE730420008D61C /* Events */,
A91EF80F2DFCB66C00B8463D /* SettingsView.swift */,
);
path = Views;
@@ -374,15 +371,6 @@
path = NearFutureWidgets;
sourceTree = "<group>";
};
A98C20C82DE730420008D61C /* Events */ = {
isa = PBXGroup;
children = (
A9B78B932DF9F3CF00647399 /* AddEventView.swift */,
A98C20C92DE730740008D61C /* EditEventView.swift */,
);
path = Events;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -535,14 +523,14 @@
A91EF80C2DFC910000B8463D /* ViewModifiers.swift in Sources */,
A95E9ED92DFC742B00ED655F /* AccentIcon.swift in Sources */,
A91EF8102DFCB66C00B8463D /* SettingsView.swift in Sources */,
A98C20CC2DE730740008D61C /* EditEventView.swift in Sources */,
A90D495E2DDE3C7400781124 /* NFCommands.swift in Sources */,
A95E9EE52DFC77E200ED655F /* ExportView.swift in Sources */,
A91EF8132DFCC87D00B8463D /* EditEventView.swift in Sources */,
A91EF8142DFCC87D00B8463D /* AddEventView.swift in Sources */,
A98C20D42DE7339E0008D61C /* AboutView.swift in Sources */,
A98C20CE2DE7308E0008D61C /* ArchiveView.swift in Sources */,
A98C20D02DE731BD0008D61C /* HomeView.swift in Sources */,
A90D495B2DDE2EDB00781124 /* MacNearFutureApp.swift in Sources */,
A9B78B942DF9F3CF00647399 /* AddEventView.swift in Sources */,
A91EF8082DFC8B8B00B8463D /* ColorCodable.swift in Sources */,
A90D49522DDE2D0000781124 /* Extensions.swift in Sources */,
A90D49422DDE114100781124 /* Events.swift in Sources */,

View File

@@ -75,7 +75,6 @@ struct AddEventView: View {
.onSubmit {
focusedField = nil
}
// MagicClearButton(text: $eventNotes)
}
@@ -83,7 +82,9 @@ struct AddEventView: View {
HStack {
Spacer()
DatePicker("", selection: $event.date, displayedComponents: .date)
#if os(iOS)
.datePickerStyle(.wheel)
#endif
Spacer()
Button() {
event.date = Date()
@@ -118,9 +119,9 @@ struct AddEventView: View {
}
}
.navigationTitle("\(adding ? "Add Event" : "")")
.navigationBarTitleDisplayMode(.inline)
.modifier(navigationInlineLarge())
.toolbar {
ToolbarItem(placement: .topBarLeading) {
ToolbarItem(/*placement: .topBarLeading*/) {
if adding {
Button() {
resetAddEventView()

View File

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