chore: use fake aspect protocol to group extension default implementations

This commit is contained in:
CMK 2021-04-08 17:05:10 +08:00
parent 14176be4ed
commit 672db8f3c2
6 changed files with 89 additions and 39 deletions

View File

@ -8,6 +8,15 @@
import UIKit
import AVKit
// Check List Last Updated
// - FavoriteViewController: 2021/4/8
// - HashtagTimelineViewController: 2021/4/8
// - UserTimelineViewController: 2021/4/8
// * StatusTableViewControllerAspect: 2021/4/7
// (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
@ -17,9 +26,9 @@ protocol StatusTableViewControllerAspect: UIViewController {
var tableView: UITableView { get }
}
// MARK: - UIViewController
// MARK: - UIViewController [A]
// aspectViewWillAppear(_:)
// [A1] aspectViewWillAppear(_:)
extension StatusTableViewControllerAspect {
/// [UI] hook to deselect row in the transitioning for the table view
func aspectViewWillAppear(_ animated: Bool) {
@ -31,12 +40,13 @@ 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
// MARK: - UITableViewDelegate [B]
// aspectTableView(_:estimatedHeightForRowAt:)
// [B1] aspectTableView(_:estimatedHeightForRowAt:)
extension StatusTableViewControllerAspect where Self: LoadMoreConfigurableTableViewContainer {
/// [Data Source] hook to notify table view bottom loader
func aspectScrollViewDidScroll(_ scrollView: UIScrollView) {
@ -44,7 +54,7 @@ extension StatusTableViewControllerAspect where Self: LoadMoreConfigurableTableV
}
}
// aspectTableView(_:estimatedHeightForRowAt:)
// [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 {
@ -52,7 +62,14 @@ extension StatusTableViewControllerAspect where Self: TableViewCellHeightCacheab
}
}
// StatusTableViewControllerAspect.aspectTableView(_:didEndDisplaying:forRowAt:)
// [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] StatusTableViewControllerAspect.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) {
@ -76,9 +93,19 @@ extension StatusTableViewControllerAspect where Self: StatusTableViewCellDelegat
}
}
// MARK: - AVPlayerViewControllerDelegate & NeedsDependency
// MARK: - UITableViewDataSourcePrefetching [C]
// aspectPlayerViewController(_:willBeginFullScreenPresentationWithAnimationCoordinator:)
// [C1] aspectTableView(:prefetchRowsAt)
extension StatusTableViewControllerAspect where Self: UITableViewDataSourcePrefetching & StatusTableViewCellDelegate & StatusProvider {
/// [Data Source] hook to prefetch reply to info for status
func aspectTableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
handleTableView(tableView, prefetchRowsAt: 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) {
@ -86,7 +113,7 @@ extension StatusTableViewControllerAspect where Self: AVPlayerViewControllerDele
}
}
// aspectPlayerViewController(_:willEndFullScreenPresentationWithAnimationCoordinator:)
// [D2] aspectPlayerViewController(_:willEndFullScreenPresentationWithAnimationCoordinator:)
extension StatusTableViewControllerAspect where Self: AVPlayerViewControllerDelegate & NeedsDependency {
/// [Media] hook to mark transitioning to video service
func aspectPlayerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {

View File

@ -27,7 +27,7 @@ extension TableViewCellHeightCacheableContainer {
if case .bottomLoader = item {
return TimelineLoaderTableViewCell.cellHeight
} else {
return 200
return UITableView.automaticDimension
}
}

View File

@ -111,6 +111,9 @@ extension HashtagTimelineViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
aspectViewWillAppear(animated)
viewModel.fetchTag()
guard viewModel.loadLatestStateMachine.currentState is HashtagTimelineViewModel.LoadLatestState.Initial else { return }
@ -120,8 +123,8 @@ extension HashtagTimelineViewController {
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
context.videoPlaybackService.viewDidDisappear(from: self)
context.audioPlaybackService.viewDidDisappear(from: self)
aspectViewDidDisappear(animated)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
@ -158,6 +161,7 @@ extension HashtagTimelineViewController {
subtitle = L10n.Scene.Hashtag.prompt("\(peopleTalkingNumber)")
}
}
}
extension HashtagTimelineViewController {
@ -176,11 +180,20 @@ extension HashtagTimelineViewController {
}
}
// MARK: - StatusTableViewControllerAspect
extension HashtagTimelineViewController: StatusTableViewControllerAspect { }
// MARK: - TableViewCellHeightCacheableContainer
extension HashtagTimelineViewController: TableViewCellHeightCacheableContainer {
var cellFrameCache: NSCache<NSNumber, NSValue> {
return viewModel.cellFrameCache
}
}
// MARK: - UIScrollViewDelegate
extension HashtagTimelineViewController {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
handleScrollViewDidScroll(scrollView)
// self.viewModel.homeTimelineNavigationBarState.handleScrollViewDidScroll(scrollView)
aspectScrollViewDidScroll(scrollView)
}
}
@ -194,25 +207,16 @@ extension HashtagTimelineViewController: LoadMoreConfigurableTableViewContainer
// MARK: - UITableViewDelegate
extension HashtagTimelineViewController: UITableViewDelegate {
// TODO:
// func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
// guard let diffableDataSource = viewModel.diffableDataSource else { return 100 }
// guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return 100 }
//
// guard let frame = viewModel.cellFrameCache.object(forKey: NSNumber(value: item.hashValue))?.cgRectValue else {
// return 200
// }
// // os_log("%{public}s[%{public}ld], %{public}s: cache cell frame %s", ((#file as NSString).lastPathComponent), #line, #function, frame.debugDescription)
//
// return ceil(frame.height)
// }
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return aspectTableView(tableView, estimatedHeightForRowAt: indexPath)
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
handleTableView(tableView, willDisplay: cell, forRowAt: indexPath)
aspectTableView(tableView, willDisplay: cell, forRowAt: indexPath)
}
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
handleTableView(tableView, didEndDisplaying: cell, forRowAt: indexPath)
aspectTableView(tableView, didEndDisplaying: cell, forRowAt: indexPath)
}
}
@ -227,7 +231,7 @@ extension HashtagTimelineViewController: ContentOffsetAdjustableTimelineViewCont
// MARK: - UITableViewDataSourcePrefetching
extension HashtagTimelineViewController: UITableViewDataSourcePrefetching {
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
handleTableView(tableView, prefetchRowsAt: indexPaths)
aspectTableView(tableView, prefetchRowsAt: indexPaths)
}
}
@ -298,11 +302,11 @@ extension HashtagTimelineViewController: TimelineMiddleLoaderTableViewCellDelega
extension HashtagTimelineViewController: AVPlayerViewControllerDelegate {
func playerViewController(_ playerViewController: AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
handlePlayerViewController(playerViewController, willBeginFullScreenPresentationWithAnimationCoordinator: coordinator)
aspectPlayerViewController(playerViewController, willBeginFullScreenPresentationWithAnimationCoordinator: coordinator)
}
func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
handlePlayerViewController(playerViewController, willEndFullScreenPresentationWithAnimationCoordinator: coordinator)
aspectPlayerViewController(playerViewController, willEndFullScreenPresentationWithAnimationCoordinator: coordinator)
}
}

View File

@ -59,6 +59,7 @@ extension FavoriteViewController {
])
tableView.delegate = self
tableView.prefetchDataSource = self
viewModel.setupDiffableDataSource(
for: tableView,
dependency: self,
@ -105,26 +106,36 @@ extension FavoriteViewController: UITableViewDelegate {
aspectTableView(tableView, estimatedHeightForRowAt: indexPath)
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
aspectTableView(tableView, willDisplay: cell, forRowAt: indexPath)
}
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
aspectTableView(tableView, didEndDisplaying: cell, forRowAt: indexPath)
}
}
// MARK: - UITableViewDataSourcePrefetching
extension FavoriteViewController: UITableViewDataSourcePrefetching {
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
aspectTableView(tableView, prefetchRowsAt: indexPaths)
}
}
// MARK: - AVPlayerViewControllerDelegate
extension FavoriteViewController: AVPlayerViewControllerDelegate {
func playerViewController(_ playerViewController: AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
handlePlayerViewController(playerViewController, willBeginFullScreenPresentationWithAnimationCoordinator: coordinator)
aspectPlayerViewController(playerViewController, willBeginFullScreenPresentationWithAnimationCoordinator: coordinator)
}
func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) {
handlePlayerViewController(playerViewController, willEndFullScreenPresentationWithAnimationCoordinator: coordinator)
aspectPlayerViewController(playerViewController, willEndFullScreenPresentationWithAnimationCoordinator: coordinator)
}
}
// MARK: - TimelinePostTableViewCellDelegate
extension FavoriteViewController: StatusTableViewCellDelegate {
weak var playerViewControllerDelegate: AVPlayerViewControllerDelegate? { return self }

View File

@ -36,7 +36,7 @@ extension ProfileRelationshipActionButton {
setBackgroundImage(.placeholder(color: actionOptionSet.backgroundColor.withAlphaComponent(0.5)), for: .highlighted)
setBackgroundImage(.placeholder(color: actionOptionSet.backgroundColor.withAlphaComponent(0.5)), for: .disabled)
if let option = actionOptionSet.highPriorityAction(except: .editOptions), option == .blocked {
if let option = actionOptionSet.highPriorityAction(except: .editOptions), option == .blocked || option == .suspended {
isEnabled = false
} else {
isEnabled = true

View File

@ -57,6 +57,7 @@ extension UserTimelineViewController {
])
tableView.delegate = self
tableView.prefetchDataSource = self
viewModel.setupDiffableDataSource(
for: tableView,
dependency: self,
@ -115,12 +116,23 @@ extension UserTimelineViewController: UITableViewDelegate {
aspectTableView(tableView, estimatedHeightForRowAt: indexPath)
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
aspectTableView(tableView, willDisplay: cell, forRowAt: indexPath)
}
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
aspectTableView(tableView, didEndDisplaying: cell, forRowAt: indexPath)
}
}
// MARK: - UITableViewDataSourcePrefetching
extension UserTimelineViewController: UITableViewDataSourcePrefetching {
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
aspectTableView(tableView, prefetchRowsAt: indexPaths)
}
}
// MARK: - AVPlayerViewControllerDelegate
extension UserTimelineViewController: AVPlayerViewControllerDelegate {
@ -140,10 +152,6 @@ extension UserTimelineViewController: StatusTableViewCellDelegate {
func parent() -> UIViewController { return self }
}
//// MARK: - TimelineHeaderTableViewCellDelegate
//extension UserTimelineViewController: TimelineHeaderTableViewCellDelegate { }
// MARK: - CustomScrollViewContainerController
extension UserTimelineViewController: ScrollViewContainer {
var scrollView: UIScrollView { return tableView }