2021-04-28 09:02:34 +02:00
|
|
|
//
|
|
|
|
// MediaPreviewViewModel.swift
|
|
|
|
// Mastodon
|
|
|
|
//
|
|
|
|
// Created by MainasuK Cirno on 2021-4-28.
|
|
|
|
//
|
|
|
|
|
|
|
|
import UIKit
|
|
|
|
import Combine
|
|
|
|
import CoreData
|
|
|
|
import CoreDataStack
|
|
|
|
import Pageboy
|
|
|
|
|
|
|
|
final class MediaPreviewViewModel: NSObject {
|
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
weak var mediaPreviewImageViewControllerDelegate: MediaPreviewImageViewControllerDelegate?
|
|
|
|
|
2021-04-28 09:02:34 +02:00
|
|
|
// input
|
|
|
|
let context: AppContext
|
2022-01-27 14:23:39 +01:00
|
|
|
let item: PreviewItem
|
|
|
|
let transitionItem: MediaPreviewTransitionItem
|
|
|
|
|
|
|
|
@Published var currentPage: Int
|
2021-04-28 13:06:45 +02:00
|
|
|
|
2021-04-28 09:02:34 +02:00
|
|
|
// output
|
|
|
|
let viewControllers: [UIViewController]
|
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
init(
|
|
|
|
context: AppContext,
|
|
|
|
item: PreviewItem,
|
|
|
|
transitionItem: MediaPreviewTransitionItem
|
|
|
|
) {
|
2021-04-28 09:02:34 +02:00
|
|
|
self.context = context
|
2022-01-27 14:23:39 +01:00
|
|
|
self.item = item
|
|
|
|
var currentPage = 0
|
2021-04-28 09:02:34 +02:00
|
|
|
var viewControllers: [UIViewController] = []
|
2022-01-27 14:23:39 +01:00
|
|
|
switch item {
|
|
|
|
case .attachment(let previewContext):
|
|
|
|
currentPage = previewContext.initialIndex
|
|
|
|
for (i, attachment) in previewContext.attachments.enumerated() {
|
|
|
|
let viewController = MediaPreviewImageViewController()
|
|
|
|
let viewModel = MediaPreviewImageViewModel(
|
|
|
|
context: context,
|
|
|
|
item: .remote(.init(
|
|
|
|
assetURL: attachment.assetURL.flatMap { URL(string: $0) },
|
|
|
|
thumbnail: previewContext.thumbnail(at: i),
|
|
|
|
altText: attachment.altDescription
|
|
|
|
))
|
|
|
|
)
|
|
|
|
viewController.viewModel = viewModel
|
|
|
|
viewControllers.append(viewController)
|
|
|
|
} // end for … in …
|
|
|
|
case .profileAvatar(let previewContext):
|
|
|
|
let viewController = MediaPreviewImageViewController()
|
|
|
|
let viewModel = MediaPreviewImageViewModel(
|
|
|
|
context: context,
|
|
|
|
item: .remote(.init(
|
|
|
|
assetURL: previewContext.assetURL.flatMap { URL(string: $0) },
|
|
|
|
thumbnail: previewContext.thumbnail,
|
|
|
|
altText: nil
|
|
|
|
))
|
|
|
|
)
|
|
|
|
viewController.viewModel = viewModel
|
|
|
|
viewControllers.append(viewController)
|
|
|
|
case .profileBanner(let previewContext):
|
|
|
|
let viewController = MediaPreviewImageViewController()
|
|
|
|
let viewModel = MediaPreviewImageViewModel(
|
|
|
|
context: context,
|
|
|
|
item: .remote(.init(
|
|
|
|
assetURL: previewContext.assetURL.flatMap { URL(string: $0) },
|
|
|
|
thumbnail: previewContext.thumbnail,
|
|
|
|
altText: nil
|
|
|
|
))
|
|
|
|
)
|
|
|
|
viewController.viewModel = viewModel
|
|
|
|
viewControllers.append(viewController)
|
|
|
|
} // end switch
|
|
|
|
// let status = managedObjectContext.object(with: meta.statusObjectID) as! Status
|
|
|
|
// for (entity, image) in zip(status.attachments, meta.preloadThumbnailImages) {
|
|
|
|
// let thumbnail: UIImage? = image.flatMap { $0.size != CGSize(width: 1, height: 1) ? $0 : nil }
|
|
|
|
// switch entity.kind {
|
|
|
|
// case .image:
|
|
|
|
// guard let url = URL(string: entity.assetURL ?? "") else { continue }
|
|
|
|
// let meta = MediaPreviewImageViewModel.RemoteImagePreviewMeta(url: url, thumbnail: thumbnail, altText: entity.altDescription)
|
|
|
|
// let mediaPreviewImageModel = MediaPreviewImageViewModel(meta: meta)
|
|
|
|
// let mediaPreviewImageViewController = MediaPreviewImageViewController()
|
|
|
|
// mediaPreviewImageViewController.viewModel = mediaPreviewImageModel
|
|
|
|
// viewControllers.append(mediaPreviewImageViewController)
|
|
|
|
// default:
|
|
|
|
// continue
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
2021-04-28 09:02:34 +02:00
|
|
|
self.viewControllers = viewControllers
|
2022-01-27 14:23:39 +01:00
|
|
|
self.currentPage = currentPage
|
|
|
|
self.transitionItem = transitionItem
|
2021-04-28 09:02:34 +02:00
|
|
|
super.init()
|
|
|
|
}
|
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
// init(context: AppContext, meta: ProfileBannerImagePreviewMeta, pushTransitionItem: MediaPreviewTransitionItem) {
|
|
|
|
// self.context = context
|
|
|
|
// self.item = .profileBanner(meta)
|
|
|
|
// var viewControllers: [UIViewController] = []
|
|
|
|
// let managedObjectContext = self.context.managedObjectContext
|
|
|
|
// managedObjectContext.performAndWait {
|
|
|
|
// let account = managedObjectContext.object(with: meta.accountObjectID) as! MastodonUser
|
|
|
|
// let avatarURL = account.headerImageURLWithFallback(domain: account.domain)
|
|
|
|
// let meta = MediaPreviewImageViewModel.RemoteImagePreviewMeta(url: avatarURL, thumbnail: meta.preloadThumbnailImage, altText: nil)
|
|
|
|
// let mediaPreviewImageModel = MediaPreviewImageViewModel(meta: meta)
|
|
|
|
// let mediaPreviewImageViewController = MediaPreviewImageViewController()
|
|
|
|
// mediaPreviewImageViewController.viewModel = mediaPreviewImageModel
|
|
|
|
// viewControllers.append(mediaPreviewImageViewController)
|
|
|
|
// }
|
|
|
|
// self.viewControllers = viewControllers
|
|
|
|
// self.currentPage = CurrentValueSubject(0)
|
|
|
|
// self.transitionItem = pushTransitionItem
|
|
|
|
// super.init()
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// init(context: AppContext, meta: ProfileAvatarImagePreviewMeta, pushTransitionItem: MediaPreviewTransitionItem) {
|
|
|
|
// self.context = context
|
|
|
|
// self.item = .profileAvatar(meta)
|
|
|
|
// var viewControllers: [UIViewController] = []
|
|
|
|
// let managedObjectContext = self.context.managedObjectContext
|
|
|
|
// managedObjectContext.performAndWait {
|
|
|
|
// let account = managedObjectContext.object(with: meta.accountObjectID) as! MastodonUser
|
|
|
|
// let avatarURL = account.avatarImageURLWithFallback(domain: account.domain)
|
|
|
|
// let meta = MediaPreviewImageViewModel.RemoteImagePreviewMeta(url: avatarURL, thumbnail: meta.preloadThumbnailImage, altText: nil)
|
|
|
|
// let mediaPreviewImageModel = MediaPreviewImageViewModel(meta: meta)
|
|
|
|
// let mediaPreviewImageViewController = MediaPreviewImageViewController()
|
|
|
|
// mediaPreviewImageViewController.viewModel = mediaPreviewImageModel
|
|
|
|
// viewControllers.append(mediaPreviewImageViewController)
|
|
|
|
// }
|
|
|
|
// self.viewControllers = viewControllers
|
|
|
|
// self.currentPage = CurrentValueSubject(0)
|
|
|
|
// self.transitionItem = pushTransitionItem
|
|
|
|
// super.init()
|
|
|
|
// }
|
2021-04-28 14:10:17 +02:00
|
|
|
|
2021-04-28 09:02:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
extension MediaPreviewViewModel {
|
|
|
|
|
|
|
|
enum PreviewItem {
|
2022-01-27 14:23:39 +01:00
|
|
|
case attachment(AttachmentPreviewContext)
|
|
|
|
case profileAvatar(ProfileAvatarPreviewContext)
|
|
|
|
case profileBanner(ProfileBannerPreviewContext)
|
|
|
|
// case local(LocalImagePreviewMeta)
|
2021-04-28 09:02:34 +02:00
|
|
|
}
|
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
struct AttachmentPreviewContext {
|
|
|
|
let attachments: [MastodonAttachment]
|
2021-04-28 09:02:34 +02:00
|
|
|
let initialIndex: Int
|
2022-01-27 14:23:39 +01:00
|
|
|
let thumbnails: [UIImage?]
|
|
|
|
|
|
|
|
func thumbnail(at index: Int) -> UIImage? {
|
|
|
|
guard index < thumbnails.count else { return nil }
|
|
|
|
return thumbnails[index]
|
|
|
|
}
|
2021-04-28 14:36:10 +02:00
|
|
|
}
|
|
|
|
|
2022-01-27 14:23:39 +01:00
|
|
|
struct ProfileAvatarPreviewContext {
|
|
|
|
let assetURL: String?
|
|
|
|
let thumbnail: UIImage?
|
2021-04-28 14:10:17 +02:00
|
|
|
}
|
2022-01-27 14:23:39 +01:00
|
|
|
|
|
|
|
struct ProfileBannerPreviewContext {
|
|
|
|
let assetURL: String?
|
|
|
|
let thumbnail: UIImage?
|
2021-04-28 09:02:34 +02:00
|
|
|
}
|
2022-01-27 14:23:39 +01:00
|
|
|
|
|
|
|
// struct LocalImagePreviewMeta {
|
|
|
|
// let image: UIImage
|
|
|
|
// }
|
2021-04-28 09:02:34 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - PageboyViewControllerDataSource
|
|
|
|
extension MediaPreviewViewModel: PageboyViewControllerDataSource {
|
|
|
|
|
|
|
|
func numberOfViewControllers(in pageboyViewController: PageboyViewController) -> Int {
|
|
|
|
return viewControllers.count
|
|
|
|
}
|
|
|
|
|
|
|
|
func viewController(for pageboyViewController: PageboyViewController, at index: PageboyViewController.PageIndex) -> UIViewController? {
|
|
|
|
let viewController = viewControllers[index]
|
|
|
|
if let mediaPreviewImageViewController = viewController as? MediaPreviewImageViewController {
|
|
|
|
mediaPreviewImageViewController.delegate = mediaPreviewImageViewControllerDelegate
|
|
|
|
}
|
|
|
|
return viewController
|
|
|
|
}
|
|
|
|
|
|
|
|
func defaultPage(for pageboyViewController: PageboyViewController) -> PageboyViewController.Page? {
|
2022-01-27 14:23:39 +01:00
|
|
|
guard case let .attachment(previewContext) = item else { return nil }
|
|
|
|
return .at(index: previewContext.initialIndex)
|
2021-04-28 09:02:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|