session-ios/Session/Media Viewing & Editing/MediaInfoVC.swift

152 lines
5.3 KiB
Swift

// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
import UIKit
import SessionUIKit
import SessionMessagingKit
import SessionUtilitiesKit
import SignalUtilitiesKit
final class MediaInfoVC: BaseVC, SessionCarouselViewDelegate {
internal static let mediaSize: CGFloat = UIScreen.main.bounds.width - 2 * Values.veryLargeSpacing
internal static let arrowSize: CGSize = CGSize(width: 20, height: 30)
private let attachments: [Attachment]
private let isOutgoing: Bool
private let threadId: String
private let threadVariant: SessionThread.Variant
private let interactionId: Int64
private var currentPage: Int = 0
// MARK: - UI
private lazy var mediaInfoView: MediaInfoView = MediaInfoView(attachment: nil)
private lazy var mediaCarouselView: SessionCarouselView = {
let slices: [MediaPreviewView] = self.attachments.map {
MediaPreviewView(
attachment: $0,
isOutgoing: self.isOutgoing
)
}
let result: SessionCarouselView = SessionCarouselView(
info: SessionCarouselView.Info(
slices: slices,
copyOfFirstSlice: slices.first?.copyView(),
copyOfLastSlice: slices.last?.copyView(),
sliceSize: CGSize(
width: Self.mediaSize,
height: Self.mediaSize
),
shouldShowPageControl: true,
pageControlStyle: SessionCarouselView.PageControlStyle(
size: .medium,
backgroundColor: .init(white: 0, alpha: 0.4),
bottomInset: Values.mediumSpacing
),
shouldShowArrows: true,
arrowsSize: Self.arrowSize,
cornerRadius: 8
)
)
result.set(.height, to: Self.mediaSize)
result.delegate = self
return result
}()
private lazy var fullScreenButton: UIButton = {
let result: UIButton = UIButton(type: .custom)
result.setImage(
UIImage(systemName: "arrow.up.left.and.arrow.down.right")?
.withRenderingMode(.alwaysTemplate),
for: .normal
)
result.themeTintColor = .textPrimary
result.backgroundColor = .init(white: 0, alpha: 0.4)
result.layer.cornerRadius = 14
result.set(.width, to: 28)
result.set(.height, to: 28)
result.addTarget(self, action: #selector(showMediaFullScreen), for: .touchUpInside)
return result
}()
// MARK: - Initialization
init(
attachments: [Attachment],
isOutgoing: Bool,
threadId: String,
threadVariant: SessionThread.Variant,
interactionId: Int64
) {
self.threadId = threadId
self.threadVariant = threadVariant
self.interactionId = interactionId
self.isOutgoing = isOutgoing
self.attachments = attachments
super.init(nibName: nil, bundle: nil)
}
override init(nibName: String?, bundle: Bundle?) {
preconditionFailure("Use init(attachments:) instead.")
}
required init?(coder: NSCoder) {
preconditionFailure("Use init(attachments:) instead.")
}
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
ViewControllerUtilities.setUpDefaultSessionStyle(
for: self,
title: "message_info_title".localized(),
hasCustomBackButton: false
)
let mediaStackView: UIStackView = UIStackView()
mediaStackView.axis = .horizontal
mediaInfoView.update(attachment: attachments[0])
mediaCarouselView.addSubview(fullScreenButton)
fullScreenButton.pin(.trailing, to: .trailing, of: mediaCarouselView, withInset: -(Values.smallSpacing + Values.veryLargeSpacing))
fullScreenButton.pin(.bottom, to: .bottom, of: mediaCarouselView, withInset: -Values.smallSpacing)
let stackView: UIStackView = UIStackView(arrangedSubviews: [ mediaCarouselView, mediaInfoView ])
stackView.axis = .vertical
stackView.alignment = .center
stackView.spacing = Values.largeSpacing
self.view.addSubview(stackView)
stackView.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing ], to: self.view)
stackView.pin(.top, to: .top, of: self.view, withInset: Values.veryLargeSpacing)
}
// MARK: - Interaction
@objc func showMediaFullScreen() {
let attachment = self.attachments[self.currentPage]
let viewController: UIViewController? = MediaGalleryViewModel.createDetailViewController(
for: self.threadId,
threadVariant: self.threadVariant,
interactionId: self.interactionId,
selectedAttachmentId: attachment.id,
options: [ .sliderEnabled ]
)
if let viewController: UIViewController = viewController {
viewController.transitioningDelegate = nil
self.present(viewController, animated: true)
}
}
// MARK: - SessionCarouselViewDelegate
func carouselViewDidScrollToNewSlice(currentPage: Int) {
self.currentPage = currentPage
mediaInfoView.update(attachment: attachments[currentPage])
}
}