declared types on all views, trying to make a nice mac app

This commit is contained in:
neon443
2025-05-21 17:02:21 +01:00
parent 4bf33d50d6
commit e051d73b7e
11 changed files with 377 additions and 74 deletions

View File

@@ -0,0 +1,24 @@
//
// MacNearFutureApp.swift
// MacNearFuture
//
// Created by neon443 on 21/05/2025.
//
import Foundation
import SwiftUI
@main
struct NearFutureApp: App {
@StateObject var settingsModel: SettingsViewModel = SettingsViewModel()
var body: some Scene {
WindowGroup {
ContentView(
viewModel: EventViewModel(),
settingsModel: settingsModel
)
.tint(settingsModel.settings.tint.color)
}
.windowIdealSize(.fitToContent)
}
}

View File

@@ -12,15 +12,11 @@ struct ContentView: View {
@ObservedObject var settingsModel: SettingsViewModel
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
Text(getVersion())
.foregroundStyle(Color("uiColors/bloo"))
}
.padding()
ScrollView {
ForEach(viewModel.events) { event in
EventListView(viewModel: viewModel, event: event)
}
}
}
}

View File

@@ -0,0 +1,61 @@
//
// 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
fileprivate func saveEdits() {
//if there is an event in vM.events with the id of the event we r editing,
//firstindex - loops through the arr and finds first element where that events id matches editing event's id
if let index = viewModel.events.firstIndex(where: { xEvent in
xEvent.id == event.id
}) {
viewModel.events[index] = event
}
viewModel.saveEvents()
dismiss()
}
var body: some View {
AddEventView(
viewModel: viewModel,
eventName: $event.name,
eventComplete: $event.complete,
eventCompleteDesc: $event.completeDesc,
eventSymbol: $event.symbol,
eventColor: $event.color.colorBind,
eventNotes: $event.notes,
eventDate: $event.date,
eventRecurrence: $event.recurrence,
adding: false //bc we editing existing event
)
.navigationTitle("Edit Event")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button() {
saveEdits()
} label: {
Text("Done")
.bold()
}
.disabled(event.name == "")
}
}
}
}
#Preview {
EditEventView(
viewModel: dummyEventViewModel(),
event: .constant(dummyEventViewModel().template)
)
}

View File

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