You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.4 KiB
144 lines
4.4 KiB
//
|
|
// NotesPageView.swift
|
|
// Notes
|
|
//
|
|
// Created by Claude Code on 13/10/2025.
|
|
//
|
|
|
|
import SwiftUI
|
|
import CoreData
|
|
|
|
struct NotesPageView: View {
|
|
@Environment(\.managedObjectContext) private var viewContext
|
|
|
|
@FetchRequest(
|
|
sortDescriptors: [NSSortDescriptor(keyPath: \Note.lastEditDate, ascending: true)],
|
|
animation: .default)
|
|
private var notes: FetchedResults<Note>
|
|
|
|
@State private var selectedIndex: Int = 0
|
|
@State private var showDeleteAlert = false
|
|
|
|
var body: some View {
|
|
NavigationStack {
|
|
VStack {
|
|
|
|
if notes.isEmpty {
|
|
Text("No notes")
|
|
.foregroundColor(.gray)
|
|
} else {
|
|
TabView(selection: $selectedIndex) {
|
|
ForEach(Array(notes.enumerated()), id: \.element.objectID) { index, note in
|
|
NoteEditorView(note: note)
|
|
.tag(index)
|
|
}
|
|
}
|
|
.tabViewStyle(.page(indexDisplayMode: .never))
|
|
}
|
|
}
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
ToolbarItemGroup(placement: .navigationBarTrailing) {
|
|
Button(action: addNote) {
|
|
Image(systemName: "plus")
|
|
}
|
|
|
|
Button(action: shareNote) {
|
|
Image(systemName: "square.and.arrow.up")
|
|
}
|
|
.disabled(notes.isEmpty)
|
|
|
|
Button(action: { showDeleteAlert = true }) {
|
|
Image(systemName: "trash")
|
|
}
|
|
.disabled(notes.isEmpty)
|
|
}
|
|
}
|
|
.alert("Delete Note", isPresented: $showDeleteAlert) {
|
|
Button("Cancel", role: .cancel) { }
|
|
Button("Delete", role: .destructive) {
|
|
deleteNote()
|
|
}
|
|
} message: {
|
|
if selectedIndex < notes.count {
|
|
let content = notes[selectedIndex].content ?? ""
|
|
Text("Do you want to delete this: \(content.prefix(20))...?")
|
|
}
|
|
}
|
|
.onAppear {
|
|
createNoteIfNeeded()
|
|
selectLastNote()
|
|
}
|
|
}
|
|
}
|
|
|
|
private func addNote() {
|
|
withAnimation {
|
|
let newNote = Note(context: viewContext)
|
|
newNote.content = ""
|
|
newNote.lastEditDate = Date()
|
|
|
|
PersistenceController.shared.save()
|
|
|
|
// Select the newly created note (last in the list)
|
|
selectedIndex = notes.count - 1
|
|
}
|
|
}
|
|
|
|
private func deleteNote() {
|
|
guard selectedIndex < notes.count else { return }
|
|
|
|
withAnimation {
|
|
let noteToDelete = notes[selectedIndex]
|
|
viewContext.delete(noteToDelete)
|
|
PersistenceController.shared.save()
|
|
|
|
// Select the last note after deletion
|
|
if !notes.isEmpty {
|
|
selectedIndex = min(selectedIndex, notes.count - 1)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func shareNote() {
|
|
guard selectedIndex < notes.count,
|
|
let content = notes[selectedIndex].content,
|
|
!content.isEmpty else {
|
|
return
|
|
}
|
|
|
|
let activityVC = UIActivityViewController(
|
|
activityItems: [content],
|
|
applicationActivities: nil
|
|
)
|
|
|
|
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
|
let window = windowScene.windows.first,
|
|
let rootVC = window.rootViewController {
|
|
activityVC.popoverPresentationController?.sourceView = rootVC.view
|
|
rootVC.present(activityVC, animated: true)
|
|
}
|
|
}
|
|
|
|
private func createNoteIfNeeded() {
|
|
if notes.isEmpty {
|
|
let newNote = Note(context: viewContext)
|
|
newNote.content = ""
|
|
newNote.lastEditDate = Date()
|
|
PersistenceController.shared.save()
|
|
}
|
|
}
|
|
|
|
private func selectLastNote() {
|
|
if !notes.isEmpty {
|
|
selectedIndex = notes.count - 1
|
|
}
|
|
}
|
|
}
|
|
|
|
struct NotesPageView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
NotesPageView()
|
|
.environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
|
|
}
|
|
}
|
|
|