mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2025-02-02 19:22:18 +00:00
* 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
3 changed files with 55 additions and 7 deletions
|
@ -166,6 +166,7 @@ public struct StatusRowMediaPreviewView: View {
|
||||||
.frame(width: newSize.width, height: newSize.height)
|
.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)
|
.frame(width: newSize.width, height: newSize.height)
|
||||||
|
|
||||||
case .gifv, .video, .audio:
|
case .gifv, .video, .audio:
|
||||||
|
@ -205,13 +206,14 @@ public struct StatusRowMediaPreviewView: View {
|
||||||
GeometryReader { proxy in
|
GeometryReader { proxy in
|
||||||
switch type {
|
switch type {
|
||||||
case .image:
|
case .image:
|
||||||
|
let width = isNotifications ? imageMaxHeight : proxy.frame(in: .local).width
|
||||||
ZStack(alignment: .bottomTrailing) {
|
ZStack(alignment: .bottomTrailing) {
|
||||||
LazyImage(url: attachment.url) { state in
|
LazyImage(url: attachment.previewUrl ?? attachment.url) { state in
|
||||||
if let image = state.imageContainer?.image {
|
if let image = state.imageContainer?.image {
|
||||||
SwiftUI.Image(uiImage: image)
|
SwiftUI.Image(uiImage: image)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fill)
|
.aspectRatio(contentMode: .fill)
|
||||||
.frame(maxWidth: isNotifications ? imageMaxHeight : proxy.frame(in: .local).width)
|
.frame(maxWidth: width)
|
||||||
.frame(maxHeight: imageMaxHeight)
|
.frame(maxHeight: imageMaxHeight)
|
||||||
.clipped()
|
.clipped()
|
||||||
.cornerRadius(4)
|
.cornerRadius(4)
|
||||||
|
@ -219,9 +221,10 @@ public struct StatusRowMediaPreviewView: View {
|
||||||
RoundedRectangle(cornerRadius: 4)
|
RoundedRectangle(cornerRadius: 4)
|
||||||
.fill(Color.gray)
|
.fill(Color.gray)
|
||||||
.frame(maxHeight: imageMaxHeight)
|
.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 {
|
if sensitive {
|
||||||
cornerSensitiveButton
|
cornerSensitiveButton
|
||||||
}
|
}
|
||||||
|
|
42
Packages/Timeline/Sources/Timeline/TimelinePrefetcher.swift
Normal file
42
Packages/Timeline/Sources/Timeline/TimelinePrefetcher.swift
Normal file
|
@ -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
|
@EnvironmentObject private var routerPath: RouterPath
|
||||||
|
|
||||||
@StateObject private var viewModel = TimelineViewModel()
|
@StateObject private var viewModel = TimelineViewModel()
|
||||||
|
@StateObject private var prefetcher = TimelinePrefetcher()
|
||||||
|
|
||||||
@State private var wasBackgrounded: Bool = false
|
@State private var wasBackgrounded: Bool = false
|
||||||
@State private var collectionView: UICollectionView?
|
@State private var collectionView: UICollectionView?
|
||||||
|
@ -53,10 +54,12 @@ public struct TimelineView: View {
|
||||||
.listStyle(.plain)
|
.listStyle(.plain)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.primaryBackgroundColor)
|
.background(theme.primaryBackgroundColor)
|
||||||
.introspect(selector: TargetViewSelector.ancestorOrSiblingContaining,
|
.introspect(selector: TargetViewSelector.ancestorOrSiblingContaining) { (collectionView: UICollectionView) in
|
||||||
customize: { (collectionView: UICollectionView) in
|
self.collectionView = collectionView
|
||||||
self.collectionView = collectionView
|
self.prefetcher.viewModel = viewModel
|
||||||
})
|
collectionView.isPrefetchingEnabled = true
|
||||||
|
collectionView.prefetchDataSource = self.prefetcher
|
||||||
|
}
|
||||||
if viewModel.pendingStatusesEnabled {
|
if viewModel.pendingStatusesEnabled {
|
||||||
PendingStatusesObserverView(observer: viewModel.pendingStatusesObserver)
|
PendingStatusesObserverView(observer: viewModel.pendingStatusesObserver)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue