NCMedia+CollectionViewDataSource.swift 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //
  2. // NCMedia+CollectionViewDataSource.swift
  3. // Nextcloud
  4. //
  5. // Created by Marino Faggiana on 16/07/24.
  6. // Copyright © 2024 Marino Faggiana. All rights reserved.
  7. //
  8. // Author Marino Faggiana <marino.faggiana@nextcloud.com>
  9. //
  10. // This program is free software: you can redistribute it and/or modify
  11. // it under the terms of the GNU General Public License as published by
  12. // the Free Software Foundation, either version 3 of the License, or
  13. // (at your option) any later version.
  14. //
  15. // This program is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. // GNU General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU General Public License
  21. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. //
  23. import UIKit
  24. import NextcloudKit
  25. import RealmSwift
  26. extension NCMedia: UICollectionViewDataSource {
  27. func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
  28. if kind == mediaSectionHeader {
  29. guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionFirstHeaderEmptyData", for: indexPath) as? NCSectionFirstHeaderEmptyData else { return NCSectionFirstHeaderEmptyData() }
  30. header.emptyImage.image = utility.loadImage(named: "photo", colors: [NCBrandColor.shared.getElement(account: session.account)])
  31. if self.hasRunSearchMedia {
  32. header.emptyTitle.text = NSLocalizedString("_search_in_progress_", comment: "")
  33. } else {
  34. header.emptyTitle.text = NSLocalizedString("_tutorial_photo_view_", comment: "")
  35. }
  36. header.emptyDescription.text = ""
  37. return header
  38. } else {
  39. guard let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionFooter", for: indexPath) as? NCSectionFooter else { return NCSectionFooter() }
  40. let images = dataSource.metadatas.filter({ $0.isImage }).count
  41. let video = dataSource.metadatas.count - images
  42. footer.setTitleLabel("\(images) " + NSLocalizedString("_images_", comment: "") + " • " + "\(video) " + NSLocalizedString("_video_", comment: ""))
  43. footer.separatorIsHidden(true)
  44. return footer
  45. }
  46. }
  47. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  48. let numberOfItemsInSection = dataSource.metadatas.count
  49. self.numberOfColumns = getColumnCount()
  50. if numberOfItemsInSection == 0 || NCNetworking.shared.isOffline {
  51. selectOrCancelButton.isHidden = true
  52. menuButton.isHidden = false
  53. gradientView.alpha = 0
  54. activityIndicatorTrailing.constant = 50
  55. } else if isEditMode {
  56. selectOrCancelButton.isHidden = false
  57. menuButton.isHidden = true
  58. activityIndicatorTrailing.constant = 150
  59. } else {
  60. selectOrCancelButton.isHidden = false
  61. menuButton.isHidden = false
  62. activityIndicatorTrailing.constant = 150
  63. }
  64. DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
  65. self.setTitleDate()
  66. }
  67. return numberOfItemsInSection
  68. }
  69. func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
  70. guard let metadata = dataSource.getMetadata(indexPath: indexPath) else { return }
  71. if !hiddenCellMetadats.contains(metadata.ocId + metadata.etag) {
  72. hiddenCellMetadats.append(metadata.ocId + metadata.etag)
  73. }
  74. if !collectionView.indexPathsForVisibleItems.contains(indexPath) {
  75. for case let operation as NCMediaDownloadThumbnail in NCNetworking.shared.downloadThumbnailQueue.operations where operation.metadata.ocId == metadata.ocId {
  76. operation.cancel()
  77. }
  78. }
  79. }
  80. func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
  81. guard let metadata = dataSource.getMetadata(indexPath: indexPath) else { return }
  82. if !utilityFileSystem.fileProviderStorageImageExists(metadata.ocId, etag: metadata.etag),
  83. NCNetworking.shared.downloadThumbnailQueue.operations.filter({ ($0 as? NCMediaDownloadThumbnail)?.metadata.ocId == metadata.ocId }).isEmpty {
  84. NCNetworking.shared.downloadThumbnailQueue.addOperation(NCMediaDownloadThumbnail(metadata: metadata, media: self))
  85. }
  86. }
  87. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  88. guard let cell = (collectionView.dequeueReusableCell(withReuseIdentifier: "mediaCell", for: indexPath) as? NCMediaCell) else {
  89. fatalError("Unable to dequeue MediaCell with identifier mediaCell")
  90. }
  91. guard let metadata = dataSource.getMetadata(indexPath: indexPath) else { return cell }
  92. let ext = global.getSizeExtension(column: self.numberOfColumns)
  93. let imageCache = imageCache.getImageCache(ocId: metadata.ocId, etag: metadata.etag, ext: ext)
  94. cell.imageItem.image = imageCache
  95. cell.date = metadata.date as Date
  96. cell.ocId = metadata.ocId
  97. cell.imageStatus.image = nil
  98. if cell.imageItem.frame.width > 60 {
  99. if metadata.isVideo {
  100. cell.imageStatus.image = playImage
  101. } else if metadata.isLivePhoto {
  102. cell.imageStatus.image = livePhotoImage
  103. }
  104. }
  105. if isEditMode, fileSelect.contains(metadata.ocId) {
  106. cell.selected(true)
  107. } else {
  108. cell.selected(false)
  109. }
  110. if cell.imageItem.image == nil {
  111. if isPinchGestureActive || ext == global.previewExt512 || ext == global.previewExt1024 {
  112. cell.imageItem.image = utility.getImage(ocId: metadata.ocId, etag: metadata.etag, ext: ext)
  113. } else {
  114. DispatchQueue.global(qos: .userInteractive).async {
  115. let image = self.utility.getImage(ocId: metadata.ocId, etag: metadata.etag, ext: ext)
  116. DispatchQueue.main.async {
  117. if let currentCell = collectionView.cellForItem(at: indexPath) as? NCMediaCell,
  118. currentCell.ocId == metadata.ocId, let image {
  119. self.imageCache.addImageCache(ocId: metadata.ocId, etag: metadata.etag, image: image, ext: ext, cost: indexPath.row)
  120. currentCell.imageItem.image = image
  121. }
  122. }
  123. }
  124. }
  125. }
  126. return cell
  127. }
  128. }