Merge pull request #492 from j-f1/share-metadata
Use LPLinkMetadata to improve sharing behavior
This commit is contained in:
commit
505ca804b3
|
@ -7,9 +7,13 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import CoreDataStack
|
import CoreDataStack
|
||||||
|
import Alamofire
|
||||||
|
import AlamofireImage
|
||||||
import MastodonCore
|
import MastodonCore
|
||||||
import MastodonUI
|
import MastodonUI
|
||||||
import MastodonLocalization
|
import MastodonLocalization
|
||||||
|
import LinkPresentation
|
||||||
|
import UniformTypeIdentifiers
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
extension DataSourceFacade {
|
extension DataSourceFacade {
|
||||||
|
@ -56,8 +60,7 @@ extension DataSourceFacade {
|
||||||
) async throws -> UIActivityViewController {
|
) async throws -> UIActivityViewController {
|
||||||
var activityItems: [Any] = try await dependency.context.managedObjectContext.perform {
|
var activityItems: [Any] = try await dependency.context.managedObjectContext.perform {
|
||||||
guard let status = status.object(in: dependency.context.managedObjectContext) else { return [] }
|
guard let status = status.object(in: dependency.context.managedObjectContext) else { return [] }
|
||||||
let url = status.url ?? status.uri
|
return [StatusActivityItem(status: status)].compactMap { $0 } as [Any]
|
||||||
return [URL(string: url)].compactMap { $0 } as [Any]
|
|
||||||
}
|
}
|
||||||
var applicationActivities: [UIActivity] = [
|
var applicationActivities: [UIActivity] = [
|
||||||
SafariActivity(sceneCoordinator: dependency.coordinator), // open URL
|
SafariActivity(sceneCoordinator: dependency.coordinator), // open URL
|
||||||
|
@ -74,6 +77,54 @@ extension DataSourceFacade {
|
||||||
)
|
)
|
||||||
return activityViewController
|
return activityViewController
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class StatusActivityItem: NSObject, UIActivityItemSource {
|
||||||
|
init?(status: Status) {
|
||||||
|
guard let url = URL(string: status.url ?? status.uri) else { return nil }
|
||||||
|
self.url = url
|
||||||
|
self.metadata = LPLinkMetadata()
|
||||||
|
metadata.url = url
|
||||||
|
metadata.title = "\(status.author.displayName) (@\(status.author.username)@\(status.author.domain))"
|
||||||
|
metadata.iconProvider = NSItemProvider(object: IconProvider(url: status.author.avatarImageURLWithFallback(domain: status.author.domain)))
|
||||||
|
}
|
||||||
|
|
||||||
|
let url: URL
|
||||||
|
let metadata: LPLinkMetadata
|
||||||
|
|
||||||
|
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
|
||||||
|
url
|
||||||
|
}
|
||||||
|
|
||||||
|
func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
|
||||||
|
url
|
||||||
|
}
|
||||||
|
|
||||||
|
func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
|
||||||
|
metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
private class IconProvider: NSObject, NSItemProviderWriting {
|
||||||
|
let url: URL
|
||||||
|
init(url: URL) {
|
||||||
|
self.url = url
|
||||||
|
}
|
||||||
|
|
||||||
|
static var writableTypeIdentifiersForItemProvider: [String] {
|
||||||
|
[UTType.png.identifier]
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadData(withTypeIdentifier typeIdentifier: String, forItemProviderCompletionHandler completionHandler: @escaping @Sendable (Data?, Error?) -> Void) -> Progress? {
|
||||||
|
let filter = ScaledToSizeFilter(size: CGSize.authorAvatarButtonSize)
|
||||||
|
let receipt = UIImageView.af.sharedImageDownloader.download(URLRequest(url: url), filter: filter, completion: { response in
|
||||||
|
switch response.result {
|
||||||
|
case .failure(let error): completionHandler(nil, error)
|
||||||
|
case .success(let image): completionHandler(image.pngData(), nil)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return receipt?.request.downloadProgress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionToolBar
|
// ActionToolBar
|
||||||
|
|
|
@ -226,14 +226,13 @@ extension NotificationView {
|
||||||
.store(in: &_disposeBag)
|
.store(in: &_disposeBag)
|
||||||
|
|
||||||
// avatarButton
|
// avatarButton
|
||||||
let authorAvatarButtonSize = CGSize(width: 46, height: 46)
|
avatarButton.size = CGSize.authorAvatarButtonSize
|
||||||
avatarButton.size = authorAvatarButtonSize
|
avatarButton.avatarImageView.imageViewSize = CGSize.authorAvatarButtonSize
|
||||||
avatarButton.avatarImageView.imageViewSize = authorAvatarButtonSize
|
|
||||||
avatarButton.translatesAutoresizingMaskIntoConstraints = false
|
avatarButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
authorContainerView.addArrangedSubview(avatarButton)
|
authorContainerView.addArrangedSubview(avatarButton)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
avatarButton.widthAnchor.constraint(equalToConstant: authorAvatarButtonSize.width).priority(.required - 1),
|
avatarButton.widthAnchor.constraint(equalToConstant: CGSize.authorAvatarButtonSize.width).priority(.required - 1),
|
||||||
avatarButton.heightAnchor.constraint(equalToConstant: authorAvatarButtonSize.height).priority(.required - 1),
|
avatarButton.heightAnchor.constraint(equalToConstant: CGSize.authorAvatarButtonSize.height).priority(.required - 1),
|
||||||
])
|
])
|
||||||
avatarButton.setContentHuggingPriority(.required - 1, for: .vertical)
|
avatarButton.setContentHuggingPriority(.required - 1, for: .vertical)
|
||||||
avatarButton.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
avatarButton.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
||||||
|
|
|
@ -210,14 +210,13 @@ extension StatusAuthorView {
|
||||||
// author container: H - [ avatarButton | authorMetaContainer ]
|
// author container: H - [ avatarButton | authorMetaContainer ]
|
||||||
private func layoutBase() {
|
private func layoutBase() {
|
||||||
// avatarButton
|
// avatarButton
|
||||||
let authorAvatarButtonSize = CGSize(width: 46, height: 46)
|
avatarButton.size = CGSize.authorAvatarButtonSize
|
||||||
avatarButton.size = authorAvatarButtonSize
|
avatarButton.avatarImageView.imageViewSize = CGSize.authorAvatarButtonSize
|
||||||
avatarButton.avatarImageView.imageViewSize = authorAvatarButtonSize
|
|
||||||
avatarButton.translatesAutoresizingMaskIntoConstraints = false
|
avatarButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
addArrangedSubview(avatarButton)
|
addArrangedSubview(avatarButton)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
avatarButton.widthAnchor.constraint(equalToConstant: authorAvatarButtonSize.width).priority(.required - 1),
|
avatarButton.widthAnchor.constraint(equalToConstant: CGSize.authorAvatarButtonSize.width).priority(.required - 1),
|
||||||
avatarButton.heightAnchor.constraint(equalToConstant: authorAvatarButtonSize.height).priority(.required - 1),
|
avatarButton.heightAnchor.constraint(equalToConstant: CGSize.authorAvatarButtonSize.height).priority(.required - 1),
|
||||||
])
|
])
|
||||||
avatarButton.setContentHuggingPriority(.required - 1, for: .vertical)
|
avatarButton.setContentHuggingPriority(.required - 1, for: .vertical)
|
||||||
avatarButton.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
avatarButton.setContentCompressionResistancePriority(.required - 1, for: .vertical)
|
||||||
|
|
|
@ -14,6 +14,10 @@ import MastodonAsset
|
||||||
import MastodonCore
|
import MastodonCore
|
||||||
import MastodonLocalization
|
import MastodonLocalization
|
||||||
|
|
||||||
|
public extension CGSize {
|
||||||
|
static let authorAvatarButtonSize = CGSize(width: 46, height: 46)
|
||||||
|
}
|
||||||
|
|
||||||
public protocol StatusViewDelegate: AnyObject {
|
public protocol StatusViewDelegate: AnyObject {
|
||||||
func statusView(_ statusView: StatusView, headerDidPressed header: UIView)
|
func statusView(_ statusView: StatusView, headerDidPressed header: UIView)
|
||||||
func statusView(_ statusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton)
|
func statusView(_ statusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton)
|
||||||
|
|
Loading…
Reference in New Issue