Compare commits
3 Commits
71fa3910a1
...
8deb502140
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 8deb502140 | |
Shadowfacts | 2582907919 | |
Shadowfacts | 266868376d |
|
@ -222,6 +222,7 @@
|
||||||
D690797324A4EF9700023A34 /* UIBezierPath+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D690797224A4EF9700023A34 /* UIBezierPath+Helpers.swift */; };
|
D690797324A4EF9700023A34 /* UIBezierPath+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D690797224A4EF9700023A34 /* UIBezierPath+Helpers.swift */; };
|
||||||
D691771129A2B76A0054D7EF /* MainActor+Unsafe.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691771029A2B76A0054D7EF /* MainActor+Unsafe.swift */; };
|
D691771129A2B76A0054D7EF /* MainActor+Unsafe.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691771029A2B76A0054D7EF /* MainActor+Unsafe.swift */; };
|
||||||
D691771529A6FCAB0054D7EF /* StateRestorableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691771429A6FCAB0054D7EF /* StateRestorableViewController.swift */; };
|
D691771529A6FCAB0054D7EF /* StateRestorableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691771429A6FCAB0054D7EF /* StateRestorableViewController.swift */; };
|
||||||
|
D691771729A710520054D7EF /* ProfileNoContentCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D691771629A710520054D7EF /* ProfileNoContentCollectionViewCell.swift */; };
|
||||||
D693A72825CF282E003A14E2 /* TrendingHashtagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693A72725CF282E003A14E2 /* TrendingHashtagsViewController.swift */; };
|
D693A72825CF282E003A14E2 /* TrendingHashtagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693A72725CF282E003A14E2 /* TrendingHashtagsViewController.swift */; };
|
||||||
D693A72A25CF8C1E003A14E2 /* ProfileDirectoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693A72925CF8C1E003A14E2 /* ProfileDirectoryViewController.swift */; };
|
D693A72A25CF8C1E003A14E2 /* ProfileDirectoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693A72925CF8C1E003A14E2 /* ProfileDirectoryViewController.swift */; };
|
||||||
D693A72F25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693A72D25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift */; };
|
D693A72F25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693A72D25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift */; };
|
||||||
|
@ -639,6 +640,7 @@
|
||||||
D690797224A4EF9700023A34 /* UIBezierPath+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIBezierPath+Helpers.swift"; sourceTree = "<group>"; };
|
D690797224A4EF9700023A34 /* UIBezierPath+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIBezierPath+Helpers.swift"; sourceTree = "<group>"; };
|
||||||
D691771029A2B76A0054D7EF /* MainActor+Unsafe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainActor+Unsafe.swift"; sourceTree = "<group>"; };
|
D691771029A2B76A0054D7EF /* MainActor+Unsafe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainActor+Unsafe.swift"; sourceTree = "<group>"; };
|
||||||
D691771429A6FCAB0054D7EF /* StateRestorableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateRestorableViewController.swift; sourceTree = "<group>"; };
|
D691771429A6FCAB0054D7EF /* StateRestorableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateRestorableViewController.swift; sourceTree = "<group>"; };
|
||||||
|
D691771629A710520054D7EF /* ProfileNoContentCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileNoContentCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
D693A72725CF282E003A14E2 /* TrendingHashtagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingHashtagsViewController.swift; sourceTree = "<group>"; };
|
D693A72725CF282E003A14E2 /* TrendingHashtagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingHashtagsViewController.swift; sourceTree = "<group>"; };
|
||||||
D693A72925CF8C1E003A14E2 /* ProfileDirectoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileDirectoryViewController.swift; sourceTree = "<group>"; };
|
D693A72925CF8C1E003A14E2 /* ProfileDirectoryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileDirectoryViewController.swift; sourceTree = "<group>"; };
|
||||||
D693A72D25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedProfileCollectionViewCell.swift; sourceTree = "<group>"; };
|
D693A72D25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeaturedProfileCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
|
@ -1096,6 +1098,7 @@
|
||||||
D61DC84C28F500D200B82C6E /* ProfileViewController.swift */,
|
D61DC84C28F500D200B82C6E /* ProfileViewController.swift */,
|
||||||
D61ABEF728EFC3F900B29151 /* ProfileStatusesViewController.swift */,
|
D61ABEF728EFC3F900B29151 /* ProfileStatusesViewController.swift */,
|
||||||
D61DC84A28F4FD2000B82C6E /* ProfileHeaderCollectionViewCell.swift */,
|
D61DC84A28F4FD2000B82C6E /* ProfileHeaderCollectionViewCell.swift */,
|
||||||
|
D691771629A710520054D7EF /* ProfileNoContentCollectionViewCell.swift */,
|
||||||
);
|
);
|
||||||
path = Profile;
|
path = Profile;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1969,6 +1972,7 @@
|
||||||
0427033A22B31269000D31B6 /* AdvancedPrefsView.swift in Sources */,
|
0427033A22B31269000D31B6 /* AdvancedPrefsView.swift in Sources */,
|
||||||
D6C3F4F5298ED0890009FCFF /* LocalPredicateStatusesViewController.swift in Sources */,
|
D6C3F4F5298ED0890009FCFF /* LocalPredicateStatusesViewController.swift in Sources */,
|
||||||
D662AEEF263A3B880082A153 /* PollFinishedTableViewCell.swift in Sources */,
|
D662AEEF263A3B880082A153 /* PollFinishedTableViewCell.swift in Sources */,
|
||||||
|
D691771729A710520054D7EF /* ProfileNoContentCollectionViewCell.swift in Sources */,
|
||||||
D626493C23C1000300612E6E /* AlbumTableViewCell.swift in Sources */,
|
D626493C23C1000300612E6E /* AlbumTableViewCell.swift in Sources */,
|
||||||
D62275A624F1C81800B82A16 /* ComposeReplyView.swift in Sources */,
|
D62275A624F1C81800B82A16 /* ComposeReplyView.swift in Sources */,
|
||||||
D60E2F292442372B005F8713 /* AccountMO.swift in Sources */,
|
D60E2F292442372B005F8713 /* AccountMO.swift in Sources */,
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
import UIKit
|
import UIKit
|
||||||
import Pachyderm
|
import Pachyderm
|
||||||
|
|
||||||
class ConversationCollectionViewController: UIViewController, CollectionViewController {
|
class ConversationCollectionViewController: UIViewController, CollectionViewController, RefreshableViewController {
|
||||||
|
|
||||||
|
private unowned let conversationViewController: ConversationViewController
|
||||||
private let mastodonController: MastodonController
|
private let mastodonController: MastodonController
|
||||||
private let mainStatusID: String
|
private let mainStatusID: String
|
||||||
private let mainStatusState: CollapseState
|
private let mainStatusState: CollapseState
|
||||||
|
@ -22,11 +23,12 @@ class ConversationCollectionViewController: UIViewController, CollectionViewCont
|
||||||
}
|
}
|
||||||
private var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
|
private var dataSource: UICollectionViewDiffableDataSource<Section, Item>!
|
||||||
|
|
||||||
init(for mainStatusID: String, state: CollapseState, mastodonController: MastodonController) {
|
init(for mainStatusID: String, state: CollapseState, conversationViewController: ConversationViewController) {
|
||||||
self.mainStatusID = mainStatusID
|
self.mainStatusID = mainStatusID
|
||||||
self.mainStatusState = state
|
self.mainStatusState = state
|
||||||
self.statusIDToScrollToOnLoad = mainStatusID
|
self.statusIDToScrollToOnLoad = mainStatusID
|
||||||
self.mastodonController = mastodonController
|
self.conversationViewController = conversationViewController
|
||||||
|
self.mastodonController = conversationViewController.mastodonController
|
||||||
|
|
||||||
super.init(nibName: nil, bundle: nil)
|
super.init(nibName: nil, bundle: nil)
|
||||||
}
|
}
|
||||||
|
@ -68,6 +70,11 @@ class ConversationCollectionViewController: UIViewController, CollectionViewCont
|
||||||
collectionView.dragDelegate = self
|
collectionView.dragDelegate = self
|
||||||
collectionView.allowsFocus = true
|
collectionView.allowsFocus = true
|
||||||
|
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
|
collectionView.refreshControl = UIRefreshControl()
|
||||||
|
collectionView.refreshControl!.addTarget(self, action: #selector(refresh), for: .valueChanged)
|
||||||
|
#endif
|
||||||
|
|
||||||
dataSource = createDataSource()
|
dataSource = createDataSource()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,9 +139,10 @@ class ConversationCollectionViewController: UIViewController, CollectionViewCont
|
||||||
}
|
}
|
||||||
|
|
||||||
func addTree(_ tree: ConversationTree, mainStatus: StatusMO) {
|
func addTree(_ tree: ConversationTree, mainStatus: StatusMO) {
|
||||||
var snapshot = dataSource.snapshot()
|
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||||
snapshot.deleteItems([.loadingIndicator])
|
snapshot.appendSections([.ancestors, .mainStatus])
|
||||||
let mainStatusItem = Item.status(id: mainStatusID, node: tree.mainStatus, state: mainStatusState, prevLink: mainStatus.inReplyToID != nil, nextLink: false)
|
let mainStatusItem = Item.status(id: mainStatusID, node: tree.mainStatus, state: mainStatusState, prevLink: mainStatus.inReplyToID != nil, nextLink: false)
|
||||||
|
snapshot.appendItems([mainStatusItem], toSection: .mainStatus)
|
||||||
let parentItems = tree.ancestors.enumerated().map { index, node in
|
let parentItems = tree.ancestors.enumerated().map { index, node in
|
||||||
Item.status(id: node.status.id, node: node, state: .unknown, prevLink: index > 0, nextLink: true)
|
Item.status(id: node.status.id, node: node, state: .unknown, prevLink: index > 0, nextLink: true)
|
||||||
}
|
}
|
||||||
|
@ -240,6 +248,15 @@ class ConversationCollectionViewController: UIViewController, CollectionViewCont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func refresh() {
|
||||||
|
Task {
|
||||||
|
await conversationViewController.refreshContext()
|
||||||
|
#if !targetEnvironment(macCatalyst)
|
||||||
|
self.collectionView.refreshControl!.endRefreshing()
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ConversationCollectionViewController {
|
extension ConversationCollectionViewController {
|
||||||
|
|
|
@ -227,7 +227,7 @@ class ConversationViewController: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func mainStatusLoaded(_ mainStatus: StatusMO) {
|
private func mainStatusLoaded(_ mainStatus: StatusMO) {
|
||||||
let vc = ConversationCollectionViewController(for: mainStatus.id, state: mainStatusState, mastodonController: mastodonController)
|
let vc = ConversationCollectionViewController(for: mainStatus.id, state: mainStatusState, conversationViewController: self)
|
||||||
vc.statusIDToScrollToOnLoad = statusIDToScrollToOnLoad ?? mainStatus.id
|
vc.statusIDToScrollToOnLoad = statusIDToScrollToOnLoad ?? mainStatus.id
|
||||||
vc.showStatusesAutomatically = showStatusesAutomatically
|
vc.showStatusesAutomatically = showStatusesAutomatically
|
||||||
vc.addMainStatus(mainStatus)
|
vc.addMainStatus(mainStatus)
|
||||||
|
@ -290,6 +290,15 @@ class ConversationViewController: UIViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func refreshContext() async {
|
||||||
|
guard case .localID(let id) = mode,
|
||||||
|
let status = mastodonController.persistentContainer.status(for: id),
|
||||||
|
case .displaying(_) = state else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await loadTree(for: status)
|
||||||
|
}
|
||||||
|
|
||||||
private func showMainStatusNotFound() {
|
private func showMainStatusNotFound() {
|
||||||
let notFoundView = StatusNotFoundView(frame: .zero)
|
let notFoundView = StatusNotFoundView(frame: .zero)
|
||||||
notFoundView.translatesAutoresizingMaskIntoConstraints = false
|
notFoundView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
//
|
||||||
|
// ProfileNoContentCollectionViewCell.swift
|
||||||
|
// Tusker
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 2/22/23.
|
||||||
|
// Copyright © 2023 Shadowfacts. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class ProfileNoContentCollectionViewCell: UICollectionViewListCell {
|
||||||
|
|
||||||
|
weak var delegate: TuskerNavigationDelegate?
|
||||||
|
private var accountURL: URL?
|
||||||
|
|
||||||
|
private var button: UIButton!
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
let title = UILabel()
|
||||||
|
title.text = "There's nothing here"
|
||||||
|
title.adjustsFontForContentSizeCategory = true
|
||||||
|
title.font = .preferredFont(forTextStyle: .headline)
|
||||||
|
title.numberOfLines = 0
|
||||||
|
title.textAlignment = .center
|
||||||
|
title.textColor = .secondaryLabel
|
||||||
|
|
||||||
|
let body = UILabel()
|
||||||
|
body.text = "Your instance may not show all of the posts from accounts on other instances."
|
||||||
|
body.adjustsFontForContentSizeCategory = true
|
||||||
|
body.font = .preferredFont(forTextStyle: .body)
|
||||||
|
body.numberOfLines = 0
|
||||||
|
body.textAlignment = .center
|
||||||
|
body.textColor = .secondaryLabel
|
||||||
|
|
||||||
|
button = UIButton(configuration: .plain(), primaryAction: UIAction(handler: { [unowned self] _ in
|
||||||
|
if let delegate = self.delegate,
|
||||||
|
let accountURL = self.accountURL {
|
||||||
|
delegate.selected(url: accountURL)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
let stack = UIStackView(arrangedSubviews: [
|
||||||
|
title,
|
||||||
|
body,
|
||||||
|
button,
|
||||||
|
])
|
||||||
|
stack.axis = .vertical
|
||||||
|
stack.alignment = .center
|
||||||
|
stack.spacing = 4
|
||||||
|
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
contentView.addSubview(stack)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
stack.leadingAnchor.constraint(equalToSystemSpacingAfter: contentView.leadingAnchor, multiplier: 1),
|
||||||
|
contentView.trailingAnchor.constraint(equalToSystemSpacingAfter: stack.trailingAnchor, multiplier: 1),
|
||||||
|
stack.topAnchor.constraint(equalToSystemSpacingBelow: contentView.topAnchor, multiplier: 1),
|
||||||
|
contentView.bottomAnchor.constraint(equalToSystemSpacingBelow: stack.bottomAnchor, multiplier: 1),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUI(accountURL: URL) {
|
||||||
|
self.accountURL = accountURL
|
||||||
|
|
||||||
|
var title: AttributedString = "View on "
|
||||||
|
var host = AttributedString(accountURL.host!)
|
||||||
|
host.font = .preferredFont(forTextStyle: .body).withTraits(.traitBold)
|
||||||
|
title += host
|
||||||
|
|
||||||
|
var config = UIButton.Configuration.plain()
|
||||||
|
config.attributedTitle = title
|
||||||
|
config.image = UIImage(systemName: "safari")
|
||||||
|
config.imagePadding = 4
|
||||||
|
button.configuration = config
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -159,6 +159,10 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
|
||||||
}
|
}
|
||||||
let zeroHeightCell = UICollectionView.CellRegistration<ZeroHeightCollectionViewCell, Void> { _, _, _ in
|
let zeroHeightCell = UICollectionView.CellRegistration<ZeroHeightCollectionViewCell, Void> { _, _, _ in
|
||||||
}
|
}
|
||||||
|
let noContentCell = UICollectionView.CellRegistration<ProfileNoContentCollectionViewCell, URL> { [unowned self] cell, _, item in
|
||||||
|
cell.delegate = self
|
||||||
|
cell.updateUI(accountURL: item)
|
||||||
|
}
|
||||||
return UICollectionViewDiffableDataSource(collectionView: collectionView) { [unowned self] collectionView, indexPath, itemIdentifier in
|
return UICollectionViewDiffableDataSource(collectionView: collectionView) { [unowned self] collectionView, indexPath, itemIdentifier in
|
||||||
switch itemIdentifier {
|
switch itemIdentifier {
|
||||||
case .header(let id):
|
case .header(let id):
|
||||||
|
@ -197,6 +201,8 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
|
||||||
return loadingIndicatorCell(for: indexPath)
|
return loadingIndicatorCell(for: indexPath)
|
||||||
case .confirmLoadMore:
|
case .confirmLoadMore:
|
||||||
return confirmLoadMoreCell(for: indexPath)
|
return confirmLoadMoreCell(for: indexPath)
|
||||||
|
case .noContent(let accountURL):
|
||||||
|
return collectionView.dequeueConfiguredReusableCell(using: noContentCell, for: indexPath, item: accountURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +231,7 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
|
||||||
guard isViewLoaded,
|
guard isViewLoaded,
|
||||||
let accountID,
|
let accountID,
|
||||||
state == .unloaded,
|
state == .unloaded,
|
||||||
mastodonController.persistentContainer.account(for: accountID) != nil else {
|
let account = mastodonController.persistentContainer.account(for: accountID) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,6 +252,14 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
|
||||||
await controller.loadInitial()
|
await controller.loadInitial()
|
||||||
await tryLoadPinned()
|
await tryLoadPinned()
|
||||||
|
|
||||||
|
var newSnapshot = dataSource.snapshot()
|
||||||
|
if newSnapshot.numberOfItems(inSection: .pinned) == 0,
|
||||||
|
newSnapshot.numberOfItems(inSection: .statuses) == 0,
|
||||||
|
account.url.host != mastodonController.instanceURL.host {
|
||||||
|
newSnapshot.appendItems([.noContent(accountURL: account.url)], toSection: .pinned)
|
||||||
|
await apply(newSnapshot, animatingDifferences: true)
|
||||||
|
}
|
||||||
|
|
||||||
state = .loaded
|
state = .loaded
|
||||||
|
|
||||||
// remove any content inset that was added when switching pages to this VC
|
// remove any content inset that was added when switching pages to this VC
|
||||||
|
@ -410,6 +424,7 @@ extension ProfileStatusesViewController {
|
||||||
case status(id: String, collapseState: CollapseState, filterState: FilterState, pinned: Bool)
|
case status(id: String, collapseState: CollapseState, filterState: FilterState, pinned: Bool)
|
||||||
case loadingIndicator
|
case loadingIndicator
|
||||||
case confirmLoadMore
|
case confirmLoadMore
|
||||||
|
case noContent(accountURL: URL)
|
||||||
|
|
||||||
static func fromTimelineItem(_ item: String) -> Self {
|
static func fromTimelineItem(_ item: String) -> Self {
|
||||||
return .status(id: item, collapseState: .unknown, filterState: .unknown, pinned: false)
|
return .status(id: item, collapseState: .unknown, filterState: .unknown, pinned: false)
|
||||||
|
@ -425,6 +440,8 @@ extension ProfileStatusesViewController {
|
||||||
return true
|
return true
|
||||||
case (.confirmLoadMore, .confirmLoadMore):
|
case (.confirmLoadMore, .confirmLoadMore):
|
||||||
return true
|
return true
|
||||||
|
case (.noContent(let a), .noContent(let b)):
|
||||||
|
return a == b
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -443,12 +460,15 @@ extension ProfileStatusesViewController {
|
||||||
hasher.combine(2)
|
hasher.combine(2)
|
||||||
case .confirmLoadMore:
|
case .confirmLoadMore:
|
||||||
hasher.combine(3)
|
hasher.combine(3)
|
||||||
|
case .noContent(let accountURL):
|
||||||
|
hasher.combine(4)
|
||||||
|
hasher.combine(accountURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var hideSeparators: Bool {
|
var hideSeparators: Bool {
|
||||||
switch self {
|
switch self {
|
||||||
case .loadingIndicator, .confirmLoadMore:
|
case .loadingIndicator, .confirmLoadMore, .noContent(_):
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -17,8 +17,7 @@ class StatusActionAccountListCollectionViewController: UIViewController, Collect
|
||||||
private let actionType: StatusActionAccountListViewController.ActionType
|
private let actionType: StatusActionAccountListViewController.ActionType
|
||||||
private let mastodonController: MastodonController
|
private let mastodonController: MastodonController
|
||||||
|
|
||||||
/// If `true`, a warning will be shown below the account list describing that the total favs/reblogs may be innacurate.
|
private var needsInaccurateCountWarning = false
|
||||||
var showInacurateCountWarning = false
|
|
||||||
|
|
||||||
var collectionView: UICollectionView! {
|
var collectionView: UICollectionView! {
|
||||||
view as? UICollectionView
|
view as? UICollectionView
|
||||||
|
@ -64,7 +63,7 @@ class StatusActionAccountListCollectionViewController: UIViewController, Collect
|
||||||
switch dataSource.sectionIdentifier(for: sectionIndex)! {
|
switch dataSource.sectionIdentifier(for: sectionIndex)! {
|
||||||
case .status:
|
case .status:
|
||||||
var config = UICollectionLayoutListConfiguration(appearance: .grouped)
|
var config = UICollectionLayoutListConfiguration(appearance: .grouped)
|
||||||
config.footerMode = self.showInacurateCountWarning ? .supplementary : .none
|
config.footerMode = self.needsInaccurateCountWarning ? .supplementary : .none
|
||||||
config.backgroundColor = .appGroupedBackground
|
config.backgroundColor = .appGroupedBackground
|
||||||
config.leadingSwipeActionsConfigurationProvider = { [unowned self] in
|
config.leadingSwipeActionsConfigurationProvider = { [unowned self] in
|
||||||
(collectionView.cellForItem(at: $0) as? TimelineStatusCollectionViewCell)?.leadingSwipeActions()
|
(collectionView.cellForItem(at: $0) as? TimelineStatusCollectionViewCell)?.leadingSwipeActions()
|
||||||
|
@ -149,9 +148,11 @@ class StatusActionAccountListCollectionViewController: UIViewController, Collect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addStatus(_ status: StatusMO, state: CollapseState) {
|
func addStatus(_ status: StatusMO, state: CollapseState, showInaccurateCountWarning: Bool) {
|
||||||
loadViewIfNeeded()
|
loadViewIfNeeded()
|
||||||
|
|
||||||
|
needsInaccurateCountWarning = showInaccurateCountWarning && status.url?.host != mastodonController.instanceURL.host
|
||||||
|
|
||||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||||
snapshot.appendSections([.status, .accounts])
|
snapshot.appendSections([.status, .accounts])
|
||||||
snapshot.appendItems([.status(status.id, state)], toSection: .status)
|
snapshot.appendItems([.status(status.id, state)], toSection: .status)
|
||||||
|
|
|
@ -18,13 +18,7 @@ class StatusActionAccountListViewController: UIViewController {
|
||||||
private var accountIDs: [String]?
|
private var accountIDs: [String]?
|
||||||
|
|
||||||
/// If `true`, a warning will be shown below the account list describing that the total favs/reblogs may be innacurate.
|
/// If `true`, a warning will be shown below the account list describing that the total favs/reblogs may be innacurate.
|
||||||
var showInacurateCountWarning = false {
|
var showInaccurateCountWarning = false
|
||||||
didSet {
|
|
||||||
if case .displaying(let vc) = state {
|
|
||||||
vc.showInacurateCountWarning = showInacurateCountWarning
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var state: State = .unloaded {
|
private var state: State = .unloaded {
|
||||||
didSet {
|
didSet {
|
||||||
|
@ -147,8 +141,7 @@ class StatusActionAccountListViewController: UIViewController {
|
||||||
|
|
||||||
private func statusLoaded(_ status: StatusMO) async {
|
private func statusLoaded(_ status: StatusMO) async {
|
||||||
let vc = StatusActionAccountListCollectionViewController(statusID: statusID, actionType: actionType, mastodonController: mastodonController)
|
let vc = StatusActionAccountListCollectionViewController(statusID: statusID, actionType: actionType, mastodonController: mastodonController)
|
||||||
vc.addStatus(status, state: statusState)
|
vc.addStatus(status, state: statusState, showInaccurateCountWarning: showInaccurateCountWarning)
|
||||||
vc.showInacurateCountWarning = showInacurateCountWarning
|
|
||||||
if let accountIDs {
|
if let accountIDs {
|
||||||
vc.setAccounts(accountIDs, animated: false)
|
vc.setAccounts(accountIDs, animated: false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,7 +274,7 @@ extension ActionNotificationGroupTableViewCell: SelectableTableViewCell {
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
let vc = StatusActionAccountListViewController(actionType: action, statusID: statusID, statusState: .unknown, accountIDs: accountIDs, mastodonController: mastodonController)
|
let vc = StatusActionAccountListViewController(actionType: action, statusID: statusID, statusState: .unknown, accountIDs: accountIDs, mastodonController: mastodonController)
|
||||||
vc.showInacurateCountWarning = false
|
vc.showInaccurateCountWarning = false
|
||||||
delegate.show(vc)
|
delegate.show(vc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,7 +294,7 @@ extension ActionNotificationGroupTableViewCell: MenuPreviewProvider {
|
||||||
fatalError()
|
fatalError()
|
||||||
}
|
}
|
||||||
let vc = StatusActionAccountListViewController(actionType: action, statusID: self.statusID, statusState: .unknown, accountIDs: accountIDs, mastodonController: self.mastodonController)
|
let vc = StatusActionAccountListViewController(actionType: action, statusID: self.statusID, statusState: .unknown, accountIDs: accountIDs, mastodonController: self.mastodonController)
|
||||||
vc.showInacurateCountWarning = false
|
vc.showInaccurateCountWarning = false
|
||||||
return vc
|
return vc
|
||||||
}, actions: {
|
}, actions: {
|
||||||
return []
|
return []
|
||||||
|
|
|
@ -417,8 +417,7 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let vc = StatusActionAccountListViewController(actionType: .favorite, statusID: statusID, statusState: statusState.copy(), accountIDs: nil, mastodonController: mastodonController)
|
let vc = StatusActionAccountListViewController(actionType: .favorite, statusID: statusID, statusState: statusState.copy(), accountIDs: nil, mastodonController: mastodonController)
|
||||||
// TODO: only show warning if the instance isn't the logged in one
|
vc.showInaccurateCountWarning = true
|
||||||
vc.showInacurateCountWarning = true
|
|
||||||
delegate.show(vc)
|
delegate.show(vc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +426,7 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let vc = StatusActionAccountListViewController(actionType: .reblog, statusID: statusID, statusState: statusState.copy(), accountIDs: nil, mastodonController: mastodonController)
|
let vc = StatusActionAccountListViewController(actionType: .reblog, statusID: statusID, statusState: statusState.copy(), accountIDs: nil, mastodonController: mastodonController)
|
||||||
vc.showInacurateCountWarning = true
|
vc.showInaccurateCountWarning = true
|
||||||
delegate.show(vc)
|
delegate.show(vc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue