mirror of
https://github.com/neon443/NearFuture.git
synced 2026-03-11 14:56:15 +00:00
fix "new edit event window" on mac not working
- it would save events with the same id and modify the previous one if u opened another one add symbols to ios date picker looks better mac
This commit is contained in:
@@ -65,9 +65,7 @@ struct ContentView: View {
|
||||
}
|
||||
.sheet(isPresented: $showAddEventView) {
|
||||
AddEventView(
|
||||
viewModel: viewModel,
|
||||
event: $viewModel.editableTemplate,
|
||||
adding: true
|
||||
viewModel: viewModel
|
||||
)
|
||||
.presentationSizing(.page)
|
||||
}
|
||||
@@ -75,8 +73,7 @@ struct ContentView: View {
|
||||
Button() {
|
||||
showAddEventView.toggle()
|
||||
} label: {
|
||||
Image(systemName: "plus")
|
||||
Text("New")
|
||||
Label("New", systemImage: "plus")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
//
|
||||
// EventListView.swift
|
||||
// MacNearFuture
|
||||
//
|
||||
// Created by neon443 on 21/05/2025.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct EventListView: View {
|
||||
@ObservedObject var viewModel: EventViewModel
|
||||
@State var event: Event
|
||||
|
||||
@State var largeTick: Bool = false
|
||||
@State var hovering: Bool = false
|
||||
|
||||
@State var completeInProgress: Bool = false
|
||||
@State var completeStartTime: Date = .now
|
||||
@State var progress: Double = 0
|
||||
@State var timer: Timer?
|
||||
private let completeDuration: TimeInterval = 3.0
|
||||
@Environment(\.openWindow) var openWindow
|
||||
|
||||
func startCompleting() {
|
||||
NSHapticFeedbackManager.defaultPerformer.perform(.generic, performanceTime: .now)
|
||||
completeInProgress = true
|
||||
progress = 0
|
||||
completeStartTime = .now
|
||||
|
||||
timer = Timer(timeInterval: 0.05, repeats: true) { timer in
|
||||
let elapsed = Date().timeIntervalSince(completeStartTime)
|
||||
progress = min(elapsed, 1.0)
|
||||
|
||||
if progress >= 1.0 {
|
||||
timer.invalidate()
|
||||
viewModel.completeEvent(&event)
|
||||
completeInProgress = false
|
||||
}
|
||||
}
|
||||
RunLoop.main.add(timer!, forMode: .common)
|
||||
}
|
||||
var body: some View {
|
||||
ZStack {
|
||||
Color.black.opacity(hovering ? 0.5 : 0.0)
|
||||
HStack {
|
||||
RoundedRectangle(cornerRadius: 5)
|
||||
.frame(width: 7)
|
||||
.foregroundStyle(
|
||||
event.color.color.opacity(
|
||||
event.complete ? 0.5 : 1
|
||||
)
|
||||
)
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Image(systemName: event.symbol)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 20, height: 20)
|
||||
.shadow(radius: 5)
|
||||
.foregroundStyle(
|
||||
.one.opacity(
|
||||
event.complete ? 0.5 : 1
|
||||
)
|
||||
)
|
||||
Text("\(event.name)")
|
||||
.bold()
|
||||
.foregroundStyle(.one)
|
||||
.strikethrough(event.complete)
|
||||
.multilineTextAlignment(.leading)
|
||||
}
|
||||
if !event.notes.isEmpty {
|
||||
Text(event.notes)
|
||||
.foregroundStyle(.one.opacity(0.8))
|
||||
.multilineTextAlignment(.leading)
|
||||
}
|
||||
Text(
|
||||
event.date.formatted(
|
||||
date: .long,
|
||||
time: .shortened
|
||||
)
|
||||
)
|
||||
.foregroundStyle(
|
||||
.one.opacity(
|
||||
event.complete ? 0.5 : 1
|
||||
)
|
||||
)
|
||||
if event.recurrence != .none {
|
||||
Text("Occurs \(event.recurrence.rawValue)")
|
||||
.font(.subheadline)
|
||||
.foregroundStyle(
|
||||
.one.opacity(event.complete ? 0.5 : 1))
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
VStack {
|
||||
Text("\(daysUntilEvent(event.date).long)")
|
||||
.multilineTextAlignment(.trailing)
|
||||
.foregroundStyle(event.date.timeIntervalSinceNow < 0 ? .red : .one)
|
||||
}
|
||||
Button() {
|
||||
startCompleting()
|
||||
} label: {
|
||||
if completeInProgress {
|
||||
ZStack {
|
||||
ProgressView(value: progress)
|
||||
.progressViewStyle(.circular)
|
||||
Image(systemName: "xmark")
|
||||
.bold()
|
||||
}
|
||||
} else {
|
||||
Image(systemName: event.complete ? "checkmark.circle.fill" : "circle")
|
||||
.resizable().scaledToFit()
|
||||
.foregroundStyle(event.complete ? .green : event.color.color)
|
||||
.bold()
|
||||
}
|
||||
}
|
||||
.onHover() { hovering in
|
||||
withAnimation {
|
||||
largeTick.toggle()
|
||||
}
|
||||
}
|
||||
.buttonStyle(.borderless)
|
||||
.scaleEffect(
|
||||
completeInProgress ? 1 :
|
||||
largeTick ? 1.5 : 1
|
||||
)
|
||||
.frame(maxWidth: 20)
|
||||
.shadow(radius: 5)
|
||||
.padding(.trailing, 15)
|
||||
.animation(
|
||||
.spring(response: 0.2, dampingFraction: 0.75, blendDuration: 2),
|
||||
value: largeTick
|
||||
)
|
||||
}
|
||||
.transition(.opacity)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
.onHover { isHovering in
|
||||
withAnimation {
|
||||
hovering.toggle()
|
||||
}
|
||||
}
|
||||
.onTapGesture {
|
||||
openWindow(value: event.id)
|
||||
}
|
||||
.contextMenu() {
|
||||
Button(role: .destructive) {
|
||||
let eventToModify = viewModel.events.firstIndex() { currEvent in
|
||||
currEvent.id == event.id
|
||||
}
|
||||
if let eventToModify = eventToModify {
|
||||
viewModel.events.remove(at: eventToModify)
|
||||
viewModel.saveEvents()
|
||||
}
|
||||
} label: {
|
||||
Label("Delete", systemImage: "trash")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user