From 652e802ca6acfe95e819d961fdbb05e67f864ea1 Mon Sep 17 00:00:00 2001 From: alltheseas Date: Wed, 4 Mar 2026 23:11:34 -0600 Subject: [PATCH] Improve BlurOverlayView to look protective, not broken The blur overlay previously used error-state iconography (eye.slash icon, "Tap to load" button, raw URL display) which made users think media was broken rather than intentionally hidden. Redesign to communicate intentional protection: - Replace eye.slash icon with shield icon - Change title from "Media from someone you don't follow" to "Content hidden" (the old text was also wrong for undistractMode) - Rename button from "Tap to load" to "Show" - Remove raw URL display that added noise - Remove unused properties (artifacts, size, damus_state, parentView) and dead ParentViewType enum that only existed for the URL display - Simplify all 4 call sites to pass only the blur binding Changelog-Changed: Redesigned media blur overlay to look like intentional protection instead of a broken state Closes: https://github.com/damus-io/damus/issues/3662 Signed-off-by: alltheseas Co-Authored-By: Claude Opus 4.6 --- damus/Features/Events/NoteContentView.swift | 61 ++++++------------- .../FollowPack/Views/FollowPackPreview.swift | 2 +- .../Longform/Views/LongformPreview.swift | 4 +- 3 files changed, 23 insertions(+), 44 deletions(-) diff --git a/damus/Features/Events/NoteContentView.swift b/damus/Features/Events/NoteContentView.swift index cad09f21..09ae8555 100644 --- a/damus/Features/Events/NoteContentView.swift +++ b/damus/Features/Events/NoteContentView.swift @@ -215,7 +215,7 @@ struct NoteContentView: View { ImageCarousel(state: damus_state, evid: event.id, urls: artifacts.media) { dismiss in fullscreen_preview(dismiss: dismiss) } - BlurOverlayView(blur_images: $blur_images, artifacts: artifacts, size: size, damus_state: damus_state, parentView: .noteContentView) + BlurOverlayView(blur_images: $blur_images) } } } @@ -615,60 +615,39 @@ func lookup_cached_preview_size(previews: PreviewCache, evid: NoteId) -> CGFloat struct BlurOverlayView: View { @Binding var blur_images: Bool - let artifacts: NoteArtifactsSeparated? - let size: EventViewKind? - let damus_state: DamusState? - let parentView: ParentViewType + var body: some View { ZStack { - - Color.black - .opacity(0.54) - + Color.black.opacity(0.54) Blur() - - VStack(alignment: .center) { - Image(systemName: "eye.slash") + VStack(spacing: 12) { + Image(systemName: "shield") + .font(.system(size: 28)) + .foregroundStyle(.white.opacity(0.9)) + .accessibilityHidden(true) + + Text(NSLocalizedString("Content hidden", comment: "Title on the image blur overlay indicating media is intentionally hidden")) .foregroundStyle(.white) - .bold() - .padding(EdgeInsets(top: 5, leading: 10, bottom: 0, trailing: 10)) - Text("Media from someone you don't follow", comment: "Label on the image blur mask") - .multilineTextAlignment(.center) - .foregroundStyle(Color.white) - .font(.title2) - .padding(EdgeInsets(top: 5, leading: 10, bottom: 0, trailing: 10)) - Button(NSLocalizedString("Tap to load", comment: "Label for button that allows user to dismiss media content warning and unblur the image")) { + .font(.headline) + + Text(NSLocalizedString("This content is from a user you do not follow.", comment: "Explanation on the image blur overlay that indicates media is intentionally hidden")) + .foregroundStyle(.white.opacity(0.75)) + .font(.caption) + + Button(NSLocalizedString("Show", comment: "Button to reveal hidden media on the blur overlay")) { blur_images = false } .buttonStyle(.bordered) - .fontWeight(.bold) + .fontWeight(.semibold) .foregroundStyle(.white) - .padding(EdgeInsets(top: 5, leading: 10, bottom: 0, trailing: 10)) - - if parentView == .noteContentView, - let artifacts = artifacts, - let size = size, - let damus_state = damus_state - { - switch artifacts.media[0] { - case .image(let url), .video(let url): - Text(verbatim: "\(abbreviateURL(url, maxLength: 30))") - .font(eventviewsize_to_font(size, font_size: damus_state.settings.font_size * 0.8)) - .foregroundStyle(.white) - .multilineTextAlignment(.center) - .padding(EdgeInsets(top: 20, leading: 10, bottom: 5, trailing: 10)) - } - } + .padding(.top, 4) } + .padding(.horizontal, 20) } .onTapGesture { blur_images = false } } - - enum ParentViewType { - case noteContentView, longFormView - } } struct NoteContentView_Previews: PreviewProvider { diff --git a/damus/Features/FollowPack/Views/FollowPackPreview.swift b/damus/Features/FollowPack/Views/FollowPackPreview.swift index db97bfe5..b5149ccf 100644 --- a/damus/Features/FollowPack/Views/FollowPackPreview.swift +++ b/damus/Features/FollowPack/Views/FollowPackPreview.swift @@ -75,7 +75,7 @@ struct FollowPackBannerImage: View { } else { ZStack { titleImage(url: url, preview: preview) - BlurOverlayView(blur_images: $blur_imgs, artifacts: nil, size: nil, damus_state: nil, parentView: .longFormView) + BlurOverlayView(blur_images: $blur_imgs) .frame(maxWidth: preview ? 350 : UIScreen.main.bounds.width, minHeight: preview ? 180 : 200, maxHeight: preview ? 180 : 200) } } diff --git a/damus/Features/Longform/Views/LongformPreview.swift b/damus/Features/Longform/Views/LongformPreview.swift index 0fd681b2..ba48d983 100644 --- a/damus/Features/Longform/Views/LongformPreview.swift +++ b/damus/Features/Longform/Views/LongformPreview.swift @@ -146,7 +146,7 @@ struct LongformPreviewBody: View { } else { ZStack { titleImage(url: url) - BlurOverlayView(blur_images: $blur_images, artifacts: nil, size: nil, damus_state: nil, parentView: .longFormView) + BlurOverlayView(blur_images: $blur_images) } } } @@ -207,7 +207,7 @@ struct LongformPreviewBody: View { } else { ZStack { titleImage(url: url) - BlurOverlayView(blur_images: $blur_images, artifacts: nil, size: nil, damus_state: nil, parentView: .longFormView) + BlurOverlayView(blur_images: $blur_images) } } }