Revert "Fix AttributeGraph cycle on Profile View"
This reverts commit cba554b6ce.
This commit was reverted because although it fixed one AttributeGraph
cycle, it caused other aesthetic issues.
The fix should be revisited to avoid AttributeGraph cycles.
This commit is contained in:
@@ -102,9 +102,7 @@ struct ProfileView: View {
|
||||
colorScheme == .light ? DamusColors.white : DamusColors.black
|
||||
}
|
||||
|
||||
/// Returns the blur opacity for the collapsing banner based on the current scroll offset and top safe-area inset.
|
||||
func bannerBlurViewOpacity(topSafeAreaInset: CGFloat) -> Double {
|
||||
let navbarHeight = navbarHeight(topSafeAreaInset: topSafeAreaInset)
|
||||
func bannerBlurViewOpacity() -> Double {
|
||||
let progress = -(yOffset + navbarHeight) / 100
|
||||
return Double(-yOffset > navbarHeight ? progress : 0)
|
||||
}
|
||||
@@ -116,9 +114,8 @@ struct ProfileView: View {
|
||||
return (displayName, "@\(userName)")
|
||||
}
|
||||
|
||||
/// Determines whether the follow button should appear in the collapsed banner state.
|
||||
func showFollowBtnInBlurrBanner(topSafeAreaInset: CGFloat) -> Bool {
|
||||
damus_state.contacts.follow_state(profile.pubkey) == .unfollows && bannerBlurViewOpacity(topSafeAreaInset: topSafeAreaInset) > 1.0
|
||||
func showFollowBtnInBlurrBanner() -> Bool {
|
||||
damus_state.contacts.follow_state(profile.pubkey) == .unfollows && bannerBlurViewOpacity() > 1.0
|
||||
}
|
||||
|
||||
/// Builds the profile timeline filter, while ensuring the user's own profile bypasses NSFW and hashtag-spam content filters.
|
||||
@@ -136,12 +133,10 @@ struct ProfileView: View {
|
||||
return ContentFilters(filters: filters).filter
|
||||
}
|
||||
|
||||
/// Builds the stretching and collapsing banner while avoiding synchronous window safe-area queries on the main thread.
|
||||
func bannerSection(topSafeAreaInset: CGFloat) -> some View {
|
||||
var bannerSection: some View {
|
||||
GeometryReader { proxy -> AnyView in
|
||||
|
||||
let minY = proxy.frame(in: .global).minY
|
||||
let navbarHeight = navbarHeight(topSafeAreaInset: topSafeAreaInset)
|
||||
let blurOpacity = bannerBlurViewOpacity(topSafeAreaInset: topSafeAreaInset)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.yOffset = minY
|
||||
@@ -155,10 +150,10 @@ struct ProfileView: View {
|
||||
.frame(width: proxy.size.width, height: minY > 0 ? bannerHeight + minY : bannerHeight)
|
||||
.clipped()
|
||||
|
||||
VisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial)).opacity(blurOpacity)
|
||||
VisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial)).opacity(bannerBlurViewOpacity())
|
||||
}
|
||||
|
||||
Divider().opacity(blurOpacity)
|
||||
Divider().opacity(bannerBlurViewOpacity())
|
||||
}
|
||||
.frame(height: minY > 0 ? bannerHeight + minY : nil)
|
||||
.offset(y: minY > 0 ? -minY : -minY < navbarHeight ? 0 : -minY - navbarHeight)
|
||||
@@ -169,9 +164,8 @@ struct ProfileView: View {
|
||||
.allowsHitTesting(false)
|
||||
}
|
||||
|
||||
/// Computes the profile navigation height using the view's current safe-area context instead of querying the key window during SwiftUI updates.
|
||||
func navbarHeight(topSafeAreaInset: CGFloat) -> CGFloat {
|
||||
100.0 - topSafeAreaInset
|
||||
var navbarHeight: CGFloat {
|
||||
return 100.0 - (Theme.safeAreaInsets?.top ?? 0)
|
||||
}
|
||||
|
||||
func navImage(img: String) -> some View {
|
||||
@@ -305,30 +299,27 @@ struct ProfileView: View {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the avatar's vertical offset during banner collapse.
|
||||
func pfpOffset(topSafeAreaInset: CGFloat) -> CGFloat {
|
||||
let progress = -yOffset / navbarHeight(topSafeAreaInset: topSafeAreaInset)
|
||||
func pfpOffset() -> CGFloat {
|
||||
let progress = -yOffset / navbarHeight
|
||||
let offset = (pfp_size / 4.0) * (progress < 1.0 ? progress : 1)
|
||||
return offset > 0 ? offset : 0
|
||||
}
|
||||
|
||||
/// Returns the avatar's scale during banner collapse.
|
||||
func pfpScale(topSafeAreaInset: CGFloat) -> CGFloat {
|
||||
let progress = -yOffset / navbarHeight(topSafeAreaInset: topSafeAreaInset)
|
||||
func pfpScale() -> CGFloat {
|
||||
let progress = -yOffset / navbarHeight
|
||||
let scale = 1.0 - (0.5 * (progress < 1.0 ? progress : 1))
|
||||
return scale < 1 ? scale : 1
|
||||
}
|
||||
|
||||
/// Builds the name and avatar section using geometry-provided safe-area values to avoid AttributeGraph cycles.
|
||||
func nameSection(ndbprofile: Profile?, lnurl: String?, topSafeAreaInset: CGFloat) -> some View {
|
||||
func nameSection(ndbprofile: Profile?, lnurl: String?) -> 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, damusState: damus_state)
|
||||
.padding(.top, -(pfp_size / 2.0))
|
||||
.offset(y: pfpOffset(topSafeAreaInset: topSafeAreaInset))
|
||||
.scaleEffect(pfpScale(topSafeAreaInset: topSafeAreaInset))
|
||||
.offset(y: pfpOffset())
|
||||
.scaleEffect(pfpScale())
|
||||
.onTapGesture {
|
||||
is_zoomed.toggle()
|
||||
}
|
||||
@@ -366,13 +357,12 @@ struct ProfileView: View {
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds the profile summary section using safe-area values from the surrounding geometry.
|
||||
func aboutSection(topSafeAreaInset: CGFloat) -> some View {
|
||||
var aboutSection: some View {
|
||||
VStack(alignment: .leading, spacing: 8.0) {
|
||||
let lnurl = try? damus_state.profiles.lookup_lnurl(profile.pubkey)
|
||||
let ndbprofile = try? damus_state.profiles.lookup(id: profile.pubkey)
|
||||
|
||||
nameSection(ndbprofile: ndbprofile, lnurl: lnurl, topSafeAreaInset: topSafeAreaInset)
|
||||
nameSection(ndbprofile: ndbprofile, lnurl: lnurl)
|
||||
|
||||
if let about = ndbprofile?.about {
|
||||
AboutView(state: damus_state, about: about)
|
||||
@@ -461,20 +451,14 @@ struct ProfileView: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { geometry in
|
||||
let safeAreaInsets = geometry.safeAreaInsets
|
||||
let topSafeAreaInset = safeAreaInsets.top
|
||||
let navbarHeight = navbarHeight(topSafeAreaInset: topSafeAreaInset)
|
||||
let blurOpacity = bannerBlurViewOpacity(topSafeAreaInset: topSafeAreaInset)
|
||||
|
||||
ZStack {
|
||||
ScrollView(.vertical) {
|
||||
VStack(spacing: 0) {
|
||||
bannerSection(topSafeAreaInset: topSafeAreaInset)
|
||||
bannerSection
|
||||
.zIndex(1)
|
||||
|
||||
VStack {
|
||||
aboutSection(topSafeAreaInset: topSafeAreaInset)
|
||||
VStack() {
|
||||
aboutSection
|
||||
|
||||
VStack(spacing: 0) {
|
||||
CustomPicker(tabs: tabs, selection: $filter_state)
|
||||
@@ -493,11 +477,11 @@ struct ProfileView: View {
|
||||
InnerTimelineView(events: profile.events, damus: damus_state, filter: content_filter(FilterState.conversations))
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, safeAreaInsets.leading)
|
||||
.padding(.horizontal, Theme.safeAreaInsets?.left)
|
||||
.zIndex(-yOffset > navbarHeight ? 0 : 1)
|
||||
}
|
||||
}
|
||||
.padding(.bottom, tabHeight + safeAreaInsets.bottom)
|
||||
.padding(.bottom, tabHeight + getSafeAreaBottom())
|
||||
.ignoresSafeArea()
|
||||
.navigationTitle("")
|
||||
.navigationBarBackButtonHidden()
|
||||
@@ -515,14 +499,14 @@ struct ProfileView: View {
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.white.opacity(0.8))
|
||||
}
|
||||
.opacity(blurOpacity)
|
||||
.opacity(bannerBlurViewOpacity())
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
.padding(.top, max(5, 15 + (yOffset / 30)))
|
||||
}
|
||||
}
|
||||
.hideToolbarBackground()
|
||||
|
||||
if showFollowBtnInBlurrBanner(topSafeAreaInset: topSafeAreaInset) {
|
||||
if showFollowBtnInBlurrBanner() {
|
||||
ToolbarItem(placement: .topBarTrailing) {
|
||||
FollowButtonView(
|
||||
target: profile.get_follow_target(),
|
||||
@@ -572,7 +556,6 @@ struct ProfileView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ProfileView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
|
||||
Reference in New Issue
Block a user