Merge pull request #449 from mastodon/feature-following-indicator

Add follows you indicator. resolve #397
This commit is contained in:
CMK 2022-06-09 18:10:18 +08:00 committed by GitHub
commit 08d55dd419
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 10 deletions

View File

@ -24,17 +24,17 @@
<key>Mastodon - RTL.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>11</integer>
<integer>12</integer>
</dict>
<key>Mastodon - Release.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
<integer>5</integer>
</dict>
<key>Mastodon - Snapshot.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>6</integer>
<integer>7</integer>
</dict>
<key>Mastodon - ar.xcscheme</key>
<dict>
@ -114,7 +114,7 @@
<key>MastodonIntent.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>30</integer>
<integer>23</integer>
</dict>
<key>MastodonIntents.xcscheme_^#shared#^_</key>
<dict>
@ -129,12 +129,12 @@
<key>NotificationService.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>29</integer>
<integer>24</integer>
</dict>
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>31</integer>
<integer>22</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@ -88,6 +88,13 @@ extension ProfileHeaderView.ViewModel {
)
}
.store(in: &disposeBag)
// follows you
$relationshipActionOptionSet
.map { $0.contains(.followingBy) && !$0.contains(.isMyself) }
.sink { isFollowingBy in
view.followsYouBlurEffectView.isHidden = !isFollowingBy
}
.store(in: &disposeBag)
// avatar
Publishers.CombineLatest4(
$avatarImageURL,
@ -102,7 +109,7 @@ extension ProfileHeaderView.ViewModel {
))
}
.store(in: &disposeBag)
// blur
// blur for blocking & blockingBy
$relationshipActionOptionSet
.map { $0.contains(.blocking) || $0.contains(.blockingBy) }
.sink { needsImageOverlayBlurred in

View File

@ -71,6 +71,16 @@ final class ProfileHeaderView: UIView {
}()
var bannerImageViewTopLayoutConstraint: NSLayoutConstraint!
var bannerImageViewBottomLayoutConstraint: NSLayoutConstraint!
let followsYouBlurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
let followsYouVibrantEffectView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .regular), style: .label))
let followsYouLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
label.text = "Follows You" // TODO: i18n
return label
}()
let followsYouMaskView = UIView()
let avatarImageViewBackgroundView: UIView = {
let view = UIView()
@ -173,9 +183,6 @@ final class ProfileHeaderView: UIView {
button.titleLabel?.minimumScaleFactor = 0.5
return button
}()
// let bioContainerView = UIView()
// let fieldContainerStackView = UIStackView()
let bioMetaText: MetaText = {
let metaText = MetaText()
@ -262,7 +269,41 @@ extension ProfileHeaderView {
bannerImageViewOverlayVisualEffectView.trailingAnchor.constraint(equalTo: bannerImageView.trailingAnchor),
bannerImageViewOverlayVisualEffectView.bottomAnchor.constraint(equalTo: bannerImageView.bottomAnchor),
])
// follows you
followsYouBlurEffectView.translatesAutoresizingMaskIntoConstraints = false
addSubview(followsYouBlurEffectView)
NSLayoutConstraint.activate([
layoutMarginsGuide.trailingAnchor.constraint(equalTo: followsYouBlurEffectView.trailingAnchor),
bannerContainerView.bottomAnchor.constraint(equalTo: followsYouBlurEffectView.bottomAnchor, constant: 16),
])
followsYouBlurEffectView.layer.masksToBounds = true
followsYouBlurEffectView.layer.cornerRadius = 8
followsYouBlurEffectView.layer.cornerCurve = .continuous
followsYouBlurEffectView.isHidden = true
followsYouVibrantEffectView.translatesAutoresizingMaskIntoConstraints = false
followsYouBlurEffectView.contentView.addSubview(followsYouVibrantEffectView)
NSLayoutConstraint.activate([
followsYouVibrantEffectView.topAnchor.constraint(equalTo: followsYouBlurEffectView.topAnchor),
followsYouVibrantEffectView.leadingAnchor.constraint(equalTo: followsYouBlurEffectView.leadingAnchor),
followsYouVibrantEffectView.trailingAnchor.constraint(equalTo: followsYouBlurEffectView.trailingAnchor),
followsYouVibrantEffectView.bottomAnchor.constraint(equalTo: followsYouBlurEffectView.bottomAnchor),
])
followsYouLabel.translatesAutoresizingMaskIntoConstraints = false
followsYouVibrantEffectView.contentView.addSubview(followsYouLabel)
NSLayoutConstraint.activate([
followsYouLabel.topAnchor.constraint(equalTo: followsYouVibrantEffectView.topAnchor, constant: 4),
followsYouLabel.leadingAnchor.constraint(equalTo: followsYouVibrantEffectView.leadingAnchor, constant: 6),
followsYouVibrantEffectView.trailingAnchor.constraint(equalTo: followsYouLabel.trailingAnchor, constant: 6),
followsYouVibrantEffectView.bottomAnchor.constraint(equalTo: followsYouLabel.bottomAnchor, constant: 4),
])
followsYouMaskView.frame = CGRect(x: 0, y: 0, width: 1000, height: 1000)
followsYouMaskView.backgroundColor = .red
followsYouBlurEffectView.mask = followsYouMaskView
// avatar
avatarImageViewBackgroundView.translatesAutoresizingMaskIntoConstraints = false
addSubview(avatarImageViewBackgroundView)
@ -406,6 +447,7 @@ extension ProfileHeaderView {
container.addArrangedSubview(bioMetaText.textView)
bringSubviewToFront(bannerContainerView)
bringSubviewToFront(followsYouBlurEffectView)
bringSubviewToFront(avatarImageViewBackgroundView)
statusDashboardView.delegate = self

View File

@ -584,6 +584,22 @@ extension ProfileViewController: TabBarPagerDelegate {
progress = 0
}
// setup follows you mask
// 1. set mask size
profileHeaderViewController.profileHeaderView.followsYouMaskView.frame = profileHeaderViewController.profileHeaderView.followsYouBlurEffectView.bounds
// 2. check follows you view overflow navigation bar or not
let followsYouBlurEffectViewInWindow = profileHeaderViewController.profileHeaderView.convert(
profileHeaderViewController.profileHeaderView.followsYouBlurEffectView.frame,
to: nil
)
if followsYouBlurEffectViewInWindow.minY < tabBarPagerController.containerScrollView.safeAreaInsets.top {
let offestY = tabBarPagerController.containerScrollView.safeAreaInsets.top - followsYouBlurEffectViewInWindow.minY
let height = profileHeaderViewController.profileHeaderView.followsYouMaskView.frame.height
profileHeaderViewController.profileHeaderView.followsYouMaskView.frame.origin.y = min(offestY, height)
} else {
profileHeaderViewController.profileHeaderView.followsYouMaskView.frame.origin.y = .zero
}
// setup titleView offset and fade avatar
profileHeaderViewController.updateHeaderScrollProgress(progress, throttle: throttle)