// // StatusAttachmentsGalleryDataSource.swift // Tusker // // Created by Shadowfacts on 3/17/24. // Copyright © 2024 Shadowfacts. All rights reserved. // import Foundation import GalleryVC import Pachyderm import TuskerComponents import AVFoundation class StatusAttachmentsGalleryDataSource: GalleryDataSource { let attachments: [Attachment] let sourceViews: NSHashTable init(attachments: [Attachment], sourceViews: NSHashTable) { self.attachments = attachments self.sourceViews = sourceViews } func galleryItemsCount() -> Int { attachments.count } func galleryContentViewController(forItemAt index: Int) -> any GalleryContentViewController { let attachment = attachments[index] switch attachment.kind { case .image: if let view = attachmentView(for: attachment), let image = view.image { return ImageGalleryContentViewController( url: attachment.url, caption: attachment.description, originalData: view.originalData, image: image, // TODO: if automatically play gifs is off, this will start the source view playing too gifController: view.gifController ) } else { return LoadingGalleryContentViewController { let (data, image) = await ImageCache.attachments.get(attachment.url, loadOriginal: true) if let image { let gifController: GIFController? = if attachment.url.pathExtension == "gif", let data { GIFController(gifData: data) } else { nil } return ImageGalleryContentViewController( url: attachment.url, caption: attachment.description, originalData: data, image: image, gifController: gifController ) } else { return nil } } } case .gifv: let controller: GifvController = if Preferences.shared.automaticallyPlayGifs, let view = attachmentView(for: attachment), let controller = view.gifvView?.controller { controller } else { GifvController(asset: AVAsset(url: attachment.url)) } return GifvGalleryContentViewController(controller: controller, caption: attachment.description) case .video: return VideoGalleryContentViewController(url: attachment.url, caption: attachment.description) case .audio: // TODO: use separate content VC with audio visualization? return VideoGalleryContentViewController(url: attachment.url, caption: attachment.description) case .unknown: return LoadingGalleryContentViewController { do { let (data, _) = try await URLSession.shared.data(from: attachment.url) let url = FileManager.default.temporaryDirectory.appendingPathComponent(attachment.url.lastPathComponent) try data.write(to: url) return FallbackGalleryNavigationController(url: url) } catch { return nil } } } } func galleryContentTransitionSourceView(forItemAt index: Int) -> UIView? { let attachment = attachments[index] return attachmentView(for: attachment) } func galleryApplicationActivities(forItemAt index: Int) -> [UIActivity]? { [SaveToPhotosActivity()] } private func attachmentView(for attachment: Attachment) -> AttachmentView? { return sourceViews.allObjects.first(where: { $0.attachment?.id == attachment.id }) } }