feat: add favicon for NewsView
This commit is contained in:
parent
7772783555
commit
03af68924c
|
@ -55,6 +55,15 @@
|
||||||
"version": "1.2.0"
|
"version": "1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"package": "FaviconFinder",
|
||||||
|
"repositoryURL": "https://github.com/will-lumley/FaviconFinder.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "1f74844f77f79b95c0bb0130b3a87d4f340e6d3a",
|
||||||
|
"version": "3.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"package": "FLAnimatedImage",
|
"package": "FLAnimatedImage",
|
||||||
"repositoryURL": "https://github.com/Flipboard/FLAnimatedImage.git",
|
"repositoryURL": "https://github.com/Flipboard/FLAnimatedImage.git",
|
||||||
|
@ -172,6 +181,15 @@
|
||||||
"version": "1.0.0"
|
"version": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"package": "SwiftSoup",
|
||||||
|
"repositoryURL": "https://github.com/scinfu/SwiftSoup.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "41e7c263fb8c277e980ebcb9b0b5f6031d3d4886",
|
||||||
|
"version": "2.4.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"package": "Introspect",
|
"package": "Introspect",
|
||||||
"repositoryURL": "https://github.com/siteline/SwiftUI-Introspect.git",
|
"repositoryURL": "https://github.com/siteline/SwiftUI-Introspect.git",
|
||||||
|
|
|
@ -37,7 +37,8 @@ let package = Package(
|
||||||
.package(url: "https://github.com/Alamofire/AlamofireImage.git", from: "4.1.0"),
|
.package(url: "https://github.com/Alamofire/AlamofireImage.git", from: "4.1.0"),
|
||||||
.package(name: "NukeFLAnimatedImagePlugin", url: "https://github.com/kean/Nuke-FLAnimatedImage-Plugin.git", from: "8.0.0"),
|
.package(name: "NukeFLAnimatedImagePlugin", url: "https://github.com/kean/Nuke-FLAnimatedImage-Plugin.git", from: "8.0.0"),
|
||||||
.package(name: "UITextView+Placeholder", url: "https://github.com/MainasuK/UITextView-Placeholder.git", from: "1.4.1"),
|
.package(name: "UITextView+Placeholder", url: "https://github.com/MainasuK/UITextView-Placeholder.git", from: "1.4.1"),
|
||||||
.package(name: "Introspect", url: "https://github.com/siteline/SwiftUI-Introspect.git", from: "0.1.3")
|
.package(name: "Introspect", url: "https://github.com/siteline/SwiftUI-Introspect.git", from: "0.1.3"),
|
||||||
|
.package(name: "FaviconFinder", url: "https://github.com/will-lumley/FaviconFinder.git", from: "3.2.2"),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||||
|
@ -95,6 +96,7 @@ let package = Package(
|
||||||
.product(name: "AlamofireImage", package: "AlamofireImage"),
|
.product(name: "AlamofireImage", package: "AlamofireImage"),
|
||||||
.product(name: "MetaTextKit", package: "MetaTextKit"),
|
.product(name: "MetaTextKit", package: "MetaTextKit"),
|
||||||
.product(name: "FLAnimatedImage", package: "FLAnimatedImage"),
|
.product(name: "FLAnimatedImage", package: "FLAnimatedImage"),
|
||||||
|
.product(name: "FaviconFinder", package: "FaviconFinder"),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
.testTarget(
|
.testTarget(
|
||||||
|
|
|
@ -9,9 +9,28 @@ import UIKit
|
||||||
import MastodonSDK
|
import MastodonSDK
|
||||||
import MastodonLocalization
|
import MastodonLocalization
|
||||||
import AlamofireImage
|
import AlamofireImage
|
||||||
|
import FaviconFinder
|
||||||
|
|
||||||
extension NewsView {
|
extension NewsView {
|
||||||
public func configure(link: Mastodon.Entity.Link) {
|
public func configure(link: Mastodon.Entity.Link) {
|
||||||
|
let faviconPlaceholder = UIImage(systemName: "network")
|
||||||
|
providerFaviconImageView.image = faviconPlaceholder
|
||||||
|
if let url = URL(string: link.url) {
|
||||||
|
let token = providerFaviconImageView.tag
|
||||||
|
FaviconFinder(url: url).downloadFavicon { [weak self] result in
|
||||||
|
guard let self = self else { return }
|
||||||
|
switch result {
|
||||||
|
case .success(let favicon):
|
||||||
|
DispatchQueue.main.async { [weak self] in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard self.providerFaviconImageView.tag == token else { return }
|
||||||
|
self.providerFaviconImageView.image = favicon.image
|
||||||
|
}
|
||||||
|
case .failure:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
providerNameLabel.text = link.providerName
|
providerNameLabel.text = link.providerName
|
||||||
headlineLabel.text = link.title
|
headlineLabel.text = link.title
|
||||||
footnoteLabel.text = L10n.Plural.peopleTalking(link.talkingPeopleCount ?? 0)
|
footnoteLabel.text = L10n.Plural.peopleTalking(link.talkingPeopleCount ?? 0)
|
||||||
|
|
|
@ -12,6 +12,15 @@ public final class NewsView: UIView {
|
||||||
|
|
||||||
let container = UIStackView()
|
let container = UIStackView()
|
||||||
|
|
||||||
|
let providerFaviconImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView()
|
||||||
|
imageView.contentMode = .scaleAspectFit
|
||||||
|
imageView.layer.masksToBounds = true
|
||||||
|
imageView.layer.cornerRadius = 2
|
||||||
|
imageView.layer.cornerCurve = .continuous
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
let providerNameLabel: UILabel = {
|
let providerNameLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .semibold))
|
label.font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .semibold))
|
||||||
|
@ -37,6 +46,7 @@ public final class NewsView: UIView {
|
||||||
let imageView = MediaView()
|
let imageView = MediaView()
|
||||||
|
|
||||||
public func prepareForReuse() {
|
public func prepareForReuse() {
|
||||||
|
providerFaviconImageView.tag = (0..<Int.max).randomElement() ?? -1
|
||||||
imageView.prepareForReuse()
|
imageView.prepareForReuse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,12 +82,27 @@ extension NewsView {
|
||||||
textContainer.spacing = 4
|
textContainer.spacing = 4
|
||||||
container.addArrangedSubview(textContainer)
|
container.addArrangedSubview(textContainer)
|
||||||
|
|
||||||
// providerContainer: H - [ providerFavIconImageView | providerNameLabel | (spacer) ]
|
// providerContainer: H - [ providerFaviconImageView | providerNameLabel | (spacer) ]
|
||||||
let providerContainer = UIStackView()
|
let providerContainer = UIStackView()
|
||||||
providerContainer.axis = .horizontal
|
providerContainer.axis = .horizontal
|
||||||
|
providerContainer.spacing = 4
|
||||||
textContainer.addArrangedSubview(providerContainer)
|
textContainer.addArrangedSubview(providerContainer)
|
||||||
|
|
||||||
|
providerFaviconImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
providerContainer.addArrangedSubview(providerFaviconImageView)
|
||||||
providerContainer.addArrangedSubview(providerNameLabel)
|
providerContainer.addArrangedSubview(providerNameLabel)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
providerFaviconImageView.heightAnchor.constraint(equalTo: providerNameLabel.heightAnchor, multiplier: 1.0).priority(.required - 10),
|
||||||
|
providerFaviconImageView.widthAnchor.constraint(equalTo: providerNameLabel.heightAnchor, multiplier: 1.0).priority(.required - 10),
|
||||||
|
])
|
||||||
|
// low priority for intrinsic size hugging
|
||||||
|
providerFaviconImageView.setContentHuggingPriority(.defaultLow - 10, for: .vertical)
|
||||||
|
providerFaviconImageView.setContentHuggingPriority(.defaultLow - 10, for: .horizontal)
|
||||||
|
// high priority but lower then layout constraint for size compression
|
||||||
|
providerFaviconImageView.setContentCompressionResistancePriority(.required - 11, for: .vertical)
|
||||||
|
providerFaviconImageView.setContentCompressionResistancePriority(.required - 11, for: .horizontal)
|
||||||
|
providerNameLabel.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
||||||
|
providerNameLabel.setContentHuggingPriority(.required - 1, for: .vertical)
|
||||||
|
|
||||||
// headlineLabel
|
// headlineLabel
|
||||||
textContainer.addArrangedSubview(headlineLabel)
|
textContainer.addArrangedSubview(headlineLabel)
|
||||||
|
|
Loading…
Reference in New Issue