forked from shadowfacts/Tusker
Fix relationship change breaking header layout because the collection view wasn't resizing the cell
This commit is contained in:
parent
f815d4e2e4
commit
fa31c28e92
|
@ -104,12 +104,27 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
|
||||||
switch state {
|
switch state {
|
||||||
case .unloaded:
|
case .unloaded:
|
||||||
Task {
|
Task {
|
||||||
await load()
|
await self.load()
|
||||||
}
|
}
|
||||||
case .loaded, .setupInitialSnapshot:
|
case .loaded, .setupInitialSnapshot:
|
||||||
var snapshot = dataSource.snapshot()
|
var snapshot = self.dataSource.snapshot()
|
||||||
snapshot.reconfigureItems([.header(id)])
|
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)
|
.store(in: &cancellables)
|
||||||
|
@ -132,6 +147,7 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
|
||||||
switch itemIdentifier {
|
switch itemIdentifier {
|
||||||
case .header(let id):
|
case .header(let id):
|
||||||
if let headerCell = self.headerCell {
|
if let headerCell = self.headerCell {
|
||||||
|
headerCell.view?.updateUI(for: id)
|
||||||
return headerCell
|
return headerCell
|
||||||
} else {
|
} else {
|
||||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "headerCell", for: indexPath) as! ProfileHeaderCollectionViewCell
|
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)
|
view.pagesSegmentedControl.setSelectedOption(self.owner!.currentPage, animated: false)
|
||||||
cell.addHeader(view)
|
cell.addHeader(view)
|
||||||
case .useExistingView(let view):
|
case .useExistingView(let view):
|
||||||
|
view.updateUI(for: id)
|
||||||
cell.addHeader(view)
|
cell.addHeader(view)
|
||||||
case .placeholder(height: let height):
|
case .placeholder(height: let height):
|
||||||
_ = cell.addConstraint(height: height)
|
_ = cell.addConstraint(height: height)
|
||||||
|
@ -205,6 +222,13 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
|
||||||
|
|
||||||
state = .setupInitialSnapshot
|
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 controller.loadInitial()
|
||||||
await tryLoadPinned()
|
await tryLoadPinned()
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ extension MenuActionProvider {
|
||||||
|
|
||||||
private var mastodonController: MastodonController? { navigationDelegate?.apiController }
|
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,
|
guard let mastodonController = mastodonController,
|
||||||
let account = mastodonController.persistentContainer.account(for: accountID) else { return [] }
|
let account = mastodonController.persistentContainer.account(for: accountID) else { return [] }
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ extension MenuActionProvider {
|
||||||
|
|
||||||
if let ownAccount = mastodonController.account,
|
if let ownAccount = mastodonController.account,
|
||||||
accountID != ownAccount.id {
|
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
|
actionsSection.append(UIDeferredMenuElement.uncached({ elementHandler in
|
||||||
let listActions = mastodonController.lists.map { list in
|
let listActions = mastodonController.lists.map { list in
|
||||||
UIAction(title: list.title, image: UIImage(systemName: "plus")) { [unowned self] _ 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)])
|
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(fetchRelationship, 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.muteAction(for: $0, mastodonController: $1) }))
|
||||||
}
|
}
|
||||||
|
|
||||||
addOpenInNewWindow(actions: &shareSection, activity: UserActivityManager.showProfileActivity(id: accountID, accountID: loggedInAccountID))
|
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
|
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
|
// 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) {
|
let mo = mastodonController.persistentContainer.relationship(forAccount: accountID) {
|
||||||
elementHandler([builder(mo, mastodonController)])
|
elementHandler([builder(mo, mastodonController)])
|
||||||
} else {
|
} else {
|
||||||
|
let relationship = Task {
|
||||||
|
await fetchRelationship(accountID: accountID, mastodonController: mastodonController)
|
||||||
|
}
|
||||||
Task { @MainActor in
|
Task { @MainActor in
|
||||||
if let relationship = await relationship.value {
|
if let relationship = await relationship.value {
|
||||||
elementHandler([builder(relationship, mastodonController)])
|
elementHandler([builder(relationship, mastodonController)])
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import Pachyderm
|
import Pachyderm
|
||||||
import Combine
|
|
||||||
|
|
||||||
protocol ProfileHeaderViewDelegate: TuskerNavigationDelegate, MenuActionProvider {
|
protocol ProfileHeaderViewDelegate: TuskerNavigationDelegate, MenuActionProvider {
|
||||||
func profileHeader(_ headerView: ProfileHeaderView, selectedPageChangedTo newPage: ProfileViewController.Page)
|
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
|
return nib.instantiate(withOwner: nil, options: nil).first as! ProfileHeaderView
|
||||||
}
|
}
|
||||||
|
|
||||||
weak var delegate: ProfileHeaderViewDelegate? {
|
weak var delegate: ProfileHeaderViewDelegate?
|
||||||
didSet {
|
|
||||||
createObservers()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var mastodonController: MastodonController! { delegate?.apiController }
|
var mastodonController: MastodonController! { delegate?.apiController }
|
||||||
|
|
||||||
@IBOutlet weak var headerImageView: UIImageView!
|
@IBOutlet weak var headerImageView: UIImageView!
|
||||||
|
@ -57,8 +52,6 @@ class ProfileHeaderView: UIView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var cancellables = [AnyCancellable]()
|
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
avatarRequest?.cancel()
|
avatarRequest?.cancel()
|
||||||
headerRequest?.cancel()
|
headerRequest?.cancel()
|
||||||
|
@ -122,27 +115,6 @@ class ProfileHeaderView: UIView {
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
|
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) {
|
func updateUI(for accountID: String) {
|
||||||
self.accountID = accountID
|
self.accountID = accountID
|
||||||
|
|
||||||
|
@ -158,7 +130,7 @@ class ProfileHeaderView: UIView {
|
||||||
|
|
||||||
updateImages(account: account)
|
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.navigationDelegate = delegate
|
||||||
noteTextView.setTextFromHtml(account.note)
|
noteTextView.setTextFromHtml(account.note)
|
||||||
|
@ -171,16 +143,6 @@ class ProfileHeaderView: UIView {
|
||||||
|
|
||||||
// while fetching the most up-to-date, show the current data (if any)
|
// while fetching the most up-to-date, show the current data (if any)
|
||||||
updateRelationship()
|
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
|
fieldsView.delegate = delegate
|
||||||
|
|
Loading…
Reference in New Issue