Handle taps
This commit is contained in:
parent
f8d1afc7e4
commit
ba7955bdb5
|
@ -48,18 +48,12 @@ extension DataSourceFacade {
|
|||
assertionFailure()
|
||||
return
|
||||
}
|
||||
let domain = provider.authContext.mastodonAuthenticationBox.domain
|
||||
if url.host == domain,
|
||||
url.pathComponents.count >= 4,
|
||||
url.pathComponents[0] == "/",
|
||||
url.pathComponents[1] == "web",
|
||||
url.pathComponents[2] == "statuses" {
|
||||
let statusID = url.pathComponents[3]
|
||||
let threadViewModel = RemoteThreadViewModel(context: provider.context, authContext: provider.authContext, statusID: statusID)
|
||||
_ = await provider.coordinator.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show)
|
||||
} else {
|
||||
_ = await provider.coordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil))
|
||||
}
|
||||
|
||||
await responseToURLAction(
|
||||
provider: provider,
|
||||
status: status,
|
||||
url: url
|
||||
)
|
||||
case .hashtag(_, let hashtag, _):
|
||||
let hashtagTimelineViewModel = HashtagTimelineViewModel(context: provider.context, authContext: provider.authContext, hashtag: hashtag)
|
||||
_ = await provider.coordinator.present(scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: provider, transition: .show)
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// DataSourceFacade+URL.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by Kyle Bashour on 11/24/22.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreDataStack
|
||||
import MetaTextKit
|
||||
import MastodonCore
|
||||
|
||||
extension DataSourceFacade {
|
||||
static func responseToURLAction(
|
||||
provider: DataSourceProvider & AuthContextProvider,
|
||||
status: ManagedObjectRecord<Status>,
|
||||
url: URL
|
||||
) async {
|
||||
let domain = provider.authContext.mastodonAuthenticationBox.domain
|
||||
if url.host == domain,
|
||||
url.pathComponents.count >= 4,
|
||||
url.pathComponents[0] == "/",
|
||||
url.pathComponents[1] == "web",
|
||||
url.pathComponents[2] == "statuses" {
|
||||
let statusID = url.pathComponents[3]
|
||||
let threadViewModel = RemoteThreadViewModel(context: provider.context, authContext: provider.authContext, statusID: statusID)
|
||||
_ = await provider.coordinator.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show)
|
||||
} else {
|
||||
_ = await provider.coordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -516,6 +516,61 @@ extension NotificationTableViewCellDelegate where Self: DataSourceProvider & Aut
|
|||
|
||||
}
|
||||
|
||||
// MARK: - card
|
||||
extension NotificationTableViewCellDelegate where Self: DataSourceProvider & AuthContextProvider {
|
||||
|
||||
func tableViewCell(
|
||||
_ cell: UITableViewCell,
|
||||
notificationView: NotificationView,
|
||||
statusView: StatusView,
|
||||
didTapCardWithURL url: URL
|
||||
) {
|
||||
Task {
|
||||
let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil)
|
||||
guard let item = await item(from: source) else {
|
||||
assertionFailure()
|
||||
return
|
||||
}
|
||||
guard case let .status(status) = item else {
|
||||
assertionFailure("only works for status data provider")
|
||||
return
|
||||
}
|
||||
|
||||
await DataSourceFacade.responseToURLAction(
|
||||
provider: self,
|
||||
status: status,
|
||||
url: url
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func tableViewCell(
|
||||
_ cell: UITableViewCell,
|
||||
notificationView: NotificationView,
|
||||
quoteStatusView: StatusView,
|
||||
didTapCardWithURL url: URL
|
||||
) {
|
||||
Task {
|
||||
let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil)
|
||||
guard let item = await item(from: source) else {
|
||||
assertionFailure()
|
||||
return
|
||||
}
|
||||
guard case let .status(status) = item else {
|
||||
assertionFailure("only works for status data provider")
|
||||
return
|
||||
}
|
||||
|
||||
await DataSourceFacade.responseToURLAction(
|
||||
provider: self,
|
||||
status: status,
|
||||
url: url
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: a11y
|
||||
extension NotificationTableViewCellDelegate where Self: DataSourceProvider & AuthContextProvider {
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, accessibilityActivate: Void) {
|
||||
|
|
|
@ -120,7 +120,36 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthConte
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: - card
|
||||
extension StatusTableViewCellDelegate where Self: DataSourceProvider & AuthContextProvider {
|
||||
|
||||
func tableViewCell(
|
||||
_ cell: UITableViewCell,
|
||||
statusView: StatusView,
|
||||
didTapCardWithURL url: URL
|
||||
) {
|
||||
Task {
|
||||
let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil)
|
||||
guard let item = await item(from: source) else {
|
||||
assertionFailure()
|
||||
return
|
||||
}
|
||||
guard case let .status(status) = item else {
|
||||
assertionFailure("only works for status data provider")
|
||||
return
|
||||
}
|
||||
|
||||
await DataSourceFacade.responseToURLAction(
|
||||
provider: self,
|
||||
status: status,
|
||||
url: url
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - media
|
||||
|
|
|
@ -28,11 +28,13 @@ protocol NotificationTableViewCellDelegate: AnyObject, AutoGenerateProtocolDeleg
|
|||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, acceptFollowRequestButtonDidPressed button: UIButton)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, rejectFollowRequestButtonDidPressed button: UIButton)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, didTapCardWithURL url: URL)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, actionToolbarContainer: ActionToolbarContainer, buttonDidPressed button: UIButton, action: ActionToolbarContainer.Action)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, didTapCardWithURL url: URL)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, quoteStatusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int)
|
||||
func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, accessibilityActivate: Void)
|
||||
|
@ -63,6 +65,10 @@ extension NotificationViewDelegate where Self: NotificationViewContainerTableVie
|
|||
delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, metaText: metaText, didSelectMeta: meta)
|
||||
}
|
||||
|
||||
func notificationView(_ notificationView: NotificationView, statusView: StatusView, didTapCardWithURL url: URL) {
|
||||
delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, didTapCardWithURL: url)
|
||||
}
|
||||
|
||||
func notificationView(_ notificationView: NotificationView, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) {
|
||||
delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, spoilerOverlayViewDidPressed: overlayView)
|
||||
}
|
||||
|
@ -83,6 +89,10 @@ extension NotificationViewDelegate where Self: NotificationViewContainerTableVie
|
|||
delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, metaText: metaText, didSelectMeta: meta)
|
||||
}
|
||||
|
||||
func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, didTapCardWithURL url: URL) {
|
||||
delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, didTapCardWithURL: url)
|
||||
}
|
||||
|
||||
func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) {
|
||||
delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, spoilerOverlayViewDidPressed: overlayView)
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ protocol StatusTableViewCellDelegate: AnyObject, AutoGenerateProtocolDelegate {
|
|||
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton)
|
||||
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, contentSensitiveeToggleButtonDidPressed button: UIButton)
|
||||
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta)
|
||||
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, didTapCardWithURL url: URL)
|
||||
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int)
|
||||
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, pollTableView tableView: UITableView, didSelectRowAt indexPath: IndexPath)
|
||||
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, pollVoteButtonPressed button: UIButton)
|
||||
|
@ -61,6 +62,10 @@ extension StatusViewDelegate where Self: StatusViewContainerTableViewCell {
|
|||
delegate?.tableViewCell(self, statusView: statusView, metaText: metaText, didSelectMeta: meta)
|
||||
}
|
||||
|
||||
func statusView(_ statusView: StatusView, didTapCardWithURL url: URL) {
|
||||
delegate?.tableViewCell(self, statusView: statusView, didTapCardWithURL: url)
|
||||
}
|
||||
|
||||
func statusView(_ statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) {
|
||||
delegate?.tableViewCell(self, statusView: statusView, mediaGridContainerView: mediaGridContainerView, mediaView: mediaView, didSelectMediaViewAt: index)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ public final class LinkPreviewButton: UIControl {
|
|||
private let containerStackView = UIStackView()
|
||||
private let labelStackView = UIStackView()
|
||||
|
||||
private let highlightView = UIView()
|
||||
private let imageView = UIImageView()
|
||||
private let titleLabel = UILabel()
|
||||
private let linkLabel = UILabel()
|
||||
|
@ -30,6 +31,12 @@ public final class LinkPreviewButton: UIControl {
|
|||
imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: 21 / 40),
|
||||
]
|
||||
|
||||
public override var isHighlighted: Bool {
|
||||
didSet {
|
||||
highlightView.isHidden = !isHighlighted
|
||||
}
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
|
@ -38,6 +45,9 @@ public final class LinkPreviewButton: UIControl {
|
|||
layer.cornerRadius = 10
|
||||
layer.borderColor = ThemeService.shared.currentTheme.value.separator.cgColor
|
||||
|
||||
highlightView.backgroundColor = UIColor.black.withAlphaComponent(0.1)
|
||||
highlightView.isHidden = true
|
||||
|
||||
titleLabel.numberOfLines = 2
|
||||
titleLabel.setContentCompressionResistancePriority(.defaultLow - 1, for: .horizontal)
|
||||
titleLabel.text = "This is where I'd put a title... if I had one"
|
||||
|
@ -61,17 +71,23 @@ public final class LinkPreviewButton: UIControl {
|
|||
|
||||
containerStackView.addArrangedSubview(imageView)
|
||||
containerStackView.addArrangedSubview(labelStackView)
|
||||
containerStackView.distribution = .fill
|
||||
|
||||
addSubview(containerStackView)
|
||||
addSubview(highlightView)
|
||||
|
||||
containerStackView.isUserInteractionEnabled = false
|
||||
containerStackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
highlightView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
containerStackView.topAnchor.constraint(equalTo: topAnchor),
|
||||
containerStackView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
containerStackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
containerStackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
highlightView.topAnchor.constraint(equalTo: topAnchor),
|
||||
highlightView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
highlightView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
highlightView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -100,10 +116,12 @@ public final class LinkPreviewButton: UIControl {
|
|||
if isCompact {
|
||||
containerStackView.alignment = .center
|
||||
containerStackView.axis = .horizontal
|
||||
containerStackView.distribution = .fill
|
||||
NSLayoutConstraint.activate(compactImageConstraints)
|
||||
} else {
|
||||
containerStackView.alignment = .fill
|
||||
containerStackView.axis = .vertical
|
||||
containerStackView.distribution = .equalSpacing
|
||||
NSLayoutConstraint.activate(largeImageConstraints)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ public protocol NotificationViewDelegate: AnyObject {
|
|||
func notificationView(_ notificationView: NotificationView, rejectFollowRequestButtonDidPressed button: UIButton)
|
||||
|
||||
func notificationView(_ notificationView: NotificationView, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta)
|
||||
func notificationView(_ notificationView: NotificationView, statusView: StatusView, didTapCardWithURL url: URL)
|
||||
func notificationView(_ notificationView: NotificationView, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView)
|
||||
func notificationView(_ notificationView: NotificationView, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int)
|
||||
|
||||
|
@ -29,6 +30,7 @@ public protocol NotificationViewDelegate: AnyObject {
|
|||
|
||||
func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton)
|
||||
func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta)
|
||||
func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, didTapCardWithURL url: URL)
|
||||
func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView)
|
||||
func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int)
|
||||
|
||||
|
@ -496,7 +498,17 @@ extension NotificationView {
|
|||
|
||||
// MARK: - StatusViewDelegate
|
||||
extension NotificationView: StatusViewDelegate {
|
||||
|
||||
public func statusView(_ statusView: StatusView, didTapCardWithURL url: URL) {
|
||||
switch statusView {
|
||||
case self.statusView:
|
||||
delegate?.notificationView(self, statusView: statusView, didTapCardWithURL: url)
|
||||
case quoteStatusView:
|
||||
delegate?.notificationView(self, quoteStatusView: statusView, didTapCardWithURL: url)
|
||||
default:
|
||||
assertionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
public func statusView(_ statusView: StatusView, headerDidPressed header: UIView) {
|
||||
// do nothing
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ public protocol StatusViewDelegate: AnyObject {
|
|||
func statusView(_ statusView: StatusView, authorAvatarButtonDidPressed button: AvatarButton)
|
||||
func statusView(_ statusView: StatusView, contentSensitiveeToggleButtonDidPressed button: UIButton)
|
||||
func statusView(_ statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta)
|
||||
func statusView(_ statusView: StatusView, didTapCardWithURL url: URL)
|
||||
func statusView(_ statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int)
|
||||
func statusView(_ statusView: StatusView, pollTableView tableView: UITableView, didSelectRowAt indexPath: IndexPath)
|
||||
func statusView(_ statusView: StatusView, pollVoteButtonPressed button: UIButton)
|
||||
|
@ -263,7 +264,13 @@ extension StatusView {
|
|||
|
||||
// media
|
||||
mediaGridContainerView.delegate = self
|
||||
|
||||
|
||||
linkPreviewButton.addTarget(
|
||||
self,
|
||||
action: #selector(linkPreviewButtonPressed),
|
||||
for: .touchUpInside
|
||||
)
|
||||
|
||||
// poll
|
||||
pollTableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
pollTableViewHeightLayoutConstraint = pollTableView.heightAnchor.constraint(equalToConstant: 44.0).priority(.required - 1)
|
||||
|
@ -298,6 +305,12 @@ extension StatusView {
|
|||
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
||||
delegate?.statusView(self, spoilerOverlayViewDidPressed: spoilerOverlayView)
|
||||
}
|
||||
|
||||
@objc private func linkPreviewButtonPressed(_ sender: LinkPreviewButton) {
|
||||
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
||||
guard let url = viewModel.card?.url else { return }
|
||||
delegate?.statusView(self, didTapCardWithURL: url)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue