1
0
mirror of git://jb55.com/damus synced 2024-10-06 03:33:22 +00:00

carousel: switch to media carousel and include video

This commit is contained in:
William Casarin 2023-05-26 10:16:14 -07:00
parent 6214ab8d8f
commit 80fac1903e
4 changed files with 103 additions and 58 deletions

View File

@ -54,7 +54,7 @@ enum ImageShape {
// MARK: - Image Carousel
struct ImageCarousel: View {
var urls: [URL]
var urls: [MediaUrl]
let evid: String
@ -69,8 +69,9 @@ struct ImageCarousel: View {
@State private var firstImageHeight: CGFloat? = nil
@State private var currentImageHeight: CGFloat?
@State private var selectedIndex = 0
@State private var video_size: CGSize? = nil
init(state: DamusState, evid: String, urls: [URL]) {
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))
@ -112,47 +113,79 @@ struct ImageCarousel: View {
}
}
var Images: some View {
TabView(selection: $selectedIndex) {
func Media(geo: GeometryProxy, url: MediaUrl, index: Int) -> some View {
Group {
switch url {
case .image(let url):
Img(geo: geo, url: url, index: index)
.onTapGesture {
open_sheet = true
}
case .video(let url):
DamusVideoPlayer(url: url, video_size: $video_size)
.onTapGesture {
print("video tap")
}
.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)
if index == 0 {
firstImageHeight = fill.height
}
}
}
}
}
func Img(geo: GeometryProxy, url: URL, index: Int) -> some View {
KFAnimatedImage(url)
.callbackQueue(.dispatch(.global(qos:.background)))
.backgroundDecode(true)
.imageContext(.note, disable_animation: state.settings.disable_animation)
.image_fade(duration: 0.25)
.cancelOnDisappear(true)
.configure { view in
view.framePreloadCount = 3
}
.imageFill(for: geo.size, max: maxHeight, fill: fillHeight) { fill in
state.previews.cache_image_meta(evid: evid, image_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
// earlier than this (by the preloader, etc)
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
state.events.lookup_img_metadata(url: url)?.state = .not_needed
}
image_fill = fill
if index == 0 {
firstImageHeight = fill.height
//maxHeight = firstImageHeight ?? maxHeight
} else {
//maxHeight = firstImageHeight ?? fill.height
}
}
.background {
Placeholder(url: url, geo_size: geo.size, num_urls: urls.count)
}
.aspectRatio(contentMode: filling ? .fill : .fit)
.tabItem {
Text(url.absoluteString)
}
.id(url.absoluteString)
.padding(0)
}
var Medias: some View {
TabView {
ForEach(urls.indices, id: \.self) { index in
let url = urls[index]
GeometryReader { geo in
KFAnimatedImage(url)
.callbackQueue(.dispatch(.global(qos:.background)))
.backgroundDecode(true)
.imageContext(.note, disable_animation: state.settings.disable_animation)
.image_fade(duration: 0.25)
.cancelOnDisappear(true)
.configure { view in
view.framePreloadCount = 3
}
.imageFill(for: geo.size, max: maxHeight, fill: fillHeight) { fill in
state.previews.cache_image_meta(evid: evid, image_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
// earlier than this (by the preloader, etc)
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
state.events.lookup_img_metadata(url: url)?.state = .not_needed
}
image_fill = fill
if index == 0 {
firstImageHeight = fill.height
//maxHeight = firstImageHeight ?? maxHeight
} else {
//maxHeight = firstImageHeight ?? fill.height
}
}
.background {
Placeholder(url: url, geo_size: geo.size, num_urls: urls.count)
}
.aspectRatio(contentMode: filling ? .fill : .fit)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.tabItem {
Text(url.absoluteString)
}
.id(url.absoluteString)
.padding(0)
Media(geo: geo, url: urls[index], index: index)
}
}
}
@ -165,14 +198,14 @@ struct ImageCarousel: View {
open_sheet = true
}
.onChange(of: selectedIndex) { value in
selectedIndex = value
}
selectedIndex = value
}
.tabViewStyle(PageTabViewStyle())
}
var body: some View {
VStack {
Images
Medias
// This is our custom carousel image indicator
CarouselDotsView(urls: urls, selectedIndex: $selectedIndex)
@ -181,8 +214,8 @@ struct ImageCarousel: View {
}
// MARK: - Custom Carousel
struct CarouselDotsView: View {
let urls: [URL]
struct CarouselDotsView<T>: View {
let urls: [T]
@Binding var selectedIndex: Int
var body: some View {
@ -254,7 +287,8 @@ public struct ImageFill {
// MARK: - Preview Provider
struct ImageCarousel_Previews: PreviewProvider {
static var previews: some View {
ImageCarousel(state: test_damus_state(), evid: "evid", urls: [URL(string: "https://jb55.com/red-me.jpg")!,URL(string: "https://jb55.com/red-me.jpg")!])
let url: MediaUrl = .image(URL(string: "https://jb55.com/red-me.jpg")!)
ImageCarousel(state: test_damus_state(), evid: "evid", urls: [url, url])
}
}

View File

@ -10,10 +10,11 @@ import Kingfisher
struct ImageContainerView: View {
let url: URL?
let url: MediaUrl
@State private var image: UIImage?
@State private var showShareSheet = false
@State private var video_size: CGSize? = nil
let disable_animation: Bool
@ -26,8 +27,7 @@ struct ImageContainerView: View {
}
}
var body: some View {
func Img(url: URL) -> some View {
KFAnimatedImage(url)
.imageContext(.note, disable_animation: disable_animation)
.configure { view in
@ -40,12 +40,23 @@ struct ImageContainerView: View {
ShareSheet(activityItems: [url])
}
}
var body: some View {
Group {
switch url {
case .image(let url):
Img(url: url)
case .video(let url):
DamusVideoPlayer(url: url, video_size: $video_size)
}
}
}
}
let test_image_url = URL(string: "https://jb55.com/red-me.jpg")!
struct ImageContainerView_Previews: PreviewProvider {
static var previews: some View {
ImageContainerView(url: test_image_url, disable_animation: false)
ImageContainerView(url: .image(test_image_url), disable_animation: false)
}
}

View File

@ -8,8 +8,7 @@
import SwiftUI
struct ImageView: View {
let urls: [URL?]
let urls: [MediaUrl]
@Environment(\.presentationMode) var presentationMode
@ -79,6 +78,7 @@ struct ImageView: View {
struct ImageView_Previews: PreviewProvider {
static var previews: some View {
ImageView(urls: [URL(string: "https://jb55.com/red-me.jpg")], disable_animation: false)
let url: MediaUrl = .image(URL(string: "https://jb55.com/red-me.jpg")!)
ImageView(urls: [url], disable_animation: false)
}
}

View File

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