Fix relationship change breaking header layout because the collection view wasn't resizing the cell

This commit is contained in:
Shadowfacts 2022-12-22 18:27:04 -05:00
parent f815d4e2e4
commit fa31c28e92
3 changed files with 38 additions and 52 deletions

View File

@ -104,12 +104,27 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
switch state {
case .unloaded:
Task {
await load()
await self.load()
}
case .loaded, .setupInitialSnapshot:
var snapshot = dataSource.snapshot()
var snapshot = self.dataSource.snapshot()
snapshot.reconfigureItems([.header(id)])
dataSource.apply(snapshot, animatingDifferences: true)
self.dataSource.apply(snapshot, animatingDifferences: true)
}
}
.store(in: &cancellables)
mastodonController.persistentContainer.relationshipSubject
.receive(on: DispatchQueue.main)
.filter { [unowned self] in $0 == self.accountID }
.sink { [unowned self] id in
switch state {
case .unloaded:
break
case .loaded, .setupInitialSnapshot:
var snapshot = self.dataSource.snapshot()
snapshot.reconfigureItems([.header(id)])
self.dataSource.apply(snapshot, animatingDifferences: true)
}
}
.store(in: &cancellables)
@ -132,6 +147,7 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
switch itemIdentifier {
case .header(let id):
if let headerCell = self.headerCell {
headerCell.view?.updateUI(for: id)
return headerCell
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "headerCell", for: indexPath) as! ProfileHeaderCollectionViewCell
@ -145,6 +161,7 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
view.pagesSegmentedControl.setSelectedOption(self.owner!.currentPage, animated: false)
cell.addHeader(view)
case .useExistingView(let view):
view.updateUI(for: id)
cell.addHeader(view)
case .placeholder(height: let height):
_ = cell.addConstraint(height: height)
@ -205,6 +222,13 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
state = .setupInitialSnapshot
Task {
if let (all, _) = try? await mastodonController.run(Client.getRelationships(accounts: [accountID])),
let relationship = all.first {
self.mastodonController.persistentContainer.addOrUpdate(relationship: relationship)
}
}
await controller.loadInitial()
await tryLoadPinned()

View File

@ -39,7 +39,7 @@ extension MenuActionProvider {
private var mastodonController: MastodonController? { navigationDelegate?.apiController }
func actionsForProfile(accountID: String, source: PopoverSource) -> [UIMenuElement] {
func actionsForProfile(accountID: String, source: PopoverSource, fetchRelationship: Bool = true) -> [UIMenuElement] {
guard let mastodonController = mastodonController,
let account = mastodonController.persistentContainer.account(for: accountID) else { return [] }
@ -68,7 +68,7 @@ extension MenuActionProvider {
if let ownAccount = mastodonController.account,
accountID != ownAccount.id {
actionsSection.append(relationshipAction(accountID: accountID, mastodonController: mastodonController, builder: { [unowned self] in self.followAction(for: $0, mastodonController: $1) }))
actionsSection.append(relationshipAction(fetchRelationship, accountID: accountID, mastodonController: mastodonController, builder: { [unowned self] in self.followAction(for: $0, mastodonController: $1) }))
actionsSection.append(UIDeferredMenuElement.uncached({ elementHandler in
let listActions = mastodonController.lists.map { list in
UIAction(title: list.title, image: UIImage(systemName: "plus")) { [unowned self] _ in
@ -82,8 +82,8 @@ extension MenuActionProvider {
}
elementHandler([UIMenu(title: "Add to List", image: UIImage(systemName: "list.bullet"), children: listActions)])
}))
suppressSection.append(relationshipAction(accountID: accountID, mastodonController: mastodonController, builder: { [unowned self] in self.blockAction(for: $0, mastodonController: $1) }))
suppressSection.append(relationshipAction(accountID: accountID, mastodonController: mastodonController, builder: { [unowned self] in self.muteAction(for: $0, mastodonController: $1) }))
suppressSection.append(relationshipAction(fetchRelationship, accountID: accountID, mastodonController: mastodonController, builder: { [unowned self] in self.blockAction(for: $0, mastodonController: $1) }))
suppressSection.append(relationshipAction(fetchRelationship, accountID: accountID, mastodonController: mastodonController, builder: { [unowned self] in self.muteAction(for: $0, mastodonController: $1) }))
}
addOpenInNewWindow(actions: &shareSection, activity: UserActivityManager.showProfileActivity(id: accountID, accountID: loggedInAccountID))
@ -377,16 +377,16 @@ extension MenuActionProvider {
}
}
private func relationshipAction(accountID: String, mastodonController: MastodonController, builder: @escaping @MainActor (RelationshipMO, MastodonController) -> UIMenuElement) -> UIDeferredMenuElement {
private func relationshipAction(_ fetch: Bool, accountID: String, mastodonController: MastodonController, builder: @escaping @MainActor (RelationshipMO, MastodonController) -> UIMenuElement) -> UIDeferredMenuElement {
return UIDeferredMenuElement.uncached({ @MainActor elementHandler in
let relationship = Task {
await fetchRelationship(accountID: accountID, mastodonController: mastodonController)
}
// workaround for #198, may result in showing outdated relationship, so only do so where necessary
if ProcessInfo.processInfo.isiOSAppOnMac,
if !fetch || ProcessInfo.processInfo.isiOSAppOnMac,
let mo = mastodonController.persistentContainer.relationship(forAccount: accountID) {
elementHandler([builder(mo, mastodonController)])
} else {
let relationship = Task {
await fetchRelationship(accountID: accountID, mastodonController: mastodonController)
}
Task { @MainActor in
if let relationship = await relationship.value {
elementHandler([builder(relationship, mastodonController)])

View File

@ -8,7 +8,6 @@
import UIKit
import Pachyderm
import Combine
protocol ProfileHeaderViewDelegate: TuskerNavigationDelegate, MenuActionProvider {
func profileHeader(_ headerView: ProfileHeaderView, selectedPageChangedTo newPage: ProfileViewController.Page)
@ -21,11 +20,7 @@ class ProfileHeaderView: UIView {
return nib.instantiate(withOwner: nil, options: nil).first as! ProfileHeaderView
}
weak var delegate: ProfileHeaderViewDelegate? {
didSet {
createObservers()
}
}
weak var delegate: ProfileHeaderViewDelegate?
var mastodonController: MastodonController! { delegate?.apiController }
@IBOutlet weak var headerImageView: UIImageView!
@ -57,8 +52,6 @@ class ProfileHeaderView: UIView {
}
}
private var cancellables = [AnyCancellable]()
deinit {
avatarRequest?.cancel()
headerRequest?.cancel()
@ -122,27 +115,6 @@ class ProfileHeaderView: UIView {
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
}
private func createObservers() {
// mastodonController may be nil if the ProfileViewController is deinit'd before the header is even created
guard let mastodonController else {
return
}
cancellables = []
mastodonController.persistentContainer.accountSubject
.receive(on: DispatchQueue.main)
.filter { [weak self] in $0 == self?.accountID }
.sink { [weak self] in self?.updateUI(for: $0) }
.store(in: &cancellables)
mastodonController.persistentContainer.relationshipSubject
.receive(on: DispatchQueue.main)
.filter { [weak self] in $0 == self?.accountID }
.sink { [weak self] (_) in self?.updateRelationship() }
.store(in: &cancellables)
}
func updateUI(for accountID: String) {
self.accountID = accountID
@ -158,7 +130,7 @@ class ProfileHeaderView: UIView {
updateImages(account: account)
moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: delegate?.actionsForProfile(accountID: accountID, source: .view(moreButton)) ?? [])
moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: delegate?.actionsForProfile(accountID: accountID, source: .view(moreButton), fetchRelationship: false) ?? [])
noteTextView.navigationDelegate = delegate
noteTextView.setTextFromHtml(account.note)
@ -171,16 +143,6 @@ class ProfileHeaderView: UIView {
// while fetching the most up-to-date, show the current data (if any)
updateRelationship()
let request = Client.getRelationships(accounts: [accountID])
mastodonController.run(request) { [weak self] (response) in
guard let mastodonController = self?.mastodonController,
case let .success(results, _) = response,
let relationship = results.first else {
return
}
mastodonController.persistentContainer.addOrUpdate(relationship: relationship)
}
}
fieldsView.delegate = delegate