Merge pull request #20 from dscyrescotti/feature/memo-grid-view

Implement memo grid view
This commit is contained in:
Aye Chan
2024-05-09 15:36:23 +08:00
committed by GitHub
4 changed files with 113 additions and 30 deletions

View File

@@ -11,8 +11,7 @@ import SwiftUI
struct MemolaApp: App {
var body: some Scene {
WindowGroup {
MemoView()
.environmentObject(Canvas())
MemosView()
.environment(\.managedObjectContext, Persistence.shared.viewContext)
}
}

View File

@@ -58,16 +58,16 @@ final class Canvas: NSObject, ObservableObject, Identifiable, Codable, GraphicCo
// MARK: - Actions
extension Canvas {
func load() {
// guard let graphicLoader else { return }
guard let graphicLoader else { return }
Task(priority: .high) { [unowned self, graphicLoader] in
await MainActor.run {
self.state = .loading
}
do {
// let graphicContext = try graphicLoader()
let graphicContext = try graphicLoader()
graphicContext.delegate = self
await MainActor.run {
// self.graphicContext = graphicContext
self.graphicContext = graphicContext
self.state = .loaded
}
} catch {
@@ -91,11 +91,11 @@ extension Canvas {
}
func listen(on managedObjectContext: NSManagedObjectContext) {
Task(priority: .background) { [unowned self] in
for await _ in didUpdate.values {
await save(on: managedObjectContext)
}
}
// Task(priority: .utility) { [unowned self] in
// for await _ in didUpdate.throttle(for: 500, scheduler: DispatchQueue.global(qos: .utility), latest: false).values {
// await save(on: managedObjectContext)
// }
// }
}
}

View File

@@ -29,7 +29,7 @@ struct MemoView: View {
}
.overlay(alignment: .topLeading) {
Button {
dismiss()
closeMemo()
} label: {
Image(systemName: "xmark")
.padding(15)
@@ -39,16 +39,15 @@ struct MemoView: View {
.hoverEffect(.lift)
.padding()
}
.disabled(canvas.state == .loading)
.disabled(canvas.state == .loading || canvas.state == .closing)
.overlay {
if canvas.state == .loading {
ProgressView {
Text("Loading memo...")
}
.progressViewStyle(.circular)
.padding(20)
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 20))
switch canvas.state {
case .loading:
progressView("Loading memo...")
case .closing:
progressView("Saving memo...")
default:
EmptyView()
}
}
.environmentObject(tool)
@@ -80,4 +79,27 @@ struct MemoView: View {
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 20))
}
func progressView(_ title: String) -> some View {
ProgressView {
Text(title)
}
.progressViewStyle(.circular)
.padding(20)
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 20))
}
func closeMemo() {
Task(priority: .high) {
await MainActor.run {
canvas.state = .closing
}
await canvas.save(on: managedObjectContext)
await MainActor.run {
canvas.state = .closed
dismiss()
}
}
}
}

View File

@@ -8,18 +8,80 @@
import SwiftUI
struct MemosView: View {
@State var isPresented: Bool = false
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(sortDescriptors: []) var memos: FetchedResults<Memo>
@State var canvas: Canvas?
var body: some View {
VStack {
Text("Memos View")
Button {
isPresented.toggle()
} label: {
Text("Open Memo")
}
.fullScreenCover(isPresented: $isPresented) {
MemoView()
NavigationStack {
memoGrid
.navigationTitle("Memos")
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button {
createMemo(title: "Untitled")
} label: {
Image(systemName: "plus")
}
.hoverEffect()
}
}
}
.fullScreenCover(item: $canvas) { canvas in
MemoView()
.environmentObject(canvas)
}
}
var memoGrid: some View {
ScrollView {
LazyVGrid(columns: .init(repeating: GridItem(.flexible()), count: 3)) {
ForEach(memos) { memo in
memoCard(memo)
}
}
.padding()
}
}
func memoCard(_ memo: Memo) -> some View {
VStack(alignment: .leading) {
Rectangle()
.frame(height: 150)
Text(memo.title)
}
.onTapGesture {
openMemo(for: memo)
}
}
func createMemo(title: String) {
do {
let data = try JSONEncoder().encode(Canvas())
let memo = Memo(context: managedObjectContext)
memo.id = UUID()
memo.title = title
memo.data = data
memo.createdAt = .now
memo.updatedAt = .now
try managedObjectContext.save()
openMemo(for: memo)
} catch {
NSLog("[SketchNote] - \(error.localizedDescription)")
}
}
func openMemo(for memo: Memo) {
do {
let data = memo.data
let canvas = try JSONDecoder().decode(Canvas.self, from: data)
canvas.memo = memo
self.canvas = canvas
} catch {
NSLog("[SketchNote] - \(error.localizedDescription)")
}
}
}