* Add image prefectch to the timeline * Use preview url for post with multiple attachements * Add image resize * Prefetch link cards --------- Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
This commit is contained in:
parent
7cc1ca44b5
commit
a8459638e9
|
@ -166,6 +166,7 @@ public struct StatusRowMediaPreviewView: View {
|
|||
.frame(width: newSize.width, height: newSize.height)
|
||||
}
|
||||
}
|
||||
.processors([ImageProcessors.Resize(size: .init(width: newSize.width, height: newSize.height))])
|
||||
.frame(width: newSize.width, height: newSize.height)
|
||||
|
||||
case .gifv, .video, .audio:
|
||||
|
@ -205,13 +206,14 @@ public struct StatusRowMediaPreviewView: View {
|
|||
GeometryReader { proxy in
|
||||
switch type {
|
||||
case .image:
|
||||
let width = isNotifications ? imageMaxHeight : proxy.frame(in: .local).width
|
||||
ZStack(alignment: .bottomTrailing) {
|
||||
LazyImage(url: attachment.url) { state in
|
||||
LazyImage(url: attachment.previewUrl ?? attachment.url) { state in
|
||||
if let image = state.imageContainer?.image {
|
||||
SwiftUI.Image(uiImage: image)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(maxWidth: isNotifications ? imageMaxHeight : proxy.frame(in: .local).width)
|
||||
.frame(maxWidth: width)
|
||||
.frame(maxHeight: imageMaxHeight)
|
||||
.clipped()
|
||||
.cornerRadius(4)
|
||||
|
@ -219,9 +221,10 @@ public struct StatusRowMediaPreviewView: View {
|
|||
RoundedRectangle(cornerRadius: 4)
|
||||
.fill(Color.gray)
|
||||
.frame(maxHeight: imageMaxHeight)
|
||||
.frame(maxWidth: isNotifications ? imageMaxHeight : proxy.frame(in: .local).width)
|
||||
.frame(maxWidth: width)
|
||||
}
|
||||
}
|
||||
.processors([ImageProcessors.Resize(size: .init(width: width, height: imageMaxHeight))])
|
||||
if sensitive {
|
||||
cornerSensitiveButton
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import SwiftUI
|
||||
import UIKit
|
||||
import Models
|
||||
import Nuke
|
||||
|
||||
final class TimelinePrefetcher: NSObject, ObservableObject, UICollectionViewDataSourcePrefetching {
|
||||
private let prefetcher = ImagePrefetcher()
|
||||
|
||||
weak var viewModel: TimelineViewModel?
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
|
||||
let imageURLs = getImageURLs(for: indexPaths)
|
||||
prefetcher.startPrefetching(with: imageURLs)
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cancelPrefetchingForItemsAt indexPaths: [IndexPath]) {
|
||||
let imageURLs = getImageURLs(for: indexPaths)
|
||||
prefetcher.stopPrefetching(with: imageURLs)
|
||||
}
|
||||
|
||||
private func getImageURLs(for indexPaths: [IndexPath]) -> [URL] {
|
||||
guard let viewModel, case .display(let statuses, _) = viewModel.statusesState else {
|
||||
return []
|
||||
}
|
||||
return indexPaths.compactMap {
|
||||
$0.row < statuses.endIndex ? statuses[$0.row] : nil
|
||||
}.flatMap(getImages)
|
||||
}
|
||||
}
|
||||
|
||||
private func getImages(for status: Status) -> [URL] {
|
||||
var urls = status.mediaAttachments.compactMap {
|
||||
if $0.supportedType == .image {
|
||||
return status.mediaAttachments.count > 1 ? $0.previewUrl ?? $0.url : $0.url
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if let url = status.card?.image {
|
||||
urls.append(url)
|
||||
}
|
||||
return urls
|
||||
}
|
|
@ -20,6 +20,7 @@ public struct TimelineView: View {
|
|||
@EnvironmentObject private var routerPath: RouterPath
|
||||
|
||||
@StateObject private var viewModel = TimelineViewModel()
|
||||
@StateObject private var prefetcher = TimelinePrefetcher()
|
||||
|
||||
@State private var wasBackgrounded: Bool = false
|
||||
@State private var collectionView: UICollectionView?
|
||||
|
@ -53,10 +54,12 @@ public struct TimelineView: View {
|
|||
.listStyle(.plain)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.primaryBackgroundColor)
|
||||
.introspect(selector: TargetViewSelector.ancestorOrSiblingContaining,
|
||||
customize: { (collectionView: UICollectionView) in
|
||||
self.collectionView = collectionView
|
||||
})
|
||||
.introspect(selector: TargetViewSelector.ancestorOrSiblingContaining) { (collectionView: UICollectionView) in
|
||||
self.collectionView = collectionView
|
||||
self.prefetcher.viewModel = viewModel
|
||||
collectionView.isPrefetchingEnabled = true
|
||||
collectionView.prefetchDataSource = self.prefetcher
|
||||
}
|
||||
if viewModel.pendingStatusesEnabled {
|
||||
PendingStatusesObserverView(observer: viewModel.pendingStatusesObserver)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue