diff --git a/submodules/LegacyComponents/Sources/TGCameraController.m b/submodules/LegacyComponents/Sources/TGCameraController.m index 253ee3c803..a1dcb36c64 100644 --- a/submodules/LegacyComponents/Sources/TGCameraController.m +++ b/submodules/LegacyComponents/Sources/TGCameraController.m @@ -2852,6 +2852,8 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus } } + bool isHighQualityPhoto = editingContext.isHighQualityPhoto; + if (storeAssets && !isScan) { NSMutableArray *fullSizeSignals = [[NSMutableArray alloc] init]; for (id item in selectedItems) @@ -2968,7 +2970,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus id adjustments = [editingContext adjustmentsForItem:asset]; NSNumber *timer = [editingContext timerForItem:asset]; - SSignal *inlineSignal = [[asset screenImageSignal:0.0] map:^id(UIImage *originalImage) + + SSignal *originalSignal = isHighQualityPhoto ? [asset originalImageSignal:0.0] : [asset screenImageSignal:0.0]; + SSignal *inlineSignal = [originalSignal map:^id(UIImage *originalImage) { NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; dict[@"type"] = @"editedPhoto"; @@ -2979,6 +2983,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus else if (groupedId != nil && !hasAnyTimers) dict[@"groupedId"] = groupedId; + if (isHighQualityPhoto) + dict[@"hd"] = @true; + if (isScan) { if (caption != nil) dict[@"caption"] = caption; @@ -3058,6 +3065,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus else if (groupedId != nil && !hasAnyTimers) dict[@"groupedId"] = groupedId; + if (isHighQualityPhoto) + dict[@"hd"] = @true; + if (isScan) { if (caption != nil) dict[@"caption"] = caption; diff --git a/submodules/LegacyComponents/Sources/TGImageUtils.mm b/submodules/LegacyComponents/Sources/TGImageUtils.mm index 842ae8b272..71cefd1b26 100644 --- a/submodules/LegacyComponents/Sources/TGImageUtils.mm +++ b/submodules/LegacyComponents/Sources/TGImageUtils.mm @@ -231,6 +231,10 @@ UIImage *TGScaleAndBlurImage(NSData *data, __unused CGSize size, __autoreleasing UIImage *TGScaleImageToPixelSize(UIImage *image, CGSize size) { + if (image.size.width <= size.width && image.size.height <= size.height) { + return image; + } + UIGraphicsBeginImageContextWithOptions(size, true, 1.0f); [image drawInRect:CGRectMake(0, 0, size.width, size.height) blendMode:kCGBlendModeCopy alpha:1.0f]; UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); diff --git a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryInterfaceView.m b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryInterfaceView.m index bff61ba1a5..768ebea28a 100644 --- a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryInterfaceView.m +++ b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryInterfaceView.m @@ -1108,7 +1108,7 @@ TGPhotoEditorButton *qualityButton = [_portraitToolbarView buttonForTab:TGPhotoEditorQualityTab]; if (qualityButton != nil) { - bool isPhoto = [_currentItemView isKindOfClass:[TGMediaPickerGalleryPhotoItemView class]]; + bool isPhoto = [_currentItemView isKindOfClass:[TGMediaPickerGalleryPhotoItemView class]] || [_currentItem isKindOfClass:[TGCameraCapturedPhoto class]]; if (isPhoto) { bool isHd = _editingContext.isHighQualityPhoto; UIImage *icon = [TGPhotoEditorInterfaceAssets qualityIconForHighQuality:isHd filled: false]; diff --git a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryModel.m b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryModel.m index b1d4ca2279..3e04f10560 100644 --- a/submodules/LegacyComponents/Sources/TGMediaPickerGalleryModel.m +++ b/submodules/LegacyComponents/Sources/TGMediaPickerGalleryModel.m @@ -197,7 +197,8 @@ __strong TGModernGalleryController *controller = strongSelf.controller; if ([controller.currentItem conformsToProtocol:@protocol(TGModernGalleryEditableItem)]) { - if (tab == TGPhotoEditorQualityTab && [controller.currentItem isKindOfClass:[TGMediaPickerGalleryFetchResultItem class]] && [((TGMediaPickerGalleryFetchResultItem *)controller.currentItem).backingItem isKindOfClass:[TGMediaPickerGalleryPhotoItem class]]) { + bool isPhoto = [controller.currentItem isKindOfClass:[TGMediaPickerGalleryPhotoItem class]] || ([controller.currentItem isKindOfClass:[TGMediaPickerGalleryFetchResultItem class]] && [((TGMediaPickerGalleryFetchResultItem *)controller.currentItem).backingItem isKindOfClass:[TGMediaPickerGalleryPhotoItem class]]); + if (tab == TGPhotoEditorQualityTab && isPhoto) { [strongSelf->_editingContext setHighQualityPhoto:!strongSelf->_editingContext.isHighQualityPhoto]; [strongSelf->_interfaceView showPhotoQualityTooltip:strongSelf->_editingContext.isHighQualityPhoto]; } else { diff --git a/submodules/LegacyComponents/Sources/TGPhotoEditorUtils.m b/submodules/LegacyComponents/Sources/TGPhotoEditorUtils.m index 02bfd423ba..c1d40d2075 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoEditorUtils.m +++ b/submodules/LegacyComponents/Sources/TGPhotoEditorUtils.m @@ -6,7 +6,7 @@ #import #import -const CGSize TGPhotoEditorResultImageMaxSize = { 1280, 1280 }; +const CGSize TGPhotoEditorResultImageMaxSize = { 2560, 2560 }; const CGSize TGPhotoEditorResultImageWallpaperMaxSize = { 2048, 2048 }; const CGSize TGPhotoEditorResultImageAvatarMaxSize = { 2048, 2048 }; const CGSize TGPhotoEditorScreenImageHardLimitSize = { 1280, 1280 }; diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift index 2772772e0e..0acb01ba7c 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift @@ -175,6 +175,7 @@ public func legacyAssetPickerItemGenerator() -> ((Any?, NSAttributedString?, Str let image = dict["image"] as! UIImage let thumbnail = dict["previewImage"] as? UIImage let cover = dict["coverImage"] as? UIImage + let forceHd = (dict["hd"] as? NSNumber)?.boolValue ?? false var result: [AnyHashable : Any] = [:] if let isAnimation = dict["isAnimation"] as? NSNumber, isAnimation.boolValue { @@ -184,7 +185,7 @@ public func legacyAssetPickerItemGenerator() -> ((Any?, NSAttributedString?, Str result["item" as NSString] = LegacyAssetItemWrapper(item: .video(data: .tempFile(path: url, dimensions: dimensions, duration: 4.0), thumbnail: thumbnail, cover: cover, adjustments: dict["adjustments"] as? TGVideoEditAdjustments, caption: caption, asFile: false, asAnimation: true, stickers: stickers), timer: (dict["timer"] as? NSNumber)?.intValue, spoiler: (dict["spoiler"] as? NSNumber)?.boolValue, price: price, groupedId: (dict["groupedId"] as? NSNumber)?.int64Value, uniqueId: uniqueId) } } else { - result["item" as NSString] = LegacyAssetItemWrapper(item: .image(data: .image(image), thumbnail: thumbnail, caption: caption, stickers: stickers), timer: (dict["timer"] as? NSNumber)?.intValue, spoiler: (dict["spoiler"] as? NSNumber)?.boolValue, price: price, groupedId: (dict["groupedId"] as? NSNumber)?.int64Value, uniqueId: uniqueId) + result["item" as NSString] = LegacyAssetItemWrapper(item: .image(data: .image(image), thumbnail: thumbnail, caption: caption, stickers: stickers), timer: (dict["timer"] as? NSNumber)?.intValue, spoiler: (dict["spoiler"] as? NSNumber)?.boolValue, price: price, forceHd: forceHd, groupedId: (dict["groupedId"] as? NSNumber)?.int64Value, uniqueId: uniqueId) } return result } else if (dict["type"] as! NSString) == "cloudPhoto" { @@ -400,7 +401,9 @@ public func legacyAssetPickerEnqueueMessages(context: AccountContext, account: A var randomId: Int64 = 0 arc4random_buf(&randomId, 8) let tempFilePath = NSTemporaryDirectory() + "\(randomId).jpeg" - let scaledSize = image.size.aspectFittedOrSmaller(CGSize(width: 1280.0, height: 1280.0)) + let maxSize = item.forceHd ? CGSize(width: 2560.0, height: 2560.0) : CGSize(width: 1280.0, height: 1280.0) + let scaledSize = image.size.aspectFittedOrSmaller(maxSize) + if let scaledImage = TGScaleImageToPixelSize(image, scaledSize) { let tempFile = TempBox.shared.tempFile(fileName: "file") defer { diff --git a/submodules/TelegramUI/Components/ShareExtensionContext/Sources/ShareExtensionContext.swift b/submodules/TelegramUI/Components/ShareExtensionContext/Sources/ShareExtensionContext.swift index bdf41bf34c..6af3a29ac9 100644 --- a/submodules/TelegramUI/Components/ShareExtensionContext/Sources/ShareExtensionContext.swift +++ b/submodules/TelegramUI/Components/ShareExtensionContext/Sources/ShareExtensionContext.swift @@ -596,58 +596,71 @@ public class ShareRootControllerImpl { //inForeground.set(false) self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil) } - shareController.shareStory = { [weak self] in - guard let self else { - return - } - - if let inputItems = self.getExtensionContext()?.inputItems, inputItems.count == 1, let item = inputItems[0] as? NSExtensionItem, let attachments = item.attachments { - let sessionId = Int64.random(in: 1000000 ..< .max) - - let storiesPath = rootPath + "/share/stories/\(sessionId)" - let _ = try? FileManager.default.createDirectory(atPath: storiesPath, withIntermediateDirectories: true, attributes: nil) - var index = 0 - - let dispatchGroup = DispatchGroup() - - for attachment in attachments { - let fileIndex = index - if attachment.hasItemConformingToTypeIdentifier(kUTTypeImage as String) { - dispatchGroup.enter() - attachment.loadFileRepresentation(forTypeIdentifier: kUTTypeImage as String, completionHandler: { url, _ in - if let url, let imageData = try? Data(contentsOf: url) { - let filePath = storiesPath + "/\(fileIndex).jpg" - try? FileManager.default.removeItem(atPath: filePath) - - do { - try imageData.write(to: URL(fileURLWithPath: filePath)) - } catch { - print("Error: \(error)") - } - } - dispatchGroup.leave() - }) - } else if attachment.hasItemConformingToTypeIdentifier(kUTTypeMovie as String) { - dispatchGroup.enter() - attachment.loadFileRepresentation(forTypeIdentifier: kUTTypeMovie as String, completionHandler: { url, _ in - if let url { - let filePath = storiesPath + "/\(fileIndex).mp4" - try? FileManager.default.removeItem(atPath: filePath) - - do { - try FileManager.default.copyItem(at: url, to: URL(fileURLWithPath: filePath)) - } catch { - print("Error: \(error)") - } - } - dispatchGroup.leave() - }) - } - index += 1 + + var canShareToStory = true + if let inputItems = self?.getExtensionContext()?.inputItems, inputItems.count == 1, let item = inputItems[0] as? NSExtensionItem, let attachments = item.attachments { + for attachment in attachments { + if attachment.hasItemConformingToTypeIdentifier(kUTTypeImage as String) { + } else if attachment.hasItemConformingToTypeIdentifier(kUTTypeMovie as String) { + } else { + canShareToStory = false } - - dispatchGroup.notify(queue: .main) { - self.openUrl("tg://shareStory?session=\(sessionId)") + } + } + + if canShareToStory { + shareController.shareStory = { [weak self] in + guard let self else { + return + } + if let inputItems = self.getExtensionContext()?.inputItems, inputItems.count == 1, let item = inputItems[0] as? NSExtensionItem, let attachments = item.attachments { + let sessionId = Int64.random(in: 1000000 ..< .max) + + let storiesPath = rootPath + "/share/stories/\(sessionId)" + let _ = try? FileManager.default.createDirectory(atPath: storiesPath, withIntermediateDirectories: true, attributes: nil) + var index = 0 + + let dispatchGroup = DispatchGroup() + + for attachment in attachments { + let fileIndex = index + if attachment.hasItemConformingToTypeIdentifier(kUTTypeImage as String) { + dispatchGroup.enter() + attachment.loadFileRepresentation(forTypeIdentifier: kUTTypeImage as String, completionHandler: { url, _ in + if let url, let imageData = try? Data(contentsOf: url) { + let filePath = storiesPath + "/\(fileIndex).jpg" + try? FileManager.default.removeItem(atPath: filePath) + + do { + try imageData.write(to: URL(fileURLWithPath: filePath)) + } catch { + print("Error: \(error)") + } + } + dispatchGroup.leave() + }) + } else if attachment.hasItemConformingToTypeIdentifier(kUTTypeMovie as String) { + dispatchGroup.enter() + attachment.loadFileRepresentation(forTypeIdentifier: kUTTypeMovie as String, completionHandler: { url, _ in + if let url { + let filePath = storiesPath + "/\(fileIndex).mp4" + try? FileManager.default.removeItem(atPath: filePath) + + do { + try FileManager.default.copyItem(at: url, to: URL(fileURLWithPath: filePath)) + } catch { + print("Error: \(error)") + } + } + dispatchGroup.leave() + }) + } + index += 1 + } + + dispatchGroup.notify(queue: .main) { + self.openUrl("tg://shareStory?session=\(sessionId)") + } } } }