Cache image heights to reduce popping
This commit is contained in:
@@ -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")!])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 = [:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user