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.
104 lines
3.8 KiB
Swift
104 lines
3.8 KiB
Swift
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import Foundation
|
|
import Combine
|
|
import GRDB
|
|
import DifferenceKit
|
|
import SessionUIKit
|
|
import SessionMessagingKit
|
|
import SessionUtilitiesKit
|
|
|
|
class PhotoCollectionPickerViewModel: SessionTableViewModel, ObservableTableSource {
|
|
public let dependencies: Dependencies
|
|
public let state: TableDataState<Section, TableItem> = TableDataState()
|
|
public let observableState: ObservableTableSourceState<Section, TableItem> = ObservableTableSourceState()
|
|
|
|
private let library: PhotoLibrary
|
|
private let onCollectionSelected: (PhotoCollection) -> Void
|
|
private var photoCollections: CurrentValueSubject<[PhotoCollection], Error>
|
|
|
|
// MARK: - Initialization
|
|
|
|
init(
|
|
library: PhotoLibrary,
|
|
using dependencies: Dependencies,
|
|
onCollectionSelected: @escaping (PhotoCollection) -> Void
|
|
) {
|
|
self.dependencies = dependencies
|
|
self.library = library
|
|
self.onCollectionSelected = onCollectionSelected
|
|
self.photoCollections = CurrentValueSubject(library.allPhotoCollections())
|
|
}
|
|
|
|
// MARK: - Config
|
|
|
|
public enum Section: SessionTableSection {
|
|
case content
|
|
}
|
|
|
|
public struct TableItem: Hashable, Differentiable {
|
|
public typealias DifferenceIdentifier = String
|
|
|
|
private let collection: PhotoCollection
|
|
public var differenceIdentifier: String { collection.id }
|
|
|
|
init(collection: PhotoCollection) {
|
|
self.collection = collection
|
|
}
|
|
|
|
public func isContentEqual(to source: TableItem) -> Bool {
|
|
return (collection.id == source.collection.id)
|
|
}
|
|
|
|
public func hash(into hasher: inout Hasher) {
|
|
collection.id.hash(into: &hasher)
|
|
}
|
|
}
|
|
|
|
// MARK: - Content
|
|
|
|
let title: String = "notificationsSound".localized()
|
|
|
|
lazy var observation: TargetObservation = ObservationBuilder
|
|
.subject(photoCollections)
|
|
.map { collections -> [SectionModel] in
|
|
[
|
|
SectionModel(
|
|
model: .content,
|
|
elements: collections.map { collection in
|
|
let contents: PhotoCollectionContents = collection.contents()
|
|
let photoMediaSize: PhotoMediaSize = PhotoMediaSize(
|
|
thumbnailSize: CGSize(
|
|
width: IconSize.extraLarge.size,
|
|
height: IconSize.extraLarge.size
|
|
)
|
|
)
|
|
let lastAssetItem: PhotoPickerAssetItem? = contents.lastAssetItem(photoMediaSize: photoMediaSize)
|
|
|
|
return SessionCell.Info(
|
|
id: TableItem(collection: collection),
|
|
leadingAccessory: .iconAsync(size: .extraLarge, shouldFill: true) { imageView in
|
|
// Note: We need to capture 'lastAssetItem' otherwise it'll be released and we won't
|
|
// be able to load the thumbnail
|
|
lastAssetItem?.asyncThumbnail { [weak imageView] image in
|
|
imageView?.image = image
|
|
}
|
|
},
|
|
title: collection.localizedTitle(),
|
|
subtitle: "\(contents.assetCount)",
|
|
onTap: { [weak self] in
|
|
self?.onCollectionSelected(collection)
|
|
}
|
|
)
|
|
}
|
|
)
|
|
]
|
|
}
|
|
|
|
// MARK: PhotoLibraryDelegate
|
|
|
|
func photoLibraryDidChange(_ photoLibrary: PhotoLibrary) {
|
|
self.photoCollections.send(library.allPhotoCollections())
|
|
}
|
|
}
|