diff --git a/Core/Protocols/PhotoLibraryProtocol.swift b/Core/Protocols/PhotoLibraryProtocol.swift index 0ce1c9a..f029865 100644 --- a/Core/Protocols/PhotoLibraryProtocol.swift +++ b/Core/Protocols/PhotoLibraryProtocol.swift @@ -11,6 +11,7 @@ struct PhotoAsset: Sendable { let duration: TimeInterval let isScreenshot: Bool let isRAW: Bool + let isScreenRecording: Bool } protocol PhotoLibraryProtocol: AnyObject { @@ -26,4 +27,5 @@ struct BackupFilter: Codable, Sendable, Equatable { var includeScreenshots: Bool = false var includeRAW: Bool = false var newFilesOnly: Bool = true + var includeScreenRecordings: Bool = false } diff --git a/Features/Settings/SettingsView.swift b/Features/Settings/SettingsView.swift index 8370fcb..7d0990b 100644 --- a/Features/Settings/SettingsView.swift +++ b/Features/Settings/SettingsView.swift @@ -124,6 +124,9 @@ struct SettingsView: View { ToggleRow(icon: "camera.viewfinder", title: "Screenshots", isOn: $store.backupFilter.includeScreenshots) hairline + ToggleRow(icon: "record.circle", title: "Screen Recordings", + isOn: $store.backupFilter.includeScreenRecordings) + hairline ToggleRow(icon: "rays", title: "RAW", isOn: $store.backupFilter.includeRAW) hairline diff --git a/Services/LocalPhotoIndex.swift b/Services/LocalPhotoIndex.swift index e6d20ac..375f957 100644 --- a/Services/LocalPhotoIndex.swift +++ b/Services/LocalPhotoIndex.swift @@ -20,6 +20,7 @@ actor LocalPhotoIndex { var mediaType: Int // PHAssetMediaType.rawValue var isScreenshot: Bool var isRAW: Bool + var isScreenRecording: Bool = false } private var records: [String: Record] = [:] @@ -118,6 +119,7 @@ actor LocalPhotoIndex { if !filter.includeVideos && record.mediaType == vid { return false } if !filter.includeScreenshots && record.isScreenshot { return false } if !filter.includeRAW && record.isRAW { return false } + if !filter.includeScreenRecordings && record.isScreenRecording { return false } return true } @@ -161,13 +163,15 @@ actor LocalPhotoIndex { ?? "\(asset.localIdentifier.prefix(8)).jpg" let isRAW = resources.contains { $0.type == .alternatePhoto } let isScreenshot = asset.mediaSubtypes.contains(.photoScreenshot) + let isScreenRecording = asset.mediaSubtypes.contains(.videoScreenRecording) return Record( localIdentifier: asset.localIdentifier, filename: filename, creationDate: asset.creationDate, mediaType: asset.mediaType.rawValue, isScreenshot: isScreenshot, - isRAW: isRAW + isRAW: isRAW, + isScreenRecording: isScreenRecording ) } } diff --git a/Services/PhotoLibraryService.swift b/Services/PhotoLibraryService.swift index 8408e4d..902bcb8 100644 --- a/Services/PhotoLibraryService.swift +++ b/Services/PhotoLibraryService.swift @@ -34,6 +34,12 @@ final class PhotoLibraryService: PhotoLibraryProtocol { PHAssetMediaSubtype.photoScreenshot.rawValue )) } + if !filter.includeScreenRecordings { + subpredicates.append(NSPredicate( + format: "NOT ((mediaSubtype & %d) != 0)", + PHAssetMediaSubtype.videoScreenRecording.rawValue + )) + } if subpredicates.count > 1 { options.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: subpredicates) @@ -46,6 +52,7 @@ final class PhotoLibraryService: PhotoLibraryProtocol { result.enumerateObjects { asset, _, _ in autoreleasepool { let isScreenshot = asset.mediaSubtypes.contains(.photoScreenshot) + let isScreenRecording = asset.mediaSubtypes.contains(.videoScreenRecording) let resources = PHAssetResource.assetResources(for: asset) let isRAW = resources.contains { $0.type == .alternatePhoto } if isRAW && !filter.includeRAW { return } @@ -61,7 +68,8 @@ final class PhotoLibraryService: PhotoLibraryProtocol { pixelHeight: asset.pixelHeight, duration: asset.duration, isScreenshot: isScreenshot, - isRAW: isRAW + isRAW: isRAW, + isScreenRecording: isScreenRecording )) } } @@ -91,6 +99,12 @@ final class PhotoLibraryService: PhotoLibraryProtocol { PHAssetMediaSubtype.photoScreenshot.rawValue )) } + if !filter.includeScreenRecordings { + subpredicates.append(NSPredicate( + format: "NOT ((mediaSubtype & %d) != 0)", + PHAssetMediaSubtype.videoScreenRecording.rawValue + )) + } if subpredicates.count > 1 { options.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: subpredicates)