fix for a crash when trying to download a media

This commit is contained in:
Mauro Romito
2026-07-28 16:37:33 +02:00
committed by Mauro
parent 7ea9aeb174
commit 30bc4a06f2
2 changed files with 77 additions and 69 deletions
@@ -21,7 +21,8 @@ protocol PhotoLibraryManagerProtocol {
struct PhotoLibraryManager: PhotoLibraryManagerProtocol {
func addResource(_ type: PHAssetResourceType, at url: URL) async -> Result<Void, PhotoLibraryManagerError> {
do {
try await PHPhotoLibrary.shared().performChanges {
// @Sendable as PhotoKit runs the block on its own queue, so it must not inherit MainActor isolation.
try await PHPhotoLibrary.shared().performChanges { @Sendable in
let request = PHAssetCreationRequest.forAsset()
let options = PHAssetResourceCreationOptions()
request.addResource(with: type, fileURL: url, options: options)
@@ -216,13 +216,6 @@ enum TimelineMediaPreviewItem: Equatable {
}
}
var galleryItem: GalleryItem? {
switch content {
case .timelineItem: nil
case .galleryItem(_, let item): item
}
}
var fileHandle: MediaFileHandleProxy? {
didSet { updatePreviewItemValues() }
}
@@ -299,55 +292,63 @@ enum TimelineMediaPreviewItem: Equatable {
enum Kind { case image, video, file }
var kind: Kind {
if let galleryItem {
switch galleryItem {
case .image: return .image
case .video: return .video
case .audio, .file, .other: return .file
switch content {
case .galleryItem(_, let item):
switch item {
case .image: .image
case .video: .video
case .audio, .file, .other: .file
}
case .timelineItem(let timelineItem):
switch timelineItem {
case is ImageRoomTimelineItem: .image
case is VideoRoomTimelineItem: .video
default: .file
}
}
return switch timelineItem {
case is ImageRoomTimelineItem: .image
case is VideoRoomTimelineItem: .video
default: .file
}
}
var mediaSource: MediaSourceProxy? {
if let galleryItem {
return galleryItem.mediaSource
}
return switch timelineItem {
case let audioItem as AudioRoomTimelineItem: audioItem.content.source
case let fileItem as FileRoomTimelineItem: fileItem.content.source
case let imageItem as ImageRoomTimelineItem: imageItem.content.imageInfo.source
case let videoItem as VideoRoomTimelineItem: videoItem.content.videoInfo.source
default: nil
switch content {
case .galleryItem(_, let item):
item.mediaSource
case .timelineItem(let timelineItem):
switch timelineItem {
case let audioItem as AudioRoomTimelineItem: audioItem.content.source
case let fileItem as FileRoomTimelineItem: fileItem.content.source
case let imageItem as ImageRoomTimelineItem: imageItem.content.imageInfo.source
case let videoItem as VideoRoomTimelineItem: videoItem.content.videoInfo.source
default: nil
}
}
}
var thumbnailMediaSource: MediaSourceProxy? {
if let galleryItem {
return galleryItem.thumbnailSource
}
return switch timelineItem {
case let fileItem as FileRoomTimelineItem: fileItem.content.thumbnailSource
case let imageItem as ImageRoomTimelineItem: imageItem.content.thumbnailInfo?.source
case let videoItem as VideoRoomTimelineItem: videoItem.content.thumbnailInfo?.source
default: nil
switch content {
case .galleryItem(_, let item):
item.thumbnailSource
case .timelineItem(let timelineItem):
switch timelineItem {
case let fileItem as FileRoomTimelineItem: fileItem.content.thumbnailSource
case let imageItem as ImageRoomTimelineItem: imageItem.content.thumbnailInfo?.source
case let videoItem as VideoRoomTimelineItem: videoItem.content.thumbnailInfo?.source
default: nil
}
}
}
var filename: String? {
if let galleryItem {
return galleryItem.filename
}
return switch timelineItem {
case let audioItem as AudioRoomTimelineItem: audioItem.content.filename
case let fileItem as FileRoomTimelineItem: fileItem.content.filename
case let imageItem as ImageRoomTimelineItem: imageItem.content.filename
case let videoItem as VideoRoomTimelineItem: videoItem.content.filename
default: nil
switch content {
case .galleryItem(_, let item):
item.filename
case .timelineItem(let timelineItem):
switch timelineItem {
case let audioItem as AudioRoomTimelineItem: audioItem.content.filename
case let fileItem as FileRoomTimelineItem: fileItem.content.filename
case let imageItem as ImageRoomTimelineItem: imageItem.content.filename
case let videoItem as VideoRoomTimelineItem: videoItem.content.filename
default: nil
}
}
}
@@ -356,15 +357,17 @@ enum TimelineMediaPreviewItem: Equatable {
}
private var expectedFileSize: UInt? {
if let galleryItem {
return galleryItem.fileSize
}
return switch timelineItem {
case let audioItem as AudioRoomTimelineItem: audioItem.content.fileSize
case let fileItem as FileRoomTimelineItem: fileItem.content.fileSize
case let imageItem as ImageRoomTimelineItem: imageItem.content.imageInfo.fileSize
case let videoItem as VideoRoomTimelineItem: videoItem.content.videoInfo.fileSize
default: nil
switch content {
case .galleryItem(_, let item):
item.fileSize
case .timelineItem(let timelineItem):
switch timelineItem {
case let audioItem as AudioRoomTimelineItem: audioItem.content.fileSize
case let fileItem as FileRoomTimelineItem: fileItem.content.fileSize
case let imageItem as ImageRoomTimelineItem: imageItem.content.imageInfo.fileSize
case let videoItem as VideoRoomTimelineItem: videoItem.content.videoInfo.fileSize
default: nil
}
}
}
@@ -382,26 +385,30 @@ enum TimelineMediaPreviewItem: Equatable {
}
var contentType: String? {
if let galleryItem {
return galleryItem.contentType?.localizedDescription
}
return switch timelineItem {
case let audioItem as AudioRoomTimelineItem: audioItem.content.contentType?.localizedDescription
case let fileItem as FileRoomTimelineItem: fileItem.content.contentType?.localizedDescription
case let imageItem as ImageRoomTimelineItem: imageItem.content.contentType?.localizedDescription
case let videoItem as VideoRoomTimelineItem: videoItem.content.contentType?.localizedDescription
default: nil
switch content {
case .galleryItem(_, let item):
item.contentType?.localizedDescription
case .timelineItem(let timelineItem):
switch timelineItem {
case let audioItem as AudioRoomTimelineItem: audioItem.content.contentType?.localizedDescription
case let fileItem as FileRoomTimelineItem: fileItem.content.contentType?.localizedDescription
case let imageItem as ImageRoomTimelineItem: imageItem.content.contentType?.localizedDescription
case let videoItem as VideoRoomTimelineItem: videoItem.content.contentType?.localizedDescription
default: nil
}
}
}
var blurhash: String? {
if let galleryItem {
return galleryItem.blurhash
}
return switch timelineItem {
case let imageItem as ImageRoomTimelineItem: imageItem.content.blurhash
case let videoItem as VideoRoomTimelineItem: videoItem.content.blurhash
default: nil
switch content {
case .galleryItem(_, let item):
item.blurhash
case .timelineItem(let timelineItem):
switch timelineItem {
case let imageItem as ImageRoomTimelineItem: imageItem.content.blurhash
case let videoItem as VideoRoomTimelineItem: videoItem.content.blurhash
default: nil
}
}
}
}