damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit b18a0c573e9dc42bb424157812209e153927758b
parent f6f7d13f1296743a4c9c95280092ce5e60d82e51
Author: Grimless <kyle@kyleroucis.com>
Date:   Sat,  2 Sep 2023 12:34:39 -0400

profile: move the "Follow you" badge into the profile header

Move the "Follow you" badge into the profile header he profile header
out-of-line with the often long and already space-constrained
username/display name text

Changelog-Changed: Move the "Follow you" badge into the profile header
Closes: https://github.com/damus-io/damus/pull/1529
Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mdamus.xcodeproj/project.pbxproj | 4----
Mdamus/Models/HomeModel.swift | 2+-
Mdamus/Util/DisplayName.swift | 20+++++++-------------
Mdamus/Views/EventView.swift | 12------------
Mdamus/Views/Notifications/NotificationsView.swift | 2+-
Mdamus/Views/Profile/EventProfileName.swift | 6+++---
Ddamus/Views/Profile/FollowsYou.swift | 29-----------------------------
Mdamus/Views/Profile/ProfileName.swift | 2+-
Mdamus/Views/Profile/ProfileNameView.swift | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Mdamus/Views/Profile/ProfileView.swift | 88+++++++++++++++++--------------------------------------------------------------
10 files changed, 114 insertions(+), 145 deletions(-)

diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj @@ -301,7 +301,6 @@ 4CB883B6297730E400DC99E7 /* LNUrls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB883B5297730E400DC99E7 /* LNUrls.swift */; }; 4CB8FC232A41ABA800763C51 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB8FC222A41ABA500763C51 /* AboutView.swift */; }; 4CB9D4A72992D02B00A9A7E4 /* ProfileNameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB9D4A62992D02B00A9A7E4 /* ProfileNameView.swift */; }; - 4CB9D4A92992D2F400A9A7E4 /* FollowsYou.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB9D4A82992D2F400A9A7E4 /* FollowsYou.swift */; }; 4CBCA930297DB57F00EC6B2F /* WebsiteLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */; }; 4CC14FEF2A73FCCB007AEB17 /* IdType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC14FEE2A73FCCB007AEB17 /* IdType.swift */; }; 4CC14FF12A73FCDB007AEB17 /* Pubkey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CC14FF02A73FCDB007AEB17 /* Pubkey.swift */; }; @@ -972,7 +971,6 @@ 4CB883B5297730E400DC99E7 /* LNUrls.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LNUrls.swift; sourceTree = "<group>"; }; 4CB8FC222A41ABA500763C51 /* AboutView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; }; 4CB9D4A62992D02B00A9A7E4 /* ProfileNameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileNameView.swift; sourceTree = "<group>"; }; - 4CB9D4A82992D2F400A9A7E4 /* FollowsYou.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowsYou.swift; sourceTree = "<group>"; }; 4CBCA92F297DB57F00EC6B2F /* WebsiteLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebsiteLink.swift; sourceTree = "<group>"; }; 4CC14FEE2A73FCCB007AEB17 /* IdType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdType.swift; sourceTree = "<group>"; }; 4CC14FF02A73FCDB007AEB17 /* Pubkey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pubkey.swift; sourceTree = "<group>"; }; @@ -1943,7 +1941,6 @@ 4CEE2AF2280B25C500AB5EEF /* ProfilePicView.swift */, 4C8682862814DE470026224F /* ProfileView.swift */, 4CB9D4A62992D02B00A9A7E4 /* ProfileNameView.swift */, - 4CB9D4A82992D2F400A9A7E4 /* FollowsYou.swift */, 4C9F18E329ABDE6D008C55EC /* MaybeAnonPfpView.swift */, 4C9BB83329C12D9900FC4E37 /* EventProfileName.swift */, 4C8D1A6B29F1DFC200ACDF75 /* FriendIcon.swift */, @@ -2788,7 +2785,6 @@ 4C3AC7A728369BA200E1F516 /* SearchHomeView.swift in Sources */, 4CB883B0297705DD00DC99E7 /* ZapButton.swift in Sources */, 4C363A922825FCF2006E126D /* ProfileUpdate.swift in Sources */, - 4CB9D4A92992D2F400A9A7E4 /* FollowsYou.swift in Sources */, 4C3BEFDA281DCA1400B3DE84 /* LikeCounter.swift in Sources */, 4C32B9502A9AD44700DC3548 /* FlatBufferBuilder.swift in Sources */, 50A60D142A28BEEE00186190 /* RelayLog.swift in Sources */, diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift @@ -1168,7 +1168,7 @@ func zap_notification_body(profiles: Profiles, zap: Zap, locale: Locale = Locale let profile = profiles.lookup(id: pk) let sats = NSNumber(value: (Double(zap.invoice.amount) / 1000.0)) let formattedSats = format_msats_abbrev(zap.invoice.amount) - let name = Profile.displayName(profile: profile, pubkey: pk).display_name.truncate(maxLength: 50) + let name = Profile.displayName(profile: profile, pubkey: pk).displayName.truncate(maxLength: 50) if src.content.isEmpty { let format = localizedStringFormat(key: "zap_notification_no_message", locale: locale) diff --git a/damus/Util/DisplayName.swift b/damus/Util/DisplayName.swift @@ -7,22 +7,16 @@ import Foundation - -struct BothNames { - let username: String - let display_name: String -} - enum DisplayName { - case both(BothNames) + case both(username: String, displayName: String) case one(String) - var display_name: String { + var displayName: String { switch self { case .one(let one): return one - case .both(let b): - return b.display_name + case .both(username: _, displayName: let displayName): + return displayName } } @@ -30,8 +24,8 @@ enum DisplayName { switch self { case .one(let one): return one - case .both(let b): - return b.username + case .both(username: let username, displayName: _): + return username } } } @@ -50,7 +44,7 @@ func parse_display_name(profile: Profile?, pubkey: Pubkey) -> DisplayName { let disp_name = profile.display_name?.isEmpty == false ? profile.display_name : nil if let name, let disp_name, name != disp_name { - return .both(BothNames(username: name, display_name: disp_name)) + return .both(username: name, displayName: disp_name) } if let one = name ?? disp_name { diff --git a/damus/Views/EventView.swift b/damus/Views/EventView.swift @@ -71,18 +71,6 @@ func should_show_images(settings: UserSettingsStore, contacts: Contacts, ev: Nos return false } -extension View { - func pubkey_context_menu(pubkey: Pubkey) -> some View { - return self.contextMenu { - Button { - UIPasteboard.general.string = pubkey.npub - } label: { - Label(NSLocalizedString("Copy Account ID", comment: "Context menu option for copying the ID of the account that created the note."), image: "copy2") - } - } - } -} - func format_relative_time(_ created_at: UInt32) -> String { return time_ago_since(Date(timeIntervalSince1970: Double(created_at))) diff --git a/damus/Views/Notifications/NotificationsView.swift b/damus/Views/Notifications/NotificationsView.swift @@ -87,7 +87,7 @@ struct NotificationsView: View { var mystery: some View { VStack(spacing: 20) { - Text("Wake up, \(Profile.displayName(profile: state.profiles.lookup(id: state.pubkey), pubkey: state.pubkey).display_name.truncate(maxLength: 50))", comment: "Text telling the user to wake up, where the argument is their display name.") + Text("Wake up, \(Profile.displayName(profile: state.profiles.lookup(id: state.pubkey), pubkey: state.pubkey).displayName.truncate(maxLength: 50))", comment: "Text telling the user to wake up, where the argument is their display name.") Text("You are dreaming...", comment: "Text telling the user that they are dreaming.") } .id("what") diff --git a/damus/Views/Profile/EventProfileName.swift b/damus/Views/Profile/EventProfileName.swift @@ -63,11 +63,11 @@ struct EventProfileName: View { Text(one) .font(.body.weight(.bold)) - case .both(let both): - Text(both.display_name) + case .both(username: let username, displayName: let displayName): + Text(verbatim: displayName) .font(.body.weight(.bold)) - Text(verbatim: "@\(both.username)") + Text(verbatim: username) .foregroundColor(.gray) .font(eventviewsize_to_font(size, font_size: damus_state.settings.font_size)) } diff --git a/damus/Views/Profile/FollowsYou.swift b/damus/Views/Profile/FollowsYou.swift @@ -1,29 +0,0 @@ -// -// FollowsYou.swift -// damus -// -// Created by William Casarin on 2023-02-07. -// - -import SwiftUI - -struct FollowsYou: View { - - var body: some View { - Text("Follows you", comment: "Text to indicate that a user is following your profile.") - .padding([.leading, .trailing], 6.0) - .padding([.top, .bottom], 2.0) - .foregroundColor(.gray) - .background { - RoundedRectangle(cornerRadius: 5.0) - .foregroundColor(DamusColors.adaptableGrey) - } - .font(.footnote) - } -} - -struct FollowsYou_Previews: PreviewProvider { - static var previews: some View { - FollowsYou() - } -} diff --git a/damus/Views/Profile/ProfileName.swift b/damus/Views/Profile/ProfileName.swift @@ -57,7 +57,7 @@ struct ProfileName: View { } var name_choice: String { - return prefix == "@" ? current_display_name.username.truncate(maxLength: 50) : current_display_name.display_name.truncate(maxLength: 50) + return prefix == "@" ? current_display_name.username.truncate(maxLength: 50) : current_display_name.displayName.truncate(maxLength: 50) } var onlyzapper: Bool { diff --git a/damus/Views/Profile/ProfileNameView.swift b/damus/Views/Profile/ProfileNameView.swift @@ -7,10 +7,87 @@ import SwiftUI +fileprivate struct KeyView: View { + let pubkey: Pubkey + + @Environment(\.colorScheme) var colorScheme + + @State private var isCopied = false + + func keyColor() -> Color { + colorScheme == .light ? DamusColors.black : DamusColors.white + } + + private func copyPubkey(_ pubkey: String) { + UIPasteboard.general.string = pubkey + UIImpactFeedbackGenerator(style: .medium).impactOccurred() + withAnimation { + isCopied = true + DispatchQueue.main.asyncAfter(deadline: .now() + 3) { + withAnimation { + isCopied = false + } + } + } + } + + func pubkey_context_menu(pubkey: Pubkey) -> some View { + return self.contextMenu { + Button { + UIPasteboard.general.string = pubkey.npub + } label: { + Label(NSLocalizedString("Copy Account ID", comment: "Context menu option for copying the ID of the account that created the note."), image: "copy2") + } + } + } + + var body: some View { + let bech32 = pubkey.npub + + HStack { + Text(verbatim: "\(abbrev_pubkey(bech32, amount: 16))") + .font(.footnote) + .foregroundColor(keyColor()) + .padding(5) + .padding([.leading, .trailing], 5) + .background(RoundedRectangle(cornerRadius: 11).foregroundColor(DamusColors.adaptableGrey)) + + if isCopied { + HStack { + Image("check-circle") + .resizable() + .frame(width: 20, height: 20) + Text(NSLocalizedString("Copied", comment: "Label indicating that a user's key was copied.")) + .font(.footnote) + .layoutPriority(1) + } + .foregroundColor(DamusColors.green) + } else { + HStack { + Button { + copyPubkey(bech32) + } label: { + Label { + Text("Public key", comment: "Label indicating that the text is a user's public account key.") + } icon: { + Image("copy2") + .resizable() + .contentShape(Rectangle()) + .foregroundColor(.accentColor) + .frame(width: 20, height: 20) + } + .labelStyle(IconOnlyLabelStyle()) + .symbolRenderingMode(.hierarchical) + } + } + } + } + } +} + struct ProfileNameView: View { let pubkey: Pubkey let profile: Profile? - let follows_you: Bool let damus: DamusState var spacing: CGFloat { 10.0 } @@ -23,22 +100,15 @@ struct ProfileNameView: View { HStack(alignment: .center, spacing: spacing) { ProfileName(pubkey: pubkey, profile: profile, damus: damus) .font(.title3.weight(.bold)) - if follows_you { - FollowsYou() - } } - case .both(let both): - Text(both.display_name) + case .both(username: _, displayName: let displayName): + Text(displayName) .font(.title3.weight(.bold)) HStack(alignment: .center, spacing: spacing) { ProfileName(pubkey: pubkey, profile: profile, prefix: "@", damus: damus) .font(.callout) .foregroundColor(.gray) - - if follows_you { - FollowsYou() - } } } @@ -54,9 +124,9 @@ struct ProfileNameView: View { struct ProfileNameView_Previews: PreviewProvider { static var previews: some View { VStack { - ProfileNameView(pubkey: test_note.pubkey, profile: nil, follows_you: true, damus: test_damus_state()) + ProfileNameView(pubkey: test_note.pubkey, profile: nil, damus: test_damus_state()) - ProfileNameView(pubkey: test_note.pubkey, profile: nil, follows_you: false, damus: test_damus_state()) + ProfileNameView(pubkey: test_note.pubkey, profile: nil, damus: test_damus_state()) } } } diff --git a/damus/Views/Profile/ProfileView.swift b/damus/Views/Profile/ProfileView.swift @@ -255,6 +255,18 @@ struct ProfileView: View { .profile_button_style(scheme: colorScheme) } } + + private var followsYouBadge: some View { + Text("Follows you", comment: "Text to indicate that a user is following your profile.") + .padding([.leading, .trailing], 6.0) + .padding([.top, .bottom], 2.0) + .foregroundColor(.gray) + .background { + RoundedRectangle(cornerRadius: 5.0) + .foregroundColor(DamusColors.adaptableGrey) + } + .font(.footnote) + } func actionSection(profile_data: Profile?) -> some View { return Group { @@ -310,12 +322,16 @@ struct ProfileView: View { } Spacer() + + let follows_you = profile.pubkey != damus_state.pubkey && profile.follows(pubkey: damus_state.pubkey) + if follows_you { + followsYouBadge + } actionSection(profile_data: profile_data) } - - let follows_you = profile.pubkey != damus_state.pubkey && profile.follows(pubkey: damus_state.pubkey) - ProfileNameView(pubkey: profile.pubkey, profile: profile_data, follows_you: follows_you, damus: damus_state) + + ProfileNameView(pubkey: profile.pubkey, profile: profile_data, damus: damus_state) } } @@ -489,72 +505,6 @@ struct ProfileView_Previews: PreviewProvider { } } -struct KeyView: View { - let pubkey: Pubkey - - @Environment(\.colorScheme) var colorScheme - - @State private var isCopied = false - - func keyColor() -> Color { - colorScheme == .light ? DamusColors.black : DamusColors.white - } - - private func copyPubkey(_ pubkey: String) { - UIPasteboard.general.string = pubkey - UIImpactFeedbackGenerator(style: .medium).impactOccurred() - withAnimation { - isCopied = true - DispatchQueue.main.asyncAfter(deadline: .now() + 3) { - withAnimation { - isCopied = false - } - } - } - } - - var body: some View { - let bech32 = pubkey.npub - - HStack { - Text(verbatim: "\(abbrev_pubkey(bech32, amount: 16))") - .font(.footnote) - .foregroundColor(keyColor()) - .padding(5) - .padding([.leading, .trailing], 5) - .background(RoundedRectangle(cornerRadius: 11).foregroundColor(DamusColors.adaptableGrey)) - - if isCopied != true { - Button { - copyPubkey(bech32) - } label: { - Label { - Text("Public key", comment: "Label indicating that the text is a user's public account key.") - } icon: { - Image("copy2") - .resizable() - .contentShape(Rectangle()) - .foregroundColor(.accentColor) - .frame(width: 20, height: 20) - } - .labelStyle(IconOnlyLabelStyle()) - .symbolRenderingMode(.hierarchical) - } - } else { - HStack { - Image("check-circle") - .resizable() - .frame(width: 20, height: 20) - Text(NSLocalizedString("Copied", comment: "Label indicating that a user's key was copied.")) - .font(.footnote) - .layoutPriority(1) - } - .foregroundColor(DamusColors.green) - } - } - } -} - extension View { func profile_button_style(scheme: ColorScheme) -> some View { self.symbolRenderingMode(.palette)