damus

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

commit ced5b4974ff3610100c550d782d34cab0a8b8199
parent 9be55b08fdfa38e763777647f4980411a796a8f7
Author: radixrat <radixrat@protonmail.com>
Date:   Thu,  2 Feb 2023 13:53:57 -0800

Add remote image loading policy settings

Changelog-Added: Ability to change remote image loading policy

Diffstat:
Mdamus/Components/TranslateView.swift | 3++-
Mdamus/Components/UserView.swift | 2+-
Mdamus/ContentView.swift | 2+-
Mdamus/Views/ChatView.swift | 4++--
Mdamus/Views/ConfigView.swift | 52++++++++++++++++++++++++++++++++++++++++++++++++++--
Mdamus/Views/DMChatView.swift | 2+-
Mdamus/Views/EditMetadataView.swift | 2+-
Mdamus/Views/EventView.swift | 10++++++++--
Mdamus/Views/Events/EventProfile.swift | 2+-
Mdamus/Views/Events/TextEvent.swift | 4++--
Mdamus/Views/NoteContentView.swift | 12++++++------
Mdamus/Views/ParicipantsView.swift | 2+-
Mdamus/Views/ProfilePicView.swift | 24+++++++++++++++++++-----
Mdamus/Views/ProfilePictureSelector.swift | 2+-
Mdamus/Views/ProfileView.swift | 4++--
Mdamus/Views/ProfileZoomView.swift | 7+++++--
Mdamus/Views/SideMenuView.swift | 2+-
17 files changed, 104 insertions(+), 32 deletions(-)

diff --git a/damus/Components/TranslateView.swift b/damus/Components/TranslateView.swift @@ -121,7 +121,8 @@ struct TranslateView: View { if let translated = translated_note { // Render translated note. let blocks = event.get_blocks(content: translated) - translated_artifacts = render_blocks(blocks: blocks, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey) + let show_images = should_show_images(contacts: damus_state.contacts, ev: event, our_pubkey: damus_state.pubkey) + translated_artifacts = render_blocks(blocks: blocks, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey, show_images: show_images) } checkingTranslationStatus = false diff --git a/damus/Components/UserView.swift b/damus/Components/UserView.swift @@ -17,7 +17,7 @@ struct UserView: View { let pv = ProfileView(damus_state: damus_state, profile: pmodel, followers: followers) NavigationLink(destination: pv) { - ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: .none, profiles: damus_state.profiles) + ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: .none, profiles: damus_state.profiles, contacts: damus_state.contacts) VStack(alignment: .leading) { let profile = damus_state.profiles.lookup(id: pubkey) diff --git a/damus/ContentView.swift b/damus/ContentView.swift @@ -252,7 +252,7 @@ struct ContentView: View { Button { isSideBarOpened.toggle() } label: { - ProfilePicView(pubkey: damus_state!.pubkey, size: 32, highlight: .none, profiles: damus_state!.profiles) + ProfilePicView(pubkey: damus_state!.pubkey, size: 32, highlight: .none, profiles: damus_state!.profiles, contacts: damus_state!.contacts) } } diff --git a/damus/Views/ChatView.swift b/damus/Views/ChatView.swift @@ -75,7 +75,7 @@ struct ChatView: View { HStack { VStack { if is_active || just_started { - ProfilePicView(pubkey: event.pubkey, size: 32, highlight: is_active ? .main : .none, profiles: damus_state.profiles) + ProfilePicView(pubkey: event.pubkey, size: 32, highlight: is_active ? .main : .none, profiles: damus_state.profiles, contacts:damus_state.contacts) } Spacer() @@ -97,7 +97,7 @@ struct ChatView: View { if let ref_id = thread.replies.lookup(event.id) { if !is_reply_to_prev() { /* - ReplyQuoteView(keypair: damus_state.keypair, quoter: event, event_id: ref_id, profiles: damus_state.profiles, previews: damus_state.previews) + ReplyQuoteView(keypair: damus_state.keypair, quoter: event, event_id: ref_id, profiles: damus_state.profiles, previews: damus_state.previews, contacts: damus_state.contacts) .frame(maxHeight: expand_reply ? nil : 100) .environmentObject(thread) .onTapGesture { diff --git a/damus/Views/ConfigView.swift b/damus/Views/ConfigView.swift @@ -8,6 +8,26 @@ import AVFoundation import Kingfisher import SwiftUI +enum RemoteImagePolicy: String, CaseIterable { + case everyone + case friendsOnly + case friendsOfFriends + case restricted +} + +func remoteImagePolicyText(_ fs: RemoteImagePolicy) -> String { + switch fs { + case .everyone: + return "Everyone" + case .friendsOnly: + return "Friends Only" + case .friendsOfFriends: + return "Friends of Friends" + case .restricted: + return "Block Images" + } +} + struct ConfigView: View { let state: DamusState @Environment(\.dismiss) var dismiss @@ -19,8 +39,8 @@ struct ConfigView: View { @State var privkey_copied: Bool = false @State var pubkey_copied: Bool = false @State var delete_text: String = "" - @ObservedObject var settings: UserSettingsStore + @AppStorage("remote_image_policy") var remote_image_policy: RemoteImagePolicy = .everyone let generator = UIImpactFeedbackGenerator(style: .light) @@ -129,7 +149,35 @@ struct ConfigView: View { KingfisherManager.shared.cache.cleanExpiredDiskCache() } } - + + Section(NSLocalizedString("Remote Image Loading Policy", comment: "Section title for remote image loading policy")) { + Menu { + Button { + self.remote_image_policy = .everyone + } label: { + Text(remoteImagePolicyText(.everyone)) + } + Button { + self.remote_image_policy = .friendsOfFriends + } label: { + Text(remoteImagePolicyText(.friendsOfFriends)) + } + Button { + self.remote_image_policy = .friendsOnly + } label: { + Text(remoteImagePolicyText(.friendsOnly)) + } + Button { + self.remote_image_policy = .restricted + } label: { + Text(remoteImagePolicyText(.restricted)) + } + } label: { + Text("\(remoteImagePolicyText(remote_image_policy))") + .frame(maxWidth: .infinity, alignment: .leading) + } + } + if state.is_privkey_user { Section(NSLocalizedString("Delete", comment: "Section title for deleting the user")) { Button(NSLocalizedString("Delete Account", comment: "Button to delete the user's account."), role: .destructive) { diff --git a/damus/Views/DMChatView.swift b/damus/Views/DMChatView.swift @@ -42,7 +42,7 @@ struct DMChatView: View { let profile_page = ProfileView(damus_state: damus_state, profile: pmodel, followers: fmodel) return NavigationLink(destination: profile_page) { HStack { - ProfilePicView(pubkey: pubkey, size: 24, highlight: .none, profiles: damus_state.profiles) + ProfilePicView(pubkey: pubkey, size: 24, highlight: .none, profiles: damus_state.profiles, contacts:damus_state.contacts) ProfileName(pubkey: pubkey, profile: profile, damus: damus_state, show_friend_confirmed: true) } diff --git a/damus/Views/EditMetadataView.swift b/damus/Views/EditMetadataView.swift @@ -120,7 +120,7 @@ struct EditMetadataView: View { let pfp_size: CGFloat = 90.0 HStack(alignment: .center) { - ProfilePicView(pubkey: damus_state.pubkey, size: pfp_size, highlight: .custom(imageBorderColor(), 4.0), profiles: damus_state.profiles) + ProfilePicView(pubkey: damus_state.pubkey, size: pfp_size, highlight: .custom(imageBorderColor(), 4.0), profiles: damus_state.profiles, contacts: damus_state.contacts) .offset(y: -(pfp_size/2.0)) // Increase if set a frame Spacer() diff --git a/damus/Views/EventView.swift b/damus/Views/EventView.swift @@ -98,12 +98,18 @@ func should_show_images(contacts: Contacts, ev: NostrEvent, our_pubkey: String, if ev.pubkey == our_pubkey { return true } - if contacts.is_in_friendosphere(ev.pubkey) { + + let remote_image_policy: RemoteImagePolicy = RemoteImagePolicy(rawValue: UserDefaults.standard.string(forKey: "remote_image_policy") ?? "") ?? .friendsOfFriends + if remote_image_policy == .everyone || + remote_image_policy == .friendsOnly && contacts.is_friend(ev.pubkey) || + remote_image_policy == .friendsOfFriends && contacts.is_in_friendosphere(ev.pubkey) { return true } - if let boost_key = booster_pubkey, contacts.is_in_friendosphere(boost_key) { + + if let boost_key = booster_pubkey, contacts.is_in_friendosphere(boost_key) && remote_image_policy != .restricted { return true } + return false } diff --git a/damus/Views/Events/EventProfile.swift b/damus/Views/Events/EventProfile.swift @@ -35,7 +35,7 @@ struct EventProfile: View { let pv = ProfileView(damus_state: damus_state, profile: pmodel, followers: FollowersModel(damus_state: damus_state, target: pubkey)) NavigationLink(destination: pv) { - ProfilePicView(pubkey: pubkey, size: pfp_size, highlight: .none, profiles: damus_state.profiles) + ProfilePicView(pubkey: pubkey, size: pfp_size, highlight: .none, profiles: damus_state.profiles, contacts: damus_state.contacts) } } diff --git a/damus/Views/Events/TextEvent.swift b/damus/Views/Events/TextEvent.swift @@ -17,13 +17,13 @@ struct TextEvent: View { var body: some View { HStack(alignment: .top) { let profile = damus.profiles.lookup(id: pubkey) - + VStack { let pmodel = ProfileModel(pubkey: pubkey, damus: damus) let pv = ProfileView(damus_state: damus, profile: pmodel, followers: FollowersModel(damus_state: damus, target: pubkey)) NavigationLink(destination: pv) { - ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: .none, profiles: damus.profiles) + ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: .none, profiles: damus.profiles, contacts: damus.contacts) } Spacer() diff --git a/damus/Views/NoteContentView.swift b/damus/Views/NoteContentView.swift @@ -65,7 +65,7 @@ struct NoteContentView: View { var body: some View { MainContent() .onAppear() { - self.artifacts = render_note_content(ev: event, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey) + self.artifacts = render_note_content(ev: event, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey, show_images: show_images) } .onReceive(handle_notify(.profile_updated)) { notif in let profile = notif.object as! ProfileUpdate @@ -74,7 +74,7 @@ struct NoteContentView: View { switch block { case .mention(let m): if m.type == .pubkey && m.ref.ref_id == profile.pubkey { - self.artifacts = render_note_content(ev: event, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey) + self.artifacts = render_note_content(ev: event, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey, show_images: show_images) } case .text: return case .hashtag: return @@ -261,12 +261,12 @@ struct NoteArtifacts { } } -func render_note_content(ev: NostrEvent, profiles: Profiles, privkey: String?) -> NoteArtifacts { +func render_note_content(ev: NostrEvent, profiles: Profiles, privkey: String?, show_images: Bool) -> NoteArtifacts { let blocks = ev.blocks(privkey) - return render_blocks(blocks: blocks, profiles: profiles, privkey: privkey) + return render_blocks(blocks: blocks, profiles: profiles, privkey: privkey, show_images: show_images) } -func render_blocks(blocks: [Block], profiles: Profiles, privkey: String?) -> NoteArtifacts { +func render_blocks(blocks: [Block], profiles: Profiles, privkey: String?, show_images: Bool) -> NoteArtifacts { var invoices: [Invoice] = [] var img_urls: [URL] = [] var link_urls: [URL] = [] @@ -283,7 +283,7 @@ func render_blocks(blocks: [Block], profiles: Profiles, privkey: String?) -> Not return str case .url(let url): // Handle Image URLs - if is_image_url(url) { + if show_images && is_image_url(url) { // Append Image img_urls.append(url) return str diff --git a/damus/Views/ParicipantsView.swift b/damus/Views/ParicipantsView.swift @@ -39,7 +39,7 @@ struct ParticipantsView: View { ForEach(originalReferences.pRefs) { participant in let pubkey = participant.id HStack { - ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: .none, profiles: damus_state.profiles) + ProfilePicView(pubkey: pubkey, size: PFP_SIZE, highlight: .none, profiles: damus_state.profiles, contacts: damus_state.contacts) VStack(alignment: .leading) { let profile = damus_state.profiles.lookup(id: pubkey) diff --git a/damus/Views/ProfilePicView.swift b/damus/Views/ProfilePicView.swift @@ -98,19 +98,21 @@ struct ProfilePicView: View { let size: CGFloat let highlight: Highlight let profiles: Profiles + let contacts: Contacts @State var picture: String? - init (pubkey: String, size: CGFloat, highlight: Highlight, profiles: Profiles, picture: String? = nil) { + init (pubkey: String, size: CGFloat, highlight: Highlight, profiles: Profiles, contacts: Contacts, picture: String? = nil) { self.pubkey = pubkey self.profiles = profiles + self.contacts = contacts self.size = size self.highlight = highlight self._picture = State(initialValue: picture) } var body: some View { - InnerProfilePicView(url: get_profile_url(picture: picture, pubkey: pubkey, profiles: profiles), fallbackUrl: URL(string: robohash(pubkey)), pubkey: pubkey, size: size, highlight: highlight) + InnerProfilePicView(url: get_profile_url(picture: picture, pubkey: pubkey, profiles: profiles, contacts: contacts), fallbackUrl: URL(string: robohash(pubkey)), pubkey: pubkey, size: size, highlight: highlight) .onReceive(handle_notify(.profile_updated)) { notif in let updated = notif.object as! ProfileUpdate @@ -125,8 +127,19 @@ struct ProfilePicView: View { } } -func get_profile_url(picture: String?, pubkey: String, profiles: Profiles) -> URL { - let pic = picture ?? profiles.lookup(id: pubkey)?.picture ?? robohash(pubkey) +func get_profile_url(picture: String?, pubkey: String, profiles: Profiles, contacts: Contacts) -> URL { + var pic: String + let remote_image_policy: RemoteImagePolicy = RemoteImagePolicy(rawValue: UserDefaults.standard.string(forKey: "remote_image_policy") ?? "") ?? .friendsOfFriends + + if pubkey == contacts.our_pubkey || + remote_image_policy == .everyone || + remote_image_policy == .friendsOnly && contacts.is_friend(pubkey) || + remote_image_policy == .friendsOfFriends && contacts.is_in_friendosphere(pubkey) { + pic = picture ?? profiles.lookup(id: pubkey)?.picture ?? robohash(pubkey) + } else { + pic = robohash(pubkey) + } + if let url = URL(string: pic) { return url } @@ -150,7 +163,8 @@ struct ProfilePicView_Previews: PreviewProvider { pubkey: pubkey, size: 100, highlight: .none, - profiles: make_preview_profiles(pubkey)) + profiles: make_preview_profiles(pubkey), + contacts: Contacts(our_pubkey: pubkey)) } } diff --git a/damus/Views/ProfilePictureSelector.swift b/damus/Views/ProfilePictureSelector.swift @@ -13,7 +13,7 @@ struct ProfilePictureSelector: View { var body: some View { let highlight: Highlight = .custom(Color.white, 2.0) ZStack { - ProfilePicView(pubkey: pubkey, size: 80.0, highlight: highlight, profiles: Profiles()) + ProfilePicView(pubkey: pubkey, size: 80.0, highlight: highlight, profiles: Profiles(), contacts: Contacts(our_pubkey: pubkey)) } } } diff --git a/damus/Views/ProfileView.swift b/damus/Views/ProfileView.swift @@ -255,12 +255,12 @@ struct ProfileView: View { let pfp_size: CGFloat = 90.0 HStack(alignment: .center) { - ProfilePicView(pubkey: profile.pubkey, size: pfp_size, highlight: .custom(imageBorderColor(), 4.0), profiles: damus_state.profiles) + ProfilePicView(pubkey: profile.pubkey, size: pfp_size, highlight: .custom(imageBorderColor(), 4.0), profiles: damus_state.profiles, contacts: damus_state.contacts) .onTapGesture { is_zoomed.toggle() } .fullScreenCover(isPresented: $is_zoomed) { - ProfileZoomView(pubkey: profile.pubkey, profiles: damus_state.profiles) } + ProfileZoomView(pubkey: profile.pubkey, profiles: damus_state.profiles, contacts: damus_state.contacts)} .offset(y: -(pfp_size/2.0)) // Increase if set a frame Spacer() diff --git a/damus/Views/ProfileZoomView.swift b/damus/Views/ProfileZoomView.swift @@ -11,6 +11,7 @@ struct ProfileZoomView: View { @Environment(\.presentationMode) var presentationMode let pubkey: String let profiles: Profiles + let contacts: Contacts @GestureState private var scaleState: CGFloat = 1 @GestureState private var offsetState = CGSize.zero @@ -68,7 +69,7 @@ struct ProfileZoomView: View { Spacer() - ProfilePicView(pubkey: pubkey, size: 200.0, highlight: .none, profiles: profiles) + ProfilePicView(pubkey: pubkey, size: 200.0, highlight: .none, profiles: profiles, contacts: contacts) .padding(100) .scaledToFit() .scaleEffect(self.scale * scaleState) @@ -92,6 +93,8 @@ struct ProfileZoomView_Previews: PreviewProvider { static var previews: some View { ProfileZoomView( pubkey: pubkey, - profiles: make_preview_profiles(pubkey)) + profiles: make_preview_profiles(pubkey), + contacts: Contacts(our_pubkey: pubkey) + ) } } diff --git a/damus/Views/SideMenuView.swift b/damus/Views/SideMenuView.swift @@ -55,7 +55,7 @@ struct SideMenuView: View { NavigationLink(destination: ProfileView(damus_state: damus_state, profile: profile_model, followers: followers)) { if let picture = damus_state.profiles.lookup(id: damus_state.pubkey)?.picture { - ProfilePicView(pubkey: damus_state.pubkey, size: 60, highlight: .none, profiles: damus_state.profiles, picture: picture) + ProfilePicView(pubkey: damus_state.pubkey, size: 60, highlight: .none, profiles: damus_state.profiles, contacts: damus_state.contacts, picture: picture) } else { Image(systemName: "person.fill") }