wip
This commit is contained in:
parent
57380b9989
commit
daeb2ef70f
|
@ -108,6 +108,15 @@
|
|||
"version" : "8.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "opengraph",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/satoshi-takano/OpenGraph",
|
||||
"state" : {
|
||||
"revision" : "3ef2b8b9b4972b57e9e78c91c26be770c0110057",
|
||||
"version" : "1.5.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "pageboy",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
|
|
@ -49,6 +49,7 @@ let package = Package(
|
|||
.package(url: "https://github.com/SDWebImage/SDWebImage.git", from: "5.12.0"),
|
||||
.package(url: "https://github.com/eneko/Stripes.git", from: "0.2.0"),
|
||||
.package(url: "https://github.com/onevcat/Kingfisher.git", from: "7.4.1"),
|
||||
.package(url: "https://github.com/satoshi-takano/OpenGraph", from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
|
@ -117,6 +118,7 @@ let package = Package(
|
|||
.product(name: "UIHostingConfigurationBackport", package: "UIHostingConfigurationBackport"),
|
||||
.product(name: "TabBarPager", package: "TabBarPager"),
|
||||
.product(name: "ThirdPartyMailer", package: "ThirdPartyMailer"),
|
||||
.product(name: "OpenGraph", package: "OpenGraph"),
|
||||
.product(name: "OrderedCollections", package: "swift-collections"),
|
||||
.product(name: "Tabman", package: "Tabman"),
|
||||
.product(name: "MetaTextKit", package: "MetaTextKit"),
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// OpenGraphView.swift
|
||||
//
|
||||
//
|
||||
// Created by Kyle Bashour on 11/11/22.
|
||||
//
|
||||
|
||||
import MastodonAsset
|
||||
import MastodonCore
|
||||
import OpenGraph
|
||||
import UIKit
|
||||
|
||||
public final class OpenGraphView: UIControl {
|
||||
private let containerStackView = UIStackView()
|
||||
private let labelStackView = UIStackView()
|
||||
|
||||
private let imageView = UIImageView()
|
||||
private let titleLabel = UILabel()
|
||||
private let subtitleLabel = UILabel()
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
clipsToBounds = true
|
||||
layer.cornerCurve = .continuous
|
||||
layer.cornerRadius = 10
|
||||
layer.borderColor = ThemeService.shared.currentTheme.value.separator.cgColor
|
||||
backgroundColor = ThemeService.shared.currentTheme.value.systemElevatedBackgroundColor
|
||||
|
||||
titleLabel.numberOfLines = 0
|
||||
titleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal)
|
||||
titleLabel.text = "This is where I'd put a title... if I had one"
|
||||
titleLabel.textColor = Asset.Colors.Label.primary.color
|
||||
|
||||
subtitleLabel.text = "Subtitle"
|
||||
subtitleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal)
|
||||
subtitleLabel.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)
|
||||
|
||||
labelStackView.addArrangedSubview(titleLabel)
|
||||
labelStackView.addArrangedSubview(subtitleLabel)
|
||||
labelStackView.layoutMargins = .init(top: 8, left: 10, bottom: 8, right: 10)
|
||||
labelStackView.isLayoutMarginsRelativeArrangement = true
|
||||
labelStackView.axis = .vertical
|
||||
|
||||
containerStackView.addArrangedSubview(imageView)
|
||||
containerStackView.addArrangedSubview(labelStackView)
|
||||
containerStackView.distribution = .fill
|
||||
containerStackView.alignment = .center
|
||||
|
||||
addSubview(containerStackView)
|
||||
|
||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
containerStackView.heightAnchor.constraint(equalToConstant: 80),
|
||||
containerStackView.topAnchor.constraint(equalTo: topAnchor),
|
||||
containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor),
|
||||
])
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public func configure(content: String) {
|
||||
self.subtitleLabel.text = content
|
||||
}
|
||||
|
||||
public override func didMoveToWindow() {
|
||||
super.didMoveToWindow()
|
||||
|
||||
if let window = window {
|
||||
layer.borderWidth = 1 / window.screen.scale
|
||||
}
|
||||
}
|
||||
}
|
|
@ -317,6 +317,22 @@ extension StatusView.ViewModel {
|
|||
)
|
||||
statusView.contentMetaText.textView.accessibilityTraits = [.staticText]
|
||||
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.linkPreview.configure(content: trimmed)
|
||||
statusView.setLinkPreviewDisplay()
|
||||
}
|
||||
} else {
|
||||
statusView.contentMetaText.reset()
|
||||
statusView.contentMetaText.textView.accessibilityLabel = ""
|
||||
|
|
|
@ -113,6 +113,8 @@ public final class StatusView: UIView {
|
|||
]
|
||||
return metaText
|
||||
}()
|
||||
|
||||
public let linkPreview = OpenGraphView()
|
||||
|
||||
// content warning
|
||||
public let spoilerOverlayView = SpoilerOverlayView()
|
||||
|
@ -217,6 +219,7 @@ public final class StatusView: UIView {
|
|||
setMediaDisplay(isDisplay: false)
|
||||
setPollDisplay(isDisplay: false)
|
||||
setFilterHintLabelDisplay(isDisplay: false)
|
||||
setLinkPreviewDisplay(isDisplay: false)
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
|
@ -378,7 +381,7 @@ extension StatusView.Style {
|
|||
statusView.contentContainer.axis = .vertical
|
||||
statusView.contentContainer.spacing = 12
|
||||
statusView.contentContainer.distribution = .fill
|
||||
statusView.contentContainer.alignment = .top
|
||||
statusView.contentContainer.alignment = .fill
|
||||
|
||||
statusView.contentAdaptiveMarginContainerView.contentView = statusView.contentContainer
|
||||
statusView.contentAdaptiveMarginContainerView.margin = StatusView.containerLayoutMargin
|
||||
|
@ -389,6 +392,8 @@ extension StatusView.Style {
|
|||
// status content
|
||||
statusView.contentContainer.addArrangedSubview(statusView.contentMetaText.textView)
|
||||
statusView.containerStackView.setCustomSpacing(16, after: statusView.contentMetaText.textView)
|
||||
statusView.contentContainer.addArrangedSubview(statusView.linkPreview)
|
||||
statusView.containerStackView.setCustomSpacing(16, after: statusView.linkPreview)
|
||||
|
||||
statusView.spoilerOverlayView.translatesAutoresizingMaskIntoConstraints = false
|
||||
statusView.containerStackView.addSubview(statusView.spoilerOverlayView)
|
||||
|
@ -539,6 +544,10 @@ extension StatusView {
|
|||
func setFilterHintLabelDisplay(isDisplay: Bool = true) {
|
||||
filterHintLabel.isHidden = !isDisplay
|
||||
}
|
||||
|
||||
func setLinkPreviewDisplay(isDisplay: Bool = true) {
|
||||
linkPreview.isHidden = !isDisplay
|
||||
}
|
||||
|
||||
// container width
|
||||
public var contentMaxLayoutWidth: CGFloat {
|
||||
|
|
Loading…
Reference in New Issue