Commit 656d7fa9 authored by shenyong's avatar shenyong

app内资源删除

parent d9f0c377
...@@ -69,137 +69,16 @@ actor PhotoSimilarStateManager { ...@@ -69,137 +69,16 @@ actor PhotoSimilarStateManager {
self.timeGroups = timeGroups self.timeGroups = timeGroups
self.similarGroups = similarGroups self.similarGroups = similarGroups
} }
}
// 截图状态管理 actor
actor ScreenshotSimilarStateManager {
private var timeGroups: [TimeGroupModel] = []
private var similarGroups: [SimilarGroupModel] = []
private var pendingSimilarGroups: [SimilarGroupModel] = []
private var processedGroupCount: Int = 0
private var assetsImageCache: [String: UIImage] = [:]
private var hashCache: [String: String] = [:]
func appendTimeGroup(_ group: TimeGroupModel) {
timeGroups.append(group)
}
func appendSimilarGroup(_ group: SimilarGroupModel) {
pendingSimilarGroups.append(group)
processedGroupCount += 1
}
func getAllTimeGroups() -> [TimeGroupModel] {
return timeGroups
}
func getpendingSimilarGroups() -> [SimilarGroupModel] {
return pendingSimilarGroups
}
func getAllSimilarGroups() -> [SimilarGroupModel] {
return similarGroups
}
func getCachedImage(for identifier: String) -> UIImage? {
return assetsImageCache[identifier]
}
func setCachedImage(_ image: UIImage, for identifier: String) {
assetsImageCache[identifier] = image
}
func shouldSavePendingGroups() -> Bool {
return processedGroupCount >= 10
}
func getCachedHash(for identifier: String) async -> String? {
return hashCache[identifier]
}
func setCachedHash(_ hash: String, for identifier: String) async {
hashCache[identifier] = hash
}
func savePendingGroups() {
similarGroups.append(contentsOf: pendingSimilarGroups)
pendingSimilarGroups.removeAll()
processedGroupCount = 0
}
func loadStoredData(timeGroups: [TimeGroupModel], similarGroups: [SimilarGroupModel]) {
self.timeGroups = timeGroups
self.similarGroups = similarGroups
}
}
// 视频状态管理 actor
actor VideoSimilarStateManager {
private var timeGroups: [TimeGroupModel] = []
private var similarGroups: [SimilarGroupModel] = []
private var pendingSimilarGroups: [SimilarGroupModel] = []
private var processedGroupCount: Int = 0
private var assetsImageCache: [String: UIImage] = [:]
private var hashCache: [String: String] = [:]
func appendTimeGroup(_ group: TimeGroupModel) {
timeGroups.append(group)
}
func appendSimilarGroup(_ group: SimilarGroupModel) { func deleteData(for idsToRemove:[String]){
pendingSimilarGroups.append(group) let updateGroups = self.similarGroups.removingGroupsWithEmptyAssetsWithDetails(afterRemovingIDs: idsToRemove)
processedGroupCount += 1 self.similarGroups = updateGroups.updatedGroups
}
func getAllTimeGroups() -> [TimeGroupModel] {
return timeGroups
}
func getpendingSimilarGroups() -> [SimilarGroupModel] {
return pendingSimilarGroups
}
func getAllSimilarGroups() -> [SimilarGroupModel] {
return similarGroups
}
func getCachedImage(for identifier: String) -> UIImage? {
return assetsImageCache[identifier]
}
func setCachedImage(_ image: UIImage, for identifier: String) {
assetsImageCache[identifier] = image
}
func shouldSavePendingGroups() -> Bool {
return processedGroupCount >= 10
}
func getCachedHash(for identifier: String) async -> String? {
return hashCache[identifier]
}
func setCachedHash(_ hash: String, for identifier: String) async {
hashCache[identifier] = hash
}
func savePendingGroups() {
similarGroups.append(contentsOf: pendingSimilarGroups)
pendingSimilarGroups.removeAll()
processedGroupCount = 0
}
func loadStoredData(timeGroups: [TimeGroupModel], similarGroups: [SimilarGroupModel]) {
self.timeGroups = timeGroups
self.similarGroups = similarGroups
} }
} }
actor PhotoDuplicateStateManager { actor PhotoDuplicateStateManager {
private var duplicateGroups: [DuplicateGroupModel] = [] private var duplicateGroups: [SimilarGroupModel] = []
private var pendingDuplicateGroups: [DuplicateGroupModel] = [] private var pendingDuplicateGroups: [SimilarGroupModel] = []
// 缓存 // 缓存
private var imageCache: [String: UIImage] = [:] private var imageCache: [String: UIImage] = [:]
...@@ -207,15 +86,15 @@ actor PhotoDuplicateStateManager { ...@@ -207,15 +86,15 @@ actor PhotoDuplicateStateManager {
// MARK: - 公共方法 // MARK: - 公共方法
func loadStoredData(duplicateGroups: [DuplicateGroupModel]) { func loadStoredData(duplicateGroups: [SimilarGroupModel]) {
self.duplicateGroups = duplicateGroups self.duplicateGroups = duplicateGroups
} }
func getAllDuplicateGroups() -> [DuplicateGroupModel] { func getAllDuplicateGroups() -> [SimilarGroupModel] {
return duplicateGroups return duplicateGroups
} }
func appendDuplicateGroup(_ group: DuplicateGroupModel) { func appendDuplicateGroup(_ group: SimilarGroupModel) {
pendingDuplicateGroups.append(group) pendingDuplicateGroups.append(group)
} }
...@@ -228,7 +107,7 @@ actor PhotoDuplicateStateManager { ...@@ -228,7 +107,7 @@ actor PhotoDuplicateStateManager {
pendingDuplicateGroups.removeAll() pendingDuplicateGroups.removeAll()
} }
func getPendingDuplicateGroups() -> [DuplicateGroupModel] { func getPendingDuplicateGroups() -> [SimilarGroupModel] {
return pendingDuplicateGroups return pendingDuplicateGroups
} }
...@@ -253,5 +132,10 @@ actor PhotoDuplicateStateManager { ...@@ -253,5 +132,10 @@ actor PhotoDuplicateStateManager {
func setCachedHash(_ hash: String, for identifier: String) { func setCachedHash(_ hash: String, for identifier: String) {
hashCache[identifier] = hash hashCache[identifier] = hash
} }
func deleteData(for idsToRemove:[String]){
let updateGroups = self.duplicateGroups.removingGroupsWithEmptyAssetsWithDetails(afterRemovingIDs: idsToRemove)
self.duplicateGroups = updateGroups.updatedGroups
}
} }
...@@ -126,7 +126,7 @@ class PhotoDuplicateManager: @unchecked Sendable { ...@@ -126,7 +126,7 @@ class PhotoDuplicateManager: @unchecked Sendable {
// 保存重复组 // 保存重复组
await self.stateManager.appendDuplicateGroup( await self.stateManager.appendDuplicateGroup(
DuplicateGroupModel(groupId: groupId, assets: assetModels) SimilarGroupModel(groupId: groupId, assets: assetModels)
) )
if await self.stateManager.shouldSavePendingGroups() { if await self.stateManager.shouldSavePendingGroups() {
...@@ -151,196 +151,7 @@ class PhotoDuplicateManager: @unchecked Sendable { ...@@ -151,196 +151,7 @@ class PhotoDuplicateManager: @unchecked Sendable {
} }
} }
// func findDuplicateAssets(
// in assets: [PHAsset],
// mediaType: MediaType = .photo,
// loacalHandler: @Sendable @escaping ([[AssetModel]]) -> Void,
// progressHandler: @Sendable @escaping ([AssetModel]) -> Void,
// completionHandler: @Sendable @escaping ([[AssetModel]]) -> Void
// ) {
// // 使用后台优先级
// Task.detached(priority: .background) { [weak self] in
// guard let self = self else { return }
//
// do {
// // 批量处理,减少主线程切换
// let batchSize = 100
// var accumulatedProgress: [AssetModel] = []
//
// for i in stride(from: 0, to: assets.count, by: batchSize) {
// let end = min(i + batchSize, assets.count)
// let batchAssets = Array(assets[i..<end])
//
// // 处理一批资源
// let results = try await self.processBatch(batchAssets)
// accumulatedProgress.append(contentsOf: results)
//
// // 每处理一定数量后才更新UI
// if accumulatedProgress.count >= 50 {
// await MainActor.run {
// progressHandler(accumulatedProgress)
// }
// accumulatedProgress.removeAll()
// }
//
// // 给主线程喘息的机会
// try await Task.sleep(nanoseconds: 1_000_000) // 1ms
// }
//
// // 1. 加载本地数据
// await self.loadStoredData()
// print("本地数据加载完成")
//
// // 2. 通知已缓存的结果
// let cachedGroups = await self.stateManager.getAllDuplicateGroups()
// print("通知已缓存的结果", cachedGroups.count)
//
// await MainActor.run {
// let groups = cachedGroups.map { $0.assets }
// loacalHandler(groups)
// }
//
// // 3. 按特征预分组(分辨率、时间、文件大小)
// let featureGroups = try await self.groupAssetsByFeatures(assets)
//
// // 如果没有需要处理的组,直接返回缓存结果
// if featureGroups.isEmpty {
// let total = cachedGroups.map { $0.assets }
// await MainActor.run {
// completionHandler(total)
// }
// return
// }
//
// // 4. 并发处理每组资源
// try await self.processFeatureGroups(featureGroups, progressHandler: progressHandler)
//
// // 5. 完成处理
// if await !self.stateManager.getPendingDuplicateGroups().isEmpty {
// await self.savePendingDuplicateGroups()
// }
//
// let allGroups = await self.stateManager.getAllDuplicateGroups()
// await MainActor.run {
// print("执行完毕")
// completionHandler(allGroups.map { $0.assets })
// }
// } catch {
// print("查找重复资源失败: \(error)")
// await MainActor.run {
// completionHandler([]) // 返回空数组或错误处理
// }
// }
// }
// }
// 按特征分组(分辨率、文件大小等)
// private func groupAssetsByFeatures(_ assets: [PHAsset]) async throws -> [[PHAsset]] {
// var tempGroups: [String: [PHAsset]] = [:]
//
// // 使用串行队列确保线程安全
// let queue = DispatchQueue(label: "com.example.assetGrouping")
//
// // 并发处理所有资源
// await withThrowingTaskGroup(of: Void.self) { group in
// for asset in assets {
// group.addTask {
// // 创建特征键(分辨率+文件大小)
// let resolution = "\(asset.pixelWidth)x\(asset.pixelHeight)"
// let fileSize = await self.getAssetSize(asset: asset)
// let featureKey = "\(resolution)_\(fileSize)"
//
// // 使用同步队列更新共享字典
// queue.sync {
// if tempGroups[featureKey] == nil {
// tempGroups[featureKey] = []
// }
// tempGroups[featureKey]?.append(asset)
// }
// }
// }
// }
//
// // 只保留有多个资源的组
// return tempGroups.values.filter { $0.count > 1 }
// }
// 处理特征分组并查找重复项
// private func processFeatureGroups(
// _ featureGroups: [[PHAsset]],
// progressHandler: (([AssetModel]) -> Void)?
// ) async throws {
// let maxConcurrency = 2 // 最大并发数
// let batchSize = max(1, featureGroups.count / maxConcurrency)
//
// for batchIndex in stride(from: 0, to: featureGroups.count, by: batchSize) {
// let endIndex = min(batchIndex + batchSize, featureGroups.count)
// let batch = Array(featureGroups[batchIndex..<endIndex])
//
// await withThrowingTaskGroup(of: Void.self) { group in
// for assets in batch {
// group.addTask { [weak self] in
// guard let self = self else { return }
//
// // 只需要计算phash值并比较
// var hashGroups: [String: [PHAsset]] = [:]
//
// // 处理单个组内的资源,控制并发
// await withThrowingTaskGroup(of: Void.self) { innerGroup in
// for asset in assets {
// innerGroup.addTask {
// if let hash = await self.getOrCalculateHash(for: asset) {
// // 使用同步队列更新共享字典
// DispatchQueue.global().sync {
// if hashGroups[hash] == nil {
// hashGroups[hash] = []
// }
// hashGroups[hash]?.append(asset)
// }
// }
// }
// }
// }
//
// // 找出phash值相同的组
// let duplicateGroups = hashGroups.values.filter { $0.count > 1 }
//
// // 处理找到的重复组
// for duplicateGroup in duplicateGroups {
// let groupId = UUID().uuidString
// let assetModels = await self.createAssetModels(from: duplicateGroup)
//
// // 通知进度
// await MainActor.run {
// progressHandler?(assetModels)
// }
//
// // 保存重复组
// await self.stateManager.appendDuplicateGroup(
// DuplicateGroupModel(groupId: groupId, assets: assetModels)
// )
//
// if await self.stateManager.shouldSavePendingGroups() {
// await self.savePendingDuplicateGroups()
// }
// }
// }
// }
// }
// }
// }
// MARK: - 辅助方法
// nonisolated private func getAssetSize(_ asset: PHAsset) -> Int64 {
// if let resource = PHAssetResource.assetResources(for: asset).first,
// let size = resource.value(forKey: "fileSize") as? Int64 {
// return size
// }
// return 0
// }
func getAssetSize(asset: PHAsset) async -> Int64 { func getAssetSize(asset: PHAsset) async -> Int64 {
// 先尝试从缓存获取 // 先尝试从缓存获取
if let cachedSize = await AssetSizeCache.shared.getSize(for: asset) { if let cachedSize = await AssetSizeCache.shared.getSize(for: asset) {
...@@ -386,10 +197,10 @@ class PhotoDuplicateManager: @unchecked Sendable { ...@@ -386,10 +197,10 @@ class PhotoDuplicateManager: @unchecked Sendable {
extension PhotoDuplicateManager { extension PhotoDuplicateManager {
private func loadStoredData() async { private func loadStoredData() async {
var loadedDuplicateGroups: [DuplicateGroupModel] = [] var loadedDuplicateGroups: [SimilarGroupModel] = []
if let data = try? Data(contentsOf: URL(fileURLWithPath: duplicateGroupsPath)), if let data = try? Data(contentsOf: URL(fileURLWithPath: duplicateGroupsPath)),
let groups = try? JSONDecoder().decode([DuplicateGroupModel].self, from: data) { let groups = try? JSONDecoder().decode([SimilarGroupModel].self, from: data) {
loadedDuplicateGroups = groups loadedDuplicateGroups = groups
} }
...@@ -401,7 +212,17 @@ extension PhotoDuplicateManager { ...@@ -401,7 +212,17 @@ extension PhotoDuplicateManager {
if let data = try? JSONEncoder().encode(await stateManager.getAllDuplicateGroups()) { if let data = try? JSONEncoder().encode(await stateManager.getAllDuplicateGroups()) {
try? data.write(to: URL(fileURLWithPath: duplicateGroupsPath)) try? data.write(to: URL(fileURLWithPath: duplicateGroupsPath))
} }
} }
// 移除本地文件资源
func removeLocalFileWithIds(for ids:[String]) async{
await stateManager.deleteData(for: ids)
// 保存到文件
if let data = try? JSONEncoder().encode(await stateManager.getAllDuplicateGroups()) {
try? data.write(to: URL(fileURLWithPath: duplicateGroupsPath))
}
}
} }
// MARK: - Hash计算相关方法 // MARK: - Hash计算相关方法
...@@ -472,45 +293,6 @@ extension PhotoDuplicateManager { ...@@ -472,45 +293,6 @@ extension PhotoDuplicateManager {
return pixels.map { $0 > average ? "1" : "0" }.joined() return pixels.map { $0 > average ? "1" : "0" }.joined()
} }
// private func processBatch(_ assets: [PHAsset]) async throws -> [AssetModel] {
// var results: [AssetModel] = []
//
// // 按特征预分组
// let featureGroups = try await self.groupAssetsByFeatures(assets)
//
// // 处理每个特征组
// for assets in featureGroups {
// // 计算hash并分组
// var hashGroups: [String: [PHAsset]] = [:]
//
// for asset in assets {
// if let hash = await self.getOrCalculateHash(for: asset) {
// if hashGroups[hash] == nil {
// hashGroups[hash] = []
// }
// hashGroups[hash]?.append(asset)
// }
// }
//
// // 找出hash值相同的组
// let duplicateGroups = hashGroups.values.filter { $0.count > 1 }
//
// // 处理找到的重复组
// for duplicateGroup in duplicateGroups {
// let assetModels = await self.createAssetModels(from: duplicateGroup)
// results.append(contentsOf: assetModels)
//
// // 保存到状态管理器
// let groupId = UUID().uuidString
// await self.stateManager.appendDuplicateGroup(
// DuplicateGroupModel(groupId: groupId, assets: assetModels)
// )
// }
// }
//
// return results
//
// }
} }
......
...@@ -702,24 +702,44 @@ extension PhotoManager{ ...@@ -702,24 +702,44 @@ extension PhotoManager{
extension PhotoManager{ extension PhotoManager{
// 处理app图片删除 // 处理app图片删除
func removeDataWhenDeleteInPage(data:[AssetModel]){ func removeDataWhenDeleteInPage(data:[AssetModel],completionHandler: (() -> Void)? = nil){
let deletes = data.compactMap{$0.localIdentifier} Task.detached(priority: .background) { [weak self] in
guard let self = self else { return }
let others = removeAssets(withIdentifiers: deletes, from: otherModels)
let videos = removeAssets(withIdentifiers: deletes, from: videoModels) let deletes = data.compactMap{$0.localIdentifier}
let screens = removeAssets(withIdentifiers: deletes, from: screenShotModels)
// 临时数据更新
otherModels = others let others = removeAssets(withIdentifiers: deletes, from: otherModels)
videoModels = videos let videos = removeAssets(withIdentifiers: deletes, from: videoModels)
screenShotModels = screens let screens = removeAssets(withIdentifiers: deletes, from: screenShotModels)
// 保存到本地 otherModels = others
saveToLocal(type: "video", models: self.videoModels) videoModels = videos
saveToLocal(type: "other", models: self.otherModels) screenShotModels = screens
saveToLocal(type: "screenshot", models: self.screenShotModels)
// 临时数据更新
let similarPhotos = filterGroups(similarModels, byExcludingIDs: deletes)
let similarVideos = filterGroups(similarVideoModels, byExcludingIDs: deletes)
let similarShots = filterGroups(similarScreenShotModels, byExcludingIDs: deletes)
similarModels = similarPhotos
similarVideoModels = similarVideos
similarScreenShotModels = similarShots
// 保存到本地
saveToLocal(type: "video", models: self.videoModels)
saveToLocal(type: "other", models: self.otherModels)
saveToLocal(type: "screenshot", models: self.screenShotModels)
await PhotoSimilarManager.shared.removeLocalFileWithIds(for: deletes)
await ScreenshotSimilarJSONManager.shared.removeLocalFileWithIds(for: deletes)
await VideoSimilarJSONManager.shared.removeLocalFileWithIds(for: deletes)
await PhotoDuplicateManager.shared.removeLocalFileWithIds(for: deletes)
completionHandler?()
}
} }
......
...@@ -86,17 +86,18 @@ struct SimilarGroupModel: Codable { ...@@ -86,17 +86,18 @@ struct SimilarGroupModel: Codable {
var assets: [AssetModel] var assets: [AssetModel]
} }
// 重复图片组模型
struct DuplicateGroupModel: Codable {
let groupId: String
let assets: [AssetModel]
}
struct Match { struct Match {
let groupIndex: Int let groupIndex: Int
let matchedElements: [AssetModel] let matchedElements: [AssetModel]
} }
struct RemovalResult {
let updatedGroups: [SimilarGroupModel]
let removedAssets: [AssetModel]
let removedGroups: [SimilarGroupModel]
}
extension Sequence where Element == [AssetModel] { extension Sequence where Element == [AssetModel] {
/// 判断二维数组中是否包含某个子数组,其元素的localIdentifier集合与给定数组完全相同(忽略顺序) /// 判断二维数组中是否包含某个子数组,其元素的localIdentifier集合与给定数组完全相同(忽略顺序)
...@@ -124,3 +125,69 @@ extension Sequence where Element == [AssetModel] { ...@@ -124,3 +125,69 @@ extension Sequence where Element == [AssetModel] {
return matches return matches
} }
} }
extension SimilarGroupModel {
/// 过滤掉assets中包含指定ID的元素
func removingAssets(withIDs ids: Set<String>) -> SimilarGroupModel {
let filteredAssets = self.assets.filter { !ids.contains($0.localIdentifier) }
return SimilarGroupModel(groupId: self.groupId, assets: filteredAssets)
}
}
extension Array where Element == SimilarGroupModel {
/// 批量过滤所有组中的assets,移除包含指定ID的元素,并移除assets为空的组
func removingGroupsWithEmptyAssets(afterRemovingIDs ids: [String]) -> [SimilarGroupModel] {
let idSet = Set(ids)
return self.compactMap { group in
let filteredGroup = group.removingAssets(withIDs: idSet)
return filteredGroup.assets.isEmpty ? nil : filteredGroup
}
}
/// 原地修改:直接在原数组上移除包含指定ID的元素,并移除assets为空的组
mutating func removeGroupsWithEmptyAssetsInPlace(afterRemovingIDs ids: [String]) {
self = self.removingGroupsWithEmptyAssets(afterRemovingIDs: ids)
}
/// 删除日志,拿到执行删除后的更新数据,删除数据,移除的组
func removingGroupsWithEmptyAssetsWithDetails(afterRemovingIDs ids: [String]) -> RemovalResult {
let idSet = Set(ids)
var removedAssets = [AssetModel]()
var removedGroups = [SimilarGroupModel]()
let updated = self.compactMap { (group: SimilarGroupModel) -> SimilarGroupModel? in
let filteredAssets = group.assets.filter { !idSet.contains($0.localIdentifier) }
let removedInGroup = group.assets.filter { idSet.contains($0.localIdentifier) }
removedAssets.append(contentsOf: removedInGroup)
// 修改判断条件:当assets数量小于2时移除整个组
if filteredAssets.count < 2 {
removedGroups.append(group)
return nil
} else {
return SimilarGroupModel(groupId: group.groupId, assets: filteredAssets)
}
}
return RemovalResult(
updatedGroups: updated,
removedAssets: removedAssets,
removedGroups: removedGroups
)
}
}
extension Sequence where Element == [AssetModel] {
/// 删除二维数组中包含指定ID的元素,并移除所有元素数量少于2的子数组
func removingElementsAndSmallGroups(ids: [String]) -> [[AssetModel]] {
let idSet = Set(ids)
return self.compactMap { group in
let filtered = group.filter { !idSet.contains($0.localIdentifier) }
return filtered.count < 2 ? nil : filtered // 修改判断条件
}
}
}
...@@ -349,6 +349,16 @@ extension PhotoSimilarManager{ ...@@ -349,6 +349,16 @@ extension PhotoSimilarManager{
return SimilarGroupModel(groupId: group.groupId, assets: validAssets) return SimilarGroupModel(groupId: group.groupId, assets: validAssets)
}.filter { !$0.assets.isEmpty } }.filter { !$0.assets.isEmpty }
} }
// 移除本地文件资源
func removeLocalFileWithIds(for ids:[String]) async{
await stateManager.deleteData(for: ids)
// 保存到文件
if let data = try? JSONEncoder().encode(await stateManager.getAllSimilarGroups()) {
try? data.write(to: URL(fileURLWithPath: similarGroupsPath))
}
}
} }
// MARK: - pHash获取 // MARK: - pHash获取
......
...@@ -382,6 +382,17 @@ extension ScreenshotSimilarJSONManager{ ...@@ -382,6 +382,17 @@ extension ScreenshotSimilarJSONManager{
return SimilarGroupModel(groupId: group.groupId, assets: validAssets) return SimilarGroupModel(groupId: group.groupId, assets: validAssets)
}.filter { !$0.assets.isEmpty } }.filter { !$0.assets.isEmpty }
} }
// 移除本地文件资源
func removeLocalFileWithIds(for ids:[String]) async{
await stateManager.deleteData(for: ids)
// 保存到文件
if let data = try? JSONEncoder().encode(await stateManager.getAllSimilarGroups()) {
try? data.write(to: URL(fileURLWithPath: similarGroupsPath))
}
}
} }
// MARK: - pHash获取 // MARK: - pHash获取
......
...@@ -47,7 +47,7 @@ private actor VideoAssetCacheManager { ...@@ -47,7 +47,7 @@ private actor VideoAssetCacheManager {
class VideoSimilarJSONManager: @unchecked Sendable { class VideoSimilarJSONManager: @unchecked Sendable {
static let shared = VideoSimilarJSONManager() static let shared = VideoSimilarJSONManager()
private let stateManager = VideoSimilarStateManager() private let stateManager = PhotoSimilarStateManager()
private init() {} private init() {}
// 类中添加缓存管理器实例 // 类中添加缓存管理器实例
...@@ -633,6 +633,16 @@ extension VideoSimilarJSONManager { ...@@ -633,6 +633,16 @@ extension VideoSimilarJSONManager {
try? data.write(to: URL(fileURLWithPath: similarGroupsPath)) try? data.write(to: URL(fileURLWithPath: similarGroupsPath))
} }
} }
// 移除本地文件资源
func removeLocalFileWithIds(for ids:[String]) async{
await stateManager.deleteData(for: ids)
// 保存到文件
if let data = try? JSONEncoder().encode(await stateManager.getAllSimilarGroups()) {
try? data.write(to: URL(fileURLWithPath: similarGroupsPath))
}
}
} }
......
...@@ -328,7 +328,8 @@ class CompressCompletedViewController : BaseViewController{ ...@@ -328,7 +328,8 @@ class CompressCompletedViewController : BaseViewController{
models.append(deleteModel) models.append(deleteModel)
} }
if(success){ if(success){
PhotoDataManager.manager.removeDataWhenDeleteInPage(data: models) // PhotoDataManager.manager.removeDataWhenDeleteInPage(data: models)
PhotoManager.shared.removeDataWhenDeleteInPage(data: models)
print("删除文件成功") print("删除文件成功")
self.showDeleteSuccess(fileCount:count, fileSize: fileSize) self.showDeleteSuccess(fileCount:count, fileSize: fileSize)
}else { }else {
......
...@@ -94,29 +94,17 @@ class HomeInfoViewController:BaseViewController { ...@@ -94,29 +94,17 @@ class HomeInfoViewController:BaseViewController {
} }
self.showDeleteSuccess(fileCount: tempStringArray.count, fileSize: fileSize) self.showDeleteSuccess(fileCount: tempStringArray.count, fileSize: fileSize)
// 删除缓存数据 PhotoManager.shared.removeDataWhenDeleteInPage(data: imgs)
PhotoDataManager.manager.removeDataWhenDeleteInPage(data: imgs)
// 更新下ids let new = self.ids?.removingElementsAndSmallGroups(ids: imgs.compactMap{$0.localIdentifier})
PhotoDataManager.manager.loadFromFileSystem(resultModel: {[weak self] model in
DispatchQueue.main.async { self.ids = new
if self?.type == .duplicates {
self?.ids = model.titleModelArray[0].assets self.tablewView.ids = self.ids
} self.tablewView.deleteModel(array: imgs)
if self?.type == .similar {
self?.ids = model.titleModelArray[1].assets
}
if self?.type == .SimilarVideos {
self?.ids = model.otherModelArray[3].assets
}
if self?.type == .similarScreenshots {
self?.ids = model.otherModelArray[1].assets
}
self?.tablewView.ids = self?.ids
self?.tablewView.deleteModel(array: imgs)
}
})
self.setDefaultPage() self.setDefaultPage()
} }
......
...@@ -36,7 +36,7 @@ class HomePhotosDetailViewController : BaseViewController { ...@@ -36,7 +36,7 @@ class HomePhotosDetailViewController : BaseViewController {
func dealData(){ func dealData(){
var dataArray : [AssetModel] = [] var dataArray : [AssetModel] = []
for item in self.model.assets { for item in self.model.originalAssets {
dataArray = dataArray + item dataArray = dataArray + item
} }
self.resourceData = self.filterTrashData(array: dataArray) self.resourceData = self.filterTrashData(array: dataArray)
...@@ -245,6 +245,8 @@ class HomePhotosDetailViewController : BaseViewController { ...@@ -245,6 +245,8 @@ class HomePhotosDetailViewController : BaseViewController {
showTipsVC() showTipsVC()
} }
func showTipsVC(){ func showTipsVC(){
guard let mediaType = mediaType else{ guard let mediaType = mediaType else{
...@@ -271,7 +273,7 @@ class HomePhotosDetailViewController : BaseViewController { ...@@ -271,7 +273,7 @@ class HomePhotosDetailViewController : BaseViewController {
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
dealData()
// 目的是为了消除cell 的选择按钮状态 // 目的是为了消除cell 的选择按钮状态
if self.selectedModel.count == 0 { if self.selectedModel.count == 0 {
self.collectionView.reloadData() self.collectionView.reloadData()
...@@ -692,8 +694,10 @@ extension HomePhotosDetailViewController:WaterfallMutiSectionDelegate,UICollecti ...@@ -692,8 +694,10 @@ extension HomePhotosDetailViewController:WaterfallMutiSectionDelegate,UICollecti
} }
// 清理下缓存数据 // 清理下缓存数据
PhotoDataManager.manager.removeDataWhenDeleteInPage(data: self.selectedModel) // PhotoDataManager.manager.removeDataWhenDeleteInPage(data: self.selectedModel)
PhotoManager.shared.removeDataWhenDeleteInPage(data: self.selectedModel) {
//删除完成刷新数据
}
// 更新页面 // 更新页面
DispatchQueue.main.async { DispatchQueue.main.async {
// 删除完成之后,移除下当前选择的数据 // 删除完成之后,移除下当前选择的数据
......
...@@ -29,7 +29,7 @@ class HomeVideoDetailController :BaseViewController { ...@@ -29,7 +29,7 @@ class HomeVideoDetailController :BaseViewController {
func dealData(){ func dealData(){
var dataArray : [AssetModel] = [] var dataArray : [AssetModel] = []
for item in self.model.assets { for item in self.model.originalAssets {
dataArray = dataArray + item dataArray = dataArray + item
} }
self.resourceData = self.filterTrashData(array: dataArray) self.resourceData = self.filterTrashData(array: dataArray)
...@@ -209,7 +209,7 @@ class HomeVideoDetailController :BaseViewController { ...@@ -209,7 +209,7 @@ class HomeVideoDetailController :BaseViewController {
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) super.viewWillAppear(animated)
dealData()
// 目的是为了消除cell 的选择按钮状态 // 目的是为了消除cell 的选择按钮状态
if self.selectedModel.count == 0 { if self.selectedModel.count == 0 {
self.collectionView.reloadData() self.collectionView.reloadData()
...@@ -345,6 +345,7 @@ extension HomeVideoDetailController:WaterfallMutiSectionDelegate,UICollectionVie ...@@ -345,6 +345,7 @@ extension HomeVideoDetailController:WaterfallMutiSectionDelegate,UICollectionVie
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "HomeVideoDetailCustomHeaderView", for: indexPath) as! HomeVideoDetailCustomHeaderView let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "HomeVideoDetailCustomHeaderView", for: indexPath) as! HomeVideoDetailCustomHeaderView
// 记录当前的 headerView // 记录当前的 headerView
currentHeaderView = header currentHeaderView = header
header.compressionTipView.reloadData()
header.sizeLabel.text = "\(self.resourceData.count) Videos" header.sizeLabel.text = "\(self.resourceData.count) Videos"
header.sortCallback = {[weak self] in header.sortCallback = {[weak self] in
guard let self else {return} guard let self else {return}
...@@ -582,9 +583,11 @@ extension HomeVideoDetailController:WaterfallMutiSectionDelegate,UICollectionVie ...@@ -582,9 +583,11 @@ extension HomeVideoDetailController:WaterfallMutiSectionDelegate,UICollectionVie
// 清理下缓存数据 // 清理下缓存数据
PhotoDataManager.manager.removeDataWhenDeleteInPage(data: self.selectedModel) //PhotoDataManager.manager.removeDataWhenDeleteInPage(data: self.selectedModel)
PhotoManager.shared.removeDataWhenDeleteInPage(data: self.selectedModel) {
// 删除完成刷新数据
}
// 更新页面 // 更新页面
......
...@@ -131,7 +131,6 @@ class HomeViewController:BaseViewController { ...@@ -131,7 +131,6 @@ class HomeViewController:BaseViewController {
if otherItemRow == 0 { if otherItemRow == 0 {
DispatchQueue.main.async { DispatchQueue.main.async {
let vc:HomeVideoDetailController = HomeVideoDetailController(model: model) let vc:HomeVideoDetailController = HomeVideoDetailController(model: model)
vc.dealData()
self.navigationController?.pushViewController(vc, animated: true) self.navigationController?.pushViewController(vc, animated: true)
} }
} }
...@@ -158,7 +157,6 @@ class HomeViewController:BaseViewController { ...@@ -158,7 +157,6 @@ class HomeViewController:BaseViewController {
}else{ }else{
vc.mediaType = .Other vc.mediaType = .Other
} }
vc.dealData()
self.navigationController?.pushViewController(vc, animated: true) self.navigationController?.pushViewController(vc, animated: true)
} }
} }
......
...@@ -35,11 +35,14 @@ class HomePhotosModel:Codable { ...@@ -35,11 +35,14 @@ class HomePhotosModel:Codable {
var folderName:String var folderName:String
var allFileSize:Double var allFileSize:Double
var assets:[[AssetModel]] var assets:[[AssetModel]]
var originalAssets:[[AssetModel]]
init(folderName: String, allFileSize: Double, assets: [[AssetModel]]) { init(folderName: String, allFileSize: Double, assets: [[AssetModel]],originalAssets:[[AssetModel]] = []) {
self.folderName = folderName self.folderName = folderName
self.allFileSize = allFileSize self.allFileSize = allFileSize
self.assets = assets self.assets = assets
self.originalAssets = originalAssets
} }
} }
......
...@@ -30,6 +30,7 @@ class HomeCollectionViewHeader : UICollectionReusableView { ...@@ -30,6 +30,7 @@ class HomeCollectionViewHeader : UICollectionReusableView {
lazy var permissionView : PMPermissionView = { lazy var permissionView : PMPermissionView = {
let view = Bundle.main.loadNibNamed("PMPermissionView", owner: nil, options: nil)?.last as! PMPermissionView let view = Bundle.main.loadNibNamed("PMPermissionView", owner: nil, options: nil)?.last as! PMPermissionView
view.isHidden = true
return view return view
}() }()
......
...@@ -261,7 +261,6 @@ extension HomeView:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICol ...@@ -261,7 +261,6 @@ extension HomeView:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICol
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: HomeTitleCollectionCell.identifiers, for: indexPath) as! HomeTitleCollectionCell let cell = collectionView.dequeueReusableCell(withReuseIdentifier: HomeTitleCollectionCell.identifiers, for: indexPath) as! HomeTitleCollectionCell
let model = viewModel.headerGroup[indexPath.row] let model = viewModel.headerGroup[indexPath.row]
cell.reloadUIWithModel(model: model) cell.reloadUIWithModel(model: model)
// cell.reloadCoverData()
cell.homeTititlAction = {[weak self] idx in cell.homeTititlAction = {[weak self] idx in
guard let self = self else { return } guard let self = self else { return }
if indexPath.row == 0 { if indexPath.row == 0 {
...@@ -270,14 +269,6 @@ extension HomeView:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICol ...@@ -270,14 +269,6 @@ extension HomeView:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICol
self.titleCallBack(model,.similar) self.titleCallBack(model,.similar)
} }
} }
// cell.reloadCoverData(viewModel.headCoverImages[indexPath.row] ?? [])
// if indexPath.row == 0 {
// self.dupHeadCell = cell
// // cell.reloadCoverData(viewModel.dupCoverImage ?? [])
// }else{
// // cell.reloadCoverData(viewModel.similarCoverImage ?? [])
// self.similarHeadCell = cell
// }
if cell.model?.assets.count ?? 0 > 0 { if cell.model?.assets.count ?? 0 > 0 {
cell.fileLabel?.isHidden = false cell.fileLabel?.isHidden = false
...@@ -291,13 +282,6 @@ extension HomeView:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICol ...@@ -291,13 +282,6 @@ extension HomeView:WaterfallMutiSectionDelegate,UICollectionViewDataSource,UICol
cell.dealMediaType(indexPath.row) cell.dealMediaType(indexPath.row)
let model = viewModel.cardGroup[indexPath.row] let model = viewModel.cardGroup[indexPath.row]
cell.reloadUIWithModel(model: model) cell.reloadUIWithModel(model: model)
// Task {
// if let image = await viewModel.coverCache.getImage(index: indexPath.row) {
// await MainActor.run {
// cell.setCoverImageOrVideo(image: image)
// }
// }
// }
return cell return cell
default: default:
return UICollectionViewCell() return UICollectionViewCell()
......
...@@ -9,10 +9,28 @@ import UIKit ...@@ -9,10 +9,28 @@ import UIKit
class VideocompressionHeadView: UIView { class VideocompressionHeadView: UIView {
@IBOutlet weak var sizeL: UILabel!
override func awakeFromNib() { override func awakeFromNib() {
super.awakeFromNib() super.awakeFromNib()
layer.cornerRadius = 8 layer.cornerRadius = 8
layer.masksToBounds = true layer.masksToBounds = true
} }
func reloadData(){
let totall = PhotoManager.shared.getTotalSize(source: [PhotoManager.shared.videoModels])
let sizeKB : Double = totall/2
if sizeKB < 1000{
self.sizeL.text = String(format: "(%.2lf) KB" ,sizeKB)
}else if sizeKB < (1000 * 1000) && sizeKB > 1000{
self.sizeL.text = String(format: "(%.2lf) MB" ,sizeKB/1000)
}else{
self.sizeL.text = String(format: "(%.2lf) GB" ,sizeKB/(1000 * 1000))
}
}
} }
...@@ -58,6 +58,9 @@ ...@@ -58,6 +58,9 @@
<constraint firstItem="vvL-sB-aRX" firstAttribute="centerX" secondItem="Qxg-Hm-QKr" secondAttribute="centerX" id="uEJ-q5-lB3"/> <constraint firstItem="vvL-sB-aRX" firstAttribute="centerX" secondItem="Qxg-Hm-QKr" secondAttribute="centerX" id="uEJ-q5-lB3"/>
</constraints> </constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<connections>
<outlet property="sizeL" destination="rDm-i5-MN1" id="AYR-5C-uKV"/>
</connections>
<point key="canvasLocation" x="187.78625954198472" y="250"/> <point key="canvasLocation" x="187.78625954198472" y="250"/>
</view> </view>
</objects> </objects>
......
...@@ -50,17 +50,10 @@ class HomeViewModel { ...@@ -50,17 +50,10 @@ class HomeViewModel {
// } // }
private var photoManager = PhotoManager.shared private var photoManager = PhotoManager.shared
// let coverCache = CoverCacheActor()
// 相册资源总大小 // 相册资源总大小
var totalSize:Int64{ var totalSize:Int64{
return photoManager.videoTotalSize + photoManager.otherTotalSize + photoManager.screenShotTotalSize //videoSize + otherSize + screentSize return photoManager.videoTotalSize + photoManager.otherTotalSize + photoManager.screenShotTotalSize //videoSize + otherSize + screentSize
} }
// var videoSize:Int64 = 0
// var otherSize:Int64 = 0
// var screentSize:Int64 = 0
var totalFilesCount:Int = 0 var totalFilesCount:Int = 0
// 首页UI数据结构 // 首页UI数据结构
...@@ -84,7 +77,9 @@ class HomeViewModel { ...@@ -84,7 +77,9 @@ class HomeViewModel {
HomePhotosModel.init( HomePhotosModel.init(
folderName: HomeUIEnum.Videos.title, folderName: HomeUIEnum.Videos.title,
allFileSize:getTotalSize(source: [photoManager.filterVideoModels]), allFileSize:getTotalSize(source: [photoManager.filterVideoModels]),
assets: [photoManager.filterVideoModels]), assets: [photoManager.filterVideoModels],
originalAssets: [photoManager.videoModels]
),
HomePhotosModel.init( HomePhotosModel.init(
folderName: HomeUIEnum.SimilarScreenshots.title, folderName: HomeUIEnum.SimilarScreenshots.title,
allFileSize: getTotalSize(source: photoManager.filterSimilarScreenShotModels), allFileSize: getTotalSize(source: photoManager.filterSimilarScreenShotModels),
...@@ -92,7 +87,9 @@ class HomeViewModel { ...@@ -92,7 +87,9 @@ class HomeViewModel {
HomePhotosModel.init( HomePhotosModel.init(
folderName: HomeUIEnum.Screensshots.title, folderName: HomeUIEnum.Screensshots.title,
allFileSize:getTotalSize(source: [photoManager.filterScreenShotModels]), allFileSize:getTotalSize(source: [photoManager.filterScreenShotModels]),
assets:[photoManager.filterScreenShotModels]), assets:[photoManager.filterScreenShotModels],
originalAssets: [photoManager.screenShotModels]
),
HomePhotosModel.init( HomePhotosModel.init(
folderName: HomeUIEnum.SimilarVideos.title, folderName: HomeUIEnum.SimilarVideos.title,
allFileSize:getTotalSize(source: photoManager.filterSimilarVideoModels), allFileSize:getTotalSize(source: photoManager.filterSimilarVideoModels),
...@@ -100,7 +97,9 @@ class HomeViewModel { ...@@ -100,7 +97,9 @@ class HomeViewModel {
HomePhotosModel.init( HomePhotosModel.init(
folderName: HomeUIEnum.Other.title, folderName: HomeUIEnum.Other.title,
allFileSize:getTotalSize(source: [photoManager.filterOtherModels]), allFileSize:getTotalSize(source: [photoManager.filterOtherModels]),
assets: [photoManager.filterOtherModels]), assets: [photoManager.filterOtherModels],
originalAssets: [photoManager.otherModels]
)
] ]
} }
...@@ -151,10 +150,6 @@ class HomeViewModel { ...@@ -151,10 +150,6 @@ class HomeViewModel {
photoManager.convertScreenShotModels {[weak self] screens, size in photoManager.convertScreenShotModels {[weak self] screens, size in
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
let type = HomeUIEnum.Screensshots let type = HomeUIEnum.Screensshots
// weakSelf.cardGroup[type.index] = HomePhotosModel.init(folderName: type.title, allFileSize: Double(size), assets: [screens])
// weakSelf.getCoverImage(type: type, identifier: screens.first?.localIdentifier)
//weakSelf.screentSize = size
weakSelf.filterResource() weakSelf.filterResource()
weakSelf.homeDataChanged?(1,type.index) weakSelf.homeDataChanged?(1,type.index)
} }
...@@ -163,9 +158,6 @@ class HomeViewModel { ...@@ -163,9 +158,6 @@ class HomeViewModel {
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
let type = HomeUIEnum.Other let type = HomeUIEnum.Other
// weakSelf.cardGroup[type.index] = HomePhotosModel.init(folderName: type.title, allFileSize: Double(size), assets: [others])
// weakSelf.getCoverImage(type: type, identifier: others.first?.localIdentifier)
// weakSelf.otherSize = size
weakSelf.filterResource() weakSelf.filterResource()
weakSelf.homeDataChanged?(1,type.index) weakSelf.homeDataChanged?(1,type.index)
} }
...@@ -174,9 +166,6 @@ class HomeViewModel { ...@@ -174,9 +166,6 @@ class HomeViewModel {
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
let type = HomeUIEnum.Videos let type = HomeUIEnum.Videos
// weakSelf.cardGroup[type.index] = HomePhotosModel.init(folderName: type.title, allFileSize: Double(size), assets: [videos])
// weakSelf.getCoverImage(type: type, identifier: videos.first?.localIdentifier)
// weakSelf.videoSize = size
weakSelf.filterResource() weakSelf.filterResource()
weakSelf.homeDataChanged?(1,type.index) weakSelf.homeDataChanged?(1,type.index)
} }
...@@ -189,43 +178,20 @@ class HomeViewModel { ...@@ -189,43 +178,20 @@ class HomeViewModel {
getSimilarScreenOptimizer() getSimilarScreenOptimizer()
getSimilarVideoOptimizer() getSimilarVideoOptimizer()
getGroupDuplicateImages() getGroupDuplicateImages()
// DispatchQueue.main.async {[weak self] in
// guard let weakSelf = self else { return }
// weakSelf.getSimilarOptimizer()
// weakSelf.getSimilarScreenOptimizer()
// weakSelf.getSimilarVideoOptimizer()
// //weakSelf.getGroupDuplicateImages()
// }
} }
// 获取相似图片 // 获取相似图片
func getSimilarOptimizer(){ func getSimilarOptimizer(){
let type = HomeUIEnum.Similar let type = HomeUIEnum.Similar
// var currentGorup:[[AssetModel]] = []
// var currentSize:Double = 0
// var firstId:String?
var hadblock = false var hadblock = false
PhotoSimilarManager.shared.findSimilarAssets(in: photoManager.otherAssets) {[weak self] group in PhotoSimilarManager.shared.findSimilarAssets(in: photoManager.otherAssets) {[weak self] group in
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
// currentGorup.append(group)
// currentSize += group.reduce(0){$0+$1.assetSize}
// weakSelf.totalSize += Int64(currentSize)
// weakSelf.headerGroup[type.index].assets = currentGorup
// weakSelf.headerGroup[type.index].allFileSize = currentSize
weakSelf.photoManager.similarModels.append(group) weakSelf.photoManager.similarModels.append(group)
// if let id = weakSelf.photoManager.similarModels.first?.first?.localIdentifier{
// if firstId != id{
// firstId = id
// weakSelf.similarCoverImage = group
// weakSelf.coverHadChange?()
// }
// }
if !hadblock{ if !hadblock{
weakSelf.reloadCellHeight?() weakSelf.reloadCellHeight?()
hadblock = true hadblock = true
...@@ -246,25 +212,10 @@ class HomeViewModel { ...@@ -246,25 +212,10 @@ class HomeViewModel {
func getSimilarScreenOptimizer(){ func getSimilarScreenOptimizer(){
let type = HomeUIEnum.SimilarScreenshots let type = HomeUIEnum.SimilarScreenshots
// var currentGorup:[[AssetModel]] = []
// var currentSize:Double = 0
// var firstId:String?
ScreenshotSimilarJSONManager.shared.findSimilarAssets(in: photoManager.screenShotAssets) {[weak self] group in ScreenshotSimilarJSONManager.shared.findSimilarAssets(in: photoManager.screenShotAssets) {[weak self] group in
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
// currentGorup.append(group)
// currentSize += group.reduce(0){$0+$1.assetSize}
// weakSelf.totalSize += Int64(currentSize)
// weakSelf.cardGroup[type.index].assets = currentGorup
// weakSelf.cardGroup[type.index].allFileSize = currentSize
//
// if let id = currentGorup.first?.first?.localIdentifier{
// if firstId != id{
// firstId = id
// weakSelf.getCoverImage(type: type, identifier: firstId)
// }
// }
weakSelf.photoManager.similarScreenShotModels.append(group) weakSelf.photoManager.similarScreenShotModels.append(group)
weakSelf.homeDataChanged?(1,type.index) weakSelf.homeDataChanged?(1,type.index)
...@@ -280,23 +231,9 @@ class HomeViewModel { ...@@ -280,23 +231,9 @@ class HomeViewModel {
func getSimilarVideoOptimizer(){ func getSimilarVideoOptimizer(){
let type = HomeUIEnum.SimilarVideos let type = HomeUIEnum.SimilarVideos
// var currentGorup:[[AssetModel]] = []
// var currentSize:Double = 0
// var firstId:String?
VideoSimilarJSONManager.shared.findSimilarVideos(in: photoManager.videoAssets) {[weak self] group in VideoSimilarJSONManager.shared.findSimilarVideos(in: photoManager.videoAssets) {[weak self] group in
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
// currentGorup.append(group)
// currentSize += group.reduce(0){$0+$1.assetSize}
//
// weakSelf.cardGroup[type.index].assets = currentGorup
// weakSelf.cardGroup[type.index].allFileSize = currentSize
//
// if let id = currentGorup.first?.first?.localIdentifier{
// if firstId != id{
// firstId = id
// weakSelf.getCoverImage(type: type, identifier: firstId)
// }
// }
weakSelf.photoManager.similarVideoModels.append(group) weakSelf.photoManager.similarVideoModels.append(group)
weakSelf.homeDataChanged?(1,type.index) weakSelf.homeDataChanged?(1,type.index)
...@@ -313,25 +250,12 @@ class HomeViewModel { ...@@ -313,25 +250,12 @@ class HomeViewModel {
func getGroupDuplicateImages(){ func getGroupDuplicateImages(){
let type = HomeUIEnum.Dublicates let type = HomeUIEnum.Dublicates
// var currentGorup:[[AssetModel]] = []
// var currentSize:Double = 0
// var firstId:String?
PhotoDuplicateManager.shared.findDuplicateAssets(in: photoManager.otherAssets, mediaType: .photo) {[weak self] groups in PhotoDuplicateManager.shared.findDuplicateAssets(in: photoManager.otherAssets, mediaType: .photo) {[weak self] groups in
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
// let size = groups.map{$0}.reduce(into: 0){$0+$1.assetSize}
// weakSelf.headerGroup[type.index].assets = groups
// weakSelf.headerGroup[type.index].allFileSize = currentSize
weakSelf.photoManager.duplicateModels = groups weakSelf.photoManager.duplicateModels = groups
// if let id = groups.first?.first?.localIdentifier{
// if firstId != id{
// firstId = id
// weakSelf.dupCoverImage = groups.first ?? []
// weakSelf.coverHadChange?()
// }
// }
let currentThread = Thread.current let currentThread = Thread.current
if currentThread.isMainThread { if currentThread.isMainThread {
print("在主线程执行") print("在主线程执行")
...@@ -342,31 +266,7 @@ class HomeViewModel { ...@@ -342,31 +266,7 @@ class HomeViewModel {
weakSelf.homeDataChanged?(0,type.index) weakSelf.homeDataChanged?(0,type.index)
} progressHandler: {group in } progressHandler: {group in
// guard let weakSelf = self else { return }
// currentGorup.append(group)
// currentSize += group.reduce(0){$0+$1.assetSize}
//
// weakSelf.headerGroup[type.index].assets = currentGorup
// weakSelf.headerGroup[type.index].allFileSize = currentSize
// weakSelf.photoManager.duplicateModels = groups
// 从 group 中过滤掉存在于 duplicateModels 中的元素
// let filteredGroup = group.filter { item in
// !weakSelf.photoManager.duplicateModels.flatMap { $0 }.contains(item)
// }
//
//
// if let id = currentGorup.first?.first?.localIdentifier{
// if firstId != id{
// firstId = id
// weakSelf.dupCoverImage = group
// weakSelf.coverHadChange?()
// }
// }
//
// weakSelf.homeDataChanged?(0,type.index)
} completionHandler: {[weak self] totalGroup in } completionHandler: {[weak self] totalGroup in
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
...@@ -383,31 +283,6 @@ class HomeViewModel { ...@@ -383,31 +283,6 @@ class HomeViewModel {
} }
} }
// func getCoverImage(type:HomeUIEnum,identifier:String?){
// guard let identifier = identifier else{
// return
// }
// print("执行一次\(type.title)获取封面,id=\(identifier)")
// Task {
// PhotoManager.shared.getImage(localIdentifier:identifier,completion: { [weak self] image in
// guard let self = self else { return }
// Task {
// switch type {
// case .Dublicates:
// break
// case .Similar:
// break
// default:
// await self.coverCache.setImage(index: type.index, image: image)
// await MainActor.run {
// self.coverHadChange?()
// }
// }
// }
// })
// }
// }
} }
extension HomeViewModel{ extension HomeViewModel{
......
...@@ -103,6 +103,18 @@ class MaintainViewListController: BaseViewController { ...@@ -103,6 +103,18 @@ class MaintainViewListController: BaseViewController {
maintaiEmptyView.frame = CGRectMake(0, 140, ScreenW, 330) maintaiEmptyView.frame = CGRectMake(0, 140, ScreenW, 330)
return maintaiEmptyView return maintaiEmptyView
}() }()
func dealBottomView(){
if selectAsset.count > 0{
let count = selectAsset.flatMap{$0}.count
maintaiBottomView.numberL.text = "\(count)"
view.addSubview(maintaiBottomView)
maintaiBottomView.show()
}else{
maintaiBottomView.disMiss()
}
}
} }
...@@ -133,6 +145,7 @@ extension MaintainViewListController:UICollectionViewDataSource,UICollectionView ...@@ -133,6 +145,7 @@ extension MaintainViewListController:UICollectionViewDataSource,UICollectionView
guard let weakSelf = self else { return } guard let weakSelf = self else { return }
weakSelf.selectAsset = selects weakSelf.selectAsset = selects
weakSelf.getData() weakSelf.getData()
weakSelf.dealBottomView()
} }
navigationController?.pushViewController(vc, animated: true) navigationController?.pushViewController(vc, animated: true)
} }
...@@ -153,14 +166,7 @@ extension MaintainViewListController:UICollectionViewDataSource,UICollectionView ...@@ -153,14 +166,7 @@ extension MaintainViewListController:UICollectionViewDataSource,UICollectionView
} }
if selectAsset.count > 0{ dealBottomView()
let count = selectAsset.flatMap{$0}.count
maintaiBottomView.numberL.text = "\(count)"
view.addSubview(maintaiBottomView)
maintaiBottomView.show()
}else{
maintaiBottomView.disMiss()
}
} }
} }
...@@ -659,10 +659,10 @@ class PhotoAndVideoMananger { ...@@ -659,10 +659,10 @@ class PhotoAndVideoMananger {
static func deleteAssets(localIdentifiers: [String],suc:@escaping () -> ()) { static func deleteAssets(localIdentifiers: [String],suc:@escaping () -> ()) {
// 获取要删除的 PHAsset // 获取要删除的 PHAsset
PMLoadingHUD.share.show()
let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: localIdentifiers, options: nil) let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: localIdentifiers, options: nil)
// 开始删除操作 // 开始删除操作
PMLoadingHUD.share.show()
PHPhotoLibrary.shared().performChanges({ PHPhotoLibrary.shared().performChanges({
// 创建删除请求 // 创建删除请求
PHAssetChangeRequest.deleteAssets(fetchResult) PHAssetChangeRequest.deleteAssets(fetchResult)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment