From 5d26a569d159747224b09b0a878e4a9c5d364692 Mon Sep 17 00:00:00 2001 From: mplorentz Date: Fri, 11 Oct 2024 15:50:24 -0400 Subject: [PATCH 1/3] WIP from pairing --- Nos.xcodeproj/project.pbxproj | 4 +- Nos/AppDelegate.swift | 1 + .../Generated/Author+CoreDataProperties.swift | 21 ++++ .../NosNotification+CoreDataProperties.swift | 1 + .../Nos.xcdatamodeld/.xccurrentversion | 2 +- .../Nos 17.xcdatamodel/.xccurrentversion | 8 ++ .../Nos.xcdatamodel/contents | 56 ++++++++++ .../Nos 17.xcdatamodel/contents | 101 ++++++++++++++++++ Nos/Models/NotificationViewModel.swift | 25 +++-- 9 files changed, 209 insertions(+), 10 deletions(-) create mode 100644 Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/.xccurrentversion create mode 100644 Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/Nos.xcdatamodel/contents create mode 100644 Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/contents diff --git a/Nos.xcodeproj/project.pbxproj b/Nos.xcodeproj/project.pbxproj index c8a27a2ec..06e3d777e 100644 --- a/Nos.xcodeproj/project.pbxproj +++ b/Nos.xcodeproj/project.pbxproj @@ -948,6 +948,7 @@ C9CDBBA329A8FA2900C555C7 /* GoldenPostView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GoldenPostView.swift; sourceTree = ""; }; C9CE5B132A0172CF008E198C /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = ""; }; C9CF23162A38A58B00EBEC31 /* ParseQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseQueue.swift; sourceTree = ""; }; + C9D2839E2CB9B177007ADCB9 /* Nos 17.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Nos 17.xcdatamodel"; sourceTree = ""; }; C9D573482AB24B7300E06BB4 /* custom-xcassets.stencil */ = {isa = PBXFileReference; lastKnownFileType = text; name = "custom-xcassets.stencil"; path = "Nos/Assets/SwiftGen Stencils/custom-xcassets.stencil"; sourceTree = SOURCE_ROOT; }; C9DC6CB92C1739AD00E1CFB3 /* View+HandleURLsInRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+HandleURLsInRouter.swift"; sourceTree = ""; }; C9DEBFCE298941000078B43A /* Nos.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Nos.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -3821,6 +3822,7 @@ C936B4572A4C7B7C00DF1EB9 /* Nos.xcdatamodeld */ = { isa = XCVersionGroup; children = ( + C9D2839E2CB9B177007ADCB9 /* Nos 17.xcdatamodel */, 033B288D2C419E7600E325E8 /* Nos 16.xcdatamodel */, 5B810DD62B55BA44008FE8A9 /* Nos 15.xcdatamodel */, 5B960D2C2B34B1B900C52C45 /* Nos 14.xcdatamodel */, @@ -3830,7 +3832,7 @@ C9C547562A4F1D1A006B0741 /* Nos 9.xcdatamodel */, 5BFF66AF2A4B55FC00AA79DD /* Nos 10.xcdatamodel */, ); - currentVersion = 033B288D2C419E7600E325E8 /* Nos 16.xcdatamodel */; + currentVersion = C9D2839E2CB9B177007ADCB9 /* Nos 17.xcdatamodel */; path = Nos.xcdatamodeld; sourceTree = ""; versionGroupType = wrapper.xcdatamodel; diff --git a/Nos/AppDelegate.swift b/Nos/AppDelegate.swift index c2ff0ed3d..ea568287e 100644 --- a/Nos/AppDelegate.swift +++ b/Nos/AppDelegate.swift @@ -48,6 +48,7 @@ class AppDelegate: NSObject, UIApplicationDelegate { await currentUser.subscribe() try await Task.sleep(for: .seconds(10)) Log.info("PushNotifications: Sync complete") + return .newData } catch { return .failed diff --git a/Nos/Models/CoreData/Generated/Author+CoreDataProperties.swift b/Nos/Models/CoreData/Generated/Author+CoreDataProperties.swift index 9e8f5a37e..0f39c2a7f 100644 --- a/Nos/Models/CoreData/Generated/Author+CoreDataProperties.swift +++ b/Nos/Models/CoreData/Generated/Author+CoreDataProperties.swift @@ -21,8 +21,13 @@ extension Author { @NSManaged public var uns: String? @NSManaged public var events: Set @NSManaged public var followers: Set + + /// All follow notifications ("This user is now following you") where this Author is the follower. + @NSManaged public var followNotifications: NSSet @NSManaged public var follows: Set @NSManaged public var relays: Set + + /// All notifications that should notify this Author if they are the logged in user. @NSManaged public var notifications: Set } @@ -74,6 +79,22 @@ extension Author { @NSManaged public func removeFromFollows(_ values: NSSet) } +// MARK: Generated accessors for followNotifications +extension Author { + + @objc(addFollowNotificationsObject:) + @NSManaged public func addToFollowNotifications(_ value: NosNotification) + + @objc(removeFollowNotificationsObject:) + @NSManaged public func removeFromFollowNotifications(_ value: NosNotification) + + @objc(addFollowNotifications:) + @NSManaged public func addToFollowNotifications(_ values: NSSet) + + @objc(removeFollowNotifications:) + @NSManaged public func removeFromFollowNotifications(_ values: NSSet) +} + // MARK: Generated accessors for relays extension Author { diff --git a/Nos/Models/CoreData/Generated/NosNotification+CoreDataProperties.swift b/Nos/Models/CoreData/Generated/NosNotification+CoreDataProperties.swift index 7fe4b3f09..3eecc9be3 100644 --- a/Nos/Models/CoreData/Generated/NosNotification+CoreDataProperties.swift +++ b/Nos/Models/CoreData/Generated/NosNotification+CoreDataProperties.swift @@ -10,6 +10,7 @@ extension NosNotification { @NSManaged public var isRead: Bool @NSManaged public var eventID: String? @NSManaged public var user: Author? + @NSManaged public var follower: Author? @NSManaged public var createdAt: Date? } diff --git a/Nos/Models/CoreData/Nos.xcdatamodeld/.xccurrentversion b/Nos/Models/CoreData/Nos.xcdatamodeld/.xccurrentversion index c25252740..37217a71f 100644 --- a/Nos/Models/CoreData/Nos.xcdatamodeld/.xccurrentversion +++ b/Nos/Models/CoreData/Nos.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - Nos 16.xcdatamodel + Nos 17.xcdatamodel diff --git a/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/.xccurrentversion b/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/.xccurrentversion new file mode 100644 index 000000000..6c8a1eef9 --- /dev/null +++ b/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/.xccurrentversion @@ -0,0 +1,8 @@ + + + + + _XCCurrentVersionName + Nos.xcdatamodel + + diff --git a/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/Nos.xcdatamodel/contents b/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/Nos.xcdatamodel/contents new file mode 100644 index 000000000..1a418ef2c --- /dev/null +++ b/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/Nos.xcdatamodel/contents @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/contents b/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/contents new file mode 100644 index 000000000..f8888a16a --- /dev/null +++ b/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/contents @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Nos/Models/NotificationViewModel.swift b/Nos/Models/NotificationViewModel.swift index 86dc8e9a6..614bf0a47 100644 --- a/Nos/Models/NotificationViewModel.swift +++ b/Nos/Models/NotificationViewModel.swift @@ -9,15 +9,14 @@ import UIKit /// `loadContent()` to populate the `content` variable because it relies on some /// database queries. class NotificationViewModel: ObservableObject, Identifiable { - let noteID: RawEventID + let noteID: RawEventID? + let authorID: RawAuthorID? let authorProfilePhotoURL: URL? let actionText: AttributedString @Published var content: AttributedString? let date: Date - var id: RawEventID { - noteID - } + var id: String = UUID().uuidString /// Generates a notification request that can be sent to the UNNotificationCenter to display a banner notification. /// You probably want to call `loadContent(in:)` before accessing this. @@ -30,7 +29,7 @@ class NotificationViewModel: ObservableObject, Identifiable { content.userInfo = ["eventID": id] let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) return UNNotificationRequest( - identifier: noteID, + identifier: id, content: content, trigger: trigger ) @@ -38,12 +37,22 @@ class NotificationViewModel: ObservableObject, Identifiable { convenience init?(coreDataModel: NosNotification, context: NSManagedObjectContext) { guard let eventID = coreDataModel.eventID, - let note = Event.find(by: eventID, context: context), let user = coreDataModel.user else { return nil } - self.init(note: note, user: user) + + if let note = Event.find(by: eventID, context: context) { + self.init(note: note, user: user) + } else if let follower = coreDataModel.follower { + self.init(follower: follower) + } else { + return nil + } + } + + init(follower: Author) { + // TODO: initialize date, authorProfilePhotoURL, actionText } init(note: Event, user: Author) { @@ -85,7 +94,7 @@ class NotificationViewModel: ObservableObject, Identifiable { /// Populates the `content` variable. This is not done at init in order to keep /// it synchronous for use in a View. @MainActor @discardableResult func loadContent(in context: NSManagedObjectContext) async -> AttributedString? { - content = await Event.attributedContent(noteID: id, context: context) + content = await Event.attributedContent(noteID: noteID, context: context) return content } } From 2e752392351c3177a1eb90998cfc85c74764e373 Mon Sep 17 00:00:00 2001 From: Itunu Raimi Date: Sun, 13 Oct 2024 19:10:43 +0100 Subject: [PATCH 2/3] remove changes that are not needed yet --- Nos/AppDelegate.swift | 1 - Nos/Models/NotificationViewModel.swift | 29 +++++++++----------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/Nos/AppDelegate.swift b/Nos/AppDelegate.swift index ea568287e..c2ff0ed3d 100644 --- a/Nos/AppDelegate.swift +++ b/Nos/AppDelegate.swift @@ -48,7 +48,6 @@ class AppDelegate: NSObject, UIApplicationDelegate { await currentUser.subscribe() try await Task.sleep(for: .seconds(10)) Log.info("PushNotifications: Sync complete") - return .newData } catch { return .failed diff --git a/Nos/Models/NotificationViewModel.swift b/Nos/Models/NotificationViewModel.swift index 614bf0a47..121541c78 100644 --- a/Nos/Models/NotificationViewModel.swift +++ b/Nos/Models/NotificationViewModel.swift @@ -9,15 +9,16 @@ import UIKit /// `loadContent()` to populate the `content` variable because it relies on some /// database queries. class NotificationViewModel: ObservableObject, Identifiable { - let noteID: RawEventID? - let authorID: RawAuthorID? + let noteID: RawEventID let authorProfilePhotoURL: URL? let actionText: AttributedString @Published var content: AttributedString? let date: Date - var id: String = UUID().uuidString - + var id: RawEventID { + noteID + } + /// Generates a notification request that can be sent to the UNNotificationCenter to display a banner notification. /// You probably want to call `loadContent(in:)` before accessing this. var notificationCenterRequest: UNNotificationRequest { @@ -29,30 +30,20 @@ class NotificationViewModel: ObservableObject, Identifiable { content.userInfo = ["eventID": id] let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) return UNNotificationRequest( - identifier: id, - content: content, + identifier: noteID, + content: content, trigger: trigger ) } convenience init?(coreDataModel: NosNotification, context: NSManagedObjectContext) { guard let eventID = coreDataModel.eventID, + let note = Event.find(by: eventID, context: context), let user = coreDataModel.user else { return nil } - - - if let note = Event.find(by: eventID, context: context) { - self.init(note: note, user: user) - } else if let follower = coreDataModel.follower { - self.init(follower: follower) - } else { - return nil - } - } - - init(follower: Author) { - // TODO: initialize date, authorProfilePhotoURL, actionText + + self.init(note: note, user: user) } init(note: Event, user: Author) { From 972bda671c9d2ab037ad96cf543e77a18af8d9e4 Mon Sep 17 00:00:00 2001 From: Itunu Raimi Date: Sun, 13 Oct 2024 19:11:21 +0100 Subject: [PATCH 3/3] rename coredata notifications to incomingNotifications. --- .../CoreData/Generated/Author+CoreDataProperties.swift | 3 ++- .../CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/contents | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Nos/Models/CoreData/Generated/Author+CoreDataProperties.swift b/Nos/Models/CoreData/Generated/Author+CoreDataProperties.swift index 0f39c2a7f..3ee36d934 100644 --- a/Nos/Models/CoreData/Generated/Author+CoreDataProperties.swift +++ b/Nos/Models/CoreData/Generated/Author+CoreDataProperties.swift @@ -28,7 +28,8 @@ extension Author { @NSManaged public var relays: Set /// All notifications that should notify this Author if they are the logged in user. - @NSManaged public var notifications: Set + /// The notifications are intended for the current author to be received. + @NSManaged public var incomingNotifications: Set } // MARK: Generated accessors for events diff --git a/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/contents b/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/contents index f8888a16a..82fa7db41 100644 --- a/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/contents +++ b/Nos/Models/CoreData/Nos.xcdatamodeld/Nos 17.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -17,7 +17,7 @@ - + @@ -74,7 +74,7 @@ - +