Copy condensed version of user-view to collection-view in search-history (IOS-141)
This commit is contained in:
parent
a7bab76f96
commit
ce37a8eb47
@ -300,7 +300,6 @@
|
|||||||
DB63F74F2799405600455B82 /* SearchHistoryViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F74E2799405600455B82 /* SearchHistoryViewModel+Diffable.swift */; };
|
DB63F74F2799405600455B82 /* SearchHistoryViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F74E2799405600455B82 /* SearchHistoryViewModel+Diffable.swift */; };
|
||||||
DB63F752279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */; };
|
DB63F752279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */; };
|
||||||
DB63F7542799491600455B82 /* DataSourceFacade+SearchHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F7532799491600455B82 /* DataSourceFacade+SearchHistory.swift */; };
|
DB63F7542799491600455B82 /* DataSourceFacade+SearchHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F7532799491600455B82 /* DataSourceFacade+SearchHistory.swift */; };
|
||||||
DB63F75A279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F759279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift */; };
|
|
||||||
DB63F76227996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F76127996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift */; };
|
DB63F76227996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F76127996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift */; };
|
||||||
DB63F764279A5E3C00455B82 /* NotificationTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F763279A5E3C00455B82 /* NotificationTimelineViewController.swift */; };
|
DB63F764279A5E3C00455B82 /* NotificationTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F763279A5E3C00455B82 /* NotificationTimelineViewController.swift */; };
|
||||||
DB63F767279A5EB300455B82 /* NotificationTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F766279A5EB300455B82 /* NotificationTimelineViewModel.swift */; };
|
DB63F767279A5EB300455B82 /* NotificationTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F766279A5EB300455B82 /* NotificationTimelineViewModel.swift */; };
|
||||||
@ -993,7 +992,6 @@
|
|||||||
DB63F74E2799405600455B82 /* SearchHistoryViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchHistoryViewModel+Diffable.swift"; sourceTree = "<group>"; };
|
DB63F74E2799405600455B82 /* SearchHistoryViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchHistoryViewModel+Diffable.swift"; sourceTree = "<group>"; };
|
||||||
DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchHistorySectionHeaderCollectionReusableView.swift; sourceTree = "<group>"; };
|
DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchHistorySectionHeaderCollectionReusableView.swift; sourceTree = "<group>"; };
|
||||||
DB63F7532799491600455B82 /* DataSourceFacade+SearchHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+SearchHistory.swift"; sourceTree = "<group>"; };
|
DB63F7532799491600455B82 /* DataSourceFacade+SearchHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+SearchHistory.swift"; sourceTree = "<group>"; };
|
||||||
DB63F759279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchHistoryUserCollectionViewCell+ViewModel.swift"; sourceTree = "<group>"; };
|
|
||||||
DB63F76127996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchHistoryViewController+DataSourceProvider.swift"; sourceTree = "<group>"; };
|
DB63F76127996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchHistoryViewController+DataSourceProvider.swift"; sourceTree = "<group>"; };
|
||||||
DB63F763279A5E3C00455B82 /* NotificationTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTimelineViewController.swift; sourceTree = "<group>"; };
|
DB63F763279A5E3C00455B82 /* NotificationTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTimelineViewController.swift; sourceTree = "<group>"; };
|
||||||
DB63F766279A5EB300455B82 /* NotificationTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTimelineViewModel.swift; sourceTree = "<group>"; };
|
DB63F766279A5EB300455B82 /* NotificationTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTimelineViewModel.swift; sourceTree = "<group>"; };
|
||||||
@ -2295,7 +2293,6 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
DB63F74C27993F5B00455B82 /* SearchHistoryUserCollectionViewCell.swift */,
|
DB63F74C27993F5B00455B82 /* SearchHistoryUserCollectionViewCell.swift */,
|
||||||
DB63F759279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift */,
|
|
||||||
DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */,
|
DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */,
|
||||||
);
|
);
|
||||||
path = Cell;
|
path = Cell;
|
||||||
@ -3560,7 +3557,6 @@
|
|||||||
DB0FCB7427956939006C02E2 /* DataSourceFacade+Status.swift in Sources */,
|
DB0FCB7427956939006C02E2 /* DataSourceFacade+Status.swift in Sources */,
|
||||||
D81A22782AB4782400905D71 /* SearchResultOverviewSection.swift in Sources */,
|
D81A22782AB4782400905D71 /* SearchResultOverviewSection.swift in Sources */,
|
||||||
DBB525502611ED6D002F1F29 /* ProfileHeaderView.swift in Sources */,
|
DBB525502611ED6D002F1F29 /* ProfileHeaderView.swift in Sources */,
|
||||||
DB63F75A279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift in Sources */,
|
|
||||||
DB023D26279FFB0A005AC798 /* ShareActivityProvider.swift in Sources */,
|
DB023D26279FFB0A005AC798 /* ShareActivityProvider.swift in Sources */,
|
||||||
5D0393962612D266007FE196 /* WebViewModel.swift in Sources */,
|
5D0393962612D266007FE196 /* WebViewModel.swift in Sources */,
|
||||||
5B24BBDA262DB14800A9381B /* ReportViewModel.swift in Sources */,
|
5B24BBDA262DB14800A9381B /* ReportViewModel.swift in Sources */,
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
//
|
|
||||||
// SearchHistoryUserCollectionViewCell+ViewModel.swift
|
|
||||||
// Mastodon
|
|
||||||
//
|
|
||||||
// Created by MainasuK on 2022-1-20.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import CoreDataStack
|
|
||||||
import MastodonUI
|
|
||||||
import Combine
|
|
||||||
|
|
||||||
extension SearchHistoryUserCollectionViewCell {
|
|
||||||
final class ViewModel {
|
|
||||||
let value: MastodonUser
|
|
||||||
|
|
||||||
let followedUsers: AnyPublisher<[String], Never>
|
|
||||||
let blockedUsers: AnyPublisher<[String], Never>
|
|
||||||
let followRequestedUsers: AnyPublisher<[String], Never>
|
|
||||||
|
|
||||||
init(value: MastodonUser, followedUsers: AnyPublisher<[String], Never>, blockedUsers: AnyPublisher<[String], Never>, followRequestedUsers: AnyPublisher<[String], Never>) {
|
|
||||||
self.value = value
|
|
||||||
self.followedUsers = followedUsers
|
|
||||||
self.followRequestedUsers = followRequestedUsers
|
|
||||||
self.blockedUsers = blockedUsers
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SearchHistoryUserCollectionViewCell {
|
|
||||||
func configure(
|
|
||||||
me: MastodonUser?,
|
|
||||||
viewModel: ViewModel,
|
|
||||||
delegate: SearchHistorySectionHeaderCollectionReusableViewDelegate?
|
|
||||||
) {
|
|
||||||
let user = viewModel.value
|
|
||||||
|
|
||||||
userView.configure(user: user, delegate: delegate)
|
|
||||||
|
|
||||||
guard let me = me else {
|
|
||||||
return userView.setButtonState(.none)
|
|
||||||
}
|
|
||||||
|
|
||||||
if user == me {
|
|
||||||
userView.setButtonState(.none)
|
|
||||||
} else {
|
|
||||||
userView.setButtonState(.loading)
|
|
||||||
}
|
|
||||||
|
|
||||||
Publishers.CombineLatest3(
|
|
||||||
viewModel.followedUsers,
|
|
||||||
viewModel.followRequestedUsers,
|
|
||||||
viewModel.blockedUsers
|
|
||||||
)
|
|
||||||
.receive(on: DispatchQueue.main)
|
|
||||||
.sink { [weak self] followed, requested, blocked in
|
|
||||||
if user == me {
|
|
||||||
self?.userView.setButtonState(.none)
|
|
||||||
} else if blocked.contains(user.id) {
|
|
||||||
self?.userView.setButtonState(.blocked)
|
|
||||||
} else if followed.contains(user.id) {
|
|
||||||
self?.userView.setButtonState(.unfollow)
|
|
||||||
} else if requested.contains(user.id) {
|
|
||||||
self?.userView.setButtonState(.pending)
|
|
||||||
} else if user.locked {
|
|
||||||
self?.userView.setButtonState(.request)
|
|
||||||
} else if user != me {
|
|
||||||
self?.userView.setButtonState(.follow)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.store(in: &_disposeBag)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,61 +1,171 @@
|
|||||||
//
|
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||||
// SearchHistoryUserCollectionViewCell.swift
|
|
||||||
// Mastodon
|
|
||||||
//
|
|
||||||
// Created by MainasuK on 2022-1-20.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import Combine
|
import MastodonSDK
|
||||||
import MastodonCore
|
|
||||||
import MastodonUI
|
import MastodonUI
|
||||||
|
import MetaTextKit
|
||||||
|
import MastodonLocalization
|
||||||
|
import MastodonMeta
|
||||||
|
import MastodonCore
|
||||||
|
import MastodonAsset
|
||||||
|
import CoreDataStack
|
||||||
|
|
||||||
final class SearchHistoryUserCollectionViewCell: UICollectionViewCell {
|
class SearchHistoryUserCollectionViewCell: UICollectionViewCell {
|
||||||
|
static let reuseIdentifier = "SearchHistoryUserCollectionViewCell"
|
||||||
|
|
||||||
var _disposeBag = Set<AnyCancellable>()
|
private static var metricFormatter = MastodonMetricFormatter()
|
||||||
|
|
||||||
let userView = UserView()
|
private let avatarImageWrapperView: UIView
|
||||||
|
let avatarImageView: AvatarImageView
|
||||||
|
|
||||||
|
private let metaInformationStackView: UIStackView
|
||||||
|
|
||||||
|
private let upperLineStackView: UIStackView
|
||||||
|
let displayNameLabel: MetaLabel
|
||||||
|
let acctLabel: UILabel
|
||||||
|
|
||||||
|
private let lowerLineStackView: UIStackView
|
||||||
|
let followersLabel: UILabel
|
||||||
|
let verifiedLinkImageView: UIImageView
|
||||||
|
let verifiedLinkLabel: MetaLabel
|
||||||
|
|
||||||
|
private let contentStackView: UIStackView
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
avatarImageView = AvatarImageView()
|
||||||
|
avatarImageView.cornerConfiguration = AvatarImageView.CornerConfiguration(corner: .fixed(radius: 8))
|
||||||
|
avatarImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
||||||
|
avatarImageWrapperView = UIView()
|
||||||
|
avatarImageWrapperView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
avatarImageWrapperView.addSubview(avatarImageView)
|
||||||
|
|
||||||
|
displayNameLabel = MetaLabel(style: .statusName)
|
||||||
|
displayNameLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||||
|
displayNameLabel.setContentHuggingPriority(.required, for: .horizontal)
|
||||||
|
|
||||||
|
acctLabel = UILabel()
|
||||||
|
acctLabel.textColor = .secondaryLabel
|
||||||
|
acctLabel.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular))
|
||||||
|
acctLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
|
||||||
|
|
||||||
|
upperLineStackView = UIStackView(arrangedSubviews: [displayNameLabel, acctLabel])
|
||||||
|
upperLineStackView.distribution = .fill
|
||||||
|
upperLineStackView.alignment = .center
|
||||||
|
|
||||||
|
followersLabel = UILabel()
|
||||||
|
followersLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
|
||||||
|
followersLabel.textColor = .secondaryLabel
|
||||||
|
followersLabel.setContentHuggingPriority(.required, for: .horizontal)
|
||||||
|
|
||||||
|
verifiedLinkImageView = UIImageView()
|
||||||
|
verifiedLinkImageView.setContentCompressionResistancePriority(.defaultHigh - 1, for: .vertical)
|
||||||
|
verifiedLinkImageView.setContentHuggingPriority(.required, for: .horizontal)
|
||||||
|
verifiedLinkImageView.contentMode = .scaleAspectFit
|
||||||
|
|
||||||
|
verifiedLinkLabel = MetaLabel(style: .profileFieldValue)
|
||||||
|
verifiedLinkLabel.setContentCompressionResistancePriority(.defaultHigh - 2, for: .horizontal)
|
||||||
|
verifiedLinkLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
verifiedLinkLabel.textAttributes = [
|
||||||
|
.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)),
|
||||||
|
.foregroundColor: UIColor.secondaryLabel
|
||||||
|
]
|
||||||
|
verifiedLinkLabel.linkAttributes = [
|
||||||
|
.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular)),
|
||||||
|
.foregroundColor: Asset.Colors.Brand.blurple.color
|
||||||
|
]
|
||||||
|
verifiedLinkLabel.isUserInteractionEnabled = false
|
||||||
|
|
||||||
|
lowerLineStackView = UIStackView(arrangedSubviews: [followersLabel, verifiedLinkImageView, verifiedLinkLabel])
|
||||||
|
lowerLineStackView.distribution = .fill
|
||||||
|
lowerLineStackView.alignment = .center
|
||||||
|
lowerLineStackView.spacing = 4
|
||||||
|
lowerLineStackView.setCustomSpacing(2, after: verifiedLinkImageView)
|
||||||
|
|
||||||
|
metaInformationStackView = UIStackView(arrangedSubviews: [upperLineStackView, lowerLineStackView])
|
||||||
|
metaInformationStackView.axis = .vertical
|
||||||
|
metaInformationStackView.alignment = .leading
|
||||||
|
|
||||||
|
contentStackView = UIStackView(arrangedSubviews: [avatarImageWrapperView, metaInformationStackView])
|
||||||
|
contentStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
contentStackView.axis = .horizontal
|
||||||
|
contentStackView.alignment = .center
|
||||||
|
contentStackView.spacing = 16
|
||||||
|
|
||||||
|
super.init(frame: .zero)
|
||||||
|
|
||||||
|
contentView.addSubview(contentStackView)
|
||||||
|
setupConstraints()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||||
|
|
||||||
|
private func setupConstraints() {
|
||||||
|
let constraints = [
|
||||||
|
contentStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
|
||||||
|
contentStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
|
||||||
|
contentView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor, constant: 16),
|
||||||
|
contentView.bottomAnchor.constraint(equalTo: contentStackView.bottomAnchor, constant: 8),
|
||||||
|
|
||||||
|
upperLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor),
|
||||||
|
lowerLineStackView.trailingAnchor.constraint(greaterThanOrEqualTo: metaInformationStackView.trailingAnchor),
|
||||||
|
metaInformationStackView.trailingAnchor.constraint(greaterThanOrEqualTo: contentStackView.trailingAnchor),
|
||||||
|
|
||||||
|
avatarImageView.widthAnchor.constraint(equalToConstant: 30),
|
||||||
|
avatarImageView.heightAnchor.constraint(equalTo: avatarImageView.widthAnchor),
|
||||||
|
avatarImageView.topAnchor.constraint(greaterThanOrEqualTo: avatarImageWrapperView.topAnchor),
|
||||||
|
avatarImageView.leadingAnchor.constraint(equalTo: avatarImageWrapperView.leadingAnchor),
|
||||||
|
avatarImageWrapperView.trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor),
|
||||||
|
avatarImageWrapperView.bottomAnchor.constraint(greaterThanOrEqualTo: avatarImageView.bottomAnchor),
|
||||||
|
avatarImageView.centerYAnchor.constraint(equalTo: avatarImageWrapperView.centerYAnchor),
|
||||||
|
]
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate(constraints)
|
||||||
|
}
|
||||||
|
|
||||||
override func prepareForReuse() {
|
override func prepareForReuse() {
|
||||||
super.prepareForReuse()
|
super.prepareForReuse()
|
||||||
|
|
||||||
userView.prepareForReuse()
|
avatarImageView.prepareForReuse()
|
||||||
}
|
}
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
func configure(with user: MastodonUser) {
|
||||||
super.init(frame: frame)
|
let displayNameMetaContent: MetaContent
|
||||||
_init()
|
do {
|
||||||
|
let content = MastodonContent(content: user.displayNameWithFallback, emojis: user.emojis.asDictionary)
|
||||||
|
displayNameMetaContent = try MastodonMetaContent.convert(document: content)
|
||||||
|
} catch {
|
||||||
|
displayNameMetaContent = PlaintextMetaContent(string: user.displayNameWithFallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
displayNameLabel.configure(content: displayNameMetaContent)
|
||||||
super.init(coder: coder)
|
acctLabel.text = user.acct
|
||||||
_init()
|
followersLabel.attributedText = NSAttributedString(
|
||||||
|
format: NSAttributedString(string: L10n.Common.UserList.followersCount("%@"), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .regular))]),
|
||||||
|
args: NSAttributedString(string: Self.metricFormatter.string(from: Int(user.followersCount)) ?? user.followersCount.formatted(), attributes: [.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 15, weight: .bold))])
|
||||||
|
)
|
||||||
|
|
||||||
|
avatarImageView.setImage(url: user.avatarImageURL())
|
||||||
|
|
||||||
|
if let verifiedLink = user.verifiedLink?.value {
|
||||||
|
verifiedLinkImageView.image = UIImage(systemName: "checkmark")
|
||||||
|
verifiedLinkImageView.tintColor = Asset.Colors.Brand.blurple.color
|
||||||
|
|
||||||
|
let verifiedLinkMetaContent: MetaContent
|
||||||
|
do {
|
||||||
|
let mastodonContent = MastodonContent(content: verifiedLink, emojis: [:])
|
||||||
|
verifiedLinkMetaContent = try MastodonMetaContent.convert(document: mastodonContent)
|
||||||
|
} catch {
|
||||||
|
verifiedLinkMetaContent = PlaintextMetaContent(string: verifiedLink)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verifiedLinkLabel.configure(content: verifiedLinkMetaContent)
|
||||||
|
} else {
|
||||||
|
verifiedLinkImageView.image = UIImage(systemName: "questionmark.circle")
|
||||||
|
verifiedLinkImageView.tintColor = .secondaryLabel
|
||||||
|
|
||||||
|
verifiedLinkLabel.configure(content: PlaintextMetaContent(string: L10n.Common.UserList.noVerifiedLink))
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SearchHistoryUserCollectionViewCell {
|
|
||||||
|
|
||||||
private func _init() {
|
|
||||||
ThemeService.shared.currentTheme
|
|
||||||
.map { $0.secondarySystemGroupedBackgroundColor }
|
|
||||||
.sink { [weak self] backgroundColor in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.backgroundColor = backgroundColor
|
|
||||||
self.setNeedsUpdateConfiguration()
|
|
||||||
}
|
|
||||||
.store(in: &_disposeBag)
|
|
||||||
|
|
||||||
userView.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
contentView.addSubview(userView)
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
userView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
|
||||||
userView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16),
|
|
||||||
contentView.trailingAnchor.constraint(equalTo: userView.trailingAnchor, constant: 16),
|
|
||||||
userView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
|
||||||
])
|
|
||||||
|
|
||||||
userView.accessibilityTraits.insert(.button)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func updateConfiguration(using state: UICellConfigurationState) {
|
override func updateConfiguration(using state: UICellConfigurationState) {
|
||||||
@ -65,10 +175,13 @@ extension SearchHistoryUserCollectionViewCell {
|
|||||||
backgroundConfiguration.backgroundColorTransformer = .init { _ in
|
backgroundConfiguration.backgroundColorTransformer = .init { _ in
|
||||||
if state.isHighlighted || state.isSelected {
|
if state.isHighlighted || state.isSelected {
|
||||||
return ThemeService.shared.currentTheme.value.tableViewCellSelectionBackgroundColor
|
return ThemeService.shared.currentTheme.value.tableViewCellSelectionBackgroundColor
|
||||||
}
|
} else {
|
||||||
return ThemeService.shared.currentTheme.value.secondarySystemGroupedBackgroundColor
|
return ThemeService.shared.currentTheme.value.secondarySystemGroupedBackgroundColor
|
||||||
}
|
}
|
||||||
self.backgroundConfiguration = backgroundConfiguration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.backgroundConfiguration = backgroundConfiguration
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -31,16 +31,7 @@ extension SearchHistorySection {
|
|||||||
let userCellRegister = UICollectionView.CellRegistration<SearchHistoryUserCollectionViewCell, ManagedObjectRecord<MastodonUser>> { cell, indexPath, item in
|
let userCellRegister = UICollectionView.CellRegistration<SearchHistoryUserCollectionViewCell, ManagedObjectRecord<MastodonUser>> { cell, indexPath, item in
|
||||||
context.managedObjectContext.performAndWait {
|
context.managedObjectContext.performAndWait {
|
||||||
guard let user = item.object(in: context.managedObjectContext) else { return }
|
guard let user = item.object(in: context.managedObjectContext) else { return }
|
||||||
cell.configure(
|
cell.configure(with: user)
|
||||||
me: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: context.managedObjectContext)?.user,
|
|
||||||
viewModel: SearchHistoryUserCollectionViewCell.ViewModel(
|
|
||||||
value: user,
|
|
||||||
followedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followingUserIds.eraseToAnyPublisher(),
|
|
||||||
blockedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$blockedUserIds.eraseToAnyPublisher(),
|
|
||||||
followRequestedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followRequestedUserIDs.eraseToAnyPublisher()
|
|
||||||
),
|
|
||||||
delegate: configuration.searchHistorySectionHeaderCollectionReusableViewDelegate
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,6 @@ import MastodonUI
|
|||||||
|
|
||||||
final class SearchHistoryViewController: UIViewController, NeedsDependency {
|
final class SearchHistoryViewController: UIViewController, NeedsDependency {
|
||||||
|
|
||||||
let logger = Logger(subsystem: "SearchHistoryViewController", category: "ViewController")
|
|
||||||
|
|
||||||
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
||||||
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ extension SearchResultSection {
|
|||||||
return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in
|
return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in
|
||||||
switch item {
|
switch item {
|
||||||
case .user(let record):
|
case .user(let record):
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: UserTableViewCell.self), for: indexPath) as! UserTableViewCell
|
let cell = tableView.dequeueReusableCell(withIdentifier: UserTableViewCell.reuseIdentifier, for: indexPath) as! UserTableViewCell
|
||||||
context.managedObjectContext.performAndWait {
|
context.managedObjectContext.performAndWait {
|
||||||
guard let user = record.object(in: context.managedObjectContext) else { return }
|
guard let user = record.object(in: context.managedObjectContext) else { return }
|
||||||
configure(
|
configure(
|
||||||
|
@ -548,3 +548,10 @@ extension MastodonUser: AutoUpdatableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension MastodonUser {
|
||||||
|
public var verifiedLink: MastodonField? {
|
||||||
|
let firstVerified = fields.first(where: { $0.verifiedAt != nil })
|
||||||
|
return firstVerified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
// Created by MainasuK Cirno on 2021-7-21.
|
// Created by MainasuK Cirno on 2021-7-21.
|
||||||
//
|
//
|
||||||
|
|
||||||
import os.log
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import MastodonLocalization
|
import MastodonLocalization
|
||||||
|
|
||||||
@ -117,26 +116,3 @@ extension AvatarButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if canImport(SwiftUI) && DEBUG
|
|
||||||
import SwiftUI
|
|
||||||
|
|
||||||
struct AvatarButton_Previews: PreviewProvider {
|
|
||||||
|
|
||||||
static var previews: some View {
|
|
||||||
UIViewPreview(width: 42) {
|
|
||||||
let avatarButton = AvatarButton()
|
|
||||||
avatarButton.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
avatarButton.widthAnchor.constraint(equalToConstant: 42),
|
|
||||||
avatarButton.heightAnchor.constraint(equalToConstant: 42),
|
|
||||||
])
|
|
||||||
return avatarButton
|
|
||||||
}
|
|
||||||
.previewLayout(.fixed(width: 42, height: 42))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user