mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-02-05 18:58:51 +00:00
Merge commit '13b718d77bb4a218636988a1384328198d09a2d6'
This commit is contained in:
@@ -25,6 +25,8 @@
|
||||
@property (nonatomic) bool inhibitDocumentCaptions;
|
||||
@property (nonatomic) bool hasTimer;
|
||||
@property (nonatomic) bool onlyCrop;
|
||||
@property (nonatomic) bool asFile;
|
||||
@property (nonatomic) bool inhibitMute;
|
||||
|
||||
@property (nonatomic, strong) NSArray *underlyingViews;
|
||||
@property (nonatomic, assign) bool openEditor;
|
||||
@@ -38,6 +40,7 @@
|
||||
|
||||
@property (nonatomic, assign) CGFloat remainingHeight;
|
||||
@property (nonatomic, assign) bool condensed;
|
||||
@property (nonatomic, assign) bool collapsed;
|
||||
|
||||
@property (nonatomic, strong) NSString *recipientName;
|
||||
|
||||
|
||||
@@ -645,6 +645,11 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
|
||||
|
||||
- (CGFloat)preferredHeightForWidth:(CGFloat)__unused width screenHeight:(CGFloat)screenHeight
|
||||
{
|
||||
if (_collapsed) {
|
||||
self.alpha = 0.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
CGFloat progress = _zoomingIn ? _zoomingProgress : 1.0f;
|
||||
return [self _preferredHeightForZoomedIn:_zoomedIn progress:progress screenHeight:screenHeight];
|
||||
}
|
||||
@@ -763,8 +768,9 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
|
||||
__strong TGAttachmentCarouselItemView *strongSelf = weakSelf;
|
||||
if (strongSelf != nil && strongSelf.sendPressed != nil)
|
||||
{
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@(!strongSelf->_selectionContext.grouping) forKey:@"TG_mediaGroupingDisabled_v0"];
|
||||
strongSelf.sendPressed(item.asset, false);
|
||||
if (strongSelf->_selectionContext.allowGrouping)
|
||||
[[NSUserDefaults standardUserDefaults] setObject:@(!strongSelf->_selectionContext.grouping) forKey:@"TG_mediaGroupingDisabled_v0"];
|
||||
strongSelf.sendPressed(item.asset, strongSelf.asFile);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -784,7 +790,7 @@ const NSUInteger TGAttachmentDisplayedAssetLimit = 500;
|
||||
if ([cell isKindOfClass:[TGAttachmentAssetCell class]])
|
||||
thumbnailImage = cell.imageView.image;
|
||||
|
||||
TGMediaPickerModernGalleryMixin *mixin = [[TGMediaPickerModernGalleryMixin alloc] initWithContext:_context item:asset fetchResult:_fetchResult parentController:self.parentController thumbnailImage:thumbnailImage selectionContext:_selectionContext editingContext:_editingContext suggestionContext:self.suggestionContext hasCaptions:(_allowCaptions && !_forProfilePhoto) allowCaptionEntities:self.allowCaptionEntities hasTimer:self.hasTimer onlyCrop:self.onlyCrop inhibitDocumentCaptions:_inhibitDocumentCaptions asFile:false itemsLimit:TGAttachmentDisplayedAssetLimit recipientName:self.recipientName];
|
||||
TGMediaPickerModernGalleryMixin *mixin = [[TGMediaPickerModernGalleryMixin alloc] initWithContext:_context item:asset fetchResult:_fetchResult parentController:self.parentController thumbnailImage:thumbnailImage selectionContext:_selectionContext editingContext:_editingContext suggestionContext:self.suggestionContext hasCaptions:(_allowCaptions && !_forProfilePhoto) allowCaptionEntities:self.allowCaptionEntities hasTimer:self.hasTimer onlyCrop:self.onlyCrop inhibitDocumentCaptions:_inhibitDocumentCaptions inhibitMute:self.inhibitMute asFile:self.asFile itemsLimit:TGAttachmentDisplayedAssetLimit recipientName:self.recipientName];
|
||||
|
||||
__weak TGAttachmentCarouselItemView *weakSelf = self;
|
||||
mixin.thumbnailSignalForItem = ^SSignal *(id item)
|
||||
|
||||
@@ -737,7 +737,12 @@ static NSFileManager *cacheFileManager = nil;
|
||||
dispatch_async([TGCache diskCacheQueue], ^
|
||||
{
|
||||
NSError *error = nil;
|
||||
[cacheFileManager moveItemAtPath:fileUrl toPath:[_diskCachePath stringByAppendingPathComponent:md5String(cacheUrl)] error:&error];
|
||||
|
||||
NSString *targetPath = [_diskCachePath stringByAppendingPathComponent:md5String(cacheUrl)];
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:targetPath])
|
||||
[[NSFileManager defaultManager] removeItemAtPath:targetPath error:NULL];
|
||||
|
||||
[cacheFileManager moveItemAtPath:fileUrl toPath:targetPath error:&error];
|
||||
if (error != nil)
|
||||
TGLegacyLog(@"Failed to move: %@", error);
|
||||
});
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
@property (nonatomic, readonly) PGCameraShotMetadata *metadata;
|
||||
|
||||
- (instancetype)initWithImage:(UIImage *)image metadata:(PGCameraShotMetadata *)metadata;
|
||||
- (instancetype)initWithExistingImage:(UIImage *)image;
|
||||
|
||||
- (void)_cleanUp;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
NSString *_identifier;
|
||||
CGSize _dimensions;
|
||||
|
||||
UIImage *_existingImage;
|
||||
SVariable *_thumbnail;
|
||||
UIImage *_thumbImage;
|
||||
}
|
||||
@@ -31,6 +32,33 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithExistingImage:(UIImage *)image
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
_identifier = [NSString stringWithFormat:@"%ld", lrand48()];
|
||||
_dimensions = CGSizeMake(image.size.width, image.size.height);
|
||||
_thumbnail = [[SVariable alloc] init];
|
||||
|
||||
_existingImage = image;
|
||||
SSignal *thumbnailSignal = [[[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
||||
{
|
||||
CGFloat thumbnailImageSide = TGPhotoThumbnailSizeForCurrentScreen().width * TGScreenScaling();
|
||||
CGSize thumbnailSize = TGScaleToSize(image.size, CGSizeMake(thumbnailImageSide, thumbnailImageSide));
|
||||
UIImage *thumbnailImage = TGScaleImageToPixelSize(image, thumbnailSize);
|
||||
|
||||
[subscriber putNext:thumbnailImage];
|
||||
[subscriber putCompletion];
|
||||
|
||||
return nil;
|
||||
}] startOn:[SQueue concurrentDefaultQueue]];
|
||||
|
||||
[_thumbnail set:thumbnailSignal];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)_cleanUp
|
||||
{
|
||||
[[NSFileManager defaultManager] removeItemAtPath:[self filePath] error:nil];
|
||||
@@ -108,59 +136,73 @@
|
||||
|
||||
- (SSignal *)screenImageSignal:(NSTimeInterval)__unused position
|
||||
{
|
||||
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
||||
if (_existingImage != nil)
|
||||
{
|
||||
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:[self filePath]], NULL);
|
||||
if (imageSource == NULL)
|
||||
return [SSignal single:_existingImage];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
||||
{
|
||||
[subscriber putError:nil];
|
||||
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:[self filePath]], NULL);
|
||||
if (imageSource == NULL)
|
||||
{
|
||||
[subscriber putError:nil];
|
||||
return nil;
|
||||
}
|
||||
|
||||
CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, (__bridge CFDictionaryRef)@
|
||||
{
|
||||
(id)kCGImageSourceShouldAllowFloat : (id)kCFBooleanTrue,
|
||||
(id)kCGImageSourceCreateThumbnailWithTransform : (id)kCFBooleanFalse,
|
||||
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent : (id)kCFBooleanTrue,
|
||||
(id)kCGImageSourceThumbnailMaxPixelSize : @(1600)
|
||||
});
|
||||
if (imageRef == NULL)
|
||||
imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, nil);
|
||||
|
||||
UIImage *image = [UIImage imageWithCGImage:imageRef];
|
||||
CGImageRelease(imageRef);
|
||||
CFRelease(imageSource);
|
||||
|
||||
[subscriber putNext:image];
|
||||
[subscriber putCompletion];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
CGImageRef imageRef = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, (__bridge CFDictionaryRef)@
|
||||
{
|
||||
(id)kCGImageSourceShouldAllowFloat : (id)kCFBooleanTrue,
|
||||
(id)kCGImageSourceCreateThumbnailWithTransform : (id)kCFBooleanFalse,
|
||||
(id)kCGImageSourceCreateThumbnailFromImageIfAbsent : (id)kCFBooleanTrue,
|
||||
(id)kCGImageSourceThumbnailMaxPixelSize : @(1600)
|
||||
});
|
||||
if (imageRef == NULL)
|
||||
imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, nil);
|
||||
|
||||
UIImage *image = [UIImage imageWithCGImage:imageRef];
|
||||
CGImageRelease(imageRef);
|
||||
CFRelease(imageSource);
|
||||
|
||||
[subscriber putNext:image];
|
||||
[subscriber putCompletion];
|
||||
|
||||
return nil;
|
||||
}];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (SSignal *)originalImageSignal:(NSTimeInterval)__unused position
|
||||
{
|
||||
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
||||
if (_existingImage != nil)
|
||||
{
|
||||
NSData *data = [[NSData alloc] initWithContentsOfFile:[self filePath] options:NSDataReadingMappedIfSafe error:NULL];
|
||||
if (data.length == 0)
|
||||
return [SSignal single:_existingImage];
|
||||
}
|
||||
else
|
||||
{
|
||||
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
||||
{
|
||||
[subscriber putError:nil];
|
||||
NSData *data = [[NSData alloc] initWithContentsOfFile:[self filePath] options:NSDataReadingMappedIfSafe error:NULL];
|
||||
if (data.length == 0)
|
||||
{
|
||||
[subscriber putError:nil];
|
||||
return nil;
|
||||
}
|
||||
|
||||
UIImage *image = [[UIImage alloc] initWithData:data];
|
||||
if (image == nil)
|
||||
{
|
||||
[subscriber putError:nil];
|
||||
return nil;
|
||||
}
|
||||
|
||||
[subscriber putNext:image];
|
||||
[subscriber putCompletion];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
UIImage *image = [[UIImage alloc] initWithData:data];
|
||||
if (image == nil)
|
||||
{
|
||||
[subscriber putError:nil];
|
||||
return nil;
|
||||
}
|
||||
|
||||
[subscriber putNext:image];
|
||||
[subscriber putCompletion];
|
||||
|
||||
return nil;
|
||||
}];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -31,10 +31,15 @@ typedef enum {
|
||||
@property (nonatomic, assign) bool allowCaptionEntities;
|
||||
@property (nonatomic, assign) bool allowGrouping;
|
||||
@property (nonatomic, assign) bool inhibitDocumentCaptions;
|
||||
@property (nonatomic, assign) bool inhibitMultipleCapture;
|
||||
@property (nonatomic, assign) bool inhibitMute;
|
||||
@property (nonatomic, assign) bool hasTimer;
|
||||
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
|
||||
@property (nonatomic, assign) bool shortcut;
|
||||
|
||||
@property (nonatomic, strong) NSString *forcedCaption;
|
||||
@property (nonatomic, strong) NSArray *forcedEntities;
|
||||
|
||||
@property (nonatomic, strong) NSString *recipientName;
|
||||
|
||||
@property (nonatomic, copy) void(^finishedWithResults)(TGOverlayController *controller, TGMediaSelectionContext *selectionContext, TGMediaEditingContext *editingContext, id<TGMediaSelectableItem> currentItem);
|
||||
|
||||
@@ -1146,6 +1146,8 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
if (editingContext == nil)
|
||||
{
|
||||
editingContext = [[TGMediaEditingContext alloc] init];
|
||||
if (self.forcedCaption != nil)
|
||||
[editingContext setForcedCaption:self.forcedCaption entities:self.forcedEntities];
|
||||
_editingContext = editingContext;
|
||||
_interfaceView.editingContext = editingContext;
|
||||
}
|
||||
@@ -1229,8 +1231,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
}
|
||||
}];
|
||||
|
||||
bool hasCamera = (_intent == TGCameraControllerGenericIntent && !_shortcut) || (_intent == TGCameraControllerPassportMultipleIntent);
|
||||
bool hasCamera = !self.inhibitMultipleCapture && ((_intent == TGCameraControllerGenericIntent && !_shortcut) || (_intent == TGCameraControllerPassportMultipleIntent));
|
||||
TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:windowContext items:galleryItems focusItem:focusItem selectionContext:_items.count > 1 ? selectionContext : nil editingContext:editingContext hasCaptions:self.allowCaptions allowCaptionEntities:self.allowCaptionEntities hasTimer:self.hasTimer onlyCrop:_intent == TGCameraControllerPassportIntent || _intent == TGCameraControllerPassportIdIntent || _intent == TGCameraControllerPassportMultipleIntent inhibitDocumentCaptions:self.inhibitDocumentCaptions hasSelectionPanel:true hasCamera:hasCamera recipientName:self.recipientName];
|
||||
model.inhibitMute = self.inhibitMute;
|
||||
model.controller = galleryController;
|
||||
model.suggestionContext = self.suggestionContext;
|
||||
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
[data appendBytes:&length length:4];
|
||||
[data appendData:phoneData];
|
||||
|
||||
NSData *vcardData = [_vcard dataUsingEncoding:NSUTF8StringEncoding];
|
||||
length = (int)vcardData.length;
|
||||
[data appendBytes:&length length:4];
|
||||
[data appendData:vcardData];
|
||||
|
||||
int dataLength = (int)data.length - dataLengthPtr - 4;
|
||||
[data replaceBytesInRange:NSMakeRange(dataLengthPtr, 4) withBytes:&dataLength];
|
||||
}
|
||||
@@ -47,32 +52,47 @@
|
||||
- (TGMediaAttachment *)parseMediaAttachment:(NSInputStream *)is
|
||||
{
|
||||
int dataLength = 0;
|
||||
int read = 0;
|
||||
[is read:(uint8_t *)&dataLength maxLength:4];
|
||||
|
||||
TGContactMediaAttachment *contactAttachment = [[TGContactMediaAttachment alloc] init];
|
||||
|
||||
int uid = 0;
|
||||
[is read:(uint8_t *)&uid maxLength:4];
|
||||
read += 4;
|
||||
contactAttachment.uid = uid;
|
||||
|
||||
int length = 0;
|
||||
[is read:(uint8_t *)&length maxLength:4];
|
||||
uint8_t *firstNameBytes = malloc(length);
|
||||
[is read:firstNameBytes maxLength:length];
|
||||
read += length + 4;
|
||||
contactAttachment.firstName = [[NSString alloc] initWithBytesNoCopy:firstNameBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
|
||||
|
||||
length = 0;
|
||||
[is read:(uint8_t *)&length maxLength:4];
|
||||
uint8_t *lastNameBytes = malloc(length);
|
||||
[is read:lastNameBytes maxLength:length];
|
||||
read += length + 4;
|
||||
contactAttachment.lastName = [[NSString alloc] initWithBytesNoCopy:lastNameBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
|
||||
|
||||
length = 0;
|
||||
[is read:(uint8_t *)&length maxLength:4];
|
||||
uint8_t *phoneBytes = malloc(length);
|
||||
[is read:phoneBytes maxLength:length];
|
||||
read += length + 4;
|
||||
contactAttachment.phoneNumber = [[NSString alloc] initWithBytesNoCopy:phoneBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
|
||||
|
||||
if (read < dataLength)
|
||||
{
|
||||
length = 0;
|
||||
[is read:(uint8_t *)&length maxLength:4];
|
||||
uint8_t *vcardBytes = malloc(length);
|
||||
[is read:vcardBytes maxLength:length];
|
||||
read += length;
|
||||
contactAttachment.vcard = [[NSString alloc] initWithBytesNoCopy:vcardBytes length:length encoding:NSUTF8StringEncoding freeWhenDone:true];
|
||||
}
|
||||
|
||||
return contactAttachment;
|
||||
}
|
||||
|
||||
@@ -84,6 +104,7 @@
|
||||
_firstName = [aDecoder decodeObjectForKey:@"firstName"];
|
||||
_lastName = [aDecoder decodeObjectForKey:@"lastName"];
|
||||
_phoneNumber = [aDecoder decodeObjectForKey:@"phoneNumber"];
|
||||
_vcard = [aDecoder decodeObjectForKey:@"vcard"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -93,6 +114,7 @@
|
||||
[aCoder encodeObject:_firstName forKey:@"firstName"];
|
||||
[aCoder encodeObject:_lastName forKey:@"lastName"];
|
||||
[aCoder encodeObject:_phoneNumber forKey:@"phoneNumber"];
|
||||
[aCoder encodeObject:_vcard forKey:@"vcard"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -144,6 +144,9 @@
|
||||
{
|
||||
[super _watermarkAction];
|
||||
|
||||
if (self.onWatermarkAction != nil)
|
||||
self.onWatermarkAction();
|
||||
|
||||
NSString *permalink = _permalink;
|
||||
NSString *coubId = nil;
|
||||
if ([_asset isKindOfClass:[CBCoubNew class]])
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
|
||||
@property (nonatomic, assign) CGRect initialFrame;
|
||||
|
||||
@property (nonatomic, copy) void (^onWatermarkAction)(void);
|
||||
|
||||
@property (nonatomic, copy) void (^requestFullscreen)(NSTimeInterval duration);
|
||||
@property (nonatomic, copy) void (^onMetadataLoaded)(NSString *title, NSString *subtitle);
|
||||
|
||||
|
||||
@@ -199,7 +199,6 @@
|
||||
[_jsQueue dispatchSync:^
|
||||
{
|
||||
wkWebView.navigationDelegate = nil;
|
||||
[wkWebView removeObserver:self forKeyPath:@"estimatedProgress"];
|
||||
}];
|
||||
|
||||
_uiWebView.delegate = nil;
|
||||
@@ -466,15 +465,6 @@
|
||||
else
|
||||
[_wkWebView loadHTMLString:embedHTML baseURL:[self _baseURL]];
|
||||
}];
|
||||
|
||||
[_wkWebView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:NULL];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
|
||||
if ([keyPath isEqualToString:@"estimatedProgress"] && object == _wkWebView)
|
||||
return;
|
||||
else
|
||||
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
|
||||
}
|
||||
|
||||
- (void)webView:(WKWebView *)__unused webView didStartProvisionalNavigation:(WKNavigation *)__unused navigation
|
||||
@@ -848,7 +838,6 @@
|
||||
- (void)_cleanWebView
|
||||
{
|
||||
_wkWebView.navigationDelegate = nil;
|
||||
[_wkWebView removeObserver:self forKeyPath:@"estimatedProgress"];
|
||||
[_wkWebView removeFromSuperview];
|
||||
_wkWebView = nil;
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ NSString *const TGVinePlayerCallbackOnPlayback = @"onPlayback";
|
||||
{
|
||||
[super _watermarkAction];
|
||||
|
||||
if (self.onWatermarkAction != nil)
|
||||
self.onWatermarkAction();
|
||||
|
||||
NSString *videoId = _videoId;
|
||||
|
||||
NSURL *appUrl = [[NSURL alloc] initWithString:[[NSString alloc] initWithFormat:@"vine://post/%@", videoId]];
|
||||
|
||||
@@ -65,10 +65,12 @@ const NSInteger TGYTPlayerStateBufferingCode = 3;
|
||||
{
|
||||
[super _watermarkAction];
|
||||
|
||||
if (self.onWatermarkAction != nil)
|
||||
self.onWatermarkAction();
|
||||
|
||||
NSString *videoId = _playerParams[@"videoId"];
|
||||
|
||||
NSURL *appUrl = [[NSURL alloc] initWithString:[[NSString alloc] initWithFormat:@"youtube-x-callback://watch?v=%@&x-success=telegram://1&x-source=Telegram", videoId]];
|
||||
|
||||
NSURL *appUrl = [[NSURL alloc] initWithString:[[NSString alloc] initWithFormat:@"youtube://watch?v=%@", videoId]];
|
||||
if ([[LegacyComponentsGlobals provider] canOpenURL:appUrl])
|
||||
{
|
||||
[[LegacyComponentsGlobals provider] openURL:appUrl];
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
@interface TGLocationSignals : NSObject
|
||||
|
||||
+ (SSignal *)geocodeAddress:(NSString *)address;
|
||||
+ (SSignal *)geocodeAddressDictionary:(NSDictionary *)dictionary;
|
||||
|
||||
+ (SSignal *)reverseGeocodeCoordinate:(CLLocationCoordinate2D)coordinate;
|
||||
+ (SSignal *)cityForCoordinate:(CLLocationCoordinate2D)coordinate;
|
||||
+ (SSignal *)driveEta:(CLLocationCoordinate2D)coordinate;
|
||||
|
||||
@@ -78,6 +78,58 @@ NSString *const TGLocationGoogleGeocodeLocale = @"en";
|
||||
|
||||
@implementation TGLocationSignals
|
||||
|
||||
+ (SSignal *)geocodeAddress:(NSString *)address
|
||||
{
|
||||
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
||||
{
|
||||
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
|
||||
[geocoder geocodeAddressString:address completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error)
|
||||
{
|
||||
if (error != nil)
|
||||
{
|
||||
[subscriber putError:error];
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
[subscriber putNext:placemarks.firstObject];
|
||||
[subscriber putCompletion];
|
||||
}
|
||||
}];
|
||||
|
||||
return [[SBlockDisposable alloc] initWithBlock:^
|
||||
{
|
||||
[geocoder cancelGeocode];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (SSignal *)geocodeAddressDictionary:(NSDictionary *)dictionary
|
||||
{
|
||||
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
||||
{
|
||||
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
|
||||
[geocoder geocodeAddressDictionary:dictionary completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error)
|
||||
{
|
||||
if (error != nil)
|
||||
{
|
||||
[subscriber putError:error];
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
[subscriber putNext:placemarks.firstObject];
|
||||
[subscriber putCompletion];
|
||||
}
|
||||
}];
|
||||
|
||||
return [[SBlockDisposable alloc] initWithBlock:^
|
||||
{
|
||||
[geocoder cancelGeocode];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (SSignal *)reverseGeocodeCoordinate:(CLLocationCoordinate2D)coordinate
|
||||
{
|
||||
NSURL *url = [NSURL URLWithString:[[NSString alloc] initWithFormat:@"https://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=true&language=%@", coordinate.latitude, coordinate.longitude, TGLocationGoogleGeocodeLocale]];
|
||||
|
||||
@@ -43,15 +43,16 @@ typedef enum
|
||||
|
||||
@property (nonatomic, strong) TGMediaAssetsPallete *pallete;
|
||||
|
||||
@property (nonatomic, readonly) TGMediaEditingContext *editingContext;
|
||||
@property (nonatomic, strong) TGSuggestionContext *suggestionContext;
|
||||
@property (nonatomic, assign) bool localMediaCacheEnabled;
|
||||
@property (nonatomic, assign) bool captionsEnabled;
|
||||
@property (nonatomic, assign) bool allowCaptionEntities;
|
||||
@property (nonatomic, assign) bool inhibitDocumentCaptions;
|
||||
@property (nonatomic, assign) bool shouldStoreAssets;
|
||||
|
||||
@property (nonatomic, assign) bool hasTimer;
|
||||
@property (nonatomic, assign) bool onlyCrop;
|
||||
@property (nonatomic, assign) bool inhibitMute;
|
||||
|
||||
@property (nonatomic, assign) bool liveVideoUploadEnabled;
|
||||
@property (nonatomic, assign) bool shouldShowFileTipIfNeeded;
|
||||
@@ -77,6 +78,7 @@ typedef enum
|
||||
- (void)completeWithCurrentItem:(TGMediaAsset *)currentItem;
|
||||
|
||||
+ (instancetype)controllerWithContext:(id<LegacyComponentsContext>)context assetGroup:(TGMediaAssetGroup *)assetGroup intent:(TGMediaAssetsControllerIntent)intent recipientName:(NSString *)recipientName saveEditedPhotos:(bool)saveEditedPhotos allowGrouping:(bool)allowGrouping;
|
||||
+ (instancetype)controllerWithContext:(id<LegacyComponentsContext>)context assetGroup:(TGMediaAssetGroup *)assetGroup intent:(TGMediaAssetsControllerIntent)intent recipientName:(NSString *)recipientName saveEditedPhotos:(bool)saveEditedPhotos allowGrouping:(bool)allowGrouping inhibitSelection:(bool)inhibitSelection;
|
||||
|
||||
+ (TGMediaAssetType)assetTypeForIntent:(TGMediaAssetsControllerIntent)intent;
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
|
||||
TGMediaPickerToolbarView *_toolbarView;
|
||||
TGMediaSelectionContext *_selectionContext;
|
||||
TGMediaEditingContext *_editingContext;
|
||||
|
||||
SMetaDisposable *_groupingChangedDisposable;
|
||||
SMetaDisposable *_selectionChangedDisposable;
|
||||
@@ -62,6 +61,11 @@
|
||||
@implementation TGMediaAssetsController
|
||||
|
||||
+ (instancetype)controllerWithContext:(id<LegacyComponentsContext>)context assetGroup:(TGMediaAssetGroup *)assetGroup intent:(TGMediaAssetsControllerIntent)intent recipientName:(NSString *)recipientName saveEditedPhotos:(bool)saveEditedPhotos allowGrouping:(bool)allowGrouping
|
||||
{
|
||||
return [self controllerWithContext:context assetGroup:assetGroup intent:intent recipientName:recipientName saveEditedPhotos:saveEditedPhotos allowGrouping:allowGrouping inhibitSelection:false];
|
||||
}
|
||||
|
||||
+ (instancetype)controllerWithContext:(id<LegacyComponentsContext>)context assetGroup:(TGMediaAssetGroup *)assetGroup intent:(TGMediaAssetsControllerIntent)intent recipientName:(NSString *)recipientName saveEditedPhotos:(bool)saveEditedPhotos allowGrouping:(bool)allowGrouping inhibitSelection:(bool)inhibitSelection
|
||||
{
|
||||
if (intent != TGMediaAssetsControllerSendMediaIntent)
|
||||
allowGrouping = false;
|
||||
@@ -104,18 +108,15 @@
|
||||
|
||||
if ([group isKindOfClass:[TGMediaAssetGroup class]])
|
||||
{
|
||||
pickerController = [[TGMediaAssetsPickerController alloc] initWithContext:strongController->_context assetsLibrary:strongController.assetsLibrary assetGroup:group intent:intent selectionContext:strongController->_selectionContext editingContext:strongController->_editingContext saveEditedPhotos:strongController->_saveEditedPhotos];
|
||||
pickerController = [[TGMediaAssetsPickerController alloc] initWithContext:strongController->_context assetsLibrary:strongController.assetsLibrary assetGroup:group intent:intent selectionContext:inhibitSelection ? nil : strongController->_selectionContext editingContext:strongController->_editingContext saveEditedPhotos:strongController->_saveEditedPhotos];
|
||||
pickerController.pallete = strongController.pallete;
|
||||
}
|
||||
else if ([group isKindOfClass:[TGMediaAssetMomentList class]])
|
||||
{
|
||||
pickerController = [[TGMediaAssetsMomentsController alloc] initWithContext:strongController->_context assetsLibrary:strongController.assetsLibrary momentList:group intent:intent selectionContext:strongController->_selectionContext editingContext:strongController->_editingContext saveEditedPhotos:strongController->_saveEditedPhotos];
|
||||
}
|
||||
pickerController.suggestionContext = strongController.suggestionContext;
|
||||
pickerController.localMediaCacheEnabled = strongController.localMediaCacheEnabled;
|
||||
pickerController.captionsEnabled = strongController.captionsEnabled;
|
||||
pickerController.allowCaptionEntities = strongController.allowCaptionEntities;
|
||||
pickerController.inhibitDocumentCaptions = strongController.inhibitDocumentCaptions;
|
||||
pickerController.inhibitMute = strongController.inhibitMute;
|
||||
pickerController.liveVideoUploadEnabled = strongController.liveVideoUploadEnabled;
|
||||
pickerController.catchToolbarView = catchToolbarView;
|
||||
pickerController.recipientName = recipientName;
|
||||
@@ -125,7 +126,7 @@
|
||||
};
|
||||
[groupsController loadViewIfNeeded];
|
||||
|
||||
TGMediaAssetsPickerController *pickerController = [[TGMediaAssetsPickerController alloc] initWithContext:context assetsLibrary:assetsController.assetsLibrary assetGroup:assetGroup intent:intent selectionContext:assetsController->_selectionContext editingContext:assetsController->_editingContext saveEditedPhotos:saveEditedPhotos];
|
||||
TGMediaAssetsPickerController *pickerController = [[TGMediaAssetsPickerController alloc] initWithContext:context assetsLibrary:assetsController.assetsLibrary assetGroup:assetGroup intent:intent selectionContext:inhibitSelection ? nil : assetsController->_selectionContext editingContext:assetsController->_editingContext saveEditedPhotos:saveEditedPhotos];
|
||||
pickerController.pallete = assetsController.pallete;
|
||||
pickerController.catchToolbarView = catchToolbarView;
|
||||
|
||||
@@ -164,6 +165,12 @@
|
||||
self.pickerController.inhibitDocumentCaptions = inhibitDocumentCaptions;
|
||||
}
|
||||
|
||||
- (void)setInhibitMute:(bool)inhibitMute
|
||||
{
|
||||
_inhibitMute = inhibitMute;
|
||||
self.pickerController.inhibitMute = inhibitMute;
|
||||
}
|
||||
|
||||
- (void)setLiveVideoUploadEnabled:(bool)liveVideoUploadEnabled
|
||||
{
|
||||
_liveVideoUploadEnabled = liveVideoUploadEnabled;
|
||||
@@ -353,7 +360,7 @@
|
||||
_toolbarView.pallete = _pallete;
|
||||
_toolbarView.safeAreaInset = [TGViewController safeAreaInsetForOrientation:self.interfaceOrientation];
|
||||
_toolbarView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
|
||||
if (_intent != TGMediaAssetsControllerSendFileIntent && _intent != TGMediaAssetsControllerSendMediaIntent)
|
||||
if ((_intent != TGMediaAssetsControllerSendFileIntent && _intent != TGMediaAssetsControllerSendMediaIntent) || _selectionContext == nil)
|
||||
[_toolbarView setRightButtonHidden:true];
|
||||
if (_selectionContext.allowGrouping)
|
||||
{
|
||||
@@ -519,7 +526,7 @@
|
||||
if (selectedItems.count == 0 && currentItem != nil)
|
||||
[selectedItems addObject:currentItem];
|
||||
|
||||
if (saveEditedPhotos && storeAssets)
|
||||
if (saveEditedPhotos && storeAssets && editingContext != nil)
|
||||
{
|
||||
NSMutableArray *fullSizeSignals = [[NSMutableArray alloc] init];
|
||||
for (TGMediaAsset *asset in selectedItems)
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
|
||||
- (TGMediaPickerModernGalleryMixin *)_galleryMixinForItem:(id)item thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaption allowCaptionEntities:(bool)allowCaptionEntities asFile:(bool)asFile
|
||||
{
|
||||
return [[TGMediaPickerModernGalleryMixin alloc] initWithContext:_context item:item momentList:_momentList parentController:self thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaption allowCaptionEntities:allowCaptionEntities hasTimer:false onlyCrop:false inhibitDocumentCaptions:false asFile:asFile itemsLimit:0];
|
||||
return [[TGMediaPickerModernGalleryMixin alloc] initWithContext:_context item:item momentList:_momentList parentController:self thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaption allowCaptionEntities:allowCaptionEntities hasTimer:false onlyCrop:false inhibitDocumentCaptions:false inhibitMute:false asFile:asFile itemsLimit:0];
|
||||
}
|
||||
|
||||
- (id)_itemAtIndexPath:(NSIndexPath *)indexPath
|
||||
|
||||
@@ -258,7 +258,7 @@
|
||||
return TGMediaAssetsVideoCellKind;
|
||||
|
||||
case TGMediaAssetGifType:
|
||||
if (_intent == TGMediaAssetsControllerSetProfilePhotoIntent || _intent == TGMediaAssetsControllerPassportIntent || TGMediaAssetsControllerPassportMultipleIntent)
|
||||
if (_intent == TGMediaAssetsControllerSetProfilePhotoIntent || _intent == TGMediaAssetsControllerPassportIntent || _intent == TGMediaAssetsControllerPassportMultipleIntent)
|
||||
return TGMediaAssetsPhotoCellKind;
|
||||
else
|
||||
return TGMediaAssetsGifCellKind;
|
||||
@@ -321,7 +321,7 @@
|
||||
|
||||
- (TGMediaPickerModernGalleryMixin *)_galleryMixinForContext:(id<LegacyComponentsContext>)context item:(id)item thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities inhibitDocumentCaptions:(bool)inhibitDocumentCaptions asFile:(bool)asFile
|
||||
{
|
||||
return [[TGMediaPickerModernGalleryMixin alloc] initWithContext:context item:item fetchResult:_fetchResult parentController:self thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:self.hasTimer onlyCrop:self.onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions asFile:asFile itemsLimit:0 recipientName:self.recipientName];
|
||||
return [[TGMediaPickerModernGalleryMixin alloc] initWithContext:context item:item fetchResult:_fetchResult parentController:self thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:self.hasTimer onlyCrop:self.onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions inhibitMute:self.inhibitMute asFile:asFile itemsLimit:0 recipientName:self.recipientName];
|
||||
}
|
||||
|
||||
- (TGMediaPickerModernGalleryMixin *)galleryMixinForIndexPath:(NSIndexPath *)indexPath previewMode:(bool)previewMode outAsset:(TGMediaAsset **)outAsset
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
- (SSignal *)captionSignalForItem:(NSObject<TGMediaEditableItem> *)item;
|
||||
- (void)setCaption:(NSString *)caption entities:(NSArray *)entities forItem:(NSObject<TGMediaEditableItem> *)item;
|
||||
|
||||
- (void)setForcedCaption:(NSString *)caption entities:(NSArray *)entities;
|
||||
|
||||
- (NSObject<TGMediaEditAdjustments> *)adjustmentsForItem:(NSObject<TGMediaEditableItem> *)item;
|
||||
- (SSignal *)adjustmentsSignalForItem:(NSObject<TGMediaEditableItem> *)item;
|
||||
- (void)setAdjustments:(NSObject<TGMediaEditAdjustments> *)adjustments forItem:(NSObject<TGMediaEditableItem> *)item;
|
||||
|
||||
@@ -99,6 +99,9 @@
|
||||
SPipe *_timerPipe;
|
||||
SPipe *_fullSizePipe;
|
||||
SPipe *_cropPipe;
|
||||
|
||||
NSString *_forcedCaption;
|
||||
NSArray *_forcedEntities;
|
||||
}
|
||||
@end
|
||||
|
||||
@@ -338,6 +341,9 @@
|
||||
|
||||
- (NSString *)captionForItem:(id<TGMediaEditableItem>)item
|
||||
{
|
||||
if (_forcedCaption != nil)
|
||||
return _forcedCaption;
|
||||
|
||||
NSString *itemId = [self _contextualIdForItemId:item.uniqueIdentifier];
|
||||
if (itemId == nil)
|
||||
return nil;
|
||||
@@ -347,6 +353,9 @@
|
||||
|
||||
- (NSArray *)entitiesForItem:(NSObject<TGMediaEditableItem> *)item
|
||||
{
|
||||
if (_forcedCaption != nil)
|
||||
return _forcedEntities;
|
||||
|
||||
NSString *itemId = [self _contextualIdForItemId:item.uniqueIdentifier];
|
||||
if (itemId == nil)
|
||||
return nil;
|
||||
@@ -356,6 +365,14 @@
|
||||
|
||||
- (void)setCaption:(NSString *)caption entities:(NSArray *)entities forItem:(id<TGMediaEditableItem>)item
|
||||
{
|
||||
if (_forcedCaption != nil)
|
||||
{
|
||||
_forcedCaption = caption;
|
||||
_forcedEntities = entities;
|
||||
_captionPipe.sink([TGMediaCaptionUpdate captionUpdateWithItem:item caption:caption entities:entities]);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *itemId = [self _contextualIdForItemId:item.uniqueIdentifier];
|
||||
if (itemId == nil)
|
||||
return;
|
||||
@@ -373,6 +390,12 @@
|
||||
_captionPipe.sink([TGMediaCaptionUpdate captionUpdateWithItem:item caption:caption entities:entities]);
|
||||
}
|
||||
|
||||
- (void)setForcedCaption:(NSString *)caption entities:(NSArray *)entities
|
||||
{
|
||||
_forcedCaption = caption;
|
||||
_forcedEntities = entities;
|
||||
}
|
||||
|
||||
- (SSignal *)captionSignalForItem:(NSObject<TGMediaEditableItem> *)item
|
||||
{
|
||||
NSString *uniqueIdentifier = item.uniqueIdentifier;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
@property (nonatomic, assign) bool shouldStoreAssets;
|
||||
@property (nonatomic, assign) bool hasTimer;
|
||||
@property (nonatomic, assign) bool onlyCrop;
|
||||
@property (nonatomic, assign) bool inhibitMute;
|
||||
@property (nonatomic, strong) NSString *recipientName;
|
||||
|
||||
@property (nonatomic, strong) TGMediaAssetsPallete *pallete;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
@property (nonatomic, assign) bool usesSimpleLayout;
|
||||
@property (nonatomic, assign) bool hasSwipeGesture;
|
||||
@property (nonatomic, assign) bool usesFadeOutForDismissal;
|
||||
@property (nonatomic, assign) bool inhibitMute;
|
||||
|
||||
@property (nonatomic, assign) bool capturing;
|
||||
|
||||
|
||||
@@ -557,7 +557,7 @@
|
||||
[strongSelf->_portraitToolbarView setEditButtonsEnabled:available animated:true];
|
||||
[strongSelf->_landscapeToolbarView setEditButtonsEnabled:available animated:true];
|
||||
|
||||
bool sendableAsGif = [strongItemView isKindOfClass:[TGMediaPickerGalleryVideoItemView class]];
|
||||
bool sendableAsGif = !strongSelf->_inhibitMute && [strongItemView isKindOfClass:[TGMediaPickerGalleryVideoItemView class]];
|
||||
strongSelf->_muteButton.hidden = !sendableAsGif;
|
||||
}
|
||||
}]];
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
@property (nonatomic, assign) bool useGalleryImageAsEditableItemImage;
|
||||
@property (nonatomic, weak) TGModernGalleryController *controller;
|
||||
|
||||
@property (nonatomic, assign) bool inhibitMute;
|
||||
|
||||
@property (nonatomic, readonly, strong) TGMediaPickerGalleryInterfaceView *interfaceView;
|
||||
@property (nonatomic, readonly, strong) TGMediaPickerGallerySelectedItemsModel *selectedItemsModel;
|
||||
|
||||
|
||||
@@ -189,6 +189,7 @@
|
||||
_interfaceView.hasTimer = _hasTimer;
|
||||
_interfaceView.onlyCrop = _onlyCrop;
|
||||
_interfaceView.inhibitDocumentCaptions = _inhibitDocumentCaptions;
|
||||
_interfaceView.inhibitMute = _inhibitMute;
|
||||
[_interfaceView setEditorTabPressed:^(TGPhotoEditorTab tab)
|
||||
{
|
||||
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
||||
|
||||
@@ -533,7 +533,7 @@
|
||||
};
|
||||
|
||||
if (_scrubberView.frame.size.width < FLT_EPSILON)
|
||||
TGDispatchAfter(0.01, dispatch_get_main_queue(), block);
|
||||
TGDispatchAfter(0.05, dispatch_get_main_queue(), block);
|
||||
else
|
||||
block();
|
||||
}
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
@property (nonatomic, copy) void (^editorOpened)(void);
|
||||
@property (nonatomic, copy) void (^editorClosed)(void);
|
||||
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName;
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName;
|
||||
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit;
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit;
|
||||
|
||||
- (void)present;
|
||||
- (void)updateWithFetchResult:(TGMediaAssetFetchResult *)fetchResult;
|
||||
|
||||
@@ -37,17 +37,17 @@
|
||||
|
||||
@implementation TGMediaPickerModernGalleryMixin
|
||||
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName
|
||||
{
|
||||
return [self initWithContext:context item:item fetchResult:fetchResult momentList:nil parentController:parentController thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:hasTimer onlyCrop:onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions asFile:asFile itemsLimit:itemsLimit recipientName:recipientName];
|
||||
return [self initWithContext:context item:item fetchResult:fetchResult momentList:nil parentController:parentController thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:hasTimer onlyCrop:onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions inhibitMute:inhibitMute asFile:asFile itemsLimit:itemsLimit recipientName:recipientName];
|
||||
}
|
||||
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit
|
||||
{
|
||||
return [self initWithContext:context item:item fetchResult:nil momentList:momentList parentController:parentController thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:hasTimer onlyCrop:onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions asFile:asFile itemsLimit:itemsLimit recipientName:nil];
|
||||
return [self initWithContext:context item:item fetchResult:nil momentList:momentList parentController:parentController thumbnailImage:thumbnailImage selectionContext:selectionContext editingContext:editingContext suggestionContext:suggestionContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:hasTimer onlyCrop:onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions inhibitMute:inhibitMute asFile:asFile itemsLimit:itemsLimit recipientName:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName
|
||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context item:(id)item fetchResult:(TGMediaAssetFetchResult *)fetchResult momentList:(TGMediaAssetMomentList *)momentList parentController:(TGViewController *)parentController thumbnailImage:(UIImage *)thumbnailImage selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext suggestionContext:(TGSuggestionContext *)suggestionContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions inhibitMute:(bool)inhibitMute asFile:(bool)asFile itemsLimit:(NSUInteger)itemsLimit recipientName:(NSString *)recipientName
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
@@ -81,6 +81,7 @@
|
||||
|
||||
TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:[_windowManager context] items:galleryItems focusItem:focusItem selectionContext:selectionContext editingContext:editingContext hasCaptions:hasCaptions allowCaptionEntities:allowCaptionEntities hasTimer:hasTimer onlyCrop:onlyCrop inhibitDocumentCaptions:inhibitDocumentCaptions hasSelectionPanel:true hasCamera:false recipientName:recipientName];
|
||||
_galleryModel = model;
|
||||
model.inhibitMute = inhibitMute;
|
||||
model.controller = modernGallery;
|
||||
model.suggestionContext = suggestionContext;
|
||||
model.willFinishEditingItem = ^(id<TGMediaEditableItem> editableItem, id<TGMediaEditAdjustments> adjustments, id representation, bool hasChanges)
|
||||
|
||||
@@ -250,6 +250,9 @@
|
||||
if (CMTimeCompare(videoComposition.frameDuration, kCMTimeZero) != 1)
|
||||
videoComposition.frameDuration = CMTimeMake(1, 30);
|
||||
|
||||
if (!CMTIME_IS_VALID(videoComposition.frameDuration))
|
||||
videoComposition.frameDuration = CMTimeMake(1, 30);
|
||||
|
||||
videoComposition.renderSize = [self _renderSizeWithCropSize:cropRect.size rotateSideward:TGOrientationIsSideward(adjustments.cropOrientation, NULL)];
|
||||
|
||||
AVMutableCompositionTrack *trimVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
|
||||
|
||||
@@ -22,6 +22,7 @@ typedef enum
|
||||
|
||||
- (instancetype)initWithTitle:(NSString *)title type:(TGMenuSheetButtonType)type action:(void (^)(void))action;
|
||||
|
||||
@property (nonatomic, assign) bool collapsed;
|
||||
- (void)setCollapsed:(bool)collapsed animated:(bool)animated;
|
||||
|
||||
@end
|
||||
|
||||
@@ -13,7 +13,6 @@ const CGFloat TGMenuSheetButtonItemViewHeight = 57.0f;
|
||||
|
||||
@interface TGMenuSheetButtonItemView ()
|
||||
{
|
||||
bool _collapsed;
|
||||
bool _dark;
|
||||
bool _requiresDivider;
|
||||
|
||||
@@ -36,6 +35,8 @@ const CGFloat TGMenuSheetButtonItemViewHeight = 57.0f;
|
||||
_button.exclusiveTouch = true;
|
||||
_button.highlightBackgroundColor = UIColorRGB(0xebebeb);
|
||||
[self _updateForType:type];
|
||||
_button.titleLabel.adjustsFontSizeToFitWidth = true;
|
||||
_button.titleLabel.minimumScaleFactor = 0.7f;
|
||||
[_button setTitle:title forState:UIControlStateNormal];
|
||||
[_button addTarget:self action:@selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self addSubview:_button];
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef enum {
|
||||
} TGMessageDeliveryState;
|
||||
|
||||
#define TGMessageLocalMidBaseline 800000000
|
||||
#define TGMessageLocalMidEditBaseline 900000000
|
||||
|
||||
typedef struct {
|
||||
uint8_t key[8 + 1 + 4 + 4];
|
||||
|
||||
@@ -642,28 +642,35 @@
|
||||
}
|
||||
else if (!_previewMode)
|
||||
{
|
||||
if (_finishedTransitionIn && _model.focusItem != nil)
|
||||
{
|
||||
TGModernGalleryItemView *itemView = nil;
|
||||
if (self.finishedTransitionIn && self.model.focusItem != nil)
|
||||
if (_startedTransitionIn) {
|
||||
_startedTransitionIn();
|
||||
}
|
||||
|
||||
[_view simpleTransitionInWithCompletion:
|
||||
^{
|
||||
if (_finishedTransitionIn && _model.focusItem != nil)
|
||||
{
|
||||
for (TGModernGalleryItemView *visibleItemView in self->_visibleItemViews)
|
||||
TGModernGalleryItemView *itemView = nil;
|
||||
if (self.finishedTransitionIn && self.model.focusItem != nil)
|
||||
{
|
||||
if ([visibleItemView.item isEqual:self.model.focusItem])
|
||||
for (TGModernGalleryItemView *visibleItemView in self->_visibleItemViews)
|
||||
{
|
||||
itemView = visibleItemView;
|
||||
|
||||
break;
|
||||
if ([visibleItemView.item isEqual:self.model.focusItem])
|
||||
{
|
||||
itemView = visibleItemView;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_finishedTransitionIn(_model.focusItem, itemView);
|
||||
|
||||
[_model _transitionCompleted];
|
||||
}
|
||||
|
||||
_finishedTransitionIn(_model.focusItem, itemView);
|
||||
|
||||
[_model _transitionCompleted];
|
||||
}
|
||||
else
|
||||
[_model _transitionCompleted];
|
||||
else
|
||||
[_model _transitionCompleted];
|
||||
}];
|
||||
|
||||
[_view transitionInWithDuration:0.15];
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
- (void)addItemFooterView:(UIView *)itemFooterView;
|
||||
- (void)removeItemFooterView:(UIView *)itemFooterView;
|
||||
|
||||
- (void)simpleTransitionInWithCompletion:(void (^)())completion;
|
||||
- (void)simpleTransitionOutWithVelocity:(CGFloat)velocity completion:(void (^)())completion;
|
||||
- (void)transitionInWithDuration:(NSTimeInterval)duration;
|
||||
- (void)transitionOutWithDuration:(NSTimeInterval)duration;
|
||||
|
||||
@@ -329,25 +329,60 @@ static const CGFloat swipeDistanceThreshold = 128.0f;
|
||||
self.transitionProgress(transitionProgress, manual);
|
||||
}
|
||||
|
||||
- (void)simpleTransitionInWithCompletion:(void (^)())completion
|
||||
{
|
||||
CGFloat velocity = 2000.0f;
|
||||
CGFloat distance = (velocity < FLT_EPSILON ? -1.0f : 1.0f) * self.frame.size.height;
|
||||
|
||||
CGRect targetFrame = _scrollView.frame;
|
||||
CGRect targetInterfaceFrame = _interfaceView.frame;
|
||||
CGRect interfaceViewFrame = (CGRect){{_interfaceView.frame.origin.x, distance}, _interfaceView.frame.size};
|
||||
CGRect scrollViewFrame = (CGRect){{_scrollView.frame.origin.x, distance}, _scrollView.frame.size};
|
||||
_interfaceView.frame = interfaceViewFrame;
|
||||
_scrollView.frame = scrollViewFrame;
|
||||
_overlayContainerView.alpha = 0.0f;
|
||||
self.backgroundColor = UIColorRGBA(0x000000, 0.0f);
|
||||
|
||||
[UIView animateWithDuration:ABS(distance / velocity) delay:0.0 options:7 << 16 animations:^{
|
||||
_scrollView.frame = targetFrame;
|
||||
_interfaceView.frame = targetInterfaceFrame;
|
||||
} completion:^(__unused BOOL finished)
|
||||
{
|
||||
if (completion)
|
||||
completion();
|
||||
}];
|
||||
|
||||
[UIView animateWithDuration:ABS(distance / velocity) animations:^
|
||||
{
|
||||
_overlayContainerView.alpha = 1.0f;
|
||||
self.backgroundColor = UIColorRGBA(0x000000, 1.0f);
|
||||
} completion:nil];
|
||||
}
|
||||
|
||||
- (void)simpleTransitionOutWithVelocity:(CGFloat)velocity completion:(void (^)())completion
|
||||
{
|
||||
const CGFloat minVelocity = 2000.0f;
|
||||
if (ABS(velocity) < minVelocity)
|
||||
velocity = (velocity < 0.0f ? -1.0f : 1.0f) * minVelocity;
|
||||
CGFloat distance = (velocity < FLT_EPSILON ? -1.0f : 1.0f) * self.frame.size.height;
|
||||
CGRect interfaceViewFrame = (CGRect){{_interfaceView.frame.origin.x, distance}, _interfaceView.frame.size};
|
||||
CGRect scrollViewFrame = (CGRect){{_scrollView.frame.origin.x, distance}, _scrollView.frame.size};
|
||||
|
||||
[UIView animateWithDuration:ABS(distance / velocity) animations:^
|
||||
{
|
||||
[UIView animateWithDuration:ABS(distance / velocity) delay:0.0 options:7 << 16 animations:^{
|
||||
_scrollView.frame = scrollViewFrame;
|
||||
_interfaceView.alpha = 0.0f;
|
||||
_overlayContainerView.alpha = 0.0f;
|
||||
self.backgroundColor = UIColorRGBA(0x000000, 0.0f);
|
||||
_interfaceView.frame = interfaceViewFrame;
|
||||
} completion:^(__unused BOOL finished)
|
||||
{
|
||||
if (completion)
|
||||
completion();
|
||||
}];
|
||||
|
||||
[UIView animateWithDuration:ABS(distance / velocity) animations:^
|
||||
{
|
||||
_interfaceView.alpha = 0.0f;
|
||||
_overlayContainerView.alpha = 0.0f;
|
||||
self.backgroundColor = UIColorRGBA(0x000000, 0.0f);
|
||||
} completion:nil];
|
||||
}
|
||||
|
||||
- (void)transitionInWithDuration:(NSTimeInterval)duration
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
@interface TGPhotoVideoEditor : NSObject
|
||||
|
||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName completion:(void (^)(id, TGMediaEditingContext *))completion;
|
||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSString *)caption entities:(NSArray *)entities withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
|
||||
@implementation TGPhotoVideoEditor
|
||||
|
||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion
|
||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSString *)caption entities:(NSArray *)entities withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion
|
||||
{
|
||||
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
|
||||
id<LegacyComponentsContext> windowContext = [windowManager context];
|
||||
|
||||
TGMediaEditingContext *editingContext = [[TGMediaEditingContext alloc] init];
|
||||
[editingContext setForcedCaption:caption entities:entities];
|
||||
|
||||
TGModernGalleryController *galleryController = [[TGModernGalleryController alloc] initWithContext:windowContext];
|
||||
galleryController.adjustsStatusBarVisibility = true;
|
||||
@@ -28,7 +29,7 @@
|
||||
galleryItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:item];
|
||||
galleryItem.editingContext = editingContext;
|
||||
|
||||
TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:windowContext items:@[galleryItem] focusItem:galleryItem selectionContext:nil editingContext:editingContext hasCaptions:false allowCaptionEntities:false hasTimer:false onlyCrop:false inhibitDocumentCaptions:false hasSelectionPanel:false hasCamera:false recipientName:recipientName];
|
||||
TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:windowContext items:@[galleryItem] focusItem:galleryItem selectionContext:nil editingContext:editingContext hasCaptions:true allowCaptionEntities:true hasTimer:false onlyCrop:false inhibitDocumentCaptions:false hasSelectionPanel:false hasCamera:false recipientName:recipientName];
|
||||
model.controller = galleryController;
|
||||
//model.suggestionContext = self.suggestionContext;
|
||||
|
||||
@@ -87,48 +88,18 @@
|
||||
}];
|
||||
};
|
||||
|
||||
// CGSize snapshotSize = TGScaleToFill(CGSizeMake(480, 640), CGSizeMake(self.view.frame.size.width, self.view.frame.size.width));
|
||||
// UIView *snapshotView = [_previewView snapshotViewAfterScreenUpdates:false];
|
||||
// snapshotView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
// snapshotView.frame = CGRectMake(_previewView.center.x - snapshotSize.width / 2, _previewView.center.y - snapshotSize.height / 2, snapshotSize.width, snapshotSize.height);
|
||||
// snapshotView.hidden = true;
|
||||
// [_previewView.superview insertSubview:snapshotView aboveSubview:_previewView];
|
||||
|
||||
galleryController.beginTransitionIn = ^UIView *(__unused TGMediaPickerGalleryItem *item, __unused TGModernGalleryItemView *itemView)
|
||||
{
|
||||
TGModernGalleryController *strongGalleryController = weakGalleryController;
|
||||
strongGalleryController.view.alpha = 0.0f;
|
||||
[UIView animateWithDuration:0.3f animations:^
|
||||
{
|
||||
strongGalleryController.view.alpha = 1.0f;
|
||||
}];
|
||||
//return snapshotView;
|
||||
return nil;
|
||||
};
|
||||
|
||||
galleryController.beginTransitionOut = ^UIView *(__unused TGMediaPickerGalleryItem *item, __unused TGModernGalleryItemView *itemView)
|
||||
{
|
||||
// __strong TGCameraController *strongSelf = weakSelf;
|
||||
// if (strongSelf != nil)
|
||||
// {
|
||||
TGMediaPickerGalleryModel *strongModel = weakModel;
|
||||
if (strongModel == nil)
|
||||
return nil;
|
||||
|
||||
// [UIView animateWithDuration:0.3f delay:0.1f options:UIViewAnimationOptionCurveLinear animations:^
|
||||
// {
|
||||
// strongSelf->_interfaceView.alpha = 1.0f;
|
||||
// } completion:nil];
|
||||
|
||||
// return snapshotView;
|
||||
// }
|
||||
return nil;
|
||||
};
|
||||
|
||||
galleryController.completedTransitionOut = ^
|
||||
{
|
||||
//[snapshotView removeFromSuperview];
|
||||
|
||||
TGModernGalleryController *strongGalleryController = weakGalleryController;
|
||||
if (strongGalleryController != nil && strongGalleryController.overlayWindow == nil)
|
||||
{
|
||||
@@ -141,7 +112,6 @@
|
||||
|
||||
TGOverlayControllerWindow *controllerWindow = [[TGOverlayControllerWindow alloc] initWithManager:windowManager parentController:controller contentController:galleryController];
|
||||
controllerWindow.hidden = false;
|
||||
//controllerWindow.windowLevel = self.view.window.windowLevel + 0.0001f;
|
||||
galleryController.view.clipsToBounds = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,11 @@
|
||||
_backgroundView.frame = CGRectMake(x, 2.0f - backgroundOffset + (_forceArrowOnTop ? 7.0f : 0.0f), backgroundWidth, 36.0f + backgroundOffset);
|
||||
_textLabel.frame = CGRectMake(_backgroundView.frame.origin.x + inset, 12.0f - TGScreenPixel - backgroundOffset + (_forceArrowOnTop ? 7.0f : 0.0f), labelWidth, _textLabel.frame.size.height);
|
||||
|
||||
if (_forceArrowOnTop)
|
||||
{
|
||||
_arrowView.frame = CGRectMake(_arrowView.frame.origin.x, _backgroundView.frame.origin.y - _arrowView.frame.size.height, _arrowView.frame.size.width, _arrowView.frame.size.height);
|
||||
}
|
||||
|
||||
self.transform = transform;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,13 @@
|
||||
|
||||
- (void)stopScrollingAnimation
|
||||
{
|
||||
UIView *superview = self.superview;
|
||||
NSUInteger index = [self.superview.subviews indexOfObject:self];
|
||||
[self removeFromSuperview];
|
||||
[superview insertSubview:self atIndex:index];
|
||||
CGPoint offset = self.contentOffset;
|
||||
[self setContentOffset:offset animated:false];
|
||||
|
||||
// UIView *superview = self.superview;
|
||||
// NSUInteger index = [self.superview.subviews indexOfObject:self];
|
||||
// [self removeFromSuperview];
|
||||
// [superview insertSubview:self atIndex:index];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user