Various Improvements

This commit is contained in:
Ilya Laktyushin 2021-09-29 08:04:11 +03:00
parent 3450418ad2
commit b575edfc1d
23 changed files with 148 additions and 67 deletions

View File

@ -6862,3 +6862,7 @@ Ads should no longer be synonymous with abuse of user privacy. Let us redefine h
"VoiceChat.RecordPortrait" = "Portrait"; "VoiceChat.RecordPortrait" = "Portrait";
"VoiceChat.RecordLandscape" = "Landscape"; "VoiceChat.RecordLandscape" = "Landscape";
"VoiceChat.RecordStartRecording" = "Start Recording"; "VoiceChat.RecordStartRecording" = "Start Recording";
"MediaPicker.JpegConversionText" = "Do you want to convert photos to JPEG?";
"MediaPicker.KeepHeic" = "Keep HEIC";
"MediaPicker.ConvertToJpeg" = "Convert to JPEG";

View File

@ -976,14 +976,16 @@ public final class AnimatedStickerNode: ASDisplayNode {
private var isSetUpForPlayback = false private var isSetUpForPlayback = false
public func play(firstFrame: Bool = false, fromIndex: Int? = nil) { public func play(firstFrame: Bool = false, fromIndex: Int? = nil) {
switch self.playbackMode { if !firstFrame {
case .once: switch self.playbackMode {
self.isPlaying = true case .once:
case .count: self.isPlaying = true
self.currentLoopCount = 0 case .count:
self.isPlaying = true self.currentLoopCount = 0
default: self.isPlaying = true
break default:
break
}
} }
if self.isSetUpForPlayback { if self.isSetUpForPlayback {
let directData = self.directData let directData = self.directData

View File

@ -14,7 +14,7 @@
@interface TGClipboardMenu : NSObject @interface TGClipboardMenu : NSObject
+ (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id<LegacyComponentsContext>)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<TGPhotoPaintStickersContext>)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id<TGMediaSelectableItem> currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect; + (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id<LegacyComponentsContext>)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<TGPhotoPaintStickersContext>)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id<TGMediaSelectableItem> 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<TGMediaSelectableItem>)currentItem descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *))descriptionGenerator; + (NSArray *)resultSignalsForSelectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext currentItem:(id<TGMediaSelectableItem>)currentItem descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *))descriptionGenerator;

View File

@ -48,6 +48,7 @@ typedef enum
+ (SSignal *)imageDataForAsset:(TGMediaAsset *)asset; + (SSignal *)imageDataForAsset:(TGMediaAsset *)asset;
+ (SSignal *)imageDataForAsset:(TGMediaAsset *)asset allowNetworkAccess:(bool)allowNetworkAccess; + (SSignal *)imageDataForAsset:(TGMediaAsset *)asset allowNetworkAccess:(bool)allowNetworkAccess;
+ (SSignal *)imageDataForAsset:(TGMediaAsset *)asset allowNetworkAccess:(bool)allowNetworkAccess convertToJpeg:(bool)convertToJpeg;
+ (SSignal *)imageMetadataForAsset:(TGMediaAsset *)asset; + (SSignal *)imageMetadataForAsset:(TGMediaAsset *)asset;
+ (SSignal *)fileAttributesForAsset:(TGMediaAsset *)asset; + (SSignal *)fileAttributesForAsset:(TGMediaAsset *)asset;

View File

@ -105,6 +105,6 @@ typedef enum
+ (TGMediaAssetType)assetTypeForIntent:(TGMediaAssetsControllerIntent)intent; + (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 @end

View File

@ -68,7 +68,6 @@
- (SSignal *)captionSignalForItem:(NSObject<TGMediaEditableItem> *)item; - (SSignal *)captionSignalForItem:(NSObject<TGMediaEditableItem> *)item;
- (void)setCaption:(NSString *)caption entities:(NSArray *)entities forItem:(NSObject<TGMediaEditableItem> *)item; - (void)setCaption:(NSString *)caption entities:(NSArray *)entities forItem:(NSObject<TGMediaEditableItem> *)item;
- (void)setInitialCaption:(NSString *)caption entities:(NSArray *)entities;
- (void)setForcedCaption:(NSString *)caption entities:(NSArray *)entities; - (void)setForcedCaption:(NSString *)caption entities:(NSArray *)entities;
- (NSObject<TGMediaEditAdjustments> *)adjustmentsForItem:(NSObject<TGMediaEditableItem> *)item; - (NSObject<TGMediaEditAdjustments> *)adjustmentsForItem:(NSObject<TGMediaEditableItem> *)item;

View File

@ -9,7 +9,7 @@
@implementation TGClipboardMenu @implementation TGClipboardMenu
+ (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id<LegacyComponentsContext>)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<TGPhotoPaintStickersContext>)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id<TGMediaSelectableItem> currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect + (TGMenuSheetController *)presentInParentController:(TGViewController *)parentController context:(id<LegacyComponentsContext>)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<TGPhotoPaintStickersContext>)stickersContext presentScheduleController:(void (^)(void(^)(int32_t)))presentScheduleController presentTimerController:(void (^)(void(^)(int32_t)))presentTimerController completed:(void (^)(TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id<TGMediaSelectableItem> currentItem, bool silentPosting, int32_t scheduleTime))completed dismissed:(void (^)(void))dismissed sourceView:(UIView *)sourceView sourceRect:(CGRect (^)(void))sourceRect
{ {
bool centered = false; bool centered = false;
if (sourceRect == nil) if (sourceRect == nil)
@ -39,7 +39,7 @@
NSMutableArray *itemViews = [[NSMutableArray alloc] init]; 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; __weak TGClipboardPreviewItemView *weakPreviewItem = previewItem;
previewItem.stickersContext = stickersContext; previewItem.stickersContext = stickersContext;
previewItem.suggestionContext = suggestionContext; 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<TGMediaSelectableItem>)currentItem descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *))descriptionGenerator + (NSArray *)resultSignalsForSelectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext currentItem:(id<TGMediaSelectableItem>)currentItem descriptionGenerator:(id (^)(id, NSString *, NSArray *, NSString *))descriptionGenerator
{ {
NSMutableArray *signals = [[NSMutableArray alloc] init]; NSMutableArray *signals = [[NSMutableArray alloc] init];
@ -116,6 +123,24 @@
if (selectedItems.count == 0 && currentItem != nil) if (selectedItems.count == 0 && currentItem != nil)
[selectedItems addObject:currentItem]; [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) for (UIImage *asset in selectedItems)
{ {
NSString *caption = [editingContext captionForItem:asset]; NSString *caption = [editingContext captionForItem:asset];
@ -132,6 +157,9 @@
if (timer != nil) if (timer != nil)
dict[@"timer"] = timer; dict[@"timer"] = timer;
if (groupedId != nil)
dict[@"groupedId"] = groupedId;
id generatedItem = descriptionGenerator(dict, caption, entities, nil); id generatedItem = descriptionGenerator(dict, caption, entities, nil);
return generatedItem; return generatedItem;
}]; }];
@ -176,12 +204,23 @@
if (timer != nil) if (timer != nil)
dict[@"timer"] = timer; dict[@"timer"] = timer;
if (groupedId != nil)
dict[@"groupedId"] = groupedId;
id generatedItem = descriptionGenerator(dict, caption, entities, nil); id generatedItem = descriptionGenerator(dict, caption, entities, nil);
return generatedItem; return generatedItem;
}] catch:^SSignal *(__unused id error) }] catch:^SSignal *(__unused id error)
{ {
return inlineSignal; return inlineSignal;
}]]; }]];
i++;
if (groupedId != nil && i == 10)
{
i = 0;
groupedId = @([self generateGroupedId]);
}
} }
return signals; return signals;
} }

View File

@ -29,7 +29,7 @@
@property (nonatomic, copy) void (^presentScheduleController)(void (^)(int32_t)); @property (nonatomic, copy) void (^presentScheduleController)(void (^)(int32_t));
@property (nonatomic, copy) void (^presentTimerController)(void (^)(int32_t)); @property (nonatomic, copy) void (^presentTimerController)(void (^)(int32_t));
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context images:(NSArray *)images; - (instancetype)initWithContext:(id<LegacyComponentsContext>)context images:(NSArray *)images allowGrouping:(bool)allowGrouping;
- (void)setCollapsed:(bool)collapsed animated:(bool)animated; - (void)setCollapsed:(bool)collapsed animated:(bool)animated;

View File

@ -35,7 +35,7 @@ const CGFloat TGClipboardPreviewEdgeInset = 8.0f;
@implementation TGClipboardPreviewItemView @implementation TGClipboardPreviewItemView
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context images:(NSArray *)images - (instancetype)initWithContext:(id<LegacyComponentsContext>)context images:(NSArray *)images allowGrouping:(bool)allowGrouping
{ {
self = [super initWithType:TGMenuSheetItemTypeDefault]; self = [super initWithType:TGMenuSheetItemTypeDefault];
if (self != nil) if (self != nil)
@ -61,7 +61,9 @@ const CGFloat TGClipboardPreviewEdgeInset = 8.0f;
[_collectionView registerClass:[TGClipboardPreviewCell class] forCellWithReuseIdentifier:TGClipboardPreviewCellIdentifier]; [_collectionView registerClass:[TGClipboardPreviewCell class] forCellWithReuseIdentifier:TGClipboardPreviewCellIdentifier];
[self addSubview:_collectionView]; [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) for (UIImage *image in _images)
{ {

View File

@ -58,6 +58,11 @@ static Class TGMediaAssetImageSignalsClass = nil;
return [TGMediaAssetImageSignalsClass imageDataForAsset:asset allowNetworkAccess:allowNetworkAccess]; 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 + (SSignal *)imageMetadataForAsset:(TGMediaAsset *)asset
{ {
return [TGMediaAssetImageSignalsClass imageMetadataForAsset:asset]; return [TGMediaAssetImageSignalsClass imageMetadataForAsset:asset];

View File

@ -253,6 +253,11 @@
} }
+ (SSignal *)imageDataForAsset:(TGMediaAsset *)asset allowNetworkAccess:(bool)allowNetworkAccess + (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) SSignal *(^requestDataSignal)(bool) = ^SSignal *(bool networkAccessAllowed)
{ {
@ -300,9 +305,8 @@
fileName = asset.fileName; 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]; CIContext *context = [[CIContext alloc] init];
CIImage *image = [[CIImage alloc] initWithData:imageData]; CIImage *image = [[CIImage alloc] initWithData:imageData];
NSURL *tmpURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[[NSString alloc] initWithFormat:@"%x.jpg", (int)arc4random()]]]; NSURL *tmpURL = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[[NSString alloc] initWithFormat:@"%x.jpg", (int)arc4random()]]];
@ -311,17 +315,12 @@
{ {
fileUrl = tmpURL; fileUrl = tmpURL;
dataUTI = @"public.jpeg"; dataUTI = @"public.jpeg";
#pragma clang diagnostic push imageData = [[NSData alloc] initWithContentsOfFile:fileUrl.path options:NSDataReadingMappedAlways error:nil];
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
imageData = [[NSData alloc] initWithContentsOfMappedFile:fileUrl.path];
#pragma clang diagnostic pop
NSString *lowcaseString = [fileName lowercaseString]; NSString *lowcaseString = [fileName lowercaseString];
NSRange range = [lowcaseString rangeOfString:@".heic"]; NSRange range = [lowcaseString rangeOfString:@".heic"];
if (range.location != NSNotFound) if (range.location != NSNotFound)
fileName = [fileName stringByReplacingCharactersInRange:range withString:@".JPG"]; fileName = [fileName stringByReplacingCharactersInRange:range withString:@".JPG"];
} }
//#endif
} }
TGMediaAssetImageData *data = [[TGMediaAssetImageData alloc] init]; TGMediaAssetImageData *data = [[TGMediaAssetImageData alloc] init];

View File

@ -833,7 +833,7 @@
if (_intent == TGMediaAssetsControllerSendMediaIntent && _selectionContext.allowGrouping) if (_intent == TGMediaAssetsControllerSendMediaIntent && _selectionContext.allowGrouping)
[[NSUserDefaults standardUserDefaults] setObject:@(!_selectionContext.grouping) forKey:@"TG_mediaGroupingDisabled_v0"]; [[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 + (int64_t)generateGroupedId
@ -843,7 +843,7 @@
return value; 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 *signals = [[NSMutableArray alloc] init];
NSMutableArray *selectedItems = selectionContext.selectedItems ? [selectionContext.selectedItems mutableCopy] : [[NSMutableArray alloc] init]; NSMutableArray *selectedItems = selectionContext.selectedItems ? [selectionContext.selectedItems mutableCopy] : [[NSMutableArray alloc] init];
@ -947,7 +947,7 @@
NSString *caption = [editingContext captionForItem:asset]; NSString *caption = [editingContext captionForItem:asset];
NSArray *entities = [editingContext entitiesForItem: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); NSString *tempFileName = TGTemporaryFileName(nil);
[assetData.imageData writeToURL:[NSURL fileURLWithPath:tempFileName] atomically:true]; [assetData.imageData writeToURL:[NSURL fileURLWithPath:tempFileName] atomically:true];

View File

@ -106,9 +106,6 @@
NSString *_forcedCaption; NSString *_forcedCaption;
NSArray *_forcedEntities; NSArray *_forcedEntities;
NSString *_initialCaption;
NSArray *_initialEntities;
} }
@end @end
@ -433,12 +430,6 @@
_forcedEntities = entities; _forcedEntities = entities;
} }
- (void)setInitialCaption:(NSString *)caption entities:(NSArray *)entities
{
_initialCaption = caption;
_initialEntities = entities;
}
- (SSignal *)captionSignalForItem:(NSObject<TGMediaEditableItem> *)item - (SSignal *)captionSignalForItem:(NSObject<TGMediaEditableItem> *)item
{ {
NSString *uniqueIdentifier = item.uniqueIdentifier; NSString *uniqueIdentifier = item.uniqueIdentifier;

View File

@ -76,7 +76,7 @@
self.scrollViewsForAutomaticInsetsAdjustment = @[ _collectionView ]; self.scrollViewsForAutomaticInsetsAdjustment = @[ _collectionView ];
self.explicitTableInset = UIEdgeInsetsMake(0, 0, TGMediaPickerToolbarHeight, 0); self.explicitTableInset = UIEdgeInsetsMake(0, 0, TGMediaPickerToolbarHeight, 0);
self.explicitScrollIndicatorInset = self.explicitTableInset; self.explicitScrollIndicatorInset = UIEdgeInsetsMake(14.0, 0, TGMediaPickerToolbarHeight, 0);
[self _setupSelectionGesture]; [self _setupSelectionGesture];

View File

@ -126,6 +126,14 @@ const CGFloat TGSelectionGestureVerticalFailureThreshold = 5.0f;
_gestureRecognizer.enabled = true; _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 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)__unused otherGestureRecognizer
{ {
if ([otherGestureRecognizer.view isKindOfClass:[UIScrollView class]]) if ([otherGestureRecognizer.view isKindOfClass:[UIScrollView class]])

View File

@ -24,6 +24,10 @@ CGSize TGPhotoThumbnailSizeForCurrentScreen()
if ([UIScreen mainScreen].scale >= 2.0f - FLT_EPSILON) 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) if (widescreenWidth >= 896.0f - FLT_EPSILON)
{ {
return CGSizeMake(137.0f - TGScreenPixel, 137.0f - TGScreenPixel); return CGSizeMake(137.0f - TGScreenPixel, 137.0f - TGScreenPixel);

View File

@ -1206,7 +1206,7 @@ static id<LegacyComponentsContext> _defaultContext = nil;
UIEdgeInsets finalInset = self.controllerInset; UIEdgeInsets finalInset = self.controllerInset;
scrollView.contentInset = finalInset; scrollView.contentInset = finalInset;
scrollView.scrollIndicatorInsets = self.controllerScrollInset; scrollView.scrollIndicatorInsets = _explicitScrollIndicatorInset;
if (!UIEdgeInsetsEqualToEdgeInsets(previousInset, UIEdgeInsetsZero)) if (!UIEdgeInsetsEqualToEdgeInsets(previousInset, UIEdgeInsetsZero))
{ {

View File

@ -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<PresentationData, NoError>), 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<PresentationData, NoError>), 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) let defaultVideoPreset = defaultVideoPresetForContext(context)
UserDefaults.standard.set(defaultVideoPreset.rawValue as NSNumber, forKey: "TG_preferredVideoPreset_v0") 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 carouselItem.sendPressed = { [weak controller, weak carouselItem] currentItem, asFiles, silentPosting, scheduleTime, isFromPicker in
if let controller = controller, let carouselItem = carouselItem { if let controller = controller, let carouselItem = carouselItem {
let intent: TGMediaAssetsControllerIntent = asFiles ? TGMediaAssetsControllerSendFileIntent : TGMediaAssetsControllerSendMediaIntent 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() presentCantSendMultipleFiles()
} else { } else {
sendMessagesWithSignals(signals, silentPosting, scheduleTime, isFromPicker ? nil : { [weak carouselItem] uniqueId in let process: (Bool) -> Void = { convert in
if let carouselItem = carouselItem { let signals = TGMediaAssetsController.resultSignals(for: carouselItem.selectionContext, editingContext: carouselItem.editingContext, intent: intent, currentItem: currentItem, storeAssets: true, convertToJpeg: convert, descriptionGenerator: legacyAssetPickerItemGenerator(), saveEditedPhotos: saveEditedPhotos)
return carouselItem.getItemSnapshot(uniqueId) sendMessagesWithSignals(signals, silentPosting, scheduleTime, isFromPicker ? nil : { [weak carouselItem] uniqueId in
} if let carouselItem = carouselItem {
return nil return carouselItem.getItemSnapshot(uniqueId)
}, { [weak controller] in }
controller?.dismiss(animated: true) return nil
}) }, { [weak controller] in
controller?.dismiss(animated: true)
})
}
if hasHeic && asFiles {
presentJpegConversionAlert({ convert in
process(convert)
})
} else {
process(false)
}
} }
} }
}; };
carouselItem.allowCaptions = true carouselItem.allowCaptions = true
carouselItem.editingContext.setInitialCaption(initialCaption, entities: []) carouselItem.editingContext.setForcedCaption(initialCaption, entities: [])
itemViews.append(carouselItem) itemViews.append(carouselItem)
let galleryItem = TGMenuSheetButtonItemView(title: editing ? presentationData.strings.Conversation_EditingMessageMediaChange : presentationData.strings.AttachmentMenu_PhotoOrVideo, type: TGMenuSheetButtonTypeDefault, fontSize: fontSize, action: { [weak controller] in 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 presentSchedulePicker { time in
done?(time) done?(time)
} }

View File

@ -60,7 +60,7 @@ public func configureLegacyAssetPicker(_ controller: TGMediaAssetsController, co
controller.shouldShowFileTipIfNeeded = showFileTooltip controller.shouldShowFileTipIfNeeded = showFileTooltip
controller.requestSearchController = presentWebSearch 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> { public func legacyAssetPicker(context: AccountContext, presentationData: PresentationData, editingMedia: Bool, fileMode: Bool, peer: Peer?, saveEditedPhotos: Bool, allowGrouping: Bool, selectionLimit: Int) -> Signal<(LegacyComponentsContext) -> TGMediaAssetsController, Void> {

View File

@ -551,19 +551,13 @@ public final class ShareController: ViewController {
case let .image(representations): case let .image(representations):
for peerId in peerIds { for peerId in peerIds {
var messages: [EnqueueMessage] = [] var messages: [EnqueueMessage] = []
if !text.isEmpty { 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))
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))
shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages)) shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages))
} }
case let .media(mediaReference): case let .media(mediaReference):
for peerId in peerIds { for peerId in peerIds {
var messages: [EnqueueMessage] = [] var messages: [EnqueueMessage] = []
if !text.isEmpty { messages.append(.message(text: text, attributes: [], mediaReference: mediaReference, replyToMessageId: nil, localGroupingKey: nil, correlationId: nil))
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))
shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages)) shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages))
} }
case let .mapMedia(media): case let .mapMedia(media):

View File

@ -5931,6 +5931,7 @@ public final class VoiceChatController: ViewController {
if bounds.minY < -60 || (bounds.minY < 0.0 && velocity.y > 300.0) { if bounds.minY < -60 || (bounds.minY < 0.0 && velocity.y > 300.0) {
if self.isScheduling { if self.isScheduling {
self.dismissScheduled() self.dismissScheduled()
dismissing = true
} else if case .regular = layout.metrics.widthClass { } else if case .regular = layout.metrics.widthClass {
self.controller?.dismiss(closing: false, manual: true) self.controller?.dismiss(closing: false, manual: true)
dismissing = true dismissing = true

View File

@ -8070,6 +8070,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
interfaceState = interfaceState.withUpdatedHistoryScrollState(scrollState) interfaceState = interfaceState.withUpdatedHistoryScrollState(scrollState)
} }
interfaceState = interfaceState.withUpdatedInputLanguage(self.chatDisplayNode.currentTextInputLanguage) 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 let _ = ChatInterfaceState.update(engine: self.context.engine, peerId: peerId, threadId: threadId, { _ in
return interfaceState return interfaceState
}).start() }).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: { 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 self?.presentMediaPicker(fileMode: false, editingMedia: editMediaOptions != nil, completion: { signals, silentPosting, scheduleTime in
if !inputText.string.isEmpty { if !inputText.string.isEmpty {
//strongSelf.clearInputText() strongSelf.clearInputText()
} }
if editMediaOptions != nil { if editMediaOptions != nil {
self?.editMessageMediaWithLegacySignals(signals) 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) strongSelf.enqueueMediaMessages(signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime > 0 ? scheduleTime : nil)
} }
if !inputText.string.isEmpty { if !inputText.string.isEmpty {
//strongSelf.clearInputText() strongSelf.clearInputText()
} }
} }
}, recognizedQRCode: { [weak self] code in }, recognizedQRCode: { [weak self] code in
if let strongSelf = self { if let strongSelf = self {
if let (host, port, username, password, secret) = parseProxyUrl(code) { if let (host, port, username, password, secret) = parseProxyUrl(code) {
strongSelf.openResolved(ResolvedUrl.proxy(host: host, port: port, username: username, password: password, secret: secret)) 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 }, presentSchedulePicker: { [weak self] done in
if let strongSelf = self { if let strongSelf = self {
@ -9385,6 +9386,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return 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)) 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 }, presentSchedulePicker: { [weak self] done in
if let strongSelf = self { if let strongSelf = self {
strongSelf.presentScheduleTimePicker(style: .media, completion: { [weak self] time in strongSelf.presentScheduleTimePicker(style: .media, completion: { [weak self] time in
@ -9408,7 +9415,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return return
} }
if !inputText.string.isEmpty { if !inputText.string.isEmpty {
//strongSelf.clearInputText() strongSelf.clearInputText()
} }
if editMediaOptions != nil { if editMediaOptions != nil {
strongSelf.editMessageMediaWithLegacySignals(signals!) strongSelf.editMessageMediaWithLegacySignals(signals!)
@ -11592,6 +11599,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}) })
let commit: ([EnqueueMessage]) -> Void = { result in let commit: ([EnqueueMessage]) -> Void = { result in
strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }).updatedSearch(nil) })
var displayPeers: [Peer] = [] var displayPeers: [Peer] = []
for peer in peers { for peer in peers {
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: result) let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peer.id, messages: result)

View File

@ -1,5 +1,5 @@
{ {
"app": "8.1", "app": "8.1.2",
"bazel": "4.0.0", "bazel": "4.0.0",
"xcode": "12.5.1" "xcode": "12.5.1"
} }