Show edited attachments in gallery
This commit is contained in:
parent
f102ebbfc8
commit
abbe0f82e6
@ -10,6 +10,7 @@ import Pachyderm
|
||||
import PhotosUI
|
||||
import PencilKit
|
||||
import TuskerComponents
|
||||
import GalleryVC
|
||||
|
||||
// Configuration/data injected from outside the compose UI.
|
||||
public struct ComposeUIConfig {
|
||||
@ -38,6 +39,8 @@ public struct ComposeUIConfig {
|
||||
public var fetchAvatar: AvatarImageView.FetchAvatar = { _ in nil }
|
||||
public var displayNameLabel: (any AccountProtocol, Font.TextStyle, CGFloat) -> AnyView = { _, _, _ in AnyView(EmptyView()) }
|
||||
public var replyContentView: (any StatusProtocol, @escaping (CGFloat) -> Void) -> AnyView = { _, _ in AnyView(EmptyView()) }
|
||||
public var fetchImageAndGIFData: (URL) async -> (UIImage, Data)? = { _ in nil }
|
||||
public var makeGifvGalleryContentVC: (URL) -> (any GalleryContentViewController)? = { _ in nil }
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ private struct AttachmentThumbnailViewContent: View {
|
||||
var contentMode: ContentMode = .fit
|
||||
var thumbnailSize: CGSize?
|
||||
@State private var mode: Mode = .empty
|
||||
@EnvironmentObject private var composeController: ComposeController
|
||||
@Environment(\.composeUIConfig.fetchImageAndGIFData) private var fetchImageAndGIFData
|
||||
|
||||
var body: some View {
|
||||
switch mode {
|
||||
@ -56,7 +56,7 @@ private struct AttachmentThumbnailViewContent: View {
|
||||
case .editing(_, let kind, let url):
|
||||
switch kind {
|
||||
case .image:
|
||||
if let image = await composeController.fetchAttachment(url) {
|
||||
if let (image, _) = await fetchImageAndGIFData(url) {
|
||||
self.mode = .image(image)
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// AttachmentGalleryDataSource.swift
|
||||
// AttachmentsGalleryDataSource.swift
|
||||
// ComposeUI
|
||||
//
|
||||
// Created by Shadowfacts on 11/21/24.
|
||||
@ -12,6 +12,8 @@ import Photos
|
||||
|
||||
struct AttachmentsGalleryDataSource: GalleryDataSource {
|
||||
let collectionView: UICollectionView
|
||||
let fetchImageAndGIFData: (URL) async -> (UIImage, Data)?
|
||||
let makeGifvGalleryContentVC: (URL) -> (any GalleryContentViewController)?
|
||||
let attachmentAtIndex: (Int) -> DraftAttachment?
|
||||
|
||||
func galleryItemsCount() -> Int {
|
||||
@ -23,12 +25,32 @@ struct AttachmentsGalleryDataSource: GalleryDataSource {
|
||||
|
||||
let content: any GalleryContentViewController
|
||||
switch attachment.data {
|
||||
case .editing(_, _, _):
|
||||
fatalError("TODO")
|
||||
case .editing(_, let kind, let url):
|
||||
switch kind {
|
||||
case .image:
|
||||
content = LoadingGalleryContentViewController(caption: nil) {
|
||||
if let (image, data) = await fetchImageAndGIFData(url) {
|
||||
let gifController: GIFController? = if url.pathExtension == "gif" {
|
||||
GIFController(gifData: data)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
return ImageGalleryContentViewController(image: image, caption: nil, gifController: gifController)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
case .video, .audio:
|
||||
content = VideoGalleryContentViewController(url: url, caption: nil)
|
||||
case .gifv:
|
||||
content = LoadingGalleryContentViewController(caption: nil) { makeGifvGalleryContentVC(url) }
|
||||
case .unknown:
|
||||
content = LoadingGalleryContentViewController(caption: nil) { nil }
|
||||
}
|
||||
|
||||
case .asset(let id):
|
||||
content = LoadingGalleryContentViewController(caption: nil) {
|
||||
if let (image, gifData) = await fetchImageAndGIFData(assetID: id) {
|
||||
if let (image, gifData) = await fetchAssetImageAndGIFData(assetID: id) {
|
||||
let gifController = gifData.map(GIFController.init)
|
||||
return ImageGalleryContentViewController(image: image, caption: nil, gifController: gifController)
|
||||
} else {
|
||||
@ -72,7 +94,7 @@ struct AttachmentsGalleryDataSource: GalleryDataSource {
|
||||
}
|
||||
}
|
||||
|
||||
private func fetchImageAndGIFData(assetID id: String) async -> (UIImage, Data?)? {
|
||||
private func fetchAssetImageAndGIFData(assetID id: String) async -> (UIImage, Data?)? {
|
||||
guard let asset = PHAsset.fetchAssets(withLocalIdentifiers: [id], options: nil).firstObject else {
|
||||
return nil
|
||||
}
|
||||
|
@ -98,9 +98,16 @@ private struct WrappedCollectionView: UIViewControllerRepresentable {
|
||||
@ObservedObject var draft: Draft
|
||||
let spacing: CGFloat
|
||||
let minItemSize: CGFloat
|
||||
@Environment(\.composeUIConfig.fetchImageAndGIFData) private var fetchImageAndGIFData
|
||||
@Environment(\.composeUIConfig.makeGifvGalleryContentVC) private var makeGifvGalleryContentVC
|
||||
|
||||
func makeUIViewController(context: Context) -> WrappedCollectionViewController {
|
||||
WrappedCollectionViewController(spacing: spacing, minItemSize: minItemSize)
|
||||
WrappedCollectionViewController(
|
||||
spacing: spacing,
|
||||
minItemSize: minItemSize,
|
||||
fetchImageAndGIFData: fetchImageAndGIFData,
|
||||
makeGifvGalleryContentVC: makeGifvGalleryContentVC
|
||||
)
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
|
||||
@ -167,14 +174,23 @@ private class WrappedCollectionViewController: UIViewController {
|
||||
fileprivate var currentInteractiveMoveStartOffsetInCell: CGPoint?
|
||||
fileprivate var currentInteractiveMoveCell: HostingCollectionViewCell?
|
||||
fileprivate var addAttachment: ((DraftAttachment) -> Void)? = nil
|
||||
fileprivate var fetchImageAndGIFData: (URL) async -> (UIImage, Data)?
|
||||
fileprivate var makeGifvGalleryContentVC: (URL) -> (any GalleryContentViewController)?
|
||||
|
||||
var collectionView: UICollectionView {
|
||||
view as! UICollectionView
|
||||
}
|
||||
|
||||
init(spacing: CGFloat, minItemSize: CGFloat) {
|
||||
init(
|
||||
spacing: CGFloat,
|
||||
minItemSize: CGFloat,
|
||||
fetchImageAndGIFData: @escaping (URL) async -> (UIImage, Data)?,
|
||||
makeGifvGalleryContentVC: @escaping (URL) -> (any GalleryContentViewController)?
|
||||
) {
|
||||
self.spacing = spacing
|
||||
self.minItemSize = minItemSize
|
||||
self.fetchImageAndGIFData = fetchImageAndGIFData
|
||||
self.makeGifvGalleryContentVC = makeGifvGalleryContentVC
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
@ -330,7 +346,11 @@ extension WrappedCollectionViewController: UICollectionViewDelegate {
|
||||
guard case .attachment(_) = dataSource.itemIdentifier(for: indexPath) else {
|
||||
return
|
||||
}
|
||||
let dataSource = AttachmentsGalleryDataSource(collectionView: collectionView) { [dataSource] in
|
||||
let dataSource = AttachmentsGalleryDataSource(
|
||||
collectionView: collectionView,
|
||||
fetchImageAndGIFData: self.fetchImageAndGIFData,
|
||||
makeGifvGalleryContentVC: self.makeGifvGalleryContentVC
|
||||
) { [dataSource] in
|
||||
let item = dataSource?.itemIdentifier(for: IndexPath(item: $0, section: 0))
|
||||
switch item {
|
||||
case .attachment(let attachment):
|
||||
|
@ -55,7 +55,7 @@ public class LoadingGalleryContentViewController: UIViewController, GalleryConte
|
||||
|
||||
container?.setGalleryContentLoading(true)
|
||||
|
||||
Task {
|
||||
Task { @MainActor in
|
||||
if let wrapped = await provider() {
|
||||
self.wrapped = wrapped
|
||||
wrapped.container = container
|
||||
|
@ -104,6 +104,18 @@ class ComposeHostingController: UIHostingController<ComposeHostingController.Vie
|
||||
config.fetchAvatar = { @MainActor in await ImageCache.avatars.get($0).1 }
|
||||
config.displayNameLabel = { AnyView(AccountDisplayNameView(account: $0, textStyle: $1, emojiSize: $2)) }
|
||||
config.replyContentView = { [mastodonController] in AnyView(ComposeReplyContentView(status: $0, mastodonController: mastodonController, heightChanged: $1)) }
|
||||
config.fetchImageAndGIFData = {
|
||||
if case let (.some(data), .some(image)) = await ImageCache.attachments.get($0) {
|
||||
return (image, data)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
config.makeGifvGalleryContentVC = {
|
||||
let asset = AVAsset(url: $0)
|
||||
let controller = GifvController(asset: asset)
|
||||
return GifvGalleryContentViewController(controller: controller, url: $0, caption: nil)
|
||||
}
|
||||
|
||||
self.config = config
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user