Cache image heights to reduce popping

This commit is contained in:
William Casarin
2023-04-03 15:02:35 -07:00
parent 1bf171a09e
commit e0d4841147
3 changed files with 36 additions and 8 deletions

View File

@@ -39,17 +39,30 @@ enum ImageShape {
case unknown case unknown
} }
struct ImageCarousel: View { struct ImageCarousel: View {
var urls: [URL] var urls: [URL]
let evid: String
let previews: PreviewCache
let minHeight: CGFloat = 150
let maxHeight: CGFloat = 500
@State private var open_sheet: Bool = false @State private var open_sheet: Bool = false
@State private var current_url: URL? = nil @State private var current_url: URL? = nil
@State private var height: CGFloat = .zero @State private var height: CGFloat? = nil
@State private var minHeight: CGFloat = 150
@State private var maxHeight: CGFloat = 500
@State private var filling: Bool = false @State private var filling: Bool = false
init(previews: PreviewCache, evid: String, urls: [URL]) {
_open_sheet = State(initialValue: false)
_current_url = State(initialValue: nil)
_height = State(initialValue: previews.lookup_image_height(evid))
_filling = State(initialValue: false)
self.urls = urls
self.evid = evid
self.previews = previews
}
var body: some View { var body: some View {
TabView { TabView {
ForEach(urls, id: \.absoluteString) { url in ForEach(urls, id: \.absoluteString) { url in
@@ -64,6 +77,9 @@ struct ImageCarousel: View {
view.framePreloadCount = 3 view.framePreloadCount = 3
} }
.imageModifier({ img in .imageModifier({ img in
guard self.height == nil else {
return
}
let img_size = img.size let img_size = img.size
let is_animated = img.kf.imageFrameCount != nil let is_animated = img.kf.imageFrameCount != nil
@@ -74,6 +90,7 @@ struct ImageCarousel: View {
self.filling = filling self.filling = filling
} }
self.previews.cache_image_height(evid: evid, height: fill.height)
self.height = fill.height self.height = fill.height
} }
}) })
@@ -89,7 +106,7 @@ struct ImageCarousel: View {
.fullScreenCover(isPresented: $open_sheet) { .fullScreenCover(isPresented: $open_sheet) {
ImageView(urls: urls) ImageView(urls: urls)
} }
.frame(height: height) .frame(height: height ?? 0)
.onTapGesture { .onTapGesture {
open_sheet = true open_sheet = true
} }
@@ -147,6 +164,7 @@ func calculate_image_fill(geo: GeometryProxy, img_size: CGSize, is_animated: Boo
struct ImageCarousel_Previews: PreviewProvider { struct ImageCarousel_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
ImageCarousel(urls: [URL(string: "https://jb55.com/red-me.jpg")!,URL(string: "https://jb55.com/red-me.jpg")!]) ImageCarousel(previews: test_damus_state().previews, evid: "evid", urls: [URL(string: "https://jb55.com/red-me.jpg")!,URL(string: "https://jb55.com/red-me.jpg")!])
} }
} }

View File

@@ -24,12 +24,21 @@ enum Preview {
} }
class PreviewCache { class PreviewCache {
var previews: [String: Preview] private var previews: [String: Preview]
private var image_heights: [String: CGFloat]
func lookup(_ evid: String) -> Preview? { func lookup(_ evid: String) -> Preview? {
return previews[evid] return previews[evid]
} }
func lookup_image_height(_ evid: String) -> CGFloat? {
return image_heights[evid]
}
func cache_image_height(evid: String, height: CGFloat) {
self.image_heights[evid] = height
}
func store(evid: String, preview: LPLinkMetadata?) { func store(evid: String, preview: LPLinkMetadata?) {
switch preview { switch preview {
case .none: case .none:
@@ -41,5 +50,6 @@ class PreviewCache {
init() { init() {
self.previews = [:] self.previews = [:]
self.image_heights = [:]
} }
} }

View File

@@ -105,10 +105,10 @@ struct NoteContentView: View {
} }
if show_images && artifacts.images.count > 0 { if show_images && artifacts.images.count > 0 {
ImageCarousel(urls: artifacts.images) ImageCarousel(previews: damus_state.previews, evid: event.id, urls: artifacts.images)
} else if !show_images && artifacts.images.count > 0 { } else if !show_images && artifacts.images.count > 0 {
ZStack { ZStack {
ImageCarousel(urls: artifacts.images) ImageCarousel(previews: damus_state.previews, evid: event.id, urls: artifacts.images)
Blur() Blur()
.disabled(true) .disabled(true)
} }