diff --git a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist index a5240e44a..7e9982d3c 100644 --- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,7 +7,7 @@ AppShared.xcscheme_^#shared#^_ orderHint - 25 + 20 CoreDataStack.xcscheme_^#shared#^_ @@ -97,7 +97,7 @@ MastodonIntent.xcscheme_^#shared#^_ orderHint - 27 + 19 MastodonIntents.xcscheme_^#shared#^_ @@ -117,7 +117,7 @@ ShareActionExtension.xcscheme_^#shared#^_ orderHint - 26 + 18 SuppressBuildableAutocreation diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift index f062f01d8..0924028ff 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift @@ -102,6 +102,119 @@ extension NotificationTableViewCellDelegate where Self: DataSourceProvider { } } +private struct NotificationMediaTransitionContext { + let status: ManagedObjectRecord + let needsToggleMediaSensitive: Bool +} + +extension NotificationTableViewCellDelegate where Self: DataSourceProvider & MediaPreviewableViewController { + + func tableViewCell( + _ cell: UITableViewCell, + notificationView: NotificationView, + statusView: StatusView, + mediaGridContainerView: MediaGridContainerView, + mediaView: MediaView, + didSelectMediaViewAt index: Int + ) { + Task { + let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) + guard let item = await item(from: source) else { + assertionFailure() + return + } + guard case let .notification(record) = item else { + assertionFailure("only works for status data provider") + return + } + + let managedObjectContext = self.context.managedObjectContext + let _mediaTransitionContext: NotificationMediaTransitionContext? = try await managedObjectContext.perform { + guard let notification = record.object(in: managedObjectContext) else { return nil } + guard let _status = notification.status else { return nil } + let status = _status.reblog ?? _status + return NotificationMediaTransitionContext( + status: .init(objectID: status.objectID), + needsToggleMediaSensitive: status.isMediaSensitiveToggled ? !status.sensitive : status.sensitive + ) + } + + guard let mediaTransitionContext = _mediaTransitionContext else { return } + + guard !mediaTransitionContext.needsToggleMediaSensitive else { + try await DataSourceFacade.responseToToggleSensitiveAction( + dependency: self, + status: mediaTransitionContext.status + ) + return + } + + try await DataSourceFacade.coordinateToMediaPreviewScene( + dependency: self, + status: mediaTransitionContext.status, + previewContext: DataSourceFacade.AttachmentPreviewContext( + containerView: .mediaGridContainerView(mediaGridContainerView), + mediaView: mediaView, + index: index + ) + ) + } // end Task + } + + func tableViewCell( + _ cell: UITableViewCell, + notificationView: NotificationView, + quoteStatusView: StatusView, + mediaGridContainerView: MediaGridContainerView, + mediaView: MediaView, + didSelectMediaViewAt index: Int + ) { + Task { + let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) + guard let item = await item(from: source) else { + assertionFailure() + return + } + guard case let .notification(record) = item else { + assertionFailure("only works for status data provider") + return + } + + let managedObjectContext = self.context.managedObjectContext + let _mediaTransitionContext: NotificationMediaTransitionContext? = try await managedObjectContext.perform { + guard let notification = record.object(in: managedObjectContext) else { return nil } + guard let _status = notification.status else { return nil } + let status = _status.reblog ?? _status + return NotificationMediaTransitionContext( + status: .init(objectID: status.objectID), + needsToggleMediaSensitive: status.isMediaSensitiveToggled ? !status.sensitive : status.sensitive + ) + } + + guard let mediaTransitionContext = _mediaTransitionContext else { return } + + guard !mediaTransitionContext.needsToggleMediaSensitive else { + try await DataSourceFacade.responseToToggleSensitiveAction( + dependency: self, + status: mediaTransitionContext.status + ) + return + } + + try await DataSourceFacade.coordinateToMediaPreviewScene( + dependency: self, + status: mediaTransitionContext.status, + previewContext: DataSourceFacade.AttachmentPreviewContext( + containerView: .mediaGridContainerView(mediaGridContainerView), + mediaView: mediaView, + index: index + ) + ) + } // end Task + } + +} + // MARK: - Status Toolbar extension NotificationTableViewCellDelegate where Self: DataSourceProvider { func tableViewCell( @@ -142,7 +255,6 @@ extension NotificationTableViewCellDelegate where Self: DataSourceProvider { } } - // MARK: - Status Author Avatar extension NotificationTableViewCellDelegate where Self: DataSourceProvider { func tableViewCell( diff --git a/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift b/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift index 07bc5ff97..d13ce7195 100644 --- a/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift +++ b/Mastodon/Scene/Notification/Cell/NotificationTableViewCellDelegate.swift @@ -27,10 +27,12 @@ protocol NotificationTableViewCellDelegate: AnyObject, AutoGenerateProtocolDeleg func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, menuButton button: UIButton, didSelectAction action: MastodonMenu.Action) func tableViewCell(_ cell: UITableViewCell, notificationView: NotificationView, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) 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, 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) // sourcery:end } @@ -55,6 +57,10 @@ extension NotificationViewDelegate where Self: NotificationViewContainerTableVie delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, spoilerOverlayViewDidPressed: overlayView) } + func notificationView(_ notificationView: NotificationView, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) { + delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, mediaGridContainerView: mediaGridContainerView, mediaView: mediaView, didSelectMediaViewAt: index) + } + func notificationView(_ notificationView: NotificationView, statusView: StatusView, actionToolbarContainer: ActionToolbarContainer, buttonDidPressed button: UIButton, action: ActionToolbarContainer.Action) { delegate?.tableViewCell(self, notificationView: notificationView, statusView: statusView, actionToolbarContainer: actionToolbarContainer, buttonDidPressed: button, action: action) } @@ -71,6 +77,10 @@ extension NotificationViewDelegate where Self: NotificationViewContainerTableVie delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, spoilerOverlayViewDidPressed: overlayView) } + func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) { + delegate?.tableViewCell(self, notificationView: notificationView, quoteStatusView: quoteStatusView, mediaGridContainerView: mediaGridContainerView, mediaView: mediaView, didSelectMediaViewAt: index) + } + func notificationView(_ notificationView: NotificationView, accessibilityActivate: Void) { delegate?.tableViewCell(self, notificationView: notificationView, accessibilityActivate: accessibilityActivate) } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index 78ebdbcda..99b2d69aa 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -19,14 +19,14 @@ public protocol NotificationViewDelegate: AnyObject { func notificationView(_ notificationView: NotificationView, statusView: StatusView, metaText: MetaText, didSelectMeta meta: Meta) func notificationView(_ notificationView: NotificationView, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) -// func notificationView(_ notificationView: NotificationView, statusView: StatusView, spoilerBannerViewDidPressed bannerView: SpoilerBannerView) + func notificationView(_ notificationView: NotificationView, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) func notificationView(_ notificationView: NotificationView, statusView: StatusView, actionToolbarContainer: ActionToolbarContainer, buttonDidPressed button: UIButton, action: ActionToolbarContainer.Action) 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, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) - // func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, spoilerBannerViewDidPressed bannerView: SpoilerBannerView) + func notificationView(_ notificationView: NotificationView, quoteStatusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) // a11y func notificationView(_ notificationView: NotificationView, accessibilityActivate: Void) @@ -366,7 +366,14 @@ extension NotificationView: StatusViewDelegate { } public func statusView(_ statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaView: MediaView, didSelectMediaViewAt index: Int) { - assertionFailure() + switch statusView { + case self.statusView: + delegate?.notificationView(self, statusView: statusView, mediaGridContainerView: mediaGridContainerView, mediaView: mediaView, didSelectMediaViewAt: index) + case quoteStatusView: + delegate?.notificationView(self, quoteStatusView: statusView, mediaGridContainerView: mediaGridContainerView, mediaView: mediaView, didSelectMediaViewAt: index) + default: + assertionFailure() + } } public func statusView(_ statusView: StatusView, pollTableView tableView: UITableView, didSelectRowAt indexPath: IndexPath) {