1 // Copyright 2022-present 650 Industries. All rights reserved. 2 3 import ABI49_0_0ExpoModulesCore 4 import MobileCoreServices 5 import PhotosUI 6 7 internal let DEFAULT_QUALITY = 0.2 8 internal let MAXIMUM_QUALITY = 1.0 9 10 internal let UNLIMITED_SELECTION = 0 11 internal let SINGLE_SELECTION = 1 12 13 internal struct ImagePickerOptions: Record { 14 @Field 15 var allowsEditing: Bool = false 16 17 @Field 18 var aspect: [Double] 19 20 @Field 21 var quality: Double? 22 23 @Field 24 var mediaTypes: MediaType = .images 25 26 @Field 27 var exif: Bool 28 29 @Field 30 var base64: Bool = false 31 32 @Field 33 var videoExportPreset: VideoExportPreset = .passthrough 34 35 @Field 36 var videoQuality: VideoQuality = .typeHigh 37 38 @Field 39 var videoMaxDuration: Double = 0 40 41 @Field 42 var presentationStyle: PresentationStyle = .automatic 43 44 @Field 45 var preferredAssetRepresentationMode: PreferredAssetRepresentationMode = .automatic 46 47 @Field 48 var cameraType: CameraType = .back 49 50 @Field 51 var allowsMultipleSelection: Bool = false 52 53 @Field 54 var selectionLimit: Int = UNLIMITED_SELECTION 55 56 @Field 57 var orderedSelection: Bool = false 58 } 59 60 internal enum PresentationStyle: String, EnumArgument { 61 case fullScreen 62 case pageSheet 63 case formSheet 64 case currentContext 65 case overFullScreen 66 case overCurrentContext 67 case popover 68 case none 69 case automatic 70 71 func toPresentationStyle() -> UIModalPresentationStyle { 72 switch self { 73 case .fullScreen: 74 return .fullScreen 75 case .pageSheet: 76 return .pageSheet 77 case .formSheet: 78 return .formSheet 79 case .currentContext: 80 return .currentContext 81 case .overFullScreen: 82 return .overFullScreen 83 case .overCurrentContext: 84 return .overCurrentContext 85 case .popover: 86 return .popover 87 case .none: 88 return .none 89 case .automatic: 90 if #available(iOS 13.0, *) { 91 return .automatic 92 } 93 // default prior iOS 13 94 return .fullScreen 95 } 96 } 97 } 98 99 internal enum PreferredAssetRepresentationMode: String, EnumArgument { 100 case automatic 101 case compatible 102 case current 103 104 @available(iOS 14.0, *) 105 func toAssetRepresentationMode() -> PHPickerConfiguration.AssetRepresentationMode { 106 switch self { 107 case .automatic: 108 return .automatic 109 case .compatible: 110 return .compatible 111 case .current: 112 return .current 113 } 114 } 115 } 116 117 internal enum VideoQuality: Int, EnumArgument { 118 case typeHigh = 0 119 case typeMedium = 1 120 case typeLow = 2 121 case type640x480 = 3 122 case typeIFrame1280x720 = 4 123 case typeIFrame960x540 = 5 124 125 func toQualityType() -> UIImagePickerController.QualityType { 126 switch self { 127 case .typeHigh: 128 return .typeHigh 129 case .typeMedium: 130 return .typeMedium 131 case .typeLow: 132 return .typeLow 133 case .type640x480: 134 return .type640x480 135 case .typeIFrame1280x720: 136 return .typeIFrame1280x720 137 case .typeIFrame960x540: 138 return .typeIFrame960x540 139 } 140 } 141 } 142 143 internal enum MediaType: String, EnumArgument { 144 case all = "All" 145 case videos = "Videos" 146 case images = "Images" 147 148 func toArray() -> [String] { 149 switch self { 150 case .images: 151 return [kUTTypeImage as String] 152 case .videos: 153 return [kUTTypeMovie as String] 154 case .all: 155 return [kUTTypeImage as String, kUTTypeMovie as String] 156 } 157 } 158 159 @available(iOS 14, *) 160 func toPickerFilter() -> PHPickerFilter { 161 // TODO: (barthap) Maybe add support for live photos 162 switch self { 163 case .images: 164 return .images 165 case .videos: 166 return .videos 167 case .all: 168 return .any(of: [.images, .videos]) 169 } 170 } 171 } 172 173 internal enum VideoExportPreset: Int, EnumArgument { 174 case passthrough = 0 175 case lowQuality = 1 176 case mediumQuality = 2 177 case highestQuality = 3 178 case h264_640x480 = 4 179 case h264_960x540 = 5 180 case h264_1280x720 = 6 181 case h264_1920x1080 = 7 182 case h264_3840x2160 = 8 183 case hevc_1920x1080 = 9 184 case hevc_3840_2160 = 10 185 186 func toAVAssetExportPreset() -> String { 187 switch self { 188 case .passthrough: 189 return AVAssetExportPresetPassthrough 190 case .lowQuality: 191 return AVAssetExportPresetLowQuality 192 case .mediumQuality: 193 return AVAssetExportPresetMediumQuality 194 case .highestQuality: 195 return AVAssetExportPresetHighestQuality 196 case .h264_640x480: 197 return AVAssetExportPreset640x480 198 case .h264_960x540: 199 return AVAssetExportPreset960x540 200 case .h264_1280x720: 201 return AVAssetExportPreset1280x720 202 case .h264_1920x1080: 203 return AVAssetExportPreset1920x1080 204 case .h264_3840x2160: 205 return AVAssetExportPreset3840x2160 206 case .hevc_1920x1080: 207 return AVAssetExportPresetHEVC1920x1080 208 case .hevc_3840_2160: 209 return AVAssetExportPresetHEVC3840x2160 210 } 211 } 212 } 213 214 internal enum CameraType: String, EnumArgument { 215 case back 216 case front 217 } 218