mirror of
https://github.com/neon443/NearFuture.git
synced 2026-03-11 14:56:15 +00:00
New: custom alert for merge/replace imported events
This commit is contained in:
@@ -55,7 +55,6 @@
|
|||||||
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 */; };
|
||||||
A98C20D52DE7339E0008D61C /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98C20D32DE7339E0008D61C /* AboutView.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 */
|
||||||
|
|
||||||
@@ -526,7 +525,6 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
A920C28C2D24011400E4F9B1 /* Events.swift in Sources */,
|
A920C28C2D24011400E4F9B1 /* Events.swift in Sources */,
|
||||||
A98C20D52DE7339E0008D61C /* AboutView.swift in Sources */,
|
|
||||||
A949F84B2DCAABE00064DCA0 /* ArchiveView.swift in Sources */,
|
A949F84B2DCAABE00064DCA0 /* ArchiveView.swift in Sources */,
|
||||||
A914FA4F2DD276D200856265 /* AboutView.swift in Sources */,
|
A914FA4F2DD276D200856265 /* AboutView.swift in Sources */,
|
||||||
A949F84C2DCAABE00064DCA0 /* AddEventView.swift in Sources */,
|
A949F84C2DCAABE00064DCA0 /* AddEventView.swift in Sources */,
|
||||||
|
|||||||
@@ -15,7 +15,12 @@ struct ImportView: View {
|
|||||||
@State private var text: String = "Ready..."
|
@State private var text: String = "Ready..."
|
||||||
@State private var fgColor: Color = .yellow
|
@State private var fgColor: Color = .yellow
|
||||||
|
|
||||||
|
@State private var showAlert: Bool = false
|
||||||
|
|
||||||
|
@State private var replaceCurrentEvents: Bool = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
ZStack(alignment: .center) {
|
||||||
List {
|
List {
|
||||||
Section("Status") {
|
Section("Status") {
|
||||||
Label(text, systemImage: image)
|
Label(text, systemImage: image)
|
||||||
@@ -24,8 +29,52 @@ struct ImportView: View {
|
|||||||
}
|
}
|
||||||
TextField("", text: $importStr)
|
TextField("", text: $importStr)
|
||||||
Button() {
|
Button() {
|
||||||
|
withAnimation {
|
||||||
|
showAlert.toggle()
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Label("Import", systemImage: "tray.and.arrow.down.fill")
|
||||||
|
}
|
||||||
|
.disabled(importStr.isEmpty)
|
||||||
|
.onAppear() {
|
||||||
|
importStr = ""
|
||||||
|
image = "clock.fill"
|
||||||
|
text = "Ready..."
|
||||||
|
fgColor = .yellow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.blur(radius: showAlert ? 2 : 0)
|
||||||
|
Group {
|
||||||
|
Rectangle()
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
.foregroundStyle(replaceCurrentEvents ? .red.opacity(0.3) : .black.opacity(0.2))
|
||||||
|
.animation(.default, value: replaceCurrentEvents)
|
||||||
|
.ignoresSafeArea()
|
||||||
|
ZStack {
|
||||||
|
RoundedRectangle(cornerRadius: 30)
|
||||||
|
.foregroundStyle(.one.opacity(0.8))
|
||||||
|
.blur(radius: 1)
|
||||||
|
VStack(alignment: .center) {
|
||||||
|
Text("Are you sure?")
|
||||||
|
.font(.largeTitle)
|
||||||
|
.bold()
|
||||||
|
.foregroundStyle(replaceCurrentEvents ? .red : .two)
|
||||||
|
.animation(.default, value: replaceCurrentEvents)
|
||||||
|
Text("This will replace your current events!")
|
||||||
|
.lineLimit(nil)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.opacity(replaceCurrentEvents ? 1 : 0)
|
||||||
|
.animation(.default, value: replaceCurrentEvents)
|
||||||
|
.foregroundStyle(.two)
|
||||||
|
Toggle("Replace Events", isOn: $replaceCurrentEvents)
|
||||||
|
.foregroundStyle(.two)
|
||||||
|
Spacer()
|
||||||
|
Button() {
|
||||||
|
withAnimation {
|
||||||
|
showAlert.toggle()
|
||||||
|
}
|
||||||
do throws {
|
do throws {
|
||||||
try viewModel.importEvents(importStr)
|
try viewModel.importEvents(importStr, replace: replaceCurrentEvents)
|
||||||
withAnimation {
|
withAnimation {
|
||||||
image = "checkmark.circle.fill"
|
image = "checkmark.circle.fill"
|
||||||
text = "Complete"
|
text = "Complete"
|
||||||
@@ -45,17 +94,18 @@ struct ImportView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Label("Import", systemImage: "tray.and.arrow.down.fill")
|
Text("yes")
|
||||||
|
.font(.title2)
|
||||||
|
.bold()
|
||||||
}
|
}
|
||||||
.disabled(importStr.isEmpty)
|
.buttonStyle(BorderedProminentButtonStyle())
|
||||||
.onAppear() {
|
|
||||||
importStr = ""
|
|
||||||
image = "clock.fill"
|
|
||||||
text = "Ready..."
|
|
||||||
fgColor = .yellow
|
|
||||||
}
|
}
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
.frame(maxWidth: 250, maxHeight: 250)
|
||||||
|
}
|
||||||
|
.opacity(showAlert ? 1 : 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -325,14 +325,18 @@ class EventViewModel: ObservableObject, @unchecked Sendable {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func importEvents(_ imported: String) throws {
|
func importEvents(_ imported: String, replace: Bool) throws {
|
||||||
guard let data = Data(base64Encoded: imported) else {
|
guard let data = Data(base64Encoded: imported) else {
|
||||||
throw importError.invalidB64
|
throw importError.invalidB64
|
||||||
}
|
}
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
do {
|
do {
|
||||||
let decoded = try decoder.decode([Event].self, from: data)
|
let decoded = try decoder.decode([Event].self, from: data)
|
||||||
|
if replace {
|
||||||
self.events = decoded
|
self.events = decoded
|
||||||
|
} else {
|
||||||
|
self.events = self.events + decoded
|
||||||
|
}
|
||||||
saveEvents()
|
saveEvents()
|
||||||
} catch {
|
} catch {
|
||||||
throw error
|
throw error
|
||||||
|
|||||||
Reference in New Issue
Block a user