@@ -69,6 +69,7 @@ struct ArchiveFeature {
6969 case albumsResponse( Result < [ AlbumItem ] , Error > )
7070 case favoriteAlbumResponse( Result < AlbumItem , Error > )
7171 case photoListResponse( Result < [ PhotoEntity ] , Error > )
72+ case uploadSharedImagesResponse( Result < [ Int ] , Error > )
7273
7374 // Image Upload Action
7475 case imagePicker( ImagePickerFeature . Action )
@@ -85,6 +86,8 @@ struct ArchiveFeature {
8586 // Internal Action
8687 case addPhotoFromQRScanner( imageID: Int )
8788 case processUploadImages( imageIDs: [ Int ] )
89+ case addPhotoFromShareExtension( appGroupID: String )
90+ case cleanSharedImages( appGroupID: String )
8891
8992 // Delegate Action
9093 case delegate( DelegateAction )
@@ -95,6 +98,8 @@ struct ArchiveFeature {
9598 }
9699
97100 @Dependency ( \. archiveClient) var archiveClient
101+ @Dependency ( \. imageUploadClient) var imageUploadClient
102+ @Dependency ( \. sharedImageClient) var sharedImageClient
98103
99104 var body : some ReducerOf < Self > {
100105 BindingReducer ( )
@@ -282,6 +287,31 @@ struct ArchiveFeature {
282287 state. selectUploadAlbum = SelectUploadAlbumFeature . State ( uploadedImageIds: imageIDs, albums: state. albums)
283288 return . none
284289
290+ case let . addPhotoFromShareExtension( appGroupID) :
291+ state. isLoading = true
292+ return . run { send in
293+ do {
294+ let fileURLs = try await sharedImageClient. fetchSharedImageURLs ( appGroupID: appGroupID)
295+
296+ guard fileURLs. isEmpty == false else {
297+ await send ( . delegate( . showToast( NekiToastItem ( " 가져올 수 있는 이미지가 없어요. " , style: . error) ) ) )
298+ await send ( . uploadSharedImagesResponse( . failure( UploadError . uploadFailed) ) )
299+ return
300+ }
301+
302+ let uploadedMediaIDs = try await imageUploadClient. uploadConcurrentlyFromURLs ( fileURLs, . photoBooth)
303+
304+ await send ( . cleanSharedImages( appGroupID: appGroupID) )
305+ await send ( . uploadSharedImagesResponse( . success( uploadedMediaIDs) ) )
306+
307+ } catch {
308+ Logger . presentation. error ( " 공유 확장 이미지 업로드 에러: \( error) " )
309+
310+ await send ( . cleanSharedImages( appGroupID: appGroupID) )
311+ await send ( . uploadSharedImagesResponse( . failure( error) ) )
312+ }
313+ }
314+
285315 case let . selectUploadAlbum( . presented( . delegate( delegateAction) ) ) :
286316 switch delegateAction {
287317 case let . uploadDidSuccess( albumId) :
@@ -322,6 +352,22 @@ struct ArchiveFeature {
322352 await send ( . delegate( . showToast( NekiToastItem ( " 사진 등록에 실패했어요 " , style: . error) ) ) )
323353 }
324354
355+ case let . cleanSharedImages( appGroupID) :
356+ return . run { send in
357+ do {
358+ try await sharedImageClient. clearSharedImages ( appGroupID: appGroupID)
359+ } catch {
360+ Logger . presentation. error ( " 임시 파일 정리 실패: \( error) " )
361+ }
362+ }
363+
364+ case let . uploadSharedImagesResponse( . success( imageIDs) ) :
365+ return . send( . processUploadImages( imageIDs: imageIDs) )
366+
367+ case . uploadSharedImagesResponse( . failure) :
368+ state. isLoading = false
369+ return . send( . delegate( . showToast( NekiToastItem ( " 업로드에 실패했어요 " , style: . error) ) ) )
370+
325371 // MARK: - Binding
326372
327373 case . binding( \. newAlbumTitle) :
0 commit comments