From c27620cce659d5e1893e01658afb6814c3b5495c Mon Sep 17 00:00:00 2001 From: mplorentz Date: Tue, 28 Jan 2025 13:42:05 -0500 Subject: [PATCH 1/3] Fixed a crash on a malformed delete event --- CHANGELOG.md | 1 + Nos.xcodeproj/project.pbxproj | 4 ++++ Nos/Models/CoreData/Event+CoreDataClass.swift | 5 ++--- .../Fixtures/malformed_list_delete.json | 1 + NosTests/Models/CoreData/EventTests.swift | 19 +++++++++++++++++++ 5 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 NosTests/IntegrationTests/Fixtures/malformed_list_delete.json diff --git a/CHANGELOG.md b/CHANGELOG.md index b262bd193..fca3234ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added ability to delete lists. [#136](https://github.com/verse-pbc/issues/issues/136) - Added analytics for feed source selection and lists. [#129](https://github.com/verse-pbc/issues/issues/129) - Fixed: while searching for users to add to a list, NIP-05 searches dismiss the view. [#165](https://github.com/verse-pbc/issues/issues/165) +- Fixed a crash when processing a malformed delete (kind 5) event. [#170](https://github.com/verse-pbc/issues/issues/170) ### Internal Changes - Added function for creating a new list and a test verifying list editing. [#112](https://github.com/verse-pbc/issues/issues/112) diff --git a/Nos.xcodeproj/project.pbxproj b/Nos.xcodeproj/project.pbxproj index fc5620c4f..82a7b4ca2 100644 --- a/Nos.xcodeproj/project.pbxproj +++ b/Nos.xcodeproj/project.pbxproj @@ -535,6 +535,7 @@ C9CF23172A38A58B00EBEC31 /* ParseQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CF23162A38A58B00EBEC31 /* ParseQueue.swift */; }; C9CF23182A38A58B00EBEC31 /* ParseQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9CF23162A38A58B00EBEC31 /* ParseQueue.swift */; }; C9D573492AB24B7300E06BB4 /* custom-xcassets.stencil in Resources */ = {isa = PBXBuildFile; fileRef = C9D573482AB24B7300E06BB4 /* custom-xcassets.stencil */; }; + C9D846E92D43C7C900A71E30 /* malformed_list_delete.json in Resources */ = {isa = PBXBuildFile; fileRef = C9D846E82D43C7C900A71E30 /* malformed_list_delete.json */; }; C9DC6CBA2C1739AD00E1CFB3 /* View+HandleURLsInRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DC6CB92C1739AD00E1CFB3 /* View+HandleURLsInRouter.swift */; }; C9DEBFD2298941000078B43A /* NosApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DEBFD1298941000078B43A /* NosApp.swift */; }; C9DEBFD4298941000078B43A /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9DEBFD3298941000078B43A /* PersistenceController.swift */; }; @@ -1026,6 +1027,7 @@ 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; }; + C9D846E82D43C7C900A71E30 /* malformed_list_delete.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = malformed_list_delete.json; sourceTree = ""; }; 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; }; C9DEBFD1298941000078B43A /* NosApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NosApp.swift; sourceTree = ""; }; @@ -1292,6 +1294,7 @@ 03618AF72C82583D00BCBC55 /* Fixtures */ = { isa = PBXGroup; children = ( + C9D846E82D43C7C900A71E30 /* malformed_list_delete.json */, C9BD91882B61BBEF00FDA083 /* bad_contact_list.json */, 0350F1162C0A47B20024CC15 /* contact_list.json */, 03C853C52D03A50900164D6C /* follow_set.json */, @@ -2379,6 +2382,7 @@ 03618C982C826F2100BCBC55 /* text_note_with_media_metadata.json in Resources */, 032634682C10C0D600E489B5 /* nostr_build_nip96_response.json in Resources */, 03FE3F8C2C87BC9500D25810 /* text_note_multiple_media.json in Resources */, + C9D846E92D43C7C900A71E30 /* malformed_list_delete.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Nos/Models/CoreData/Event+CoreDataClass.swift b/Nos/Models/CoreData/Event+CoreDataClass.swift index 654954883..8041bc46d 100644 --- a/Nos/Models/CoreData/Event+CoreDataClass.swift +++ b/Nos/Models/CoreData/Event+CoreDataClass.swift @@ -514,9 +514,8 @@ public class Event: NosManagedObject, VerifiableEvent { for aTag in aTags.map({ $0[1] }) { let components = aTag.split(separator: ":").map { String($0) } - let pubkey = components[1] - - guard pubkey == author.hexadecimalPublicKey else { + guard let pubkey = components[safe: 1], + pubkey == author.hexadecimalPublicKey else { // ensure that this delete event only affects events with the author's pubkey continue } diff --git a/NosTests/IntegrationTests/Fixtures/malformed_list_delete.json b/NosTests/IntegrationTests/Fixtures/malformed_list_delete.json new file mode 100644 index 000000000..e07111497 --- /dev/null +++ b/NosTests/IntegrationTests/Fixtures/malformed_list_delete.json @@ -0,0 +1 @@ +{"id":"84efec01c8be4b3b30851e34f6851273273b669eaab79c2f7ae2681207e6ded2","pubkey":"d0a1ffb8761b974cec4a3be8cbcb2e96a7090dcf465ffeac839aa4ca20c9a59e","tags":[["a","9f7b7fd7ed2ec346e577d675612b3ecd60e0b6638870047ea7931968dabf70b6"]],"content":"List deleted by owner","sig":"9a61af200a7e9266855a9c3bc5bab25463fdc506a0d6f3f286704da4c4b53473205a895b6fd388b006ec2b357a6e0faf36263ba5279f9a8e3037f4c007bd9576","created_at":1697055962,"kind":5} diff --git a/NosTests/Models/CoreData/EventTests.swift b/NosTests/Models/CoreData/EventTests.swift index 85fb72a20..4af264ed8 100644 --- a/NosTests/Models/CoreData/EventTests.swift +++ b/NosTests/Models/CoreData/EventTests.swift @@ -221,4 +221,23 @@ final class EventTests: CoreDataTestCase { // Assert XCTAssertEqual(references, [alice, bob]) } + + // MARK: - Deletion + + // This is a quick test for a crash I found while doing some debugging. + func test_trackDelete_givenMalformedListDeletionRequest() throws { + // Arrange + let jsonData = try jsonData(filename: "malformed_list_delete") + let jsonEvent = try JSONDecoder().decode(JSONEvent.self, from: jsonData) + let context = persistenceController.viewContext + let parsedEvent = try EventProcessor.parse( + jsonEvent: jsonEvent, + from: nil, + in: context, + skipVerification: true + )! + + // Act & Assert + XCTAssertNoThrow(try parsedEvent.trackDelete(on: Relay(), context: context)) + } } From 28e7897cef894f26c29f48080494990b438339f2 Mon Sep 17 00:00:00 2001 From: mplorentz Date: Tue, 28 Jan 2025 13:54:01 -0500 Subject: [PATCH 2/3] Switch observation of authors to the new observation system. --- CHANGELOG.md | 1 + Nos/Views/Components/Author/AuthorCard.swift | 2 +- Nos/Views/Components/Author/AuthorLabel.swift | 2 +- Nos/Views/Components/Author/NIP05View.swift | 2 +- Nos/Views/Components/BioView.swift | 2 +- Nos/Views/Components/Button/CircularButton.swift | 2 +- Nos/Views/Components/Button/FollowButton.swift | 2 +- Nos/Views/Components/GoldenPostView.swift | 2 +- Nos/Views/Components/KnownFollowersView.swift | 2 +- Nos/Views/Home/HomeTab.swift | 2 +- Nos/Views/Note/NoteCardHeader.swift | 2 +- Nos/Views/Profile/ActivityPubBadgeView.swift | 2 +- Nos/Views/Profile/BioSheet.swift | 2 +- Nos/Views/Profile/Edit/ProfileEditView.swift | 2 +- Nos/Views/Profile/ProfileHeader.swift | 2 +- Nos/Views/Profile/ProfileTab.swift | 2 +- Nos/Views/Profile/ProfileView.swift | 2 +- Nos/Views/Relay/RelayView.swift | 2 +- 18 files changed, 18 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b262bd193..7ed28b552 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added ability to delete lists. [#136](https://github.com/verse-pbc/issues/issues/136) - Added analytics for feed source selection and lists. [#129](https://github.com/verse-pbc/issues/issues/129) - Fixed: while searching for users to add to a list, NIP-05 searches dismiss the view. [#165](https://github.com/verse-pbc/issues/issues/165) +- Fixed a performance issue that could occur after switching tabs. [#171](https://github.com/verse-pbc/issues/issues/171) ### Internal Changes - Added function for creating a new list and a test verifying list editing. [#112](https://github.com/verse-pbc/issues/issues/112) diff --git a/Nos/Views/Components/Author/AuthorCard.swift b/Nos/Views/Components/Author/AuthorCard.swift index 18ad9009c..89f10bbc6 100644 --- a/Nos/Views/Components/Author/AuthorCard.swift +++ b/Nos/Views/Components/Author/AuthorCard.swift @@ -15,7 +15,7 @@ enum AvatarOverlayMode { /// This view displays the information we have for an author suitable for being used in a list. struct AuthorCard: View { - @ObservedObject var author: Author + var author: Author @Environment(CurrentUser.self) var currentUser let avatarOverlayView: () -> AvatarOverlay? diff --git a/Nos/Views/Components/Author/AuthorLabel.swift b/Nos/Views/Components/Author/AuthorLabel.swift index 0ac212483..ec25d9468 100644 --- a/Nos/Views/Components/Author/AuthorLabel.swift +++ b/Nos/Views/Components/Author/AuthorLabel.swift @@ -2,7 +2,7 @@ import SwiftUI struct AuthorLabel: View { - @ObservedObject var author: Author + var author: Author var note: Event? private var attributedAuthor: AttributedString { diff --git a/Nos/Views/Components/Author/NIP05View.swift b/Nos/Views/Components/Author/NIP05View.swift index b9294e164..7d2e3230e 100644 --- a/Nos/Views/Components/Author/NIP05View.swift +++ b/Nos/Views/Components/Author/NIP05View.swift @@ -4,7 +4,7 @@ import SwiftUI /// Displays a user's NIP-05 in multiple colors and does some verification on it. struct NIP05View: View { - @ObservedObject var author: Author + var author: Author @State private var verifiedNip05Identifier: Bool? @Dependency(\.namesAPI) private var namesAPI diff --git a/Nos/Views/Components/BioView.swift b/Nos/Views/Components/BioView.swift index e555b66b0..7e2d59a10 100644 --- a/Nos/Views/Components/BioView.swift +++ b/Nos/Views/Components/BioView.swift @@ -3,7 +3,7 @@ import SwiftUI struct BioView: View { - @ObservedObject var author: Author + var author: Author @Environment(\.managedObjectContext) private var viewContext diff --git a/Nos/Views/Components/Button/CircularButton.swift b/Nos/Views/Components/Button/CircularButton.swift index 55b4610dc..75af409b9 100644 --- a/Nos/Views/Components/Button/CircularButton.swift +++ b/Nos/Views/Components/Button/CircularButton.swift @@ -7,7 +7,7 @@ import SwiftUI /// Allows the current user to follow or unfollow the author, /// and updates its own appearance based on follow state. struct CircularFollowButton: View { - @ObservedObject var author: Author + var author: Author @Environment(CurrentUser.self) private var currentUser @Dependency(\.analytics) private var analytics @Dependency(\.crashReporting) private var crashReporting diff --git a/Nos/Views/Components/Button/FollowButton.swift b/Nos/Views/Components/Button/FollowButton.swift index e13e9e17e..66e41b1ae 100644 --- a/Nos/Views/Components/Button/FollowButton.swift +++ b/Nos/Views/Components/Button/FollowButton.swift @@ -4,7 +4,7 @@ import CoreData struct FollowButton: View { @ObservedObject var currentUserAuthor: Author - @ObservedObject var author: Author + var author: Author /// A flag used to show a follow or unfollow icon in addition to Follow or /// Unfollow text. var shouldDisplayIcon = false diff --git a/Nos/Views/Components/GoldenPostView.swift b/Nos/Views/Components/GoldenPostView.swift index 53f923998..2e96cfeef 100644 --- a/Nos/Views/Components/GoldenPostView.swift +++ b/Nos/Views/Components/GoldenPostView.swift @@ -5,7 +5,7 @@ let goldenRatio: CGFloat = 0.618 struct GoldenPostView: View { - @ObservedObject var author: Author + var author: Author @ObservedObject var note: Event @EnvironmentObject private var router: Router diff --git a/Nos/Views/Components/KnownFollowersView.swift b/Nos/Views/Components/KnownFollowersView.swift index b10a9f778..13ab9f7bc 100644 --- a/Nos/Views/Components/KnownFollowersView.swift +++ b/Nos/Views/Components/KnownFollowersView.swift @@ -5,7 +5,7 @@ import SwiftUI /// impersonation attacks by making sure they choose the right person to follow, mention, message, etc. struct KnownFollowersView: View { - @ObservedObject var author: Author + var author: Author /// The authors that the `source` author follows who also follow the `author` @FetchRequest private var knownFollowers: FetchedResults diff --git a/Nos/Views/Home/HomeTab.swift b/Nos/Views/Home/HomeTab.swift index e61fda4fc..1b0e6def0 100644 --- a/Nos/Views/Home/HomeTab.swift +++ b/Nos/Views/Home/HomeTab.swift @@ -56,7 +56,7 @@ fileprivate struct PopoverTipView: View { } struct HomeTab: View { - @ObservedObject var user: Author + var user: Author @EnvironmentObject private var router: Router @ObserveInjection var inject diff --git a/Nos/Views/Note/NoteCardHeader.swift b/Nos/Views/Note/NoteCardHeader.swift index beb935043..3f0fe8442 100644 --- a/Nos/Views/Note/NoteCardHeader.swift +++ b/Nos/Views/Note/NoteCardHeader.swift @@ -3,7 +3,7 @@ import SwiftUI struct NoteCardHeader: View { @ObservedObject var note: Event - @ObservedObject var author: Author + var author: Author var body: some View { HStack(alignment: .center, spacing: 8) { diff --git a/Nos/Views/Profile/ActivityPubBadgeView.swift b/Nos/Views/Profile/ActivityPubBadgeView.swift index 09ba5ec2d..44ccd11ce 100644 --- a/Nos/Views/Profile/ActivityPubBadgeView.swift +++ b/Nos/Views/Profile/ActivityPubBadgeView.swift @@ -3,7 +3,7 @@ import SwiftUI /// A view that displays a badge with an ActivityPub icon. struct ActivityPubBadgeView: View { - @ObservedObject var author: Author + var author: Author var fediverseServer: String { let regex = /[0-9A-Za-z._-]+@(?[0-9A-Za-z._-]+)\.mostr\.pub/ diff --git a/Nos/Views/Profile/BioSheet.swift b/Nos/Views/Profile/BioSheet.swift index 9bc0c31aa..dd9afa760 100644 --- a/Nos/Views/Profile/BioSheet.swift +++ b/Nos/Views/Profile/BioSheet.swift @@ -3,7 +3,7 @@ import SwiftUI /// Shows the name, nip-05 and bio of a given user in a vertical stack. struct BioSheet: View { - @ObservedObject var author: Author + var author: Author @Environment(\.managedObjectContext) private var viewContext @Dependency(\.noteParser) private var noteParser diff --git a/Nos/Views/Profile/Edit/ProfileEditView.swift b/Nos/Views/Profile/Edit/ProfileEditView.swift index 8aa214096..752789c1a 100644 --- a/Nos/Views/Profile/Edit/ProfileEditView.swift +++ b/Nos/Views/Profile/Edit/ProfileEditView.swift @@ -16,7 +16,7 @@ struct ProfileEditView: View { @Dependency(\.crashReporting) private var crashReporting - @ObservedObject var author: Author + var author: Author @State private var displayNameText: String = "" @State private var bioText: String = "" diff --git a/Nos/Views/Profile/ProfileHeader.swift b/Nos/Views/Profile/ProfileHeader.swift index e5c73dcb0..5f92de9c1 100644 --- a/Nos/Views/Profile/ProfileHeader.swift +++ b/Nos/Views/Profile/ProfileHeader.swift @@ -3,7 +3,7 @@ import CoreData import Logger struct ProfileHeader: View { - @ObservedObject var author: Author + var author: Author @Environment(CurrentUser.self) private var currentUser @Binding private var selectedTab: ProfileFeedType diff --git a/Nos/Views/Profile/ProfileTab.swift b/Nos/Views/Profile/ProfileTab.swift index 05ab71b46..935006827 100644 --- a/Nos/Views/Profile/ProfileTab.swift +++ b/Nos/Views/Profile/ProfileTab.swift @@ -5,7 +5,7 @@ import SwiftUI struct ProfileTab: View { @Environment(CurrentUser.self) var currentUser - @ObservedObject var author: Author + var author: Author @Binding var path: NavigationPath diff --git a/Nos/Views/Profile/ProfileView.swift b/Nos/Views/Profile/ProfileView.swift index b12abf5a6..4bc5c1f88 100644 --- a/Nos/Views/Profile/ProfileView.swift +++ b/Nos/Views/Profile/ProfileView.swift @@ -6,7 +6,7 @@ import Logger struct ProfileView: View { - @ObservedObject var author: Author + var author: Author var addDoubleTapToPop = false @Environment(\.managedObjectContext) private var viewContext diff --git a/Nos/Views/Relay/RelayView.swift b/Nos/Views/Relay/RelayView.swift index 2825c6dd7..bb14165de 100644 --- a/Nos/Views/Relay/RelayView.swift +++ b/Nos/Views/Relay/RelayView.swift @@ -12,7 +12,7 @@ struct RelayView: View { @Environment(\.managedObjectContext) private var viewContext @Environment(RelayService.self) private var relayService @Environment(CurrentUser.self) private var currentUser - @ObservedObject var author: Author + var author: Author @State var newRelayAddress: String = "" From 6326e8f3cef0be16aa7c9bb3dd97f274e4466ce2 Mon Sep 17 00:00:00 2001 From: Matt Lorentz Date: Fri, 31 Jan 2025 09:58:20 -0500 Subject: [PATCH 3/3] Revert "Fix performance issue in ProfileView" --- CHANGELOG.md | 1 - Nos/Views/Components/Author/AuthorCard.swift | 2 +- Nos/Views/Components/Author/AuthorLabel.swift | 2 +- Nos/Views/Components/Author/NIP05View.swift | 2 +- Nos/Views/Components/BioView.swift | 2 +- Nos/Views/Components/Button/CircularButton.swift | 2 +- Nos/Views/Components/Button/FollowButton.swift | 2 +- Nos/Views/Components/GoldenPostView.swift | 2 +- Nos/Views/Components/KnownFollowersView.swift | 2 +- Nos/Views/Home/HomeTab.swift | 2 +- Nos/Views/Note/NoteCardHeader.swift | 2 +- Nos/Views/Profile/ActivityPubBadgeView.swift | 2 +- Nos/Views/Profile/BioSheet.swift | 2 +- Nos/Views/Profile/Edit/ProfileEditView.swift | 2 +- Nos/Views/Profile/ProfileHeader.swift | 2 +- Nos/Views/Profile/ProfileTab.swift | 2 +- Nos/Views/Profile/ProfileView.swift | 2 +- Nos/Views/Relay/RelayView.swift | 2 +- 18 files changed, 17 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 664f253af..fca3234ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added ability to delete lists. [#136](https://github.com/verse-pbc/issues/issues/136) - Added analytics for feed source selection and lists. [#129](https://github.com/verse-pbc/issues/issues/129) - Fixed: while searching for users to add to a list, NIP-05 searches dismiss the view. [#165](https://github.com/verse-pbc/issues/issues/165) -- Fixed a performance issue that could occur after switching tabs. [#171](https://github.com/verse-pbc/issues/issues/171) - Fixed a crash when processing a malformed delete (kind 5) event. [#170](https://github.com/verse-pbc/issues/issues/170) ### Internal Changes diff --git a/Nos/Views/Components/Author/AuthorCard.swift b/Nos/Views/Components/Author/AuthorCard.swift index 89f10bbc6..18ad9009c 100644 --- a/Nos/Views/Components/Author/AuthorCard.swift +++ b/Nos/Views/Components/Author/AuthorCard.swift @@ -15,7 +15,7 @@ enum AvatarOverlayMode { /// This view displays the information we have for an author suitable for being used in a list. struct AuthorCard: View { - var author: Author + @ObservedObject var author: Author @Environment(CurrentUser.self) var currentUser let avatarOverlayView: () -> AvatarOverlay? diff --git a/Nos/Views/Components/Author/AuthorLabel.swift b/Nos/Views/Components/Author/AuthorLabel.swift index ec25d9468..0ac212483 100644 --- a/Nos/Views/Components/Author/AuthorLabel.swift +++ b/Nos/Views/Components/Author/AuthorLabel.swift @@ -2,7 +2,7 @@ import SwiftUI struct AuthorLabel: View { - var author: Author + @ObservedObject var author: Author var note: Event? private var attributedAuthor: AttributedString { diff --git a/Nos/Views/Components/Author/NIP05View.swift b/Nos/Views/Components/Author/NIP05View.swift index 7d2e3230e..b9294e164 100644 --- a/Nos/Views/Components/Author/NIP05View.swift +++ b/Nos/Views/Components/Author/NIP05View.swift @@ -4,7 +4,7 @@ import SwiftUI /// Displays a user's NIP-05 in multiple colors and does some verification on it. struct NIP05View: View { - var author: Author + @ObservedObject var author: Author @State private var verifiedNip05Identifier: Bool? @Dependency(\.namesAPI) private var namesAPI diff --git a/Nos/Views/Components/BioView.swift b/Nos/Views/Components/BioView.swift index 7e2d59a10..e555b66b0 100644 --- a/Nos/Views/Components/BioView.swift +++ b/Nos/Views/Components/BioView.swift @@ -3,7 +3,7 @@ import SwiftUI struct BioView: View { - var author: Author + @ObservedObject var author: Author @Environment(\.managedObjectContext) private var viewContext diff --git a/Nos/Views/Components/Button/CircularButton.swift b/Nos/Views/Components/Button/CircularButton.swift index 75af409b9..55b4610dc 100644 --- a/Nos/Views/Components/Button/CircularButton.swift +++ b/Nos/Views/Components/Button/CircularButton.swift @@ -7,7 +7,7 @@ import SwiftUI /// Allows the current user to follow or unfollow the author, /// and updates its own appearance based on follow state. struct CircularFollowButton: View { - var author: Author + @ObservedObject var author: Author @Environment(CurrentUser.self) private var currentUser @Dependency(\.analytics) private var analytics @Dependency(\.crashReporting) private var crashReporting diff --git a/Nos/Views/Components/Button/FollowButton.swift b/Nos/Views/Components/Button/FollowButton.swift index 66e41b1ae..e13e9e17e 100644 --- a/Nos/Views/Components/Button/FollowButton.swift +++ b/Nos/Views/Components/Button/FollowButton.swift @@ -4,7 +4,7 @@ import CoreData struct FollowButton: View { @ObservedObject var currentUserAuthor: Author - var author: Author + @ObservedObject var author: Author /// A flag used to show a follow or unfollow icon in addition to Follow or /// Unfollow text. var shouldDisplayIcon = false diff --git a/Nos/Views/Components/GoldenPostView.swift b/Nos/Views/Components/GoldenPostView.swift index 2e96cfeef..53f923998 100644 --- a/Nos/Views/Components/GoldenPostView.swift +++ b/Nos/Views/Components/GoldenPostView.swift @@ -5,7 +5,7 @@ let goldenRatio: CGFloat = 0.618 struct GoldenPostView: View { - var author: Author + @ObservedObject var author: Author @ObservedObject var note: Event @EnvironmentObject private var router: Router diff --git a/Nos/Views/Components/KnownFollowersView.swift b/Nos/Views/Components/KnownFollowersView.swift index 13ab9f7bc..b10a9f778 100644 --- a/Nos/Views/Components/KnownFollowersView.swift +++ b/Nos/Views/Components/KnownFollowersView.swift @@ -5,7 +5,7 @@ import SwiftUI /// impersonation attacks by making sure they choose the right person to follow, mention, message, etc. struct KnownFollowersView: View { - var author: Author + @ObservedObject var author: Author /// The authors that the `source` author follows who also follow the `author` @FetchRequest private var knownFollowers: FetchedResults diff --git a/Nos/Views/Home/HomeTab.swift b/Nos/Views/Home/HomeTab.swift index 1b0e6def0..e61fda4fc 100644 --- a/Nos/Views/Home/HomeTab.swift +++ b/Nos/Views/Home/HomeTab.swift @@ -56,7 +56,7 @@ fileprivate struct PopoverTipView: View { } struct HomeTab: View { - var user: Author + @ObservedObject var user: Author @EnvironmentObject private var router: Router @ObserveInjection var inject diff --git a/Nos/Views/Note/NoteCardHeader.swift b/Nos/Views/Note/NoteCardHeader.swift index 3f0fe8442..beb935043 100644 --- a/Nos/Views/Note/NoteCardHeader.swift +++ b/Nos/Views/Note/NoteCardHeader.swift @@ -3,7 +3,7 @@ import SwiftUI struct NoteCardHeader: View { @ObservedObject var note: Event - var author: Author + @ObservedObject var author: Author var body: some View { HStack(alignment: .center, spacing: 8) { diff --git a/Nos/Views/Profile/ActivityPubBadgeView.swift b/Nos/Views/Profile/ActivityPubBadgeView.swift index 44ccd11ce..09ba5ec2d 100644 --- a/Nos/Views/Profile/ActivityPubBadgeView.swift +++ b/Nos/Views/Profile/ActivityPubBadgeView.swift @@ -3,7 +3,7 @@ import SwiftUI /// A view that displays a badge with an ActivityPub icon. struct ActivityPubBadgeView: View { - var author: Author + @ObservedObject var author: Author var fediverseServer: String { let regex = /[0-9A-Za-z._-]+@(?[0-9A-Za-z._-]+)\.mostr\.pub/ diff --git a/Nos/Views/Profile/BioSheet.swift b/Nos/Views/Profile/BioSheet.swift index dd9afa760..9bc0c31aa 100644 --- a/Nos/Views/Profile/BioSheet.swift +++ b/Nos/Views/Profile/BioSheet.swift @@ -3,7 +3,7 @@ import SwiftUI /// Shows the name, nip-05 and bio of a given user in a vertical stack. struct BioSheet: View { - var author: Author + @ObservedObject var author: Author @Environment(\.managedObjectContext) private var viewContext @Dependency(\.noteParser) private var noteParser diff --git a/Nos/Views/Profile/Edit/ProfileEditView.swift b/Nos/Views/Profile/Edit/ProfileEditView.swift index 752789c1a..8aa214096 100644 --- a/Nos/Views/Profile/Edit/ProfileEditView.swift +++ b/Nos/Views/Profile/Edit/ProfileEditView.swift @@ -16,7 +16,7 @@ struct ProfileEditView: View { @Dependency(\.crashReporting) private var crashReporting - var author: Author + @ObservedObject var author: Author @State private var displayNameText: String = "" @State private var bioText: String = "" diff --git a/Nos/Views/Profile/ProfileHeader.swift b/Nos/Views/Profile/ProfileHeader.swift index 5f92de9c1..e5c73dcb0 100644 --- a/Nos/Views/Profile/ProfileHeader.swift +++ b/Nos/Views/Profile/ProfileHeader.swift @@ -3,7 +3,7 @@ import CoreData import Logger struct ProfileHeader: View { - var author: Author + @ObservedObject var author: Author @Environment(CurrentUser.self) private var currentUser @Binding private var selectedTab: ProfileFeedType diff --git a/Nos/Views/Profile/ProfileTab.swift b/Nos/Views/Profile/ProfileTab.swift index 935006827..05ab71b46 100644 --- a/Nos/Views/Profile/ProfileTab.swift +++ b/Nos/Views/Profile/ProfileTab.swift @@ -5,7 +5,7 @@ import SwiftUI struct ProfileTab: View { @Environment(CurrentUser.self) var currentUser - var author: Author + @ObservedObject var author: Author @Binding var path: NavigationPath diff --git a/Nos/Views/Profile/ProfileView.swift b/Nos/Views/Profile/ProfileView.swift index 4bc5c1f88..b12abf5a6 100644 --- a/Nos/Views/Profile/ProfileView.swift +++ b/Nos/Views/Profile/ProfileView.swift @@ -6,7 +6,7 @@ import Logger struct ProfileView: View { - var author: Author + @ObservedObject var author: Author var addDoubleTapToPop = false @Environment(\.managedObjectContext) private var viewContext diff --git a/Nos/Views/Relay/RelayView.swift b/Nos/Views/Relay/RelayView.swift index bb14165de..2825c6dd7 100644 --- a/Nos/Views/Relay/RelayView.swift +++ b/Nos/Views/Relay/RelayView.swift @@ -12,7 +12,7 @@ struct RelayView: View { @Environment(\.managedObjectContext) private var viewContext @Environment(RelayService.self) private var relayService @Environment(CurrentUser.self) private var currentUser - var author: Author + @ObservedObject var author: Author @State var newRelayAddress: String = ""