feat: add cell height cache for user timeline

This commit is contained in:
CMK 2022-02-14 16:09:39 +08:00
parent 3d7ade1747
commit 66c1b71610
8 changed files with 79 additions and 222 deletions

View File

@ -37,7 +37,6 @@
2D35237A26256D920031AF25 /* NotificationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D35237926256D920031AF25 /* NotificationSection.swift */; }; 2D35237A26256D920031AF25 /* NotificationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D35237926256D920031AF25 /* NotificationSection.swift */; };
2D364F7225E66D7500204FDC /* MastodonResendEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */; }; 2D364F7225E66D7500204FDC /* MastodonResendEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */; };
2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */; }; 2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */; };
2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */; };
2D38F1D525CD465300561493 /* HomeTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1D425CD465300561493 /* HomeTimelineViewController.swift */; }; 2D38F1D525CD465300561493 /* HomeTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1D425CD465300561493 /* HomeTimelineViewController.swift */; };
2D38F1E525CD46C100561493 /* HomeTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1E425CD46C100561493 /* HomeTimelineViewModel.swift */; }; 2D38F1E525CD46C100561493 /* HomeTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1E425CD46C100561493 /* HomeTimelineViewModel.swift */; };
2D38F1EB25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1EA25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift */; }; 2D38F1EB25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1EA25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift */; };
@ -255,6 +254,7 @@
DB49A61F25FF32AA00B98345 /* EmojiService+CustomEmojiViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB49A61E25FF32AA00B98345 /* EmojiService+CustomEmojiViewModel.swift */; }; DB49A61F25FF32AA00B98345 /* EmojiService+CustomEmojiViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB49A61E25FF32AA00B98345 /* EmojiService+CustomEmojiViewModel.swift */; };
DB49A62525FF334C00B98345 /* EmojiService+CustomEmojiViewModel+LoadState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB49A62425FF334C00B98345 /* EmojiService+CustomEmojiViewModel+LoadState.swift */; }; DB49A62525FF334C00B98345 /* EmojiService+CustomEmojiViewModel+LoadState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB49A62425FF334C00B98345 /* EmojiService+CustomEmojiViewModel+LoadState.swift */; };
DB49A62B25FF36C700B98345 /* APIService+CustomEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB49A62A25FF36C700B98345 /* APIService+CustomEmoji.swift */; }; DB49A62B25FF36C700B98345 /* APIService+CustomEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB49A62A25FF36C700B98345 /* APIService+CustomEmoji.swift */; };
DB4AA6B327BA34B6009EC082 /* CellFrameCacheContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4AA6B227BA34B6009EC082 /* CellFrameCacheContainer.swift */; };
DB4F0963269ED06300D62E92 /* SearchResultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0962269ED06300D62E92 /* SearchResultViewController.swift */; }; DB4F0963269ED06300D62E92 /* SearchResultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0962269ED06300D62E92 /* SearchResultViewController.swift */; };
DB4F0966269ED52200D62E92 /* SearchResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0965269ED52200D62E92 /* SearchResultViewModel.swift */; }; DB4F0966269ED52200D62E92 /* SearchResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0965269ED52200D62E92 /* SearchResultViewModel.swift */; };
DB4F0968269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0967269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift */; }; DB4F0968269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0967269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift */; };
@ -558,7 +558,6 @@
DBE3CDFB261C6CA500430CC6 /* FavoriteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CDFA261C6CA500430CC6 /* FavoriteViewModel.swift */; }; DBE3CDFB261C6CA500430CC6 /* FavoriteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CDFA261C6CA500430CC6 /* FavoriteViewModel.swift */; };
DBE3CE01261D623D00430CC6 /* FavoriteViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE00261D623D00430CC6 /* FavoriteViewModel+State.swift */; }; DBE3CE01261D623D00430CC6 /* FavoriteViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE00261D623D00430CC6 /* FavoriteViewModel+State.swift */; };
DBE3CE07261D6A0E00430CC6 /* FavoriteViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE06261D6A0E00430CC6 /* FavoriteViewModel+Diffable.swift */; }; DBE3CE07261D6A0E00430CC6 /* FavoriteViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE06261D6A0E00430CC6 /* FavoriteViewModel+Diffable.swift */; };
DBE3CE13261D7D4200430CC6 /* StatusTableViewControllerAspect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE12261D7D4200430CC6 /* StatusTableViewControllerAspect.swift */; };
DBE54AC62636C89F004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; }; DBE54AC62636C89F004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; };
DBE54ACC2636C8FD004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; }; DBE54ACC2636C8FD004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; };
DBF156DF2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF156DE2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift */; }; DBF156DF2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF156DE2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift */; };
@ -729,7 +728,6 @@
2D35237926256D920031AF25 /* NotificationSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSection.swift; sourceTree = "<group>"; }; 2D35237926256D920031AF25 /* NotificationSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSection.swift; sourceTree = "<group>"; };
2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewController.swift; sourceTree = "<group>"; }; 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewController.swift; sourceTree = "<group>"; };
2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewModel.swift; sourceTree = "<group>"; }; 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewModel.swift; sourceTree = "<group>"; };
2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentOffsetAdjustableTimelineViewControllerDelegate.swift; sourceTree = "<group>"; };
2D38F1D425CD465300561493 /* HomeTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineViewController.swift; sourceTree = "<group>"; }; 2D38F1D425CD465300561493 /* HomeTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineViewController.swift; sourceTree = "<group>"; };
2D38F1E425CD46C100561493 /* HomeTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineViewModel.swift; sourceTree = "<group>"; }; 2D38F1E425CD46C100561493 /* HomeTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineViewModel.swift; sourceTree = "<group>"; };
2D38F1EA25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeTimelineViewModel+LoadLatestState.swift"; sourceTree = "<group>"; }; 2D38F1EA25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeTimelineViewModel+LoadLatestState.swift"; sourceTree = "<group>"; };
@ -978,6 +976,7 @@
DB49A61E25FF32AA00B98345 /* EmojiService+CustomEmojiViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EmojiService+CustomEmojiViewModel.swift"; sourceTree = "<group>"; }; DB49A61E25FF32AA00B98345 /* EmojiService+CustomEmojiViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EmojiService+CustomEmojiViewModel.swift"; sourceTree = "<group>"; };
DB49A62425FF334C00B98345 /* EmojiService+CustomEmojiViewModel+LoadState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EmojiService+CustomEmojiViewModel+LoadState.swift"; sourceTree = "<group>"; }; DB49A62425FF334C00B98345 /* EmojiService+CustomEmojiViewModel+LoadState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EmojiService+CustomEmojiViewModel+LoadState.swift"; sourceTree = "<group>"; };
DB49A62A25FF36C700B98345 /* APIService+CustomEmoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+CustomEmoji.swift"; sourceTree = "<group>"; }; DB49A62A25FF36C700B98345 /* APIService+CustomEmoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+CustomEmoji.swift"; sourceTree = "<group>"; };
DB4AA6B227BA34B6009EC082 /* CellFrameCacheContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CellFrameCacheContainer.swift; sourceTree = "<group>"; };
DB4B777F26CA4EFA00B087B3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Intents.strings; sourceTree = "<group>"; }; DB4B777F26CA4EFA00B087B3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Intents.strings; sourceTree = "<group>"; };
DB4B778226CA4EFA00B087B3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = "<group>"; }; DB4B778226CA4EFA00B087B3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = "<group>"; };
DB4B778326CA4EFA00B087B3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Intents.stringsdict; sourceTree = "<group>"; }; DB4B778326CA4EFA00B087B3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Intents.stringsdict; sourceTree = "<group>"; };
@ -1292,7 +1291,6 @@
DBE3CDFA261C6CA500430CC6 /* FavoriteViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteViewModel.swift; sourceTree = "<group>"; }; DBE3CDFA261C6CA500430CC6 /* FavoriteViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteViewModel.swift; sourceTree = "<group>"; };
DBE3CE00261D623D00430CC6 /* FavoriteViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavoriteViewModel+State.swift"; sourceTree = "<group>"; }; DBE3CE00261D623D00430CC6 /* FavoriteViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavoriteViewModel+State.swift"; sourceTree = "<group>"; };
DBE3CE06261D6A0E00430CC6 /* FavoriteViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavoriteViewModel+Diffable.swift"; sourceTree = "<group>"; }; DBE3CE06261D6A0E00430CC6 /* FavoriteViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavoriteViewModel+Diffable.swift"; sourceTree = "<group>"; };
DBE3CE12261D7D4200430CC6 /* StatusTableViewControllerAspect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewControllerAspect.swift; sourceTree = "<group>"; };
DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPreference.swift; sourceTree = "<group>"; }; DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPreference.swift; sourceTree = "<group>"; };
DBF156DE2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarAddAccountCollectionViewCell.swift; sourceTree = "<group>"; }; DBF156DE2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarAddAccountCollectionViewCell.swift; sourceTree = "<group>"; };
DBF156E02702DA6800EC00B7 /* Mastodon-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Mastodon-Bridging-Header.h"; sourceTree = "<group>"; }; DBF156E02702DA6800EC00B7 /* Mastodon-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Mastodon-Bridging-Header.h"; sourceTree = "<group>"; };
@ -1668,14 +1666,13 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DB697DD7278F4C34004EF2F7 /* Provider */, DB697DD7278F4C34004EF2F7 /* Provider */,
DB0FCB7127952986006C02E2 /* NamingState.swift */,
2D5A3D3725CF8D9F002347D6 /* ScrollViewContainer.swift */, 2D5A3D3725CF8D9F002347D6 /* ScrollViewContainer.swift */,
2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */, DB4AA6B227BA34B6009EC082 /* CellFrameCacheContainer.swift */,
2D38F20725CD491300561493 /* DisposeBagCollectable.swift */, 2D38F20725CD491300561493 /* DisposeBagCollectable.swift */,
DBE3CE12261D7D4200430CC6 /* StatusTableViewControllerAspect.swift */,
DB1D84372657B275000346B3 /* SegmentedControlNavigateable.swift */, DB1D84372657B275000346B3 /* SegmentedControlNavigateable.swift */,
DB1D843326579931000346B3 /* TableViewControllerNavigateable.swift */, DB1D843326579931000346B3 /* TableViewControllerNavigateable.swift */,
DB1D842D26552C4D000346B3 /* StatusTableViewControllerNavigateable.swift */, DB1D842D26552C4D000346B3 /* StatusTableViewControllerNavigateable.swift */,
DB0FCB7127952986006C02E2 /* NamingState.swift */,
); );
path = Protocol; path = Protocol;
sourceTree = "<group>"; sourceTree = "<group>";
@ -4049,7 +4046,6 @@
DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */, DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */,
DB023D2C27A10464005AC798 /* NotificationTimelineViewController+DataSourceProvider.swift in Sources */, DB023D2C27A10464005AC798 /* NotificationTimelineViewController+DataSourceProvider.swift in Sources */,
DB9D6BE925E4F5340051B173 /* SearchViewController.swift in Sources */, DB9D6BE925E4F5340051B173 /* SearchViewController.swift in Sources */,
2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */,
DBF1D257269DBAC600C1C08A /* SearchDetailViewModel.swift in Sources */, DBF1D257269DBAC600C1C08A /* SearchDetailViewModel.swift in Sources */,
DB03F7F52689B782007B274C /* ComposeTableView.swift in Sources */, DB03F7F52689B782007B274C /* ComposeTableView.swift in Sources */,
DBB45B5927B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift in Sources */, DBB45B5927B39FE4002DC5A7 /* MediaPreviewVideoViewModel.swift in Sources */,
@ -4064,6 +4060,7 @@
DB73BF4B27140C0800781945 /* UITableViewDiffableDataSource.swift in Sources */, DB73BF4B27140C0800781945 /* UITableViewDiffableDataSource.swift in Sources */,
DBB525642612C988002F1F29 /* MeProfileViewModel.swift in Sources */, DBB525642612C988002F1F29 /* MeProfileViewModel.swift in Sources */,
DB6B74EF272FB55000C70B6E /* FollowerListViewController.swift in Sources */, DB6B74EF272FB55000C70B6E /* FollowerListViewController.swift in Sources */,
DB4AA6B327BA34B6009EC082 /* CellFrameCacheContainer.swift in Sources */,
DB0FCB942797E2B0006C02E2 /* SearchResultViewModel+Diffable.swift in Sources */, DB0FCB942797E2B0006C02E2 /* SearchResultViewModel+Diffable.swift in Sources */,
DB63F752279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift in Sources */, DB63F752279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift in Sources */,
DBBC24C426A544B900398BB9 /* Theme.swift in Sources */, DBBC24C426A544B900398BB9 /* Theme.swift in Sources */,
@ -4250,7 +4247,6 @@
2D6DE40026141DF600A63F6A /* SearchViewModel.swift in Sources */, 2D6DE40026141DF600A63F6A /* SearchViewModel.swift in Sources */,
DB51D172262832380062B7A1 /* BlurHashDecode.swift in Sources */, DB51D172262832380062B7A1 /* BlurHashDecode.swift in Sources */,
DBCCC71E25F73297007E1AB6 /* APIService+Reblog.swift in Sources */, DBCCC71E25F73297007E1AB6 /* APIService+Reblog.swift in Sources */,
DBE3CE13261D7D4200430CC6 /* StatusTableViewControllerAspect.swift in Sources */,
DB0617FD27855BFE0030EE79 /* ServerRuleItem.swift in Sources */, DB0617FD27855BFE0030EE79 /* ServerRuleItem.swift in Sources */,
5BB04FD5262E7AFF0043BFF6 /* ReportViewController.swift in Sources */, 5BB04FD5262E7AFF0043BFF6 /* ReportViewController.swift in Sources */,
DBAE3F942616E28B004B8251 /* APIService+Follow.swift in Sources */, DBAE3F942616E28B004B8251 /* APIService+Follow.swift in Sources */,

View File

@ -2,7 +2,13 @@
// DO NOT EDIT // DO NOT EDIT
// sourcery:inline:FollowingListViewController.AutoGenerateTableViewDelegate
// sourcery:inline:UserTimelineViewController.AutoGenerateTableViewDelegate
// Generated using Sourcery // Generated using Sourcery
// DO NOT EDIT // DO NOT EDIT
@ -10,11 +16,20 @@ func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
aspectTableView(tableView, didSelectRowAt: indexPath) aspectTableView(tableView, didSelectRowAt: indexPath)
} }
func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
return aspectTableView(tableView, contextMenuConfigurationForRowAt: indexPath, point: point)
}
func tableView(_ tableView: UITableView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
return aspectTableView(tableView, previewForHighlightingContextMenuWithConfiguration: configuration)
}
func tableView(_ tableView: UITableView, previewForDismissingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? {
return aspectTableView(tableView, previewForDismissingContextMenuWithConfiguration: configuration)
}
func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) {
aspectTableView(tableView, willPerformPreviewActionForMenuWith: configuration, animator: animator)
}
// sourcery:end // sourcery:end

View File

@ -0,0 +1,29 @@
//
// CellFrameCacheContainer.swift
// TwidereX
//
// Created by Cirno MainasuK on 2021-10-13.
// Copyright © 2021 Twidere. All rights reserved.
//
import UIKit
protocol CellFrameCacheContainer {
var cellFrameCache: NSCache<NSNumber, NSValue> { get }
func keyForCache(tableView: UITableView, indexPath: IndexPath) -> NSNumber?
}
extension CellFrameCacheContainer {
func cacheCellFrame(tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard let key = keyForCache(tableView: tableView, indexPath: indexPath) else { return }
let value = NSValue(cgRect: cell.frame)
cellFrameCache.setObject(value, forKey: key)
}
func retrieveCellFrame(tableView: UITableView, indexPath: IndexPath) -> CGRect? {
guard let key = keyForCache(tableView: tableView, indexPath: indexPath) else { return nil }
guard let frame = cellFrameCache.object(forKey: key)?.cgRectValue else { return nil }
return frame
}
}

View File

@ -1,13 +0,0 @@
//
// ContentOffsetAdjustableTimelineViewControllerDelegate.swift
// Mastodon
//
// Created by sxiaojian on 2021/2/5.
//
import UIKit
protocol ContentOffsetAdjustableTimelineViewControllerDelegate: AnyObject {
func navigationBar() -> UINavigationBar?
}

View File

@ -1,182 +0,0 @@
////
//// 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)
// }
//}
//

View File

@ -183,7 +183,6 @@ extension HomeTimelineViewController {
]) ])
viewModel.tableView = tableView viewModel.tableView = tableView
viewModel.contentOffsetAdjustableTimelineViewControllerDelegate = self
tableView.delegate = self tableView.delegate = self
viewModel.setupDiffableDataSource( viewModel.setupDiffableDataSource(
tableView: tableView, tableView: tableView,
@ -556,13 +555,6 @@ extension HomeTimelineViewController: UITableViewDelegate, AutoGenerateTableView
} }
// MARK: - ContentOffsetAdjustableTimelineViewControllerDelegate
extension HomeTimelineViewController: ContentOffsetAdjustableTimelineViewControllerDelegate {
func navigationBar() -> UINavigationBar? {
return navigationController?.navigationBar
}
}
// MARK: - TimelineMiddleLoaderTableViewCellDelegate // MARK: - TimelineMiddleLoaderTableViewCellDelegate
extension HomeTimelineViewController: TimelineMiddleLoaderTableViewCellDelegate { extension HomeTimelineViewController: TimelineMiddleLoaderTableViewCellDelegate {
func timelineMiddleLoaderTableViewCell(_ cell: TimelineMiddleLoaderTableViewCell, loadMoreButtonDidPressed button: UIButton) { func timelineMiddleLoaderTableViewCell(_ cell: TimelineMiddleLoaderTableViewCell, loadMoreButtonDidPressed button: UIButton) {

View File

@ -35,7 +35,6 @@ final class HomeTimelineViewModel: NSObject {
@Published var displaySettingBarButtonItem = true @Published var displaySettingBarButtonItem = true
@Published var displayComposeBarButtonItem = true @Published var displayComposeBarButtonItem = true
weak var contentOffsetAdjustableTimelineViewControllerDelegate: ContentOffsetAdjustableTimelineViewControllerDelegate?
weak var tableView: UITableView? weak var tableView: UITableView?
weak var timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate? weak var timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate?

View File

@ -36,7 +36,7 @@ final class UserTimelineViewController: UIViewController, NeedsDependency, Media
return tableView return tableView
}() }()
var overrideNavigationScrollPosition: UITableView.ScrollPosition? = nil let cellFrameCache = NSCache<NSNumber, NSValue>()
deinit { deinit {
os_log("%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) os_log("%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
@ -93,6 +93,16 @@ extension UserTimelineViewController {
} }
// MARK: - CellFrameCacheContainer
extension UserTimelineViewController: CellFrameCacheContainer {
func keyForCache(tableView: UITableView, indexPath: IndexPath) -> NSNumber? {
guard let diffableDataSource = viewModel.diffableDataSource else { return nil }
guard let item = diffableDataSource.itemIdentifier(for: indexPath) else { return nil }
let key = NSNumber(value: item.hashValue)
return key
}
}
// MARK: - UITableViewDelegate // MARK: - UITableViewDelegate
extension UserTimelineViewController: UITableViewDelegate, AutoGenerateTableViewDelegate { extension UserTimelineViewController: UITableViewDelegate, AutoGenerateTableViewDelegate {
// sourcery:inline:UserTimelineViewController.AutoGenerateTableViewDelegate // sourcery:inline:UserTimelineViewController.AutoGenerateTableViewDelegate
@ -121,6 +131,17 @@ extension UserTimelineViewController: UITableViewDelegate, AutoGenerateTableView
// sourcery:end // sourcery:end
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
guard let frame = retrieveCellFrame(tableView: tableView, indexPath: indexPath) else {
return 200
}
return ceil(frame.height)
}
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cacheCellFrame(tableView: tableView, didEndDisplaying: cell, forRowAt: indexPath)
}
} }
// MARK: - CustomScrollViewContainerController // MARK: - CustomScrollViewContainerController