diff --git a/Memola.xcodeproj/project.pbxproj b/Memola.xcodeproj/project.pbxproj index bd344ef..c570ab5 100644 --- a/Memola.xcodeproj/project.pbxproj +++ b/Memola.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ EC1815082C2D980B00541369 /* Sort.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1815072C2D980B00541369 /* Sort.swift */; }; EC18150A2C2DA09E00541369 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1815092C2DA09E00541369 /* Filter.swift */; }; EC18150D2C2DAC3700541369 /* Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC18150C2C2DAC3700541369 /* Placeholder.swift */; }; + EC18150F2C2DB13200541369 /* Date++.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC18150E2C2DB13200541369 /* Date++.swift */; }; EC1B783D2BFA0AC9005A34E2 /* Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC1B783C2BFA0AC9005A34E2 /* Toolbar.swift */; }; EC2106AD2C10C2A700FBE27C /* AnyStroke.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2106AC2C10C2A700FBE27C /* AnyStroke.swift */; }; EC2BEBF42C0F5FF7005DB0AF /* RTree.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2BEBF32C0F5FF7005DB0AF /* RTree.swift */; }; @@ -123,6 +124,7 @@ EC1815072C2D980B00541369 /* Sort.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sort.swift; sourceTree = ""; }; EC1815092C2DA09E00541369 /* Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filter.swift; sourceTree = ""; }; EC18150C2C2DAC3700541369 /* Placeholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Placeholder.swift; sourceTree = ""; }; + EC18150E2C2DB13200541369 /* Date++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date++.swift"; sourceTree = ""; }; EC1B783C2BFA0AC9005A34E2 /* Toolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toolbar.swift; sourceTree = ""; }; EC2106AC2C10C2A700FBE27C /* AnyStroke.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyStroke.swift; sourceTree = ""; }; EC2BEBF32C0F5FF7005DB0AF /* RTree.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RTree.swift; sourceTree = ""; }; @@ -554,6 +556,7 @@ EC35655B2BF0712A00A4E0BF /* Float++.swift */, ECBE529D2C1DAB21006BDB3D /* UIImage++.swift */, ECC995A42C1EB4CC00B2699A /* Data++.swift */, + EC18150E2C2DB13200541369 /* Date++.swift */, ); path = Extensions; sourceTree = ""; @@ -948,6 +951,7 @@ EC4538892BEBCAE000A86FEC /* Quad.swift in Sources */, ECE883BD2C00AA170045C53D /* EraserStroke.swift in Sources */, EC42F7852C25267000E86E96 /* ElementGroup.swift in Sources */, + EC18150F2C2DB13200541369 /* Date++.swift in Sources */, ECD12A8F2C1AEBA400B96E12 /* Photo.swift in Sources */, ECD12A932C1B062000B96E12 /* Photo.metal in Sources */, ECA7388F2BE600DA00A4542E /* Grid.metal in Sources */, diff --git a/Memola/Components/Views/Placeholder/Placeholder.swift b/Memola/Components/Views/Placeholder/Placeholder.swift index 035f11d..c59a175 100644 --- a/Memola/Components/Views/Placeholder/Placeholder.swift +++ b/Memola/Components/Views/Placeholder/Placeholder.swift @@ -47,7 +47,7 @@ extension Placeholder { }() static let memoEmpty: Info = { - let icon: String = "wand.and.stars" + let icon: String = "note.text" let title: String = "No Memos" let description: String = "Create a new memo to jot your thoughts or notes down." return Placeholder.Info(title: title, description: description, icon: icon) diff --git a/Memola/Extensions/Date++.swift b/Memola/Extensions/Date++.swift new file mode 100644 index 0000000..2acaf6e --- /dev/null +++ b/Memola/Extensions/Date++.swift @@ -0,0 +1,32 @@ +// +// Date++.swift +// Memola +// +// Created by Dscyre Scotti on 6/27/24. +// + +import Foundation + +extension Date { + func getTimeDifference(to date: Date) -> String { + let calendar = Calendar.current + + let components = calendar.dateComponents([.minute, .hour, .day, .weekOfYear, .month, .year], from: self, to: date) + + if let years = components.year, years > 0 { + return "\(years) year\(years > 1 ? "s" : "") ago" + } else if let months = components.month, months > 0 { + return "\(months) month\(months > 1 ? "s" : "") ago" + } else if let weeks = components.weekOfYear, weeks > 0 { + return "\(weeks) week\(weeks > 1 ? "s" : "") ago" + } else if let days = components.day, days > 0 { + return "\(days) day\(days > 1 ? "s" : "") ago" + } else if let hours = components.hour, hours > 0 { + return "\(hours) hour\(hours > 1 ? "s" : "") ago" + } else if let minutes = components.minute, minutes > 0 { + return "\(minutes) minute\(minutes > 1 ? "s" : "") ago" + } else { + return "just now" + } + } +} diff --git a/Memola/Features/Memos/MemosView.swift b/Memola/Features/Memos/MemosView.swift index 92964f0..63f162d 100644 --- a/Memola/Features/Memos/MemosView.swift +++ b/Memola/Features/Memos/MemosView.swift @@ -14,12 +14,14 @@ struct MemosView: View { @State var memo: MemoObject? @State var query: String = "" + @State var currentDate: Date = .now @AppStorage("memola.memo-objects.sort") var sort: Sort = .recent @AppStorage("memola.memo-objects.filter") var filter: Filter = .none let cellWidth: CGFloat = 250 let cellHeight: CGFloat = 150 + let timer = Timer.publish(every: 60, on: .main, in: .common).autoconnect() init() { let standard = UserDefaults.standard @@ -92,6 +94,9 @@ struct MemosView: View { .onChange(of: filter) { oldValue, newValue in updatePredicate() } + .onReceive(timer) { date in + currentDate = date + } .onAppear { memoObjects.sortDescriptors = sort.memoSortDescriptors updatePredicate() @@ -123,9 +128,15 @@ struct MemosView: View { Rectangle() .frame(height: cellHeight) .clipShape(RoundedRectangle(cornerRadius: 10)) - Text(memoObject.title) - .font(.headline) - .fontWeight(.semibold) + VStack(alignment: .leading, spacing: 2) { + Text(memoObject.title) + .font(.headline) + .lineLimit(1) + .truncationMode(.tail) + Text("Edited \(memoObject.updatedAt.getTimeDifference(to: currentDate))") + .font(.caption) + .foregroundStyle(.secondary) + } } .onTapGesture { openMemo(for: memoObject)