Working pretty well
This commit is contained in:
parent
595b46e96e
commit
f8d1afc7e4
|
@ -9,17 +9,17 @@
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="Card" representedClassName="CoreDataStack.Card" syncable="YES">
|
<entity name="Card" representedClassName="CoreDataStack.Card" syncable="YES">
|
||||||
<attribute name="authorName" optional="YES" attributeType="String"/>
|
<attribute name="authorName" optional="YES" attributeType="String"/>
|
||||||
<attribute name="authorURL" optional="YES" attributeType="String"/>
|
<attribute name="authorURLRaw" optional="YES" attributeType="String"/>
|
||||||
<attribute name="blurhash" optional="YES" attributeType="String"/>
|
<attribute name="blurhash" optional="YES" attributeType="String"/>
|
||||||
<attribute name="desc" attributeType="String"/>
|
<attribute name="desc" attributeType="String"/>
|
||||||
<attribute name="embedURL" optional="YES" attributeType="String"/>
|
<attribute name="embedURLRaw" optional="YES" attributeType="String"/>
|
||||||
<attribute name="height" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
<attribute name="height" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
<attribute name="image" optional="YES" attributeType="String"/>
|
<attribute name="image" optional="YES" attributeType="String"/>
|
||||||
<attribute name="providerName" optional="YES" attributeType="String"/>
|
<attribute name="providerName" optional="YES" attributeType="String"/>
|
||||||
<attribute name="providerURL" optional="YES" attributeType="String"/>
|
<attribute name="providerURLRaw" optional="YES" attributeType="String"/>
|
||||||
<attribute name="title" attributeType="String"/>
|
<attribute name="title" attributeType="String"/>
|
||||||
<attribute name="typeRaw" attributeType="String"/>
|
<attribute name="typeRaw" attributeType="String"/>
|
||||||
<attribute name="url" attributeType="String"/>
|
<attribute name="urlRaw" attributeType="String"/>
|
||||||
<attribute name="width" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
<attribute name="width" optional="YES" attributeType="Integer 64" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
<relationship name="status" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Status" inverseName="card" inverseEntity="Status"/>
|
<relationship name="status" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Status" inverseName="card" inverseEntity="Status"/>
|
||||||
</entity>
|
</entity>
|
||||||
|
|
|
@ -10,7 +10,11 @@ import CoreData
|
||||||
|
|
||||||
public final class Card: NSManagedObject {
|
public final class Card: NSManagedObject {
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var url: String
|
@NSManaged public private(set) var urlRaw: String
|
||||||
|
public var url: URL? {
|
||||||
|
URL(string: urlRaw)
|
||||||
|
}
|
||||||
|
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var title: String
|
@NSManaged public private(set) var title: String
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
|
@ -26,19 +30,23 @@ public final class Card: NSManagedObject {
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var authorName: String?
|
@NSManaged public private(set) var authorName: String?
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var authorURL: String?
|
@NSManaged public private(set) var authorURLRaw: String?
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var providerName: String?
|
@NSManaged public private(set) var providerName: String?
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var providerURL: String?
|
@NSManaged public private(set) var providerURLRaw: String?
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var width: Int64
|
@NSManaged public private(set) var width: Int64
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var height: Int64
|
@NSManaged public private(set) var height: Int64
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var image: String?
|
@NSManaged public private(set) var image: String?
|
||||||
|
public var imageURL: URL? {
|
||||||
|
image.flatMap(URL.init)
|
||||||
|
}
|
||||||
|
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var embedURL: String?
|
@NSManaged public private(set) var embedURLRaw: String?
|
||||||
// sourcery: autoGenerateProperty
|
// sourcery: autoGenerateProperty
|
||||||
@NSManaged public private(set) var blurhash: String?
|
@NSManaged public private(set) var blurhash: String?
|
||||||
|
|
||||||
|
@ -75,64 +83,64 @@ extension Card: AutoGenerateProperty {
|
||||||
// Generated using Sourcery
|
// Generated using Sourcery
|
||||||
// DO NOT EDIT
|
// DO NOT EDIT
|
||||||
public struct Property {
|
public struct Property {
|
||||||
public let url: String
|
public let urlRaw: String
|
||||||
public let title: String
|
public let title: String
|
||||||
public let desc: String
|
public let desc: String
|
||||||
public let type: MastodonCardType
|
public let type: MastodonCardType
|
||||||
public let authorName: String?
|
public let authorName: String?
|
||||||
public let authorURL: String?
|
public let authorURLRaw: String?
|
||||||
public let providerName: String?
|
public let providerName: String?
|
||||||
public let providerURL: String?
|
public let providerURLRaw: String?
|
||||||
public let width: Int64
|
public let width: Int64
|
||||||
public let height: Int64
|
public let height: Int64
|
||||||
public let image: String?
|
public let image: String?
|
||||||
public let embedURL: String?
|
public let embedURLRaw: String?
|
||||||
public let blurhash: String?
|
public let blurhash: String?
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
url: String,
|
urlRaw: String,
|
||||||
title: String,
|
title: String,
|
||||||
desc: String,
|
desc: String,
|
||||||
type: MastodonCardType,
|
type: MastodonCardType,
|
||||||
authorName: String?,
|
authorName: String?,
|
||||||
authorURL: String?,
|
authorURLRaw: String?,
|
||||||
providerName: String?,
|
providerName: String?,
|
||||||
providerURL: String?,
|
providerURLRaw: String?,
|
||||||
width: Int64,
|
width: Int64,
|
||||||
height: Int64,
|
height: Int64,
|
||||||
image: String?,
|
image: String?,
|
||||||
embedURL: String?,
|
embedURLRaw: String?,
|
||||||
blurhash: String?
|
blurhash: String?
|
||||||
) {
|
) {
|
||||||
self.url = url
|
self.urlRaw = urlRaw
|
||||||
self.title = title
|
self.title = title
|
||||||
self.desc = desc
|
self.desc = desc
|
||||||
self.type = type
|
self.type = type
|
||||||
self.authorName = authorName
|
self.authorName = authorName
|
||||||
self.authorURL = authorURL
|
self.authorURLRaw = authorURLRaw
|
||||||
self.providerName = providerName
|
self.providerName = providerName
|
||||||
self.providerURL = providerURL
|
self.providerURLRaw = providerURLRaw
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self.image = image
|
self.image = image
|
||||||
self.embedURL = embedURL
|
self.embedURLRaw = embedURLRaw
|
||||||
self.blurhash = blurhash
|
self.blurhash = blurhash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func configure(property: Property) {
|
public func configure(property: Property) {
|
||||||
self.url = property.url
|
self.urlRaw = property.urlRaw
|
||||||
self.title = property.title
|
self.title = property.title
|
||||||
self.desc = property.desc
|
self.desc = property.desc
|
||||||
self.type = property.type
|
self.type = property.type
|
||||||
self.authorName = property.authorName
|
self.authorName = property.authorName
|
||||||
self.authorURL = property.authorURL
|
self.authorURLRaw = property.authorURLRaw
|
||||||
self.providerName = property.providerName
|
self.providerName = property.providerName
|
||||||
self.providerURL = property.providerURL
|
self.providerURLRaw = property.providerURLRaw
|
||||||
self.width = property.width
|
self.width = property.width
|
||||||
self.height = property.height
|
self.height = property.height
|
||||||
self.image = property.image
|
self.image = property.image
|
||||||
self.embedURL = property.embedURL
|
self.embedURLRaw = property.embedURLRaw
|
||||||
self.blurhash = property.blurhash
|
self.blurhash = property.blurhash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,18 +65,18 @@ extension Persistence.Card {
|
||||||
}
|
}
|
||||||
|
|
||||||
let property = Card.Property(
|
let property = Card.Property(
|
||||||
url: context.entity.url,
|
urlRaw: context.entity.url,
|
||||||
title: context.entity.title,
|
title: context.entity.title,
|
||||||
desc: context.entity.description,
|
desc: context.entity.description,
|
||||||
type: type,
|
type: type,
|
||||||
authorName: context.entity.authorName,
|
authorName: context.entity.authorName,
|
||||||
authorURL: context.entity.authorURL,
|
authorURLRaw: context.entity.authorURL,
|
||||||
providerName: context.entity.providerName,
|
providerName: context.entity.providerName,
|
||||||
providerURL: context.entity.providerURL,
|
providerURLRaw: context.entity.providerURL,
|
||||||
width: Int64(context.entity.width ?? 0),
|
width: Int64(context.entity.width ?? 0),
|
||||||
height: Int64(context.entity.height ?? 0),
|
height: Int64(context.entity.height ?? 0),
|
||||||
image: context.entity.image,
|
image: context.entity.image,
|
||||||
embedURL: context.entity.embedURL,
|
embedURLRaw: context.entity.embedURL,
|
||||||
blurhash: context.entity.blurhash
|
blurhash: context.entity.blurhash
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -9,18 +9,26 @@ import AlamofireImage
|
||||||
import LinkPresentation
|
import LinkPresentation
|
||||||
import MastodonAsset
|
import MastodonAsset
|
||||||
import MastodonCore
|
import MastodonCore
|
||||||
|
import CoreDataStack
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
public final class LinkPreviewButton: UIControl {
|
public final class LinkPreviewButton: UIControl {
|
||||||
private var linkPresentationTask: Task<Void, Error>?
|
|
||||||
private var url: URL?
|
|
||||||
|
|
||||||
private let containerStackView = UIStackView()
|
private let containerStackView = UIStackView()
|
||||||
private let labelStackView = UIStackView()
|
private let labelStackView = UIStackView()
|
||||||
|
|
||||||
private let imageView = UIImageView()
|
private let imageView = UIImageView()
|
||||||
private let titleLabel = UILabel()
|
private let titleLabel = UILabel()
|
||||||
private let subtitleLabel = UILabel()
|
private let linkLabel = UILabel()
|
||||||
|
|
||||||
|
private lazy var compactImageConstraints = [
|
||||||
|
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor),
|
||||||
|
imageView.heightAnchor.constraint(equalTo: heightAnchor),
|
||||||
|
containerStackView.heightAnchor.constraint(equalToConstant: 85),
|
||||||
|
]
|
||||||
|
|
||||||
|
private lazy var largeImageConstraints = [
|
||||||
|
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: 21 / 40),
|
||||||
|
]
|
||||||
|
|
||||||
public override init(frame: CGRect) {
|
public override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
@ -29,25 +37,24 @@ public final class LinkPreviewButton: UIControl {
|
||||||
layer.cornerCurve = .continuous
|
layer.cornerCurve = .continuous
|
||||||
layer.cornerRadius = 10
|
layer.cornerRadius = 10
|
||||||
layer.borderColor = ThemeService.shared.currentTheme.value.separator.cgColor
|
layer.borderColor = ThemeService.shared.currentTheme.value.separator.cgColor
|
||||||
backgroundColor = ThemeService.shared.currentTheme.value.systemElevatedBackgroundColor
|
|
||||||
|
|
||||||
titleLabel.numberOfLines = 2
|
titleLabel.numberOfLines = 2
|
||||||
titleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal)
|
titleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal)
|
||||||
titleLabel.text = "This is where I'd put a title... if I had one"
|
titleLabel.text = "This is where I'd put a title... if I had one"
|
||||||
titleLabel.textColor = Asset.Colors.Label.primary.color
|
titleLabel.textColor = Asset.Colors.Label.primary.color
|
||||||
|
|
||||||
subtitleLabel.text = "Subtitle"
|
linkLabel.text = "Subtitle"
|
||||||
subtitleLabel.numberOfLines = 1
|
linkLabel.numberOfLines = 1
|
||||||
subtitleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal)
|
linkLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal)
|
||||||
subtitleLabel.textColor = Asset.Colors.Label.secondary.color
|
linkLabel.textColor = Asset.Colors.Label.secondary.color
|
||||||
subtitleLabel.font = UIFontMetrics(forTextStyle: .subheadline).scaledFont(for: .systemFont(ofSize: 15, weight: .regular), maximumPointSize: 20)
|
|
||||||
|
|
||||||
imageView.backgroundColor = UIColor.black.withAlphaComponent(0.15)
|
imageView.tintColor = Asset.Colors.Label.secondary.color
|
||||||
|
imageView.backgroundColor = ThemeService.shared.currentTheme.value.systemElevatedBackgroundColor
|
||||||
imageView.contentMode = .scaleAspectFill
|
imageView.contentMode = .scaleAspectFill
|
||||||
imageView.clipsToBounds = true
|
imageView.clipsToBounds = true
|
||||||
|
|
||||||
|
labelStackView.addArrangedSubview(linkLabel)
|
||||||
labelStackView.addArrangedSubview(titleLabel)
|
labelStackView.addArrangedSubview(titleLabel)
|
||||||
labelStackView.addArrangedSubview(subtitleLabel)
|
|
||||||
labelStackView.layoutMargins = .init(top: 8, left: 10, bottom: 8, right: 10)
|
labelStackView.layoutMargins = .init(top: 8, left: 10, bottom: 8, right: 10)
|
||||||
labelStackView.isLayoutMarginsRelativeArrangement = true
|
labelStackView.isLayoutMarginsRelativeArrangement = true
|
||||||
labelStackView.axis = .vertical
|
labelStackView.axis = .vertical
|
||||||
|
@ -55,20 +62,16 @@ public final class LinkPreviewButton: UIControl {
|
||||||
containerStackView.addArrangedSubview(imageView)
|
containerStackView.addArrangedSubview(imageView)
|
||||||
containerStackView.addArrangedSubview(labelStackView)
|
containerStackView.addArrangedSubview(labelStackView)
|
||||||
containerStackView.distribution = .fill
|
containerStackView.distribution = .fill
|
||||||
containerStackView.alignment = .center
|
|
||||||
|
|
||||||
addSubview(containerStackView)
|
addSubview(containerStackView)
|
||||||
|
|
||||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
containerStackView.heightAnchor.constraint(equalToConstant: 85),
|
|
||||||
containerStackView.topAnchor.constraint(equalTo: topAnchor),
|
containerStackView.topAnchor.constraint(equalTo: topAnchor),
|
||||||
containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||||
containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||||
containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||||
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor),
|
|
||||||
imageView.heightAnchor.constraint(equalTo: heightAnchor),
|
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,36 +79,32 @@ public final class LinkPreviewButton: UIControl {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func configure(url: URL, trimmed: String) {
|
public func configure(card: Card) {
|
||||||
guard url != self.url else {
|
let isCompact = card.width == card.height
|
||||||
return
|
|
||||||
|
titleLabel.text = card.title
|
||||||
|
linkLabel.text = card.url?.host
|
||||||
|
imageView.contentMode = .center
|
||||||
|
|
||||||
|
imageView.sd_setImage(
|
||||||
|
with: card.imageURL,
|
||||||
|
placeholderImage: isCompact ? newsIcon : photoIcon
|
||||||
|
) { [weak imageView] image, _, _, _ in
|
||||||
|
if image != nil {
|
||||||
|
imageView?.contentMode = .scaleAspectFill
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reset()
|
NSLayoutConstraint.deactivate(compactImageConstraints + largeImageConstraints)
|
||||||
subtitleLabel.text = trimmed
|
|
||||||
self.url = url
|
|
||||||
|
|
||||||
linkPresentationTask = Task {
|
if isCompact {
|
||||||
do {
|
containerStackView.alignment = .center
|
||||||
let metadata = try await LPMetadataProvider().startFetchingMetadata(for: url)
|
containerStackView.axis = .horizontal
|
||||||
|
NSLayoutConstraint.activate(compactImageConstraints)
|
||||||
guard !Task.isCancelled else {
|
} else {
|
||||||
return
|
containerStackView.alignment = .fill
|
||||||
}
|
containerStackView.axis = .vertical
|
||||||
|
NSLayoutConstraint.activate(largeImageConstraints)
|
||||||
self.titleLabel.text = metadata.title
|
|
||||||
if let result = try await metadata.imageProvider?.loadImageData() {
|
|
||||||
let image = UIImage(data: result.data)
|
|
||||||
|
|
||||||
guard !Task.isCancelled else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.imageView.image = image
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
self.subtitleLabel.text = "Error loading link preview"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,11 +116,12 @@ public final class LinkPreviewButton: UIControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func reset() {
|
private var newsIcon: UIImage? {
|
||||||
linkPresentationTask?.cancel()
|
UIImage(systemName: "newspaper.fill")
|
||||||
url = nil
|
}
|
||||||
imageView.image = nil
|
|
||||||
titleLabel.text = nil
|
private var photoIcon: UIImage? {
|
||||||
subtitleLabel.text = nil
|
let configuration = UIImage.SymbolConfiguration(pointSize: 40)
|
||||||
|
return UIImage(systemName: "photo", withConfiguration: configuration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,14 @@ extension StatusView {
|
||||||
|
|
||||||
extension StatusView {
|
extension StatusView {
|
||||||
public func configure(status: Status) {
|
public func configure(status: Status) {
|
||||||
|
if let card = status.card {
|
||||||
|
print("---- \(card.title)")
|
||||||
|
print("---- \(card.url)")
|
||||||
|
print("---- \(card.image)")
|
||||||
|
print("---- \(card.width)")
|
||||||
|
print("---- \(card.height)")
|
||||||
|
}
|
||||||
|
|
||||||
viewModel.objects.insert(status)
|
viewModel.objects.insert(status)
|
||||||
if let reblog = status.reblog {
|
if let reblog = status.reblog {
|
||||||
viewModel.objects.insert(reblog)
|
viewModel.objects.insert(reblog)
|
||||||
|
@ -53,6 +61,7 @@ extension StatusView {
|
||||||
configureContent(status: status)
|
configureContent(status: status)
|
||||||
configureMedia(status: status)
|
configureMedia(status: status)
|
||||||
configurePoll(status: status)
|
configurePoll(status: status)
|
||||||
|
configureCard(status: status)
|
||||||
configureToolbar(status: status)
|
configureToolbar(status: status)
|
||||||
configureFilter(status: status)
|
configureFilter(status: status)
|
||||||
}
|
}
|
||||||
|
@ -349,6 +358,17 @@ extension StatusView {
|
||||||
.assign(to: \.isVoting, on: viewModel)
|
.assign(to: \.isVoting, on: viewModel)
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func configureCard(status: Status) {
|
||||||
|
let status = status.reblog ?? status
|
||||||
|
if viewModel.mediaViewConfigurations.isEmpty {
|
||||||
|
status.publisher(for: \.card)
|
||||||
|
.assign(to: \.card, on: viewModel)
|
||||||
|
.store(in: &disposeBag)
|
||||||
|
} else {
|
||||||
|
viewModel.card = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func configureToolbar(status: Status) {
|
private func configureToolbar(status: Status) {
|
||||||
let status = status.reblog ?? status
|
let status = status.reblog ?? status
|
||||||
|
|
|
@ -69,7 +69,10 @@ extension StatusView {
|
||||||
@Published public var voteCount = 0
|
@Published public var voteCount = 0
|
||||||
@Published public var expireAt: Date?
|
@Published public var expireAt: Date?
|
||||||
@Published public var expired: Bool = false
|
@Published public var expired: Bool = false
|
||||||
|
|
||||||
|
// Card
|
||||||
|
@Published public var card: Card?
|
||||||
|
|
||||||
// Visibility
|
// Visibility
|
||||||
@Published public var visibility: MastodonVisibility = .public
|
@Published public var visibility: MastodonVisibility = .public
|
||||||
|
|
||||||
|
@ -185,6 +188,7 @@ extension StatusView.ViewModel {
|
||||||
bindContent(statusView: statusView)
|
bindContent(statusView: statusView)
|
||||||
bindMedia(statusView: statusView)
|
bindMedia(statusView: statusView)
|
||||||
bindPoll(statusView: statusView)
|
bindPoll(statusView: statusView)
|
||||||
|
bindCard(statusView: statusView)
|
||||||
bindToolbar(statusView: statusView)
|
bindToolbar(statusView: statusView)
|
||||||
bindMetric(statusView: statusView)
|
bindMetric(statusView: statusView)
|
||||||
bindMenu(statusView: statusView)
|
bindMenu(statusView: statusView)
|
||||||
|
@ -306,21 +310,6 @@ extension StatusView.ViewModel {
|
||||||
statusView.contentMetaText.textView.accessibilityTraits = [.staticText]
|
statusView.contentMetaText.textView.accessibilityTraits = [.staticText]
|
||||||
statusView.contentMetaText.textView.accessibilityElementsHidden = false
|
statusView.contentMetaText.textView.accessibilityElementsHidden = false
|
||||||
|
|
||||||
if let url = content.entities.first(where: {
|
|
||||||
switch $0.meta {
|
|
||||||
case .url:
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
guard case .url(let text, let trimmed, let url, _) = url.meta, let url = URL(string: url) else {
|
|
||||||
fatalError()
|
|
||||||
}
|
|
||||||
|
|
||||||
statusView.linkPreviewButton.configure(url: url, trimmed: trimmed)
|
|
||||||
statusView.setLinkPreviewButtonDisplay()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
statusView.contentMetaText.reset()
|
statusView.contentMetaText.reset()
|
||||||
statusView.contentMetaText.textView.accessibilityLabel = ""
|
statusView.contentMetaText.textView.accessibilityLabel = ""
|
||||||
|
@ -496,6 +485,15 @@ extension StatusView.ViewModel {
|
||||||
.assign(to: \.isEnabled, on: statusView.pollVoteButton)
|
.assign(to: \.isEnabled, on: statusView.pollVoteButton)
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func bindCard(statusView: StatusView) {
|
||||||
|
$card.sink { card in
|
||||||
|
guard let card = card else { return }
|
||||||
|
statusView.linkPreviewButton.configure(card: card)
|
||||||
|
statusView.setLinkPreviewButtonDisplay()
|
||||||
|
}
|
||||||
|
.store(in: &disposeBag)
|
||||||
|
}
|
||||||
|
|
||||||
private func bindToolbar(statusView: StatusView) {
|
private func bindToolbar(statusView: StatusView) {
|
||||||
$replyCount
|
$replyCount
|
||||||
|
|
Loading…
Reference in New Issue