Kill some forced unwrapping and hide bio when blocked/blocking (IOS-192)

First rule of optionals: Don't use forced unwrapping!
This commit is contained in:
Nathan Mattes 2023-12-25 23:42:30 +01:00
parent 2f0614d9c9
commit f9492e07a3
4 changed files with 55 additions and 47 deletions

View File

@ -18,6 +18,7 @@ import MastodonCore
import MastodonUI
import MastodonLocalization
import TabBarPager
import MastodonSDK
protocol ProfileHeaderViewControllerDelegate: AnyObject {
func profileHeaderViewController(_ profileHeaderViewController: ProfileHeaderViewController, profileHeaderView: ProfileHeaderView, relationshipButtonDidPressed button: ProfileRelationshipActionButton)
@ -29,12 +30,12 @@ final class ProfileHeaderViewController: UIViewController, NeedsDependency, Medi
static let segmentedControlHeight: CGFloat = 50
static let headerMinHeight: CGFloat = segmentedControlHeight
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
weak var context: AppContext!
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
var disposeBag = Set<AnyCancellable>()
var viewModel: ProfileHeaderViewModel!
let viewModel: ProfileHeaderViewModel
weak var delegate: ProfileHeaderViewControllerDelegate?
weak var headerDelegate: TabBarPagerHeaderDelegate?
@ -51,7 +52,7 @@ final class ProfileHeaderViewController: UIViewController, NeedsDependency, Medi
return titleView
}()
let profileHeaderView = ProfileHeaderView()
let profileHeaderView: ProfileHeaderView
// private var isBannerPinned = false
@ -81,11 +82,17 @@ final class ProfileHeaderViewController: UIViewController, NeedsDependency, Medi
return documentPickerController
}()
}
init(context: AppContext, authContext: AuthContext, account: Mastodon.Entity.Account, coordinator: SceneCoordinator) {
self.context = context
self.coordinator = coordinator
self.viewModel = ProfileHeaderViewModel(context: context, authContext: authContext, account: account)
self.profileHeaderView = ProfileHeaderView(account: account)
extension ProfileHeaderViewController {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
override func viewDidLoad() {
super.viewDidLoad()
@ -135,6 +142,9 @@ extension ProfileHeaderViewController {
viewModel.$relationship
.assign(to: \.relationship, on: profileHeaderView.viewModel)
.store(in: &disposeBag)
viewModel.$account
.assign(to: \.account, on: profileHeaderView.viewModel)
.store(in: &disposeBag)
viewModel.$isMyself
.assign(to: \.isMyself, on: profileHeaderView.viewModel)
.store(in: &disposeBag)

View File

@ -46,12 +46,15 @@ extension ProfileHeaderView {
@Published var fields: [MastodonField] = []
@Published var account: Mastodon.Entity.Account
@Published var relationship: Mastodon.Entity.Relationship?
@Published var isRelationshipActionButtonHidden = false
@Published var isMyself = false
init() {
#warning("TODO: Implement")
init(account: Mastodon.Entity.Account) {
self.account = account
#warning("TODO: Implement")
// $relationshipActionOptionSet
// .compactMap { $0.highPriorityAction(except: []) }
// .map { $0 == .none }
@ -190,18 +193,23 @@ extension ProfileHeaderView.ViewModel {
view.bioMetaText.configure(content: metaContent)
}
.store(in: &disposeBag)
#warning("TODO: Implement")
// $relationshipActionOptionSet
// .receive(on: DispatchQueue.main)
// .sink { optionSet in
// let isBlocking = optionSet.contains(.blocking)
// let isBlockedBy = optionSet.contains(.blockingBy)
// let isSuspended = optionSet.contains(.suspended)
// let isNeedsHidden = isBlocking || isBlockedBy || isSuspended
//
// view.bioMetaText.textView.isHidden = isNeedsHidden
// }
// .store(in: &disposeBag)
Publishers.CombineLatest($relationship, $account)
.compactMap { relationship, account in
guard let relationship else { return nil }
let isBlocking = relationship.blocking
let isBlockedBy = relationship.blockedBy ?? false
let isSuspended = account.suspended ?? false
let isNeedsHidden = isBlocking || isBlockedBy || isSuspended
return isNeedsHidden
}
.receive(on: DispatchQueue.main)
.sink { isNeedsHidden in
view.bioMetaText.textView.isHidden = isNeedsHidden
}
.store(in: &disposeBag)
// dashboard
$isMyself
.receive(on: DispatchQueue.main)

View File

@ -13,6 +13,7 @@ import MastodonAsset
import MastodonCore
import MastodonLocalization
import MastodonUI
import MastodonSDK
protocol ProfileHeaderViewDelegate: AnyObject {
func profileHeaderView(_ profileHeaderView: ProfileHeaderView, avatarButtonDidPressed button: AvatarButton)
@ -42,12 +43,8 @@ final class ProfileHeaderView: UIView {
disposeBag.removeAll()
}
private(set) lazy var viewModel: ViewModel = {
let viewModel = ViewModel()
viewModel.bind(view: self)
return viewModel
}()
private(set) var viewModel: ViewModel
let bannerImageViewSingleTapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer
let bannerContainerView = UIView()
let bannerImageView: UIImageView = {
@ -238,20 +235,14 @@ final class ProfileHeaderView: UIView {
return metaText
}()
override init(frame: CGRect) {
super.init(frame: frame)
_init()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
_init()
}
}
init(account: Mastodon.Entity.Account) {
viewModel = ViewModel(account: account)
super.init(frame: .zero)
viewModel.bind(view: self)
extension ProfileHeaderView {
private func _init() {
setColors()
// banner
@ -460,6 +451,8 @@ extension ProfileHeaderView {
updateLayoutMargins()
}
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
private func setColors() {
backgroundColor = .systemBackground

View File

@ -119,10 +119,7 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi
private(set) lazy var tabBarPagerController = TabBarPagerController()
private(set) lazy var profileHeaderViewController: ProfileHeaderViewController = {
let viewController = ProfileHeaderViewController()
viewController.context = context
viewController.coordinator = coordinator
viewController.viewModel = ProfileHeaderViewModel(context: context, authContext: viewModel.authContext, account: viewModel.account)
let viewController = ProfileHeaderViewController(context: context, authContext: authContext, account: viewModel.account, coordinator: coordinator)
return viewController
}()
@ -300,7 +297,7 @@ extension ProfileViewController {
private func bindViewModel() {
// header
let headerViewModel = profileHeaderViewController.viewModel!
let headerViewModel = profileHeaderViewController.viewModel
viewModel.$account
.assign(to: \.account, on: headerViewModel)
.store(in: &disposeBag)
@ -698,7 +695,7 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate {
// // do nothing when updating
guard !viewModel.isUpdating else { return }
guard let profileHeaderViewModel = profileHeaderViewController.viewModel else { return }
let profileHeaderViewModel = profileHeaderViewController.viewModel
guard let profileAboutViewModel = profilePagingViewController.viewModel.profileAboutViewController.viewModel else { return }
let isEdited = profileHeaderViewModel.isEdited || profileAboutViewModel.isEdited
@ -885,7 +882,7 @@ extension ProfileViewController: MastodonMenuDelegate {
barButtonItem: self.moreMenuBarButtonItem
))
}
case .translateStatus(_),
.showOriginal,
.bookmarkStatus(_),