From bb091d072f3070fc874a58c694e59a854d82fa91 Mon Sep 17 00:00:00 2001 From: William Casarin Date: Tue, 30 May 2023 17:53:44 -0700 Subject: [PATCH] cache: move event-specific media metadata to EventCache --- damus/Components/ImageCarousel.swift | 34 ++++++++++++--------- damus/Util/EventCache.swift | 30 ++++++++++++++++++ damus/Util/PreviewCache.swift | 10 ------ damus/Views/Images/ImageContainerView.swift | 6 ++-- damus/Views/Images/ImageView.swift | 5 +-- damus/Views/Video/DamusVideoPlayer.swift | 5 ++- 6 files changed, 57 insertions(+), 33 deletions(-) diff --git a/damus/Components/ImageCarousel.swift b/damus/Components/ImageCarousel.swift index 50b974d8..446159c8 100644 --- a/damus/Components/ImageCarousel.swift +++ b/damus/Components/ImageCarousel.swift @@ -74,7 +74,8 @@ struct ImageCarousel: View { init(state: DamusState, evid: String, urls: [MediaUrl]) { _open_sheet = State(initialValue: false) _current_url = State(initialValue: nil) - _image_fill = State(initialValue: state.previews.lookup_image_meta(evid)) + let media_model = state.events.get_cache_data(evid).media_metadata_model + _image_fill = State(initialValue: media_model.fill) self.urls = urls self.evid = evid self.state = state @@ -103,16 +104,17 @@ struct ImageCarousel: View { } } .onAppear { - if self.image_fill == nil, - let meta = state.events.lookup_img_metadata(url: url), - let size = meta.meta.dim?.size - { + if self.image_fill == nil, let size = state.events.lookup_media_size(url: url) { let fill = ImageFill.calculate_image_fill(geo_size: geo_size, img_size: size, maxHeight: maxHeight, fillHeight: fillHeight) self.image_fill = fill } } } + func video_model(_ url: URL) -> VideoPlayerModel { + return state.events.get_video_player_model(url: url) + } + func Media(geo: GeometryProxy, url: MediaUrl, index: Int) -> some View { Group { switch url { @@ -122,18 +124,20 @@ struct ImageCarousel: View { open_sheet = true } case .video(let url): - DamusVideoPlayer(url: url, video_size: $video_size) + DamusVideoPlayer(url: url, model: video_model(url), video_size: $video_size) .onChange(of: video_size) { size in - guard image_fill == nil, let size else { - return - } - let fill = ImageFill.calculate_image_fill(geo_size: geo.size, img_size: size, maxHeight: maxHeight, fillHeight: fillHeight) - image_fill = fill - state.previews.cache_image_meta(evid: evid, image_fill: fill) + guard let size else { return } - if index == 0 { + let fill = ImageFill.calculate_image_fill(geo_size: geo.size, img_size: size, maxHeight: maxHeight, fillHeight: fillHeight) + + print("video_size changed \(size)") + if self.image_fill == nil { + print("video_size firstImageHeight \(fill.height)") firstImageHeight = fill.height + state.events.get_cache_data(evid).media_metadata_model.fill = fill } + + self.image_fill = fill } } } @@ -150,7 +154,7 @@ struct ImageCarousel: View { view.framePreloadCount = 3 } .imageFill(for: geo.size, max: maxHeight, fill: fillHeight) { fill in - state.previews.cache_image_meta(evid: evid, image_fill: fill) + state.events.get_cache_data(evid).media_metadata_model.fill = fill // blur hash can be discarded when we have the url // NOTE: this is the wrong place for this... we need to remove // it when the image is loaded in memory. This may happen @@ -188,7 +192,7 @@ struct ImageCarousel: View { } .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) .fullScreenCover(isPresented: $open_sheet) { - ImageView(urls: urls, disable_animation: state.settings.disable_animation) + ImageView(cache: state.events, urls: urls, disable_animation: state.settings.disable_animation) } .frame(height: height) .onChange(of: selectedIndex) { value in diff --git a/damus/Util/EventCache.swift b/damus/Util/EventCache.swift index ebed6880..58bde49d 100644 --- a/damus/Util/EventCache.swift +++ b/damus/Util/EventCache.swift @@ -101,6 +101,10 @@ class RelativeTimeModel: ObservableObject { @Published var value: String = "" } +class MediaMetaModel: ObservableObject { + @Published var fill: ImageFill? = nil +} + class EventData { var translations_model: TranslationModel var artifacts_model: NoteArtifactsModel @@ -108,6 +112,7 @@ class EventData { var zaps_model : ZapsDataModel var relative_time: RelativeTimeModel = RelativeTimeModel() var validated: ValidationResult + var media_metadata_model: MediaMetaModel var translations: TranslateStatus { return translations_model.state @@ -126,6 +131,7 @@ class EventData { self.artifacts_model = .init(state: .not_loaded) self.zaps_model = .init(zaps) self.validated = .unknown + self.media_metadata_model = MediaMetaModel() self.preview_model = .init(state: .not_loaded) } } @@ -135,6 +141,7 @@ class EventCache { private var replies = ReplyMap() private var cancellable: AnyCancellable? private var image_metadata: [String: ImageMetadataState] = [:] + private var video_meta: [String: VideoPlayerModel] = [:] private var event_data: [String: EventData] = [:] //private var thread_latest: [String: Int64] @@ -194,6 +201,28 @@ class EventCache { return image_metadata[url.absoluteString.lowercased()] } + func lookup_media_size(url: URL) -> CGSize? { + if let img_meta = lookup_img_metadata(url: url) { + return img_meta.meta.dim?.size + } + + return get_video_player_model(url: url).size + } + + func store_video_player_model(url: URL, meta: VideoPlayerModel) { + video_meta[url.absoluteString] = meta + } + + func get_video_player_model(url: URL) -> VideoPlayerModel { + if let model = video_meta[url.absoluteString] { + return model + } + + let model = VideoPlayerModel() + video_meta[url.absoluteString] = model + return model + } + func parent_events(event: NostrEvent) -> [NostrEvent] { var parents: [NostrEvent] = [] @@ -257,6 +286,7 @@ class EventCache { private func prune() { events = [:] + video_meta = [:] event_data = [:] replies.replies = [:] } diff --git a/damus/Util/PreviewCache.swift b/damus/Util/PreviewCache.swift index 92d55dc3..b54b8bcd 100644 --- a/damus/Util/PreviewCache.swift +++ b/damus/Util/PreviewCache.swift @@ -66,22 +66,12 @@ enum PreviewState { class PreviewCache { private var previews: [String: Preview] - private var image_meta: [String: ImageFill] func lookup(_ evid: String) -> Preview? { return previews[evid] } - func lookup_image_meta(_ evid: String) -> ImageFill? { - return image_meta[evid] - } - - func cache_image_meta(evid: String, image_fill: ImageFill) { - self.image_meta[evid] = image_fill - } - init() { self.previews = [:] - self.image_meta = [:] } } diff --git a/damus/Views/Images/ImageContainerView.swift b/damus/Views/Images/ImageContainerView.swift index 5ebd55de..cd4499a7 100644 --- a/damus/Views/Images/ImageContainerView.swift +++ b/damus/Views/Images/ImageContainerView.swift @@ -10,11 +10,11 @@ import Kingfisher struct ImageContainerView: View { + let cache: EventCache let url: MediaUrl @State private var image: UIImage? @State private var showShareSheet = false - @State private var video_size: CGSize? = nil let disable_animation: Bool @@ -47,7 +47,7 @@ struct ImageContainerView: View { case .image(let url): Img(url: url) case .video(let url): - DamusVideoPlayer(url: url, video_size: $video_size) + DamusVideoPlayer(url: url, model: cache.get_video_player_model(url: url), video_size: .constant(nil)) } } } @@ -57,6 +57,6 @@ let test_image_url = URL(string: "https://jb55.com/red-me.jpg")! struct ImageContainerView_Previews: PreviewProvider { static var previews: some View { - ImageContainerView(url: .image(test_image_url), disable_animation: false) + ImageContainerView(cache: test_damus_state().events, url: .image(test_image_url), disable_animation: false) } } diff --git a/damus/Views/Images/ImageView.swift b/damus/Views/Images/ImageView.swift index 0ca00d1d..a51133c7 100644 --- a/damus/Views/Images/ImageView.swift +++ b/damus/Views/Images/ImageView.swift @@ -8,6 +8,7 @@ import SwiftUI struct ImageView: View { + let cache: EventCache let urls: [MediaUrl] @Environment(\.presentationMode) var presentationMode @@ -38,7 +39,7 @@ struct ImageView: View { TabView(selection: $selectedIndex) { ForEach(urls.indices, id: \.self) { index in ZoomableScrollView { - ImageContainerView(url: urls[index], disable_animation: disable_animation) + ImageContainerView(cache: cache, url: urls[index], disable_animation: disable_animation) .aspectRatio(contentMode: .fit) .padding(.top, Theme.safeAreaInsets?.top) .padding(.bottom, Theme.safeAreaInsets?.bottom) @@ -79,6 +80,6 @@ struct ImageView: View { struct ImageView_Previews: PreviewProvider { static var previews: some View { let url: MediaUrl = .image(URL(string: "https://jb55.com/red-me.jpg")!) - ImageView(urls: [url], disable_animation: false) + ImageView(cache: test_damus_state().events, urls: [url], disable_animation: false) } } diff --git a/damus/Views/Video/DamusVideoPlayer.swift b/damus/Views/Video/DamusVideoPlayer.swift index f2f640ba..f50abe17 100644 --- a/damus/Views/Video/DamusVideoPlayer.swift +++ b/damus/Views/Video/DamusVideoPlayer.swift @@ -9,7 +9,7 @@ import SwiftUI struct DamusVideoPlayer: View { var url: URL - @StateObject var model: VideoPlayerModel = VideoPlayerModel() + @ObservedObject var model: VideoPlayerModel @Binding var video_size: CGSize? var mute_icon: String { @@ -58,9 +58,8 @@ struct DamusVideoPlayer: View { } struct DamusVideoPlayer_Previews: PreviewProvider { @StateObject static var model: VideoPlayerModel = VideoPlayerModel() - @State static var video_size: CGSize? = nil static var previews: some View { - DamusVideoPlayer(url: URL(string: "http://cdn.jb55.com/s/zaps-build.mp4")!, model: model, video_size: $video_size) + DamusVideoPlayer(url: URL(string: "http://cdn.jb55.com/s/zaps-build.mp4")!, model: model, video_size: .constant(nil)) } }