mirror of https://github.com/oxen-io/session-ios
				
				
				
			
			You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			227 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Swift
		
	
			
		
		
	
	
			227 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			Swift
		
	
| // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
 | |
| 
 | |
| import UIKit
 | |
| import QuartzCore
 | |
| import GRDB
 | |
| import DifferenceKit
 | |
| import SessionUIKit
 | |
| import SignalUtilitiesKit
 | |
| import SignalCoreKit
 | |
| 
 | |
| public class AllMediaViewController: UIViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
 | |
|     private let pageVC = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
 | |
|     private var pages: [UIViewController] = []
 | |
|     private var targetVCIndex: Int?
 | |
|     
 | |
|     // MARK: - Components
 | |
|     
 | |
|     private lazy var tabBar: TabBar = {
 | |
|         let result: TabBar = TabBar(
 | |
|             tabs: [
 | |
|                 TabBar.Tab(title: MediaStrings.media) { [weak self] in
 | |
|                     guard let self = self else { return }
 | |
|                     self.pageVC.setViewControllers([ self.pages[0] ], direction: .forward, animated: false, completion: nil)
 | |
|                     self.updateSelectButton(updatedData: self.mediaTitleViewController.viewModel.galleryData, inBatchSelectMode: self.mediaTitleViewController.isInBatchSelectMode)
 | |
|                 },
 | |
|                 TabBar.Tab(title: MediaStrings.document) { [weak self] in
 | |
|                     guard let self = self else { return }
 | |
|                     self.pageVC.setViewControllers([ self.pages[1] ], direction: .forward, animated: false, completion: nil)
 | |
|                     self.endSelectMode()
 | |
|                     self.navigationItem.rightBarButtonItem = nil
 | |
|                 }
 | |
|             ]
 | |
|         )
 | |
|         result.themeBackgroundColor = .backgroundPrimary
 | |
|         
 | |
|         return result
 | |
|     }()
 | |
|     
 | |
|     private var mediaTitleViewController: MediaTileViewController
 | |
|     private var documentTitleViewController: DocumentTileViewController
 | |
|     
 | |
|     init(mediaTitleViewController: MediaTileViewController, documentTitleViewController: DocumentTileViewController) {
 | |
|         self.mediaTitleViewController = mediaTitleViewController
 | |
|         self.documentTitleViewController = documentTitleViewController
 | |
|         
 | |
|         super.init(nibName: nil, bundle: nil)
 | |
|         
 | |
|         self.mediaTitleViewController.delegate = self
 | |
|         self.documentTitleViewController.delegate = self
 | |
|         
 | |
|         addChild(self.mediaTitleViewController)
 | |
|         addChild(self.documentTitleViewController)
 | |
|     }
 | |
|     
 | |
|     required init?(coder: NSCoder) {
 | |
|         notImplemented()
 | |
|     }
 | |
|     
 | |
|     // MARK: Lifecycle
 | |
|     public override func viewDidLoad() {
 | |
|         super.viewDidLoad()
 | |
|         
 | |
|         view.themeBackgroundColor = .newConversation_background
 | |
|         
 | |
|         // Add a custom back button if this is the only view controller
 | |
|         if self.navigationController?.viewControllers.first == self {
 | |
|             let backButton = UIViewController.createOWSBackButton(target: self, selector: #selector(didPressDismissButton))
 | |
|             self.navigationItem.leftBarButtonItem = backButton
 | |
|         }
 | |
|         
 | |
|         ViewControllerUtilities.setUpDefaultSessionStyle(
 | |
|             for: self,
 | |
|             title: MediaStrings.allMedia,
 | |
|             hasCustomBackButton: false
 | |
|         )
 | |
|         
 | |
|         // Set up page VC
 | |
|         pages = [ mediaTitleViewController, documentTitleViewController ]
 | |
|         pageVC.dataSource = self
 | |
|         pageVC.delegate = self
 | |
|         pageVC.setViewControllers([ mediaTitleViewController ], direction: .forward, animated: false, completion: nil)
 | |
|         addChild(pageVC)
 | |
|         
 | |
|         // Set up tab bar
 | |
|         view.addSubview(tabBar)
 | |
|         tabBar.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing, UIView.VerticalEdge.top ], to: view)
 | |
|         // Set up page VC constraints
 | |
|         let pageVCView = pageVC.view!
 | |
|         view.addSubview(pageVCView)
 | |
|         pageVCView.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing, UIView.VerticalEdge.bottom ], to: view)
 | |
|         pageVCView.pin(.top, to: .bottom, of: tabBar)
 | |
|     }
 | |
|     
 | |
|     // MARK: General
 | |
|     public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
 | |
|         guard let index = pages.firstIndex(of: viewController), index != 0 else { return nil }
 | |
|         return pages[index - 1]
 | |
|     }
 | |
|     
 | |
|     public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
 | |
|         guard let index = pages.firstIndex(of: viewController), index != (pages.count - 1) else { return nil }
 | |
|         return pages[index + 1]
 | |
|     }
 | |
|     
 | |
|     // MARK: Updating
 | |
|     public func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
 | |
|         guard let targetVC = pendingViewControllers.first, let index = pages.firstIndex(of: targetVC) else { return }
 | |
|         targetVCIndex = index
 | |
|     }
 | |
|     
 | |
|     public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating isFinished: Bool, previousViewControllers: [UIViewController], transitionCompleted isCompleted: Bool) {
 | |
|         guard isCompleted, let index = targetVCIndex else { return }
 | |
|         tabBar.selectTab(at: index)
 | |
|     }
 | |
|     
 | |
|     // MARK: Interaction
 | |
|     @objc public func didPressDismissButton() {
 | |
|         dismiss(animated: true, completion: nil)
 | |
|     }
 | |
|     
 | |
|     // MARK: Batch Selection
 | |
|     @objc func didTapSelect(_ sender: Any) {
 | |
|         self.mediaTitleViewController.didTapSelect(sender)
 | |
| 
 | |
|         // Don't allow the user to leave mid-selection, so they realized they have
 | |
|         // to cancel (lose) their selection if they leave.
 | |
|         self.navigationItem.hidesBackButton = true
 | |
|     }
 | |
| 
 | |
|     @objc func didCancelSelect(_ sender: Any) {
 | |
|         endSelectMode()
 | |
|     }
 | |
| 
 | |
|     func endSelectMode() {
 | |
|         self.mediaTitleViewController.endSelectMode()
 | |
|         self.navigationItem.hidesBackButton = false
 | |
|     }
 | |
| }
 | |
| 
 | |
| // MARK: - UIDocumentInteractionControllerDelegate
 | |
| 
 | |
| extension AllMediaViewController: UIDocumentInteractionControllerDelegate {
 | |
|     public func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
 | |
|         return self
 | |
|     }
 | |
| }
 | |
| 
 | |
| // MARK: - DocumentTitleViewControllerDelegate
 | |
| 
 | |
| extension AllMediaViewController: DocumentTileViewControllerDelegate {
 | |
|     public func share(fileUrl: URL) {
 | |
|         let shareVC = UIActivityViewController(activityItems: [ fileUrl ], applicationActivities: nil)
 | |
|         
 | |
|         if UIDevice.current.isIPad {
 | |
|             shareVC.excludedActivityTypes = []
 | |
|             shareVC.popoverPresentationController?.permittedArrowDirections = []
 | |
|             shareVC.popoverPresentationController?.sourceView = self.view
 | |
|             shareVC.popoverPresentationController?.sourceRect = self.view.bounds
 | |
|         }
 | |
|         
 | |
|         navigationController?.present(shareVC, animated: true, completion: nil)
 | |
|     }
 | |
|     
 | |
|     public func preview(fileUrl: URL) {
 | |
|         let interactionController: UIDocumentInteractionController = UIDocumentInteractionController(url: fileUrl)
 | |
|         interactionController.delegate = self
 | |
|         interactionController.presentPreview(animated: true)
 | |
|     }
 | |
| }
 | |
| 
 | |
| // MARK: - DocumentTitleViewControllerDelegate
 | |
| 
 | |
| extension AllMediaViewController: MediaTileViewControllerDelegate {
 | |
|     public func presentdetailViewController(_ detailViewController: UIViewController, animated: Bool) {
 | |
|         self.present(detailViewController, animated: animated)
 | |
|     }
 | |
|     
 | |
|     public func updateSelectButton(updatedData: [MediaGalleryViewModel.SectionModel], inBatchSelectMode: Bool) {
 | |
|         guard !updatedData.isEmpty else {
 | |
|             self.navigationItem.rightBarButtonItem = nil
 | |
|             return
 | |
|         }
 | |
|         
 | |
|         if inBatchSelectMode {
 | |
|             self.navigationItem.rightBarButtonItem = UIBarButtonItem(
 | |
|                 barButtonSystemItem: .cancel,
 | |
|                 target: self,
 | |
|                 action: #selector(didCancelSelect)
 | |
|             )
 | |
|         }
 | |
|         else {
 | |
|             self.navigationItem.rightBarButtonItem = UIBarButtonItem(
 | |
|                 title: "BUTTON_SELECT".localized(),
 | |
|                 style: .plain,
 | |
|                 target: self,
 | |
|                 action: #selector(didTapSelect)
 | |
|             )
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| // MARK: - UIViewControllerTransitioningDelegate
 | |
| 
 | |
| extension AllMediaViewController: UIViewControllerTransitioningDelegate {
 | |
|     public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
 | |
|         return self.mediaTitleViewController.animationController(forPresented: presented, presenting: presenting, source: source)
 | |
|     }
 | |
| 
 | |
|     public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
 | |
|         return self.mediaTitleViewController.animationController(forDismissed: dismissed)
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| // MARK: - MediaPresentationContextProvider
 | |
| 
 | |
| extension AllMediaViewController: MediaPresentationContextProvider {
 | |
|     func mediaPresentationContext(mediaItem: Media, in coordinateSpace: UICoordinateSpace) -> MediaPresentationContext? {
 | |
|         return self.mediaTitleViewController.mediaPresentationContext(mediaItem: mediaItem, in: coordinateSpace)
 | |
|     }
 | |
| 
 | |
|     func snapshotOverlayView(in coordinateSpace: UICoordinateSpace) -> (UIView, CGRect)? {
 | |
|         return self.mediaTitleViewController.snapshotOverlayView(in: coordinateSpace)
 | |
|     }
 | |
| }
 | |
| 
 |