Merge pull request #179 from tootsuite/fix/timeline

Fix UI and data source logic issues for timeline
This commit is contained in:
CMK 2021-06-24 11:46:26 +08:00 committed by GitHub
commit 65b1e40355
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 43 additions and 16 deletions

View File

@ -266,6 +266,7 @@
DB5086BE25CC0D9900C2C187 /* SplashPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5086BD25CC0D9900C2C187 /* SplashPreference.swift */; };
DB51D172262832380062B7A1 /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB51D170262832380062B7A1 /* BlurHashDecode.swift */; };
DB51D173262832380062B7A1 /* BlurHashEncode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB51D171262832380062B7A1 /* BlurHashEncode.swift */; };
DB52D33A26839DD800D43133 /* ImageTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB52D33926839DD800D43133 /* ImageTask.swift */; };
DB55D33025FB630A0002F825 /* TwitterTextEditor+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB55D32F25FB630A0002F825 /* TwitterTextEditor+String.swift */; };
DB59F0FE25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F0FD25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift */; };
DB59F10425EF5EBC001F1DAB /* TableViewCellHeightCacheableContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F10325EF5EBC001F1DAB /* TableViewCellHeightCacheableContainer.swift */; };
@ -883,6 +884,7 @@
DB5086BD25CC0D9900C2C187 /* SplashPreference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SplashPreference.swift; sourceTree = "<group>"; };
DB51D170262832380062B7A1 /* BlurHashDecode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = "<group>"; };
DB51D171262832380062B7A1 /* BlurHashEncode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlurHashEncode.swift; sourceTree = "<group>"; };
DB52D33926839DD800D43133 /* ImageTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageTask.swift; sourceTree = "<group>"; };
DB55D32F25FB630A0002F825 /* TwitterTextEditor+String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "TwitterTextEditor+String.swift"; sourceTree = "<group>"; };
DB59F0FD25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusProvider+UITableViewDelegate.swift"; sourceTree = "<group>"; };
DB59F10325EF5EBC001F1DAB /* TableViewCellHeightCacheableContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewCellHeightCacheableContainer.swift; sourceTree = "<group>"; };
@ -2267,6 +2269,7 @@
DB6D1B23263684C600ACB481 /* UserDefaults.swift */,
DB97131E2666078B00BD1E90 /* Date.swift */,
DBAC6489267DC355007FE9FD /* NSDiffableDataSourceSnapshot.swift */,
DB52D33926839DD800D43133 /* ImageTask.swift */,
);
path = Extension;
sourceTree = "<group>";
@ -3260,6 +3263,7 @@
DBCBCC012680AF2A000F5B51 /* AsyncHomeTimelineViewModel+Diffable.swift in Sources */,
DBCC3B36261440BA0045B23D /* UINavigationController.swift in Sources */,
DBB525852612D6DD002F1F29 /* ProfileStatusDashboardMeterView.swift in Sources */,
DB52D33A26839DD800D43133 /* ImageTask.swift in Sources */,
2D84350525FF858100EECE90 /* UIScrollView.swift in Sources */,
DB49A61F25FF32AA00B98345 /* EmojiService+CustomEmojiViewModel.swift in Sources */,
2D76316B25C14D4C00929FB9 /* PublicTimelineViewModel.swift in Sources */,

View File

@ -17,17 +17,17 @@
<key>Mastodon - ASDK.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
<integer>2</integer>
</dict>
<key>Mastodon - RTL.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
<integer>3</integer>
</dict>
<key>Mastodon - Release.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
<integer>1</integer>
</dict>
<key>Mastodon.xcscheme_^#shared#^_</key>
<dict>
@ -37,7 +37,7 @@
<key>NotificationService.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
<integer>20</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@ -685,7 +685,9 @@ extension StatusSection {
case .success:
statusItemAttribute.isImageLoaded.value = true
}
}
}?
.store(in: &cell.statusView.statusMosaicImageViewContainer.imageTasks)
imageView.accessibilityLabel = meta.altText

View File

@ -0,0 +1,15 @@
//
// ImageTask.swift
// Mastodon
//
// Created by Cirno MainasuK on 2021-6-24.
//
import Foundation
import Nuke
extension ImageTask {
func store(in set: inout Set<ImageTask?>) {
set.insert(self)
}
}

View File

@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.922",
"green" : "0.898",
"red" : "0.867"
"blue" : "0x43",
"green" : "0x35",
"red" : "0x31"
}
},
"idiom" : "universal"

View File

@ -62,10 +62,10 @@ final class UserTimelineViewModel {
.store(in: &disposeBag)
Publishers.CombineLatest4(
statusFetchedResultsController.objectIDs.eraseToAnyPublisher(),
isBlocking.eraseToAnyPublisher(),
isBlockedBy.eraseToAnyPublisher(),
isSuspended.eraseToAnyPublisher()
statusFetchedResultsController.objectIDs.removeDuplicates(),
isBlocking,
isBlockedBy,
isSuspended
)
.receive(on: DispatchQueue.main)
.debounce(for: .milliseconds(300), scheduler: DispatchQueue.main)
@ -76,12 +76,12 @@ final class UserTimelineViewModel {
var items: [Item] = []
var snapshot = NSDiffableDataSourceSnapshot<StatusSection, Item>()
snapshot.appendSections([.main])
defer {
// not animate when empty items fix loader first appear layout issue
diffableDataSource.apply(snapshot, animatingDifferences: !items.isEmpty)
}
guard !isBlocking else {
snapshot.appendItems([Item.emptyStateHeader(attribute: Item.EmptyStateHeaderAttribute(reason: .blocking))], toSection: .main)
return
@ -97,14 +97,14 @@ final class UserTimelineViewModel {
snapshot.appendItems([Item.emptyStateHeader(attribute: Item.EmptyStateHeaderAttribute(reason: .suspended(name: name)))], toSection: .main)
return
}
var oldSnapshotAttributeDict: [NSManagedObjectID : Item.StatusAttribute] = [:]
let oldSnapshot = diffableDataSource.snapshot()
for item in oldSnapshot.itemIdentifiers {
guard case let .status(objectID, attribute) = item else { continue }
oldSnapshotAttributeDict[objectID] = attribute
}
for objectID in objectIDs {
let attribute = oldSnapshotAttributeDict[objectID] ?? Item.StatusAttribute()
items.append(.status(objectID: objectID, attribute: attribute))

View File

@ -8,6 +8,7 @@
import os.log
import func AVFoundation.AVMakeRect
import UIKit
import Nuke
protocol MosaicImageViewContainerPresentable: AnyObject {
var mosaicImageViewContainer: MosaicImageViewContainer { get }
@ -22,6 +23,8 @@ protocol MosaicImageViewContainerDelegate: AnyObject {
final class MosaicImageViewContainer: UIView {
weak var delegate: MosaicImageViewContainerDelegate?
var imageTasks = Set<ImageTask?>()
let container = UIStackView()
private(set) lazy var imageViews: [UIImageView] = {
@ -93,6 +96,9 @@ extension MosaicImageViewContainer {
extension MosaicImageViewContainer {
func reset() {
imageTasks.forEach { $0?.cancel() }
imageTasks.removeAll()
container.arrangedSubviews.forEach { subview in
container.removeArrangedSubview(subview)
subview.removeFromSuperview()