diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index c2e713aae1..3f39afd5d3 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -6862,3 +6862,7 @@ Ads should no longer be synonymous with abuse of user privacy. Let us redefine h "VoiceChat.RecordPortrait" = "Portrait"; "VoiceChat.RecordLandscape" = "Landscape"; "VoiceChat.RecordStartRecording" = "Start Recording"; + +"MediaPicker.JpegConversionText" = "Do you want to convert photos to JPEG?"; +"MediaPicker.KeepHeic" = "Keep HEIC"; +"MediaPicker.ConvertToJpeg" = "Convert to JPEG"; diff --git a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift index b160061fda..e79a6d12c1 100644 --- a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift +++ b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift @@ -976,14 +976,16 @@ public final class AnimatedStickerNode: ASDisplayNode { private var isSetUpForPlayback = false public func play(firstFrame: Bool = false, fromIndex: Int? = nil) { - switch self.playbackMode { - case .once: - self.isPlaying = true - case .count: - self.currentLoopCount = 0 - self.isPlaying = true - default: - break + if !firstFrame { + switch self.playbackMode { + case .once: + self.isPlaying = true + case .count: + self.currentLoopCount = 0 + self.isPlaying = true + default: + break + } } if self.isSetUpForPlayback { let directData = self.directData diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGClipboardMenu.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGClipboardMenu.h index 847cf4193b..57e5a6f90e 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGClipboardMenu.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGClipboardMenu.h @@ -14,7 +14,7 @@ @interface TGClipboardMenu : NSObject -+ (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id)context images:(NSArray *)images hasCaption:(bool)hasCaption hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName suggestionContext:(TGSuggestionContext *)suggestionContext stickersContext:(id)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect; ++ (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id)context images:(NSArray *)images allowGrouping:(bool)allowGrouping hasCaption:(bool)hasCaption hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName suggestionContext:(TGSuggestionContext *)suggestionContext stickersContext:(id)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect; + (NSArray *)resultSignalsForSelectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext currentItem:(id)currentItem descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *))descriptionGenerator; diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAssetImageSignals.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAssetImageSignals.h index 136372d31f..2ee7865d72 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAssetImageSignals.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAssetImageSignals.h @@ -48,6 +48,7 @@ typedef enum + (SSignal *)imageDataForAsset:(TGMediaAsset *)asset; + (SSignal *)imageDataForAsset:(TGMediaAsset *)asset allowNetworkAccess:(bool)allowNetworkAccess; ++ (SSignal *)imageDataForAsset:(TGMediaAsset *)asset allowNetworkAccess:(bool)allowNetworkAccess convertToJpeg:(bool)convertToJpeg; + (SSignal *)imageMetadataForAsset:(TGMediaAsset *)asset; + (SSignal *)fileAttributesForAsset:(TGMediaAsset *)asset; diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAssetsController.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAssetsController.h index c94f239e0b..91658ad331 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAssetsController.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAssetsController.h @@ -105,6 +105,6 @@ typedef enum + (TGMediaAssetType)assetTypeForIntent:(TGMediaAssetsControllerIntent)intent; -+ (NSArray *)resultSignalsForSelectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext intent:(TGMediaAssetsControllerIntent)intent currentItem:(TGMediaAsset *)currentItem storeAssets:(bool)storeAssets useMediaCache:(bool)useMediaCache descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *, NSString *))descriptionGenerator saveEditedPhotos:(bool)saveEditedPhotos; ++ (NSArray *)resultSignalsForSelectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext intent:(TGMediaAssetsControllerIntent)intent currentItem:(TGMediaAsset *)currentItem storeAssets:(bool)storeAssets convertToJpeg:(bool)convertToJpeg descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *, NSString *))descriptionGenerator saveEditedPhotos:(bool)saveEditedPhotos; @end diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaEditingContext.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaEditingContext.h index 579482e894..98c7ad095c 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaEditingContext.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaEditingContext.h @@ -68,7 +68,6 @@ - (SSignal *)captionSignalForItem:(NSObject *)item; - (void)setCaption:(NSString *)caption entities:(NSArray *)entities forItem:(NSObject *)item; -- (void)setInitialCaption:(NSString *)caption entities:(NSArray *)entities; - (void)setForcedCaption:(NSString *)caption entities:(NSArray *)entities; - (NSObject *)adjustmentsForItem:(NSObject *)item; diff --git a/submodules/LegacyComponents/Sources/TGClipboardMenu.m b/submodules/LegacyComponents/Sources/TGClipboardMenu.m index f9be4fdcfc..edbe93514f 100644 --- a/submodules/LegacyComponents/Sources/TGClipboardMenu.m +++ b/submodules/LegacyComponents/Sources/TGClipboardMenu.m @@ -9,7 +9,7 @@ @implementation TGClipboardMenu -+ (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id)context images:(NSArray *)images hasCaption:(bool)hasCaption hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName suggestionContext:(TGSuggestionContext *)suggestionContext stickersContext:(id)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect ++ (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id)context images:(NSArray *)images allowGrouping:(bool)allowGrouping hasCaption:(bool)hasCaption hasTimer:(bool)hasTimer hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder recipientName:(NSString *)recipientName suggestionContext:(TGSuggestionContext *)suggestionContext stickersContext:(id)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect { bool centered = false; if (sourceRect == nil) @@ -39,7 +39,7 @@ NSMutableArray *itemViews = [[NSMutableArray alloc] init]; - TGClipboardPreviewItemView *previewItem = [[TGClipboardPreviewItemView alloc] initWithContext:context images:images]; + TGClipboardPreviewItemView *previewItem = [[TGClipboardPreviewItemView alloc] initWithContext:context images:images allowGrouping:allowGrouping]; __weak TGClipboardPreviewItemView *weakPreviewItem = previewItem; previewItem.stickersContext = stickersContext; previewItem.suggestionContext = suggestionContext; @@ -109,6 +109,13 @@ } ++ (int64_t)generateGroupedId +{ + int64_t value; + arc4random_buf(&value, sizeof(int64_t)); + return value; +} + + (NSArray *)resultSignalsForSelectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext currentItem:(id)currentItem descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *))descriptionGenerator { NSMutableArray *signals = [[NSMutableArray alloc] init]; @@ -116,6 +123,24 @@ if (selectedItems.count == 0 && currentItem != nil) [selectedItems addObject:currentItem]; + NSNumber *groupedId; + NSInteger i = 0; + bool grouping = selectionContext.grouping; + + bool hasAnyTimers = false; + if (editingContext != nil || grouping) + { + for (UIImage *asset in selectedItems) + { + if ([editingContext timerForItem:asset] != nil) { + hasAnyTimers = true; + } + } + } + + if (grouping && selectedItems.count > 1) + groupedId = @([self generateGroupedId]); + for (UIImage *asset in selectedItems) { NSString *caption = [editingContext captionForItem:asset]; @@ -132,6 +157,9 @@ if (timer != nil) dict[@"timer"] = timer; + if (groupedId != nil) + dict[@"groupedId"] = groupedId; + id generatedItem = descriptionGenerator(dict, caption, entities, nil); return generatedItem; }]; @@ -176,12 +204,23 @@ if (timer != nil) dict[@"timer"] = timer; + if (groupedId != nil) + dict[@"groupedId"] = groupedId; + id generatedItem = descriptionGenerator(dict, caption, entities, nil); return generatedItem; }] catch:^SSignal *(__unused id error) { return inlineSignal; }]]; + + i++; + + if (groupedId != nil && i == 10) + { + i = 0; + groupedId = @([self generateGroupedId]); + } } return signals; } diff --git a/submodules/LegacyComponents/Sources/TGClipboardPreviewItemView.h b/submodules/LegacyComponents/Sources/TGClipboardPreviewItemView.h index c3b5f6ef71..b32c4b0f6c 100644 --- a/submodules/LegacyComponents/Sources/TGClipboardPreviewItemView.h +++ b/submodules/LegacyComponents/Sources/TGClipboardPreviewItemView.h @@ -29,7 +29,7 @@ @property (nonatomic, copy) void (^presentScheduleController)(void (^)(int32_t)); @property (nonatomic, copy) void (^presentTimerController)(void (^)(int32_t)); -- (instancetype)initWithContext:(id)context images:(NSArray *)images; +- (instancetype)initWithContext:(id)context images:(NSArray *)images allowGrouping:(bool)allowGrouping; - (void)setCollapsed:(bool)collapsed animated:(bool)animated; diff --git a/submodules/LegacyComponents/Sources/TGClipboardPreviewItemView.m b/submodules/LegacyComponents/Sources/TGClipboardPreviewItemView.m index c51cd1f32e..9ea8a4d3a0 100644 --- a/submodules/LegacyComponents/Sources/TGClipboardPreviewItemView.m +++ b/submodules/LegacyComponents/Sources/TGClipboardPreviewItemView.m @@ -35,7 +35,7 @@ const CGFloat TGClipboardPreviewEdgeInset = 8.0f; @implementation TGClipboardPreviewItemView -- (instancetype)initWithContext:(id)context images:(NSArray *)images +- (instancetype)initWithContext:(id)context images:(NSArray *)images allowGrouping:(bool)allowGrouping { self = [super initWithType:TGMenuSheetItemTypeDefault]; if (self != nil) @@ -61,7 +61,9 @@ const CGFloat TGClipboardPreviewEdgeInset = 8.0f; [_collectionView registerClass:[TGClipboardPreviewCell class] forCellWithReuseIdentifier:TGClipboardPreviewCellIdentifier]; [self addSubview:_collectionView]; - _selectionContext = [[TGMediaSelectionContext alloc] initWithGroupingAllowed:false selectionLimit:100]; + _selectionContext = [[TGMediaSelectionContext alloc] initWithGroupingAllowed:allowGrouping selectionLimit:100]; + if (allowGrouping) + _selectionContext.grouping = true; for (UIImage *image in _images) { diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetImageSignals.m b/submodules/LegacyComponents/Sources/TGMediaAssetImageSignals.m index df1c02bfa0..795b947117 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetImageSignals.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetImageSignals.m @@ -58,6 +58,11 @@ static Class TGMediaAssetImageSignalsClass = nil; return [TGMediaAssetImageSignalsClass imageDataForAsset:asset allowNetworkAccess:allowNetworkAccess]; } ++ (SSignal *)imageDataForAsset:(TGMediaAsset *)asset allowNetworkAccess:(bool)allowNetworkAccess convertToJpeg:(bool)convertToJpeg +{ + return [TGMediaAssetImageSignalsClass imageDataForAsset:asset allowNetworkAccess:allowNetworkAccess convertToJpeg:convertToJpeg]; +} + + (SSignal *)imageMetadataForAsset:(TGMediaAsset *)asset { return [TGMediaAssetImageSignalsClass imageMetadataForAsset:asset]; diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetModernImageSignals.m b/submodules/LegacyComponents/Sources/TGMediaAssetModernImageSignals.m index 003bf452f9..01a415d803 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetModernImageSignals.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetModernImageSignals.m @@ -253,6 +253,11 @@ } + (SSignal *)imageDataForAsset:(TGMediaAsset *)asset allowNetworkAccess:(bool)allowNetworkAccess +{ + return [self imageDataForAsset:asset allowNetworkAccess:allowNetworkAccess convertToJpeg:true]; +} + ++ (SSignal *)imageDataForAsset:(TGMediaAsset *)asset allowNetworkAccess:(bool)allowNetworkAccess convertToJpeg:(bool)convertToJpeg { SSignal *(^requestDataSignal)(bool) = ^SSignal *(bool networkAccessAllowed) { @@ -300,9 +305,8 @@ fileName = asset.fileName; } - if (iosMajorVersion() >= 10 && [asset.uniformTypeIdentifier rangeOfString:@"heic"].location != NSNotFound) + if (convertToJpeg && iosMajorVersion() >= 10 && [asset.uniformTypeIdentifier rangeOfString:@"heic"].location != NSNotFound) { -//#if !DEBUG CIContext *context = [[CIContext alloc] init]; CIImage *image = [[CIImage alloc] initWithData:imageData]; NSURL *tmpURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[[NSString alloc] initWithFormat:@"%x.jpg", (int)arc4random()]]]; @@ -311,17 +315,12 @@ { fileUrl = tmpURL; dataUTI = @"public.jpeg"; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - imageData = [[NSData alloc] initWithContentsOfMappedFile:fileUrl.path]; -#pragma clang diagnostic pop - + imageData = [[NSData alloc] initWithContentsOfFile:fileUrl.path options:NSDataReadingMappedAlways error:nil]; NSString *lowcaseString = [fileName lowercaseString]; NSRange range = [lowcaseString rangeOfString:@".heic"]; if (range.location != NSNotFound) fileName = [fileName stringByReplacingCharactersInRange:range withString:@".JPG"]; } -//#endif } TGMediaAssetImageData *data = [[TGMediaAssetImageData alloc] init]; diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetsController.m b/submodules/LegacyComponents/Sources/TGMediaAssetsController.m index f6eb3eaabf..ab828dc834 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetsController.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetsController.m @@ -833,7 +833,7 @@ if (_intent == TGMediaAssetsControllerSendMediaIntent && _selectionContext.allowGrouping) [[NSUserDefaults standardUserDefaults] setObject:@(!_selectionContext.grouping) forKey:@"TG_mediaGroupingDisabled_v0"]; - return [TGMediaAssetsController resultSignalsForSelectionContext:_selectionContext editingContext:_editingContext intent:_intent currentItem:currentItem storeAssets:storeAssets useMediaCache:self.localMediaCacheEnabled descriptionGenerator:descriptionGenerator saveEditedPhotos:_saveEditedPhotos]; + return [TGMediaAssetsController resultSignalsForSelectionContext:_selectionContext editingContext:_editingContext intent:_intent currentItem:currentItem storeAssets:storeAssets convertToJpeg:false descriptionGenerator:descriptionGenerator saveEditedPhotos:_saveEditedPhotos]; } + (int64_t)generateGroupedId @@ -843,7 +843,7 @@ return value; } -+ (NSArray *)resultSignalsForSelectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext intent:(TGMediaAssetsControllerIntent)intent currentItem:(TGMediaAsset *)currentItem storeAssets:(bool)storeAssets useMediaCache:(bool)__unused useMediaCache descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *, NSString *))descriptionGenerator saveEditedPhotos:(bool)saveEditedPhotos ++ (NSArray *)resultSignalsForSelectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext intent:(TGMediaAssetsControllerIntent)intent currentItem:(TGMediaAsset *)currentItem storeAssets:(bool)storeAssets convertToJpeg:(bool)convertToJpeg descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *, NSString *))descriptionGenerator saveEditedPhotos:(bool)saveEditedPhotos { NSMutableArray *signals = [[NSMutableArray alloc] init]; NSMutableArray *selectedItems = selectionContext.selectedItems ? [selectionContext.selectedItems mutableCopy] : [[NSMutableArray alloc] init]; @@ -947,7 +947,7 @@ NSString *caption = [editingContext captionForItem:asset]; NSArray *entities = [editingContext entitiesForItem:asset]; - [signals addObject:[[[TGMediaAssetImageSignals imageDataForAsset:asset allowNetworkAccess:false] map:^NSDictionary *(TGMediaAssetImageData *assetData) + [signals addObject:[[[TGMediaAssetImageSignals imageDataForAsset:asset allowNetworkAccess:false convertToJpeg:convertToJpeg] map:^NSDictionary *(TGMediaAssetImageData *assetData) { NSString *tempFileName = TGTemporaryFileName(nil); [assetData.imageData writeToURL:[NSURL fileURLWithPath:tempFileName] atomically:true]; diff --git a/submodules/LegacyComponents/Sources/TGMediaEditingContext.m b/submodules/LegacyComponents/Sources/TGMediaEditingContext.m index 367eeaf715..3733470f54 100644 --- a/submodules/LegacyComponents/Sources/TGMediaEditingContext.m +++ b/submodules/LegacyComponents/Sources/TGMediaEditingContext.m @@ -106,9 +106,6 @@ NSString *_forcedCaption; NSArray *_forcedEntities; - - NSString *_initialCaption; - NSArray *_initialEntities; } @end @@ -433,12 +430,6 @@ _forcedEntities = entities; } -- (void)setInitialCaption:(NSString *)caption entities:(NSArray *)entities -{ - _initialCaption = caption; - _initialEntities = entities; -} - - (SSignal *)captionSignalForItem:(NSObject *)item { NSString *uniqueIdentifier = item.uniqueIdentifier; diff --git a/submodules/LegacyComponents/Sources/TGMediaPickerController.m b/submodules/LegacyComponents/Sources/TGMediaPickerController.m index 903335590e..cdc6ebec4f 100644 --- a/submodules/LegacyComponents/Sources/TGMediaPickerController.m +++ b/submodules/LegacyComponents/Sources/TGMediaPickerController.m @@ -76,7 +76,7 @@ self.scrollViewsForAutomaticInsetsAdjustment = @[ _collectionView ]; self.explicitTableInset = UIEdgeInsetsMake(0, 0, TGMediaPickerToolbarHeight, 0); - self.explicitScrollIndicatorInset = self.explicitTableInset; + self.explicitScrollIndicatorInset = UIEdgeInsetsMake(14.0, 0, TGMediaPickerToolbarHeight, 0); [self _setupSelectionGesture]; diff --git a/submodules/LegacyComponents/Sources/TGMediaPickerSelectionGestureRecognizer.m b/submodules/LegacyComponents/Sources/TGMediaPickerSelectionGestureRecognizer.m index 30f3789c5e..2689062712 100644 --- a/submodules/LegacyComponents/Sources/TGMediaPickerSelectionGestureRecognizer.m +++ b/submodules/LegacyComponents/Sources/TGMediaPickerSelectionGestureRecognizer.m @@ -126,6 +126,14 @@ const CGFloat TGSelectionGestureVerticalFailureThreshold = 5.0f; _gestureRecognizer.enabled = true; } +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { + CGPoint point = [gestureRecognizer locationInView:gestureRecognizer.view]; + if (point.x > gestureRecognizer.view.frame.size.width - 44.0) { + return false; + } + return true; +} + - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)__unused otherGestureRecognizer { if ([otherGestureRecognizer.view isKindOfClass:[UIScrollView class]]) diff --git a/submodules/LegacyComponents/Sources/TGPhotoEditorUtils.m b/submodules/LegacyComponents/Sources/TGPhotoEditorUtils.m index fd5465eefa..fb3493ab30 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoEditorUtils.m +++ b/submodules/LegacyComponents/Sources/TGPhotoEditorUtils.m @@ -24,6 +24,10 @@ CGSize TGPhotoThumbnailSizeForCurrentScreen() if ([UIScreen mainScreen].scale >= 2.0f - FLT_EPSILON) { + if (widescreenWidth >= 926.0f - FLT_EPSILON) + { + return CGSizeMake(141.0f + TGScreenPixel, 141.0 + TGScreenPixel); + } if (widescreenWidth >= 896.0f - FLT_EPSILON) { return CGSizeMake(137.0f - TGScreenPixel, 137.0f - TGScreenPixel); diff --git a/submodules/LegacyComponents/Sources/TGViewController.mm b/submodules/LegacyComponents/Sources/TGViewController.mm index 41ded68f86..13b9029bf0 100644 --- a/submodules/LegacyComponents/Sources/TGViewController.mm +++ b/submodules/LegacyComponents/Sources/TGViewController.mm @@ -1206,7 +1206,7 @@ static id _defaultContext = nil; UIEdgeInsets finalInset = self.controllerInset; scrollView.contentInset = finalInset; - scrollView.scrollIndicatorInsets = self.controllerScrollInset; + scrollView.scrollIndicatorInsets = _explicitScrollIndicatorInset; if (!UIEdgeInsetsEqualToEdgeInsets(previousInset, UIEdgeInsetsZero)) { diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift index 260cd02cd3..90fb25e0d3 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyAttachmentMenu.swift @@ -120,7 +120,7 @@ public func legacyMediaEditor(context: AccountContext, peer: Peer, media: AnyMed }) } -public func legacyAttachmentMenu(context: AccountContext, peer: Peer, chatLocation: ChatLocation, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, hasSchedule: Bool, canSendPolls: Bool, updatedPresentationData: (initial: PresentationData, signal: Signal), parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32, ((String) -> UIView?)?, @escaping () -> Void) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?, present: @escaping (ViewController, Any?) -> Void) -> TGMenuSheetController { +public func legacyAttachmentMenu(context: AccountContext, peer: Peer, chatLocation: ChatLocation, editMediaOptions: LegacyAttachmentMenuMediaEditing?, saveEditedPhotos: Bool, allowGrouping: Bool, hasSchedule: Bool, canSendPolls: Bool, updatedPresentationData: (initial: PresentationData, signal: Signal), parentController: LegacyController, recentlyUsedInlineBots: [Peer], initialCaption: String, openGallery: @escaping () -> Void, openCamera: @escaping (TGAttachmentCameraView?, TGMenuSheetController?) -> Void, openFileGallery: @escaping () -> Void, openWebSearch: @escaping () -> Void, openMap: @escaping () -> Void, openContacts: @escaping () -> Void, openPoll: @escaping () -> Void, presentSelectionLimitExceeded: @escaping () -> Void, presentCantSendMultipleFiles: @escaping () -> Void, presentJpegConversionAlert: @escaping (@escaping (Bool) -> Void) -> Void, presentSchedulePicker: @escaping (@escaping (Int32) -> Void) -> Void, presentTimerPicker: @escaping (@escaping (Int32) -> Void) -> Void, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32, ((String) -> UIView?)?, @escaping () -> Void) -> Void, selectRecentlyUsedInlineBot: @escaping (Peer) -> Void, presentStickers: @escaping (@escaping (TelegramMediaFile, Bool, UIView, CGRect) -> Void) -> TGPhotoPaintStickersScreen?, present: @escaping (ViewController, Any?) -> Void) -> TGMenuSheetController { let defaultVideoPreset = defaultVideoPresetForContext(context) UserDefaults.standard.set(defaultVideoPreset.rawValue as NSNumber, forKey: "TG_preferredVideoPreset_v0") @@ -227,23 +227,46 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, chatLocati carouselItem.sendPressed = { [weak controller, weak carouselItem] currentItem, asFiles, silentPosting, scheduleTime, isFromPicker in if let controller = controller, let carouselItem = carouselItem { let intent: TGMediaAssetsControllerIntent = asFiles ? TGMediaAssetsControllerSendFileIntent : TGMediaAssetsControllerSendMediaIntent - let signals = TGMediaAssetsController.resultSignals(for: carouselItem.selectionContext, editingContext: carouselItem.editingContext, intent: intent, currentItem: currentItem, storeAssets: true, useMediaCache: false, descriptionGenerator: legacyAssetPickerItemGenerator(), saveEditedPhotos: saveEditedPhotos) - if slowModeEnabled, let signals = signals, signals.count > 1 { + + var hasHeic = false + var allItems = carouselItem.selectionContext.selectedItems() ?? [] + if let currentItem = currentItem { + allItems.append(currentItem) + } + for item in allItems { + if let asset = item as? TGMediaAsset, asset.uniformTypeIdentifier.contains("heic") { + hasHeic = true + break + } + } + + if slowModeEnabled, allItems.count > 1 { presentCantSendMultipleFiles() } else { - sendMessagesWithSignals(signals, silentPosting, scheduleTime, isFromPicker ? nil : { [weak carouselItem] uniqueId in - if let carouselItem = carouselItem { - return carouselItem.getItemSnapshot(uniqueId) - } - return nil - }, { [weak controller] in - controller?.dismiss(animated: true) - }) + let process: (Bool) -> Void = { convert in + let signals = TGMediaAssetsController.resultSignals(for: carouselItem.selectionContext, editingContext: carouselItem.editingContext, intent: intent, currentItem: currentItem, storeAssets: true, convertToJpeg: convert, descriptionGenerator: legacyAssetPickerItemGenerator(), saveEditedPhotos: saveEditedPhotos) + sendMessagesWithSignals(signals, silentPosting, scheduleTime, isFromPicker ? nil : { [weak carouselItem] uniqueId in + if let carouselItem = carouselItem { + return carouselItem.getItemSnapshot(uniqueId) + } + return nil + }, { [weak controller] in + controller?.dismiss(animated: true) + }) + } + if hasHeic && asFiles { + presentJpegConversionAlert({ convert in + process(convert) + }) + } else { + process(false) + } + } } }; carouselItem.allowCaptions = true - carouselItem.editingContext.setInitialCaption(initialCaption, entities: []) + carouselItem.editingContext.setForcedCaption(initialCaption, entities: []) itemViews.append(carouselItem) let galleryItem = TGMenuSheetButtonItemView(title: editing ? presentationData.strings.Conversation_EditingMessageMediaChange : presentationData.strings.AttachmentMenu_PhotoOrVideo, type: TGMenuSheetButtonTypeDefault, fontSize: fontSize, action: { [weak controller] in @@ -454,7 +477,7 @@ public func presentLegacyPasteMenu(context: AccountContext, peer: Peer, chatLoca }) } - let controller = TGClipboardMenu.present(inParentController: emptyController, context: legacyController.context, images: images, hasCaption: true, hasTimer: hasTimer, hasSilentPosting: hasSilentPosting, hasSchedule: hasSchedule, reminder: peer.id == context.account.peerId, recipientName: recipientName, suggestionContext: suggestionContext, stickersContext: paintStickersContext, presentScheduleController: { done in + let controller = TGClipboardMenu.present(inParentController: emptyController, context: legacyController.context, images: images, allowGrouping: allowGrouping, hasCaption: true, hasTimer: hasTimer, hasSilentPosting: hasSilentPosting, hasSchedule: hasSchedule, reminder: peer.id == context.account.peerId, recipientName: recipientName, suggestionContext: suggestionContext, stickersContext: paintStickersContext, presentScheduleController: { done in presentSchedulePicker { time in done?(time) } diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift index fa7fa8697a..0c3b7108de 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyMediaPickers.swift @@ -60,7 +60,7 @@ public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, co controller.shouldShowFileTipIfNeeded = showFileTooltip controller.requestSearchController = presentWebSearch - controller.editingContext.setInitialCaption(initialCaption, entities: []) + controller.editingContext.setForcedCaption(initialCaption, entities: []) } public func legacyAssetPicker(context: AccountContext, presentationData: PresentationData, editingMedia: Bool, fileMode: Bool, peer: Peer?, saveEditedPhotos: Bool, allowGrouping: Bool, selectionLimit: Int) -> Signal<(LegacyComponentsContext) -> TGMediaAssetsController, Void> { diff --git a/submodules/ShareController/Sources/ShareController.swift b/submodules/ShareController/Sources/ShareController.swift index 99a49f7a53..5af7a8504e 100644 --- a/submodules/ShareController/Sources/ShareController.swift +++ b/submodules/ShareController/Sources/ShareController.swift @@ -551,19 +551,13 @@ public final class ShareController: ViewController { case let .image(representations): for peerId in peerIds { var messages: [EnqueueMessage] = [] - if !text.isEmpty { - messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)) - } - messages.append(.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)) + messages.append(.message(text: text, attributes: [], mediaReference: .standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])), replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)) shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages)) } case let .media(mediaReference): for peerId in peerIds { var messages: [EnqueueMessage] = [] - if !text.isEmpty { - messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)) - } - messages.append(.message(text: "", attributes: [], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)) + messages.append(.message(text: text, attributes: [], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil)) shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages)) } case let .mapMedia(media): diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index 84f8cef824..43a69833f3 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -5931,6 +5931,7 @@ public final class VoiceChatController: ViewController { if bounds.minY < -60 || (bounds.minY < 0.0 && velocity.y > 300.0) { if self.isScheduling { self.dismissScheduled() + dismissing = true } else if case .regular = layout.metrics.widthClass { self.controller?.dismiss(closing: false, manual: true) dismissing = true diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index bd0788dfe1..a4b9d9a9b6 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -8070,6 +8070,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G interfaceState = interfaceState.withUpdatedHistoryScrollState(scrollState) } interfaceState = interfaceState.withUpdatedInputLanguage(self.chatDisplayNode.currentTextInputLanguage) + if interfaceState.composeInputState.inputText.string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + interfaceState = interfaceState.withUpdatedComposeInputState(ChatTextInputState(inputText: NSAttributedString(string: ""))) + } let _ = ChatInterfaceState.update(engine: self.context.engine, peerId: peerId, threadId: threadId, { _ in return interfaceState }).start() @@ -9295,7 +9298,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G let controller = legacyAttachmentMenu(context: strongSelf.context, peer: peer, chatLocation: strongSelf.chatLocation, editMediaOptions: menuEditMediaOptions, saveEditedPhotos: settings.storeEditedPhotos, allowGrouping: true, hasSchedule: strongSelf.presentationInterfaceState.subject != .scheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat, canSendPolls: canSendPolls, updatedPresentationData: strongSelf.updatedPresentationData, parentController: legacyController, recentlyUsedInlineBots: strongSelf.recentlyUsedInlineBotsValue, initialCaption: inputText.string, openGallery: { self?.presentMediaPicker(fileMode: false, editingMedia: editMediaOptions != nil, completion: { signals, silentPosting, scheduleTime in if !inputText.string.isEmpty { - //strongSelf.clearInputText() + strongSelf.clearInputText() } if editMediaOptions != nil { self?.editMessageMediaWithLegacySignals(signals) @@ -9318,16 +9321,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G strongSelf.enqueueMediaMessages(signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime > 0 ? scheduleTime : nil) } if !inputText.string.isEmpty { - //strongSelf.clearInputText() + strongSelf.clearInputText() } } }, recognizedQRCode: { [weak self] code in if let strongSelf = self { if let (host, port, username, password, secret) = parseProxyUrl(code) { strongSelf.openResolved(ResolvedUrl.proxy(host: host, port: port, username: username, password: password, secret: secret)) - }/* else if let url = URL(string: code), let parsedWalletUrl = parseWalletUrl(url) { - //strongSelf.openResolved(ResolvedUrl.wallet(address: parsedWalletUrl.address, amount: parsedWalletUrl.amount, comment: parsedWalletUrl.comment)) - }*/ + } } }, presentSchedulePicker: { [weak self] done in if let strongSelf = self { @@ -9385,6 +9386,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: nil, text: strongSelf.presentationData.strings.Chat_AttachmentMultipleFilesDisabled, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), in: .window(.root)) + }, presentJpegConversionAlert: { completion in + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: nil, text: strongSelf.presentationData.strings.MediaPicker_JpegConversionText, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.MediaPicker_KeepHeic, action: { + completion(false) + }), TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.MediaPicker_ConvertToJpeg, action: { + completion(true) + })], actionLayout: .vertical), in: .window(.root)) }, presentSchedulePicker: { [weak self] done in if let strongSelf = self { strongSelf.presentScheduleTimePicker(style: .media, completion: { [weak self] time in @@ -9408,7 +9415,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G return } if !inputText.string.isEmpty { - //strongSelf.clearInputText() + strongSelf.clearInputText() } if editMediaOptions != nil { strongSelf.editMessageMediaWithLegacySignals(signals!) @@ -11592,6 +11599,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G }) let commit: ([EnqueueMessage]) -> Void = { result in + strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }).updatedSearch(nil) }) + var displayPeers: [Peer] = [] for peer in peers { let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: result) diff --git a/versions.json b/versions.json index a3127779d2..443b8984a7 100644 --- a/versions.json +++ b/versions.json @@ -1,5 +1,5 @@ { - "app": "8.1", + "app": "8.1.2", "bazel": "4.0.0", "xcode": "12.5.1" }