ndb: switch profile queries to use transactions

this should ensure no crashing occurs when querying profiles
This commit is contained in:
William Casarin
2023-09-10 14:51:55 -07:00
parent 622a436589
commit fc9b9f2940
51 changed files with 435 additions and 252 deletions
+28 -22
View File
@@ -31,11 +31,11 @@ func follow_btn_txt(_ fs: FollowState, follows_you: Bool) -> String {
}
}
func followedByString(_ friend_intersection: [Pubkey], profiles: Profiles, locale: Locale = Locale.current) -> String {
func followedByString<Y>(txn: NdbTxn<Y>, _ friend_intersection: [Pubkey], ndb: Ndb, locale: Locale = Locale.current) -> String {
let bundle = bundleForLocale(locale: locale)
let names: [String] = friend_intersection.prefix(3).map {
let profile = profiles.lookup(id: $0)
return Profile.displayName(profile: profile, pubkey: $0).username.truncate(maxLength: 20)
let names: [String] = friend_intersection.prefix(3).map { pk in
let profile = ndb.lookup_profile_with_txn(pk, txn: txn)?.profile
return Profile.displayName(profile: profile, pubkey: pk).username.truncate(maxLength: 20)
}
switch friend_intersection.count {
@@ -216,27 +216,29 @@ struct ProfileView: View {
.accentColor(DamusColors.white)
}
func lnButton(lnurl: String, record: ProfileRecord, profile: Profile) -> some View {
let profile = record.profile!
let button_img = profile.reactions == false ? "zap.fill" : "zap"
return Button(action: {
func lnButton(lnurl: String, unownedProfile: Profile?, pubkey: Pubkey) -> some View {
let reactions = unownedProfile?.reactions ?? true
let button_img = reactions ? "zap.fill" : "zap"
let lud16 = unownedProfile?.lud16
return Button(action: { [lnurl] in
present_sheet(.zap(target: .profile(self.profile.pubkey), lnurl: lnurl))
}) {
Image(button_img)
.foregroundColor(button_img == "zap.fill" ? .orange : Color.primary)
.profile_button_style(scheme: colorScheme)
.contextMenu {
if profile.reactions == false {
.contextMenu { [lud16, reactions, lnurl] in
if reactions == false {
Text("OnlyZaps Enabled", comment: "Non-tappable text in context menu that shows up when the zap button on profile is long pressed to indicate that the user has enabled OnlyZaps, meaning that they would like to be only zapped and not accept reactions to their notes.")
}
if let addr = profile.lud16 {
if let lud16 {
Button {
UIPasteboard.general.string = addr
UIPasteboard.general.string = lud16
} label: {
Label(addr, image: "copy2")
Label(lud16, image: "copy2")
}
} else if let lnurl = record.lnurl {
} else {
Button {
UIPasteboard.general.string = lnurl
} label: {
@@ -269,14 +271,14 @@ struct ProfileView: View {
.font(.footnote)
}
func actionSection(record: ProfileRecord?) -> some View {
func actionSection(record: ProfileRecord?, pubkey: Pubkey) -> some View {
return Group {
if let record,
let profile = record.profile,
let lnurl = record.lnurl,
lnurl != ""
{
lnButton(lnurl: lnurl, record: record, profile: profile)
lnButton(lnurl: lnurl, unownedProfile: profile, pubkey: pubkey)
}
dmButton
@@ -311,6 +313,7 @@ struct ProfileView: View {
func nameSection(profile_data: ProfileRecord?) -> some View {
return Group {
let follows_you = profile.pubkey != damus_state.pubkey && profile.follows(pubkey: damus_state.pubkey)
HStack(alignment: .center) {
ProfilePicView(pubkey: profile.pubkey, size: pfp_size, highlight: .custom(imageBorderColor(), 4.0), profiles: damus_state.profiles, disable_animation: damus_state.settings.disable_animation)
.padding(.top, -(pfp_size / 2.0))
@@ -329,10 +332,10 @@ struct ProfileView: View {
followsYouBadge
}
actionSection(record: profile_data)
actionSection(record: profile_data, pubkey: profile.pubkey)
}
ProfileNameView(pubkey: profile.pubkey, profile: profile_data?.profile, damus: damus_state)
ProfileNameView(pubkey: profile.pubkey, damus: damus_state)
}
}
@@ -355,7 +358,8 @@ struct ProfileView: View {
var aboutSection: some View {
VStack(alignment: .leading, spacing: 8.0) {
let profile_data = damus_state.profiles.lookup_with_timestamp(profile.pubkey)
let profile_txn = damus_state.profiles.lookup_with_timestamp(profile.pubkey)
let profile_data = profile_txn.unsafeUnownedValue
nameSection(profile_data: profile_data)
@@ -422,7 +426,7 @@ struct ProfileView: View {
NavigationLink(value: Route.FollowersYouKnow(friendedFollowers: friended_followers, followers: followers)) {
HStack {
CondensedProfilePicturesView(state: damus_state, pubkeys: friended_followers, maxPictures: 3)
let followedByString = followedByString(friended_followers, profiles: damus_state.profiles)
let followedByString = followedByString(txn: profile_txn, friended_followers, ndb: damus_state.ndb)
Text(followedByString)
.font(.subheadline).foregroundColor(.gray)
.multilineTextAlignment(.leading)
@@ -516,7 +520,9 @@ extension View {
@MainActor
func check_nip05_validity(pubkey: Pubkey, profiles: Profiles) {
guard let profile = profiles.lookup(id: pubkey),
let profile_txn = profiles.lookup(id: pubkey)
guard let profile = profile_txn.unsafeUnownedValue,
let nip05 = profile.nip05,
profiles.is_validated(pubkey) == nil
else {
@@ -532,7 +538,7 @@ func check_nip05_validity(pubkey: Pubkey, profiles: Profiles) {
Task { @MainActor in
profiles.set_validated(pubkey, nip05: validated)
profiles.nip05_pubkey[nip05] = pubkey
notify(.profile_updated(pubkey: pubkey, profile: profile))
notify(.profile_updated(.remote(pubkey: pubkey)))
}
}
}