AddToPlaylistViewController.swift 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*****************************************************************************
  2. * AddToPlaylistViewController.swift
  3. *
  4. * Copyright © 2019 VLC authors and VideoLAN
  5. *
  6. * Authors: Soomin Lee <bubu@mikan.io>
  7. *
  8. * Refer to the COPYING file of the official project for license.
  9. *****************************************************************************/
  10. import Foundation
  11. protocol AddToPlaylistViewControllerDelegate: class {
  12. func addToPlaylistViewController(_ addToPlaylistViewController: AddToPlaylistViewController,
  13. didSelectPlaylist playlist: VLCMLPlaylist)
  14. func addToPlaylistViewController(_ addToPlaylistViewController: AddToPlaylistViewController,
  15. newPlaylistWithName name: String)
  16. }
  17. class AddToPlaylistViewController: UIViewController {
  18. @IBOutlet private weak var newPlaylistButton: UIButton!
  19. @IBOutlet private weak var playlistCollectionView: UICollectionView!
  20. private let cellHeight: CGFloat = 56
  21. private let sidePadding: CGFloat = 20
  22. var playlists: [VLCMLPlaylist]
  23. private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
  24. let collectionViewLayout = UICollectionViewFlowLayout()
  25. collectionViewLayout.minimumLineSpacing = 10
  26. collectionViewLayout.minimumInteritemSpacing = 0
  27. return collectionViewLayout
  28. }()
  29. weak var delegate: AddToPlaylistViewControllerDelegate?
  30. init(playlists: [VLCMLPlaylist]) {
  31. self.playlists = playlists
  32. super.init(nibName: nil, bundle: nil)
  33. }
  34. required init?(coder aDecoder: NSCoder) {
  35. fatalError("init(coder:) has not been implemented")
  36. }
  37. override func viewWillAppear(_ animated: Bool) {
  38. super.viewWillAppear(animated)
  39. if #available(iOS 11.0, *) {
  40. navigationController?.navigationBar.prefersLargeTitles = false
  41. }
  42. navigationController?.navigationBar.isTranslucent = false
  43. playlistCollectionView.reloadData()
  44. }
  45. override func viewDidLoad() {
  46. super.viewDidLoad()
  47. initViews()
  48. NotificationCenter.default.addObserver(self,
  49. selector: #selector(themeDidChange),
  50. name: .VLCThemeDidChangeNotification,
  51. object: nil)
  52. title = NSLocalizedString("ADD_TO_PLAYLIST", comment: "")
  53. }
  54. override var preferredStatusBarStyle: UIStatusBarStyle {
  55. return PresentationTheme.current.colors.statusBarStyle
  56. }
  57. @objc private func themeDidChange() {
  58. view.backgroundColor = PresentationTheme.current.colors.background
  59. playlistCollectionView.backgroundColor = PresentationTheme.current.colors.background
  60. setNeedsStatusBarAppearanceUpdate()
  61. }
  62. @objc private func dismissView() {
  63. dismiss(animated: true, completion: nil)
  64. }
  65. @IBAction private func handleNewPlaylist(_ sender: UIButton) {
  66. let alertController = UIAlertController(title: NSLocalizedString("PLAYLISTS", comment: ""),
  67. message: NSLocalizedString("PLAYLIST_DESCRIPTION", comment: ""),
  68. preferredStyle: .alert)
  69. alertController.addTextField(configurationHandler: {
  70. textField in
  71. textField.placeholder = NSLocalizedString("PLAYLIST_PLACEHOLDER", comment: "")
  72. })
  73. let cancelButton = UIAlertAction(title: NSLocalizedString("BUTTON_CANCEL", comment: ""),
  74. style: .default)
  75. let confirmAction = UIAlertAction(title: NSLocalizedString("BUTTON_DONE", comment: ""),
  76. style: .default) {
  77. [weak alertController] _ in
  78. guard let alertController = alertController,
  79. let textField = alertController.textFields?.first else { return }
  80. guard let text = textField.text, text != "" else {
  81. DispatchQueue.main.async {
  82. VLCAlertViewController.alertViewManager(title: NSLocalizedString("ERROR_EMPTY_NAME",
  83. comment: ""),
  84. viewController: self)
  85. }
  86. return
  87. }
  88. self.delegate?.addToPlaylistViewController(self, newPlaylistWithName: text)
  89. }
  90. alertController.addAction(cancelButton)
  91. alertController.addAction(confirmAction)
  92. present(alertController, animated: true, completion: nil)
  93. }
  94. }
  95. // MARK: - Private initializers
  96. private extension AddToPlaylistViewController {
  97. private func initViews() {
  98. Bundle.main.loadNibNamed("AddToPlaylistView", owner: self, options: nil)
  99. view.backgroundColor = PresentationTheme.current.colors.background
  100. setupNavigationBar()
  101. setupNewPlaylistButton()
  102. setupPlaylistCollectionView()
  103. }
  104. private func setupNavigationBar() {
  105. navigationItem.leftBarButtonItem = UIBarButtonItem(title: NSLocalizedString("BUTTON_CANCEL",
  106. comment: ""),
  107. style: .done,
  108. target: self,
  109. action: #selector(dismissView))
  110. }
  111. private func setupNewPlaylistButton() {
  112. newPlaylistButton.layer.masksToBounds = true
  113. newPlaylistButton.layer.cornerRadius = 10
  114. newPlaylistButton.backgroundColor = PresentationTheme.current.colors.orangeUI
  115. newPlaylistButton.setTitle(NSLocalizedString("PLAYLIST_CREATION", comment: ""), for: .normal)
  116. newPlaylistButton.accessibilityLabel = NSLocalizedString("PLAYLIST_CREATION", comment: "")
  117. newPlaylistButton.accessibilityHint = NSLocalizedString("PLAYLIST_CREATION_HINT", comment: "")
  118. }
  119. private func setupPlaylistCollectionView() {
  120. let cellNib = UINib(nibName: MediaCollectionViewCell.nibName, bundle: nil)
  121. playlistCollectionView.register(cellNib,
  122. forCellWithReuseIdentifier: MediaCollectionViewCell.defaultReuseIdentifier)
  123. playlistCollectionView.delegate = self
  124. playlistCollectionView.dataSource = self
  125. playlistCollectionView.collectionViewLayout = collectionViewLayout
  126. playlistCollectionView.backgroundColor = PresentationTheme.current.colors.background
  127. }
  128. }
  129. // MARK: - UICollectionViewFlowLayout
  130. extension AddToPlaylistViewController: UICollectionViewDelegateFlowLayout {
  131. func collectionView(_ collectionView: UICollectionView,
  132. layout collectionViewLayout: UICollectionViewLayout,
  133. sizeForItemAt indexPath: IndexPath) -> CGSize {
  134. return CGSize(width: collectionView.frame.width - (sidePadding * 2), height: cellHeight)
  135. }
  136. func collectionView(_ collectionView: UICollectionView,
  137. layout collectionViewLayout: UICollectionViewLayout,
  138. insetForSectionAt section: Int) -> UIEdgeInsets {
  139. return UIEdgeInsets(top: 0, left: sidePadding, bottom: 0, right: sidePadding)
  140. }
  141. }
  142. // MARK: - UICollectionViewDelegate
  143. extension AddToPlaylistViewController: UICollectionViewDelegate {
  144. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  145. guard indexPath.row <= playlists.count else {
  146. assertionFailure("AddToPlaylistViewController: didSelectItemAt: IndexPath out of range.")
  147. return
  148. }
  149. delegate?.addToPlaylistViewController(self, didSelectPlaylist: playlists[indexPath.row])
  150. }
  151. }
  152. // MARK: - UICollectionViewDataSource
  153. extension AddToPlaylistViewController: UICollectionViewDataSource {
  154. func collectionView(_ collectionView: UICollectionView,
  155. numberOfItemsInSection section: Int) -> Int {
  156. return playlists.count
  157. }
  158. func collectionView(_ collectionView: UICollectionView,
  159. cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  160. guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MediaCollectionViewCell.defaultReuseIdentifier,
  161. for: indexPath) as? MediaCollectionViewCell else {
  162. return UICollectionViewCell()
  163. }
  164. guard indexPath.row <= playlists.count else {
  165. assertionFailure("AddToPlaylistViewController: cellForItemAt: IndexPath out of range.")
  166. return UICollectionViewCell()
  167. }
  168. cell.media = playlists[indexPath.row]
  169. return cell
  170. }
  171. }