//// //// StatusTableViewControllerAspect.swift //// Mastodon //// //// Created by MainasuK Cirno on 2021-4-7. //// // //import UIKit //import AVKit //import GameController // //// Check List Last Updated //// - HomeViewController: 2021/7/15 //// - FavoriteViewController: 2021/4/30 //// - HashtagTimelineViewController: 2021/4/30 //// - UserTimelineViewController: 2021/4/30 //// - ThreadViewController: 2021/4/30 //// - SearchResultViewController: 2021/7/15 //// * StatusTableViewControllerAspect: 2021/7/15 // //// (Fake) Aspect protocol to group common protocol extension implementations //// Needs update related view controller when aspect interface changes // ///// Status related operations aspect ///// Please check the aspect methods (Option+Click) and add hook to implement features ///// - UI ///// - Media ///// - Data Source //protocol StatusTableViewControllerAspect: UIViewController { // var tableView: UITableView { get } //} // //// MARK: - UIViewController [A] // //// [A1] aspectViewWillAppear(_:) //extension StatusTableViewControllerAspect { // /// [UI] hook to deselect row in the transitioning for the table view // func aspectViewWillAppear(_ animated: Bool) { // if GCKeyboard.coalesced != nil, let backKeyCommandPressDate = UserDefaults.shared.backKeyCommandPressDate { // guard backKeyCommandPressDate.timeIntervalSinceNow <= -0.5 else { // // break if interval greater than 0.5s // return // } // } // tableView.deselectRow(with: transitionCoordinator, animated: animated) // } //} // //// [A2] aspectViewDidDisappear(_:) //extension StatusTableViewControllerAspect where Self: NeedsDependency { // /// [Media] hook to notify video service // func aspectViewDidDisappear(_ animated: Bool) { // context.videoPlaybackService.viewDidDisappear(from: self) // context.audioPlaybackService.viewDidDisappear(from: self) // } //} // //// MARK: - UITableViewDelegate [B] // //// [B1] aspectTableView(_:estimatedHeightForRowAt:) //extension StatusTableViewControllerAspect where Self: LoadMoreConfigurableTableViewContainer { // /// [Data Source] hook to notify table view bottom loader // func aspectScrollViewDidScroll(_ scrollView: UIScrollView) { // handleScrollViewDidScroll(scrollView) // } //} // //// [B2] aspectTableView(_:estimatedHeightForRowAt:) //extension StatusTableViewControllerAspect where Self: TableViewCellHeightCacheableContainer { // /// [UI] hook to estimate table view cell height from cache // func aspectTableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { // handleTableView(tableView, estimatedHeightForRowAt: indexPath) // } //} // //// [B3] aspectTableView(_:willDisplay:forRowAt:) //extension StatusTableViewControllerAspect where Self: StatusTableViewCellDelegate & StatusProvider { // func aspectTableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { // handleTableView(tableView, willDisplay: cell, forRowAt: indexPath) // } //} // //// [B4] aspectTableView(_:didEndDisplaying:forRowAt:) //extension StatusTableViewControllerAspect where Self: StatusTableViewCellDelegate & StatusProvider { // /// [Media] hook to notify video service // func aspectTableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { // handleTableView(tableView, didEndDisplaying: cell, forRowAt: indexPath) // } //} // //extension StatusTableViewControllerAspect where Self: TableViewCellHeightCacheableContainer { // /// [UI] hook to cache table view cell height // func aspectTableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { // cacheTableView(tableView, didEndDisplaying: cell, forRowAt: indexPath) // } //} // //extension StatusTableViewControllerAspect where Self: StatusProvider & StatusTableViewCellDelegate & TableViewCellHeightCacheableContainer { // /// [Media] hook to notify video service // /// [UI] hook to cache table view cell height // func aspectTableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { // handleTableView(tableView, didEndDisplaying: cell, forRowAt: indexPath) // cacheTableView(tableView, didEndDisplaying: cell, forRowAt: indexPath) // } //} // //// [B5] aspectTableView(_:didSelectRowAt:) //extension StatusTableViewControllerAspect where Self: StatusTableViewCellDelegate & StatusProvider { // /// [UI] hook to coordinator to thread // func aspectTableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // handleTableView(tableView, didSelectRowAt: indexPath) // } //} // //// [B6] aspectTableView(_:contextMenuConfigurationForRowAt:point:) //extension StatusTableViewControllerAspect where Self: StatusTableViewCellDelegate & StatusProvider { // // [UI] hook to display context menu for images // func aspectTableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { // return handleTableView(tableView, contextMenuConfigurationForRowAt: indexPath, point: point) // } //} // //// [B7] aspectTableView(_:contextMenuConfigurationForRowAt:point:) //extension StatusTableViewControllerAspect where Self: StatusTableViewCellDelegate & StatusProvider { // // [UI] hook to configure context menu for images // func aspectTableView(_ tableView: UITableView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? { // return handleTableView(tableView, previewForHighlightingContextMenuWithConfiguration: configuration) // } //} // //// [B8] aspectTableView(_:previewForDismissingContextMenuWithConfiguration:) //extension StatusTableViewControllerAspect where Self: StatusTableViewCellDelegate & StatusProvider { // // [UI] hook to configure context menu for images // func aspectTableView(_ tableView: UITableView, previewForDismissingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? { // return handleTableView(tableView, previewForDismissingContextMenuWithConfiguration: configuration) // } //} // //// [B9] aspectTableView(_:willPerformPreviewActionForMenuWith:animator:) //extension StatusTableViewControllerAspect where Self: StatusTableViewCellDelegate & StatusProvider { // // [UI] hook to configure context menu preview action // func aspectTableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) { // handleTableView(tableView, willPerformPreviewActionForMenuWith: configuration, animator: animator) // } //} // //// MARK: - UITableViewDataSourcePrefetching [C] // //// [C1] aspectTableView(:prefetchRowsAt) //extension StatusTableViewControllerAspect where Self: UITableViewDataSourcePrefetching & StatusTableViewCellDelegate & StatusProvider { // /// [Data Source] hook to prefetch status // func aspectTableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { // handleTableView(tableView, prefetchRowsAt: indexPaths) // } //} // //// [C2] aspectTableView(:prefetchRowsAt) //extension StatusTableViewControllerAspect where Self: UITableViewDataSourcePrefetching & StatusTableViewCellDelegate & StatusProvider { // /// [Data Source] hook to cancel prefetch status // func aspectTableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) { // handleTableView(tableView, cancelPrefetchingForRowsAt: indexPaths) // } //} // //// MARK: - AVPlayerViewControllerDelegate & NeedsDependency [D] // //// [D1] aspectPlayerViewController(_:willBeginFullScreenPresentationWithAnimationCoordinator:) //extension StatusTableViewControllerAspect where Self: AVPlayerViewControllerDelegate & NeedsDependency { // /// [Media] hook to mark transitioning to video service // func aspectPlayerViewController(_ playerViewController: AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) { // handlePlayerViewController(playerViewController, willBeginFullScreenPresentationWithAnimationCoordinator: coordinator) // } //} // //// [D2] aspectPlayerViewController(_:willEndFullScreenPresentationWithAnimationCoordinator:) //extension StatusTableViewControllerAspect where Self: AVPlayerViewControllerDelegate & NeedsDependency { // /// [Media] hook to mark transitioning to video service // func aspectPlayerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) { // handlePlayerViewController(playerViewController, willEndFullScreenPresentationWithAnimationCoordinator: coordinator) // } //} //