mirror of
https://github.com/mastodon/mastodon-ios.git
synced 2025-02-03 10:47:35 +01:00
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 */; };
|
||||
DB63F752279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.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 */; };
|
||||
DB63F764279A5E3C00455B82 /* NotificationTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F763279A5E3C00455B82 /* NotificationTimelineViewController.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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@ -2295,7 +2293,6 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DB63F74C27993F5B00455B82 /* SearchHistoryUserCollectionViewCell.swift */,
|
||||
DB63F759279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift */,
|
||||
DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */,
|
||||
);
|
||||
path = Cell;
|
||||
@ -3560,7 +3557,6 @@
|
||||
DB0FCB7427956939006C02E2 /* DataSourceFacade+Status.swift in Sources */,
|
||||
D81A22782AB4782400905D71 /* SearchResultOverviewSection.swift in Sources */,
|
||||
DBB525502611ED6D002F1F29 /* ProfileHeaderView.swift in Sources */,
|
||||
DB63F75A279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift in Sources */,
|
||||
DB023D26279FFB0A005AC798 /* ShareActivityProvider.swift in Sources */,
|
||||
5D0393962612D266007FE196 /* WebViewModel.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,74 +1,187 @@
|
||||
//
|
||||
// SearchHistoryUserCollectionViewCell.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by MainasuK on 2022-1-20.
|
||||
//
|
||||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
import MastodonCore
|
||||
import MastodonSDK
|
||||
import MastodonUI
|
||||
import MetaTextKit
|
||||
import MastodonLocalization
|
||||
import MastodonMeta
|
||||
import MastodonCore
|
||||
import MastodonAsset
|
||||
import CoreDataStack
|
||||
|
||||
class SearchHistoryUserCollectionViewCell: UICollectionViewCell {
|
||||
static let reuseIdentifier = "SearchHistoryUserCollectionViewCell"
|
||||
|
||||
private static var metricFormatter = MastodonMetricFormatter()
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
final class SearchHistoryUserCollectionViewCell: UICollectionViewCell {
|
||||
|
||||
var _disposeBag = Set<AnyCancellable>()
|
||||
|
||||
let userView = UserView()
|
||||
|
||||
override func prepareForReuse() {
|
||||
super.prepareForReuse()
|
||||
|
||||
userView.prepareForReuse()
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
_init()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
_init()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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()
|
||||
avatarImageView.prepareForReuse()
|
||||
}
|
||||
|
||||
func configure(with user: MastodonUser) {
|
||||
let displayNameMetaContent: MetaContent
|
||||
do {
|
||||
let content = MastodonContent(content: user.displayNameWithFallback, emojis: user.emojis.asDictionary)
|
||||
displayNameMetaContent = try MastodonMetaContent.convert(document: content)
|
||||
} catch {
|
||||
displayNameMetaContent = PlaintextMetaContent(string: user.displayNameWithFallback)
|
||||
}
|
||||
|
||||
displayNameLabel.configure(content: displayNameMetaContent)
|
||||
acctLabel.text = user.acct
|
||||
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)
|
||||
}
|
||||
.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)
|
||||
verifiedLinkLabel.configure(content: verifiedLinkMetaContent)
|
||||
} else {
|
||||
verifiedLinkImageView.image = UIImage(systemName: "questionmark.circle")
|
||||
verifiedLinkImageView.tintColor = .secondaryLabel
|
||||
|
||||
verifiedLinkLabel.configure(content: PlaintextMetaContent(string: L10n.Common.UserList.noVerifiedLink))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override func updateConfiguration(using state: UICellConfigurationState) {
|
||||
super.updateConfiguration(using: state)
|
||||
|
||||
|
||||
var backgroundConfiguration = UIBackgroundConfiguration.listGroupedCell()
|
||||
backgroundConfiguration.backgroundColorTransformer = .init { _ in
|
||||
if state.isHighlighted || state.isSelected {
|
||||
return ThemeService.shared.currentTheme.value.tableViewCellSelectionBackgroundColor
|
||||
} else {
|
||||
return ThemeService.shared.currentTheme.value.secondarySystemGroupedBackgroundColor
|
||||
}
|
||||
return ThemeService.shared.currentTheme.value.secondarySystemGroupedBackgroundColor
|
||||
}
|
||||
|
||||
self.backgroundConfiguration = backgroundConfiguration
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -31,16 +31,7 @@ extension SearchHistorySection {
|
||||
let userCellRegister = UICollectionView.CellRegistration<SearchHistoryUserCollectionViewCell, ManagedObjectRecord<MastodonUser>> { cell, indexPath, item in
|
||||
context.managedObjectContext.performAndWait {
|
||||
guard let user = item.object(in: context.managedObjectContext) else { return }
|
||||
cell.configure(
|
||||
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
|
||||
)
|
||||
cell.configure(with: user)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,6 @@ import MastodonUI
|
||||
|
||||
final class SearchHistoryViewController: UIViewController, NeedsDependency {
|
||||
|
||||
let logger = Logger(subsystem: "SearchHistoryViewController", category: "ViewController")
|
||||
|
||||
weak var context: AppContext! { 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
|
||||
switch item {
|
||||
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 {
|
||||
guard let user = record.object(in: context.managedObjectContext) else { return }
|
||||
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.
|
||||
//
|
||||
|
||||
import os.log
|
||||
import UIKit
|
||||
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