parent
2582907919
commit
8deb502140
|
@ -222,6 +222,7 @@
|
|||
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 */; };
|
||||
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 */; };
|
||||
D693A72A25CF8C1E003A14E2 /* ProfileDirectoryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D693A72925CF8C1E003A14E2 /* ProfileDirectoryViewController.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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -1096,6 +1098,7 @@
|
|||
D61DC84C28F500D200B82C6E /* ProfileViewController.swift */,
|
||||
D61ABEF728EFC3F900B29151 /* ProfileStatusesViewController.swift */,
|
||||
D61DC84A28F4FD2000B82C6E /* ProfileHeaderCollectionViewCell.swift */,
|
||||
D691771629A710520054D7EF /* ProfileNoContentCollectionViewCell.swift */,
|
||||
);
|
||||
path = Profile;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1969,6 +1972,7 @@
|
|||
0427033A22B31269000D31B6 /* AdvancedPrefsView.swift in Sources */,
|
||||
D6C3F4F5298ED0890009FCFF /* LocalPredicateStatusesViewController.swift in Sources */,
|
||||
D662AEEF263A3B880082A153 /* PollFinishedTableViewCell.swift in Sources */,
|
||||
D691771729A710520054D7EF /* ProfileNoContentCollectionViewCell.swift in Sources */,
|
||||
D626493C23C1000300612E6E /* AlbumTableViewCell.swift in Sources */,
|
||||
D62275A624F1C81800B82A16 /* ComposeReplyView.swift in Sources */,
|
||||
D60E2F292442372B005F8713 /* AccountMO.swift in Sources */,
|
||||
|
|
|
@ -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 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
|
||||
switch itemIdentifier {
|
||||
case .header(let id):
|
||||
|
@ -197,6 +201,8 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
|
|||
return loadingIndicatorCell(for: indexPath)
|
||||
case .confirmLoadMore:
|
||||
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,
|
||||
let accountID,
|
||||
state == .unloaded,
|
||||
mastodonController.persistentContainer.account(for: accountID) != nil else {
|
||||
let account = mastodonController.persistentContainer.account(for: accountID) else {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -246,6 +252,14 @@ class ProfileStatusesViewController: UIViewController, TimelineLikeCollectionVie
|
|||
await controller.loadInitial()
|
||||
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
|
||||
|
||||
// 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 loadingIndicator
|
||||
case confirmLoadMore
|
||||
case noContent(accountURL: URL)
|
||||
|
||||
static func fromTimelineItem(_ item: String) -> Self {
|
||||
return .status(id: item, collapseState: .unknown, filterState: .unknown, pinned: false)
|
||||
|
@ -425,6 +440,8 @@ extension ProfileStatusesViewController {
|
|||
return true
|
||||
case (.confirmLoadMore, .confirmLoadMore):
|
||||
return true
|
||||
case (.noContent(let a), .noContent(let b)):
|
||||
return a == b
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
@ -443,12 +460,15 @@ extension ProfileStatusesViewController {
|
|||
hasher.combine(2)
|
||||
case .confirmLoadMore:
|
||||
hasher.combine(3)
|
||||
case .noContent(let accountURL):
|
||||
hasher.combine(4)
|
||||
hasher.combine(accountURL)
|
||||
}
|
||||
}
|
||||
|
||||
var hideSeparators: Bool {
|
||||
switch self {
|
||||
case .loadingIndicator, .confirmLoadMore:
|
||||
case .loadingIndicator, .confirmLoadMore, .noContent(_):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
|
Loading…
Reference in New Issue