mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Merge commit '071a3bdef1672c9311baf5170bb2765939a1b802'
This commit is contained in:
commit
219d4034fb
@ -7,6 +7,8 @@
|
||||
|
||||
@property (nonatomic, strong) UIImage *image;
|
||||
|
||||
@property (nonatomic, readonly) UIView *clipView;
|
||||
|
||||
@property (nonatomic, readonly) CGSize originalSize;
|
||||
@property (nonatomic, assign) CGRect cropRect;
|
||||
@property (nonatomic, assign) UIImageOrientation cropOrientation;
|
||||
@ -37,6 +39,7 @@
|
||||
- (void)animateTransitionOut;
|
||||
- (void)transitionInFinishedFromCamera:(bool)fromCamera;
|
||||
|
||||
- (void)attachEntitiesView;
|
||||
- (void)closeCurtains;
|
||||
- (void)openCurtains;
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
bool _dismissing;
|
||||
UIView *_transitionView;
|
||||
bool _noTransitionToSnapshot;
|
||||
|
||||
bool _animateScale;
|
||||
}
|
||||
|
||||
@property (nonatomic, weak) id<TGMediaEditableItem> item;
|
||||
@ -36,6 +38,7 @@
|
||||
|
||||
@property (nonatomic, assign) TGPhotoEditorTab availableTabs;
|
||||
|
||||
@property (nonatomic, assign) TGPhotoEditorTab switchingFromTab;
|
||||
@property (nonatomic, assign) TGPhotoEditorTab switchingToTab;
|
||||
|
||||
- (void)transitionOutSwitching:(bool)switching completion:(void (^)(void))completion;
|
||||
|
@ -13,6 +13,7 @@ typedef enum
|
||||
TGMediaVideoConversionPresetCompressedVeryHigh,
|
||||
TGMediaVideoConversionPresetAnimation,
|
||||
TGMediaVideoConversionPresetVideoMessage,
|
||||
TGMediaVideoConversionPresetProfileLow,
|
||||
TGMediaVideoConversionPresetProfile,
|
||||
TGMediaVideoConversionPresetProfileHigh,
|
||||
TGMediaVideoConversionPresetProfileVeryHigh,
|
||||
|
@ -125,7 +125,7 @@
|
||||
|
||||
CGSize dimensions = [avAsset tracksWithMediaType:AVMediaTypeVideo].firstObject.naturalSize;
|
||||
TGMediaVideoConversionPreset preset = adjustments.sendAsGif ? TGMediaVideoConversionPresetAnimation : [self presetFromAdjustments:adjustments];
|
||||
if (!CGSizeEqualToSize(dimensions, CGSizeZero) && preset != TGMediaVideoConversionPresetAnimation && preset != TGMediaVideoConversionPresetVideoMessage && preset != TGMediaVideoConversionPresetProfile && preset != TGMediaVideoConversionPresetProfileHigh && preset != TGMediaVideoConversionPresetProfileVeryHigh && preset != TGMediaVideoConversionPresetPassthrough)
|
||||
if (!CGSizeEqualToSize(dimensions, CGSizeZero) && preset != TGMediaVideoConversionPresetAnimation && preset != TGMediaVideoConversionPresetVideoMessage && preset != TGMediaVideoConversionPresetProfile && preset != TGMediaVideoConversionPresetProfileLow && preset != TGMediaVideoConversionPresetProfileHigh && preset != TGMediaVideoConversionPresetProfileVeryHigh && preset != TGMediaVideoConversionPresetPassthrough)
|
||||
{
|
||||
TGMediaVideoConversionPreset bestPreset = [self bestAvailablePresetForDimensions:dimensions];
|
||||
if (preset > bestPreset)
|
||||
@ -240,7 +240,7 @@
|
||||
return;
|
||||
|
||||
TGMediaVideoConversionPreset preset = TGMediaVideoConversionPresetAnimation;
|
||||
if (adjustments.preset == TGMediaVideoConversionPresetProfile || adjustments.preset == TGMediaVideoConversionPresetProfileHigh || adjustments.preset == TGMediaVideoConversionPresetProfileVeryHigh) {
|
||||
if (adjustments.preset == TGMediaVideoConversionPresetProfile || adjustments.preset != TGMediaVideoConversionPresetProfileLow || adjustments.preset == TGMediaVideoConversionPresetProfileHigh || adjustments.preset == TGMediaVideoConversionPresetProfileVeryHigh) {
|
||||
preset = adjustments.preset;
|
||||
}
|
||||
|
||||
@ -355,7 +355,7 @@
|
||||
if (TGOrientationIsSideward(adjustments.cropOrientation, NULL))
|
||||
outputDimensions = CGSizeMake(outputDimensions.height, outputDimensions.width);
|
||||
|
||||
if ((preset == TGMediaVideoConversionPresetProfile || preset == TGMediaVideoConversionPresetProfileHigh || preset == TGMediaVideoConversionPresetProfileVeryHigh) && MIN(outputDimensions.width, outputDimensions.height) < 160.0) {
|
||||
if ((preset == TGMediaVideoConversionPresetProfile || preset == TGMediaVideoConversionPresetProfileLow || preset == TGMediaVideoConversionPresetProfileHigh || preset == TGMediaVideoConversionPresetProfileVeryHigh) && MIN(outputDimensions.width, outputDimensions.height) < 160.0) {
|
||||
outputDimensions = CGSizeMake(160.0, 160.0);
|
||||
}
|
||||
|
||||
@ -1255,6 +1255,9 @@ static CGFloat progressOfSampleBufferInTimeRange(CMSampleBufferRef sampleBuffer,
|
||||
case TGMediaVideoConversionPresetVideoMessage:
|
||||
return (CGSize){ 240.0f, 240.0f };
|
||||
|
||||
case TGMediaVideoConversionPresetProfileLow:
|
||||
return (CGSize){ 720.0f, 720.0f };
|
||||
|
||||
case TGMediaVideoConversionPresetProfile:
|
||||
case TGMediaVideoConversionPresetProfileHigh:
|
||||
case TGMediaVideoConversionPresetProfileVeryHigh:
|
||||
@ -1267,7 +1270,7 @@ static CGFloat progressOfSampleBufferInTimeRange(CMSampleBufferRef sampleBuffer,
|
||||
|
||||
+ (bool)keepAudioForPreset:(TGMediaVideoConversionPreset)preset
|
||||
{
|
||||
return preset != TGMediaVideoConversionPresetAnimation && preset != TGMediaVideoConversionPresetProfile && preset != TGMediaVideoConversionPresetProfileHigh && preset != TGMediaVideoConversionPresetProfileVeryHigh;
|
||||
return preset != TGMediaVideoConversionPresetAnimation && preset != TGMediaVideoConversionPresetProfile && preset != TGMediaVideoConversionPresetProfileLow && preset != TGMediaVideoConversionPresetProfileHigh && preset != TGMediaVideoConversionPresetProfileVeryHigh;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)audioSettingsForPreset:(TGMediaVideoConversionPreset)preset
|
||||
@ -1346,6 +1349,9 @@ static CGFloat progressOfSampleBufferInTimeRange(CMSampleBufferRef sampleBuffer,
|
||||
case TGMediaVideoConversionPresetProfile:
|
||||
return 1500;
|
||||
|
||||
case TGMediaVideoConversionPresetProfileLow:
|
||||
return 1100;
|
||||
|
||||
case TGMediaVideoConversionPresetProfileHigh:
|
||||
return 2000;
|
||||
|
||||
@ -1381,6 +1387,7 @@ static CGFloat progressOfSampleBufferInTimeRange(CMSampleBufferRef sampleBuffer,
|
||||
|
||||
case TGMediaVideoConversionPresetAnimation:
|
||||
case TGMediaVideoConversionPresetProfile:
|
||||
case TGMediaVideoConversionPresetProfileLow:
|
||||
case TGMediaVideoConversionPresetProfileHigh:
|
||||
case TGMediaVideoConversionPresetProfileVeryHigh:
|
||||
return 0;
|
||||
@ -1411,6 +1418,7 @@ static CGFloat progressOfSampleBufferInTimeRange(CMSampleBufferRef sampleBuffer,
|
||||
|
||||
case TGMediaVideoConversionPresetAnimation:
|
||||
case TGMediaVideoConversionPresetProfile:
|
||||
case TGMediaVideoConversionPresetProfileLow:
|
||||
case TGMediaVideoConversionPresetProfileHigh:
|
||||
case TGMediaVideoConversionPresetProfileVeryHigh:
|
||||
return 0;
|
||||
|
@ -146,10 +146,19 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200;
|
||||
|
||||
UITapGestureRecognizer *tapRecognier = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
|
||||
[_wrapperView addGestureRecognizer:tapRecognier];
|
||||
|
||||
_clipView = [[UIView alloc] init];
|
||||
_clipView.clipsToBounds = true;
|
||||
_clipView.userInteractionEnabled = false;
|
||||
[self addSubview:_clipView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)attachEntitiesView {
|
||||
[_entitiesWrapperView addSubview:_fullEntitiesView];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
_scrollView.delegate = nil;
|
||||
@ -644,6 +653,8 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200;
|
||||
{
|
||||
[self _layoutOverlayViews];
|
||||
|
||||
_clipView.frame = self.bounds;
|
||||
|
||||
_flashView.frame = self.bounds;
|
||||
|
||||
if (_scrollView.superview == nil)
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#import "TGMediaPickerGalleryVideoScrubber.h"
|
||||
#import "TGModernGalleryVideoView.h"
|
||||
#import "TGPhotoEntitiesContainerView.h"
|
||||
|
||||
#import "TGPhotoPaintController.h"
|
||||
|
||||
@ -257,6 +258,58 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
||||
[self.view insertSubview:_transitionView belowSubview:_wrapperView];
|
||||
}
|
||||
|
||||
- (void)animateTransitionIn {
|
||||
if (self.initialAppearance) {
|
||||
[super animateTransitionIn];
|
||||
return;
|
||||
} else {
|
||||
_animateScale = true;
|
||||
|
||||
[self transitEntities:_previewView];
|
||||
|
||||
[super animateTransitionIn];
|
||||
}
|
||||
}
|
||||
|
||||
+ (CGRect)fittedCropRect:(CGRect)cropRect originalSize:(CGSize)originalSize fitSize:(CGSize)fitSize {
|
||||
CGSize fittedOriginalSize = TGScaleToSize(originalSize, fitSize);
|
||||
CGFloat scale = fittedOriginalSize.width / originalSize.width;
|
||||
|
||||
CGSize size = fittedOriginalSize;
|
||||
|
||||
return CGRectMake(-cropRect.origin.x * scale, -cropRect.origin.y * scale, size.width, size.height);
|
||||
}
|
||||
|
||||
- (void)transitEntities:(UIView *)parentView {
|
||||
UIView *containerView = [[UIView alloc] init];
|
||||
[parentView addSubview:containerView];
|
||||
|
||||
containerView.frame = CGRectMake(0.0, 0.0, _fullEntitiesView.frame.size.width, _fullEntitiesView.frame.size.height);
|
||||
[containerView addSubview:_fullEntitiesView];
|
||||
|
||||
CGFloat paintingScale = _fullEntitiesView.frame.size.width / _photoEditor.originalSize.width;
|
||||
_fullEntitiesView.frame = CGRectMake(-_photoEditor.cropRect.origin.x * paintingScale, -_photoEditor.cropRect.origin.y * paintingScale, _fullEntitiesView.frame.size.width, _fullEntitiesView.frame.size.height);
|
||||
|
||||
CGFloat cropScale = 1.0;
|
||||
if (_photoEditor.originalSize.width > _photoEditor.originalSize.height) {
|
||||
cropScale = _photoEditor.originalSize.height / _photoEditor.cropRect.size.height;
|
||||
} else {
|
||||
cropScale = _photoEditor.originalSize.width / _photoEditor.cropRect.size.width;
|
||||
}
|
||||
|
||||
UIImageOrientation imageOrientation = _photoEditor.cropOrientation;
|
||||
if ([parentView isKindOfClass:[TGPhotoEditorPreviewView class]])
|
||||
imageOrientation = UIImageOrientationUp;
|
||||
|
||||
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(TGRotationForOrientation(imageOrientation));
|
||||
if ([parentView isKindOfClass:[TGPhotoEditorPreviewView class]] && _photoEditor.cropMirrored) {
|
||||
rotationTransform = CGAffineTransformMakeScale(-1.0, 1.0);
|
||||
}
|
||||
CGFloat scale = parentView.frame.size.width / _fullEntitiesView.frame.size.width;
|
||||
containerView.transform = CGAffineTransformScale(rotationTransform, scale * cropScale, scale * cropScale);
|
||||
containerView.frame = CGRectMake(0.0, 0.0, parentView.frame.size.width, parentView.frame.size.height);
|
||||
}
|
||||
|
||||
- (void)transitionIn
|
||||
{
|
||||
if (_portraitToolsWrapperView.frame.size.height < FLT_EPSILON) {
|
||||
@ -373,13 +426,22 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
||||
|
||||
[_cropView closeCurtains];
|
||||
|
||||
[self transitEntities:_cropView.clipView];
|
||||
|
||||
CGAffineTransform initialTransform = _previewView.transform;
|
||||
[UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionLayoutSubviews animations:^
|
||||
{
|
||||
_previewView.frame = targetFrame;
|
||||
CGFloat scale = targetFrame.size.width / _previewView.frame.size.width;
|
||||
_previewView.center = CGPointMake(CGRectGetMidX(targetFrame), CGRectGetMidY(targetFrame));
|
||||
_previewView.transform = CGAffineTransformScale(initialTransform, scale, scale);
|
||||
|
||||
_cropView.center = CGPointMake(CGRectGetMidX(targetCropViewFrame), CGRectGetMidY(targetCropViewFrame));
|
||||
_cropView.transform = CGAffineTransformMakeScale(targetCropViewScale, targetCropViewScale);
|
||||
} completion:^(__unused BOOL finished)
|
||||
{
|
||||
{
|
||||
_fullEntitiesView.frame = CGRectMake(0, 0, _fullEntitiesView.frame.size.width, _fullEntitiesView.frame.size.height);
|
||||
_previewView.transform = initialTransform;
|
||||
_previewView.frame = targetFrame;
|
||||
[_cropView removeFromSuperview];
|
||||
_previewView.alpha = 1.0;
|
||||
if (self.finishedTransitionOut != nil)
|
||||
@ -504,8 +566,13 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
||||
{
|
||||
_appeared = true;
|
||||
|
||||
if (!self.initialAppearance) {
|
||||
[_fullEntitiesView.superview removeFromSuperview];
|
||||
_fullEntitiesView.frame = CGRectMake(0, 0, _fullEntitiesView.frame.size.width, _fullEntitiesView.frame.size.height);
|
||||
[_cropView attachEntitiesView];
|
||||
}
|
||||
|
||||
if ([transitionView isKindOfClass:[TGPhotoEditorPreviewView class]]) {
|
||||
|
||||
} else {
|
||||
[transitionView removeFromSuperview];
|
||||
}
|
||||
|
@ -1171,6 +1171,7 @@
|
||||
UIView *snapshotView = nil;
|
||||
|
||||
TGPhotoEditorTabController *currentController = _currentTabController;
|
||||
TGPhotoEditorTab switchingFromTab = TGPhotoEditorNoneTab;
|
||||
if (currentController != nil)
|
||||
{
|
||||
if (![currentController isDismissAllowed])
|
||||
@ -1178,13 +1179,18 @@
|
||||
|
||||
[self savePaintingData];
|
||||
|
||||
bool resetTransform = false;
|
||||
if ([self presentedForAvatarCreation] && tab == TGPhotoEditorCropTab && [currentController isKindOfClass:[TGPhotoPaintController class]]) {
|
||||
resetTransform = true;
|
||||
}
|
||||
|
||||
currentController.switchingToTab = tab;
|
||||
[currentController transitionOutSwitching:true completion:^
|
||||
{
|
||||
[currentController removeFromParentViewController];
|
||||
[currentController.view removeFromSuperview];
|
||||
|
||||
if ([self presentedForAvatarCreation] && tab == TGPhotoEditorCropTab) {
|
||||
if (resetTransform) {
|
||||
_previewView.transform = CGAffineTransformIdentity;
|
||||
}
|
||||
}];
|
||||
@ -1200,6 +1206,9 @@
|
||||
{
|
||||
_backgroundView.alpha = 0.0f;
|
||||
} completion:nil];
|
||||
switchingFromTab = TGPhotoEditorCropTab;
|
||||
} else if ([currentController isKindOfClass:[TGPhotoToolsController class]]) {
|
||||
switchingFromTab = TGPhotoEditorToolsTab;
|
||||
}
|
||||
|
||||
isInitialAppearance = false;
|
||||
@ -1281,7 +1290,7 @@
|
||||
cropController.toolbarLandscapeSize = TGPhotoEditorToolbarSize;
|
||||
cropController.controlVideoPlayback = ^(bool play) {
|
||||
__strong TGPhotoEditorController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
if (strongSelf == nil || strongSelf->_progressVisible)
|
||||
return;
|
||||
if (play) {
|
||||
[strongSelf startVideoPlayback:false];
|
||||
@ -1297,7 +1306,7 @@
|
||||
};
|
||||
cropController.togglePlayback = ^{
|
||||
__strong TGPhotoEditorController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil || !strongSelf->_item.isVideo)
|
||||
if (strongSelf == nil || !strongSelf->_item.isVideo || strongSelf->_progressVisible)
|
||||
return;
|
||||
|
||||
if (strongSelf->_isPlaying) {
|
||||
@ -1613,6 +1622,7 @@
|
||||
_currentTabController = controller;
|
||||
_currentTabController.item = _item;
|
||||
_currentTabController.intent = _intent;
|
||||
_currentTabController.switchingFromTab = switchingFromTab;
|
||||
_currentTabController.initialAppearance = isInitialAppearance;
|
||||
|
||||
if (![_currentTabController isKindOfClass:[TGPhotoPaintController class]])
|
||||
@ -1983,8 +1993,10 @@
|
||||
preset = TGMediaVideoConversionPresetProfileVeryHigh;
|
||||
} else if (duration <= 5.0) {
|
||||
preset = TGMediaVideoConversionPresetProfileHigh;
|
||||
} else {
|
||||
} else if (duration <= 8.0) {
|
||||
preset = TGMediaVideoConversionPresetProfile;
|
||||
} else {
|
||||
preset = TGMediaVideoConversionPresetProfileLow;
|
||||
}
|
||||
|
||||
TGDispatchOnMainThread(^{
|
||||
|
@ -169,22 +169,34 @@ const CGFloat TGPhotoEditorToolbarSize = 49.0f;
|
||||
|
||||
_transitionInProgress = true;
|
||||
|
||||
CGAffineTransform initialTransform = _transitionView.transform;
|
||||
[UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionLayoutSubviews animations:^
|
||||
{
|
||||
_transitionView.frame = _transitionTargetFrame;
|
||||
if (_animateScale) {
|
||||
CGFloat scale = _transitionTargetFrame.size.width / _transitionView.frame.size.width;
|
||||
_transitionView.center = CGPointMake(CGRectGetMidX(_transitionTargetFrame), CGRectGetMidY(_transitionTargetFrame));
|
||||
_transitionView.transform = CGAffineTransformScale(initialTransform, scale, scale);
|
||||
} else {
|
||||
_transitionView.frame = _transitionTargetFrame;
|
||||
}
|
||||
} completion:^(BOOL finished) {
|
||||
_transitionInProgress = false;
|
||||
|
||||
UIView *transitionView = _transitionView;
|
||||
_transitionView = nil;
|
||||
|
||||
if (self.finishedTransitionIn != nil)
|
||||
{
|
||||
self.finishedTransitionIn();
|
||||
self.finishedTransitionIn = nil;
|
||||
}
|
||||
|
||||
[self _finishedTransitionInWithView:transitionView];
|
||||
UIView *transitionView = _transitionView;
|
||||
_transitionView = nil;
|
||||
|
||||
if (_animateScale) {
|
||||
_transitionView.transform = initialTransform;
|
||||
_transitionView.frame = _transitionTargetFrame;
|
||||
}
|
||||
|
||||
if (self.finishedTransitionIn != nil)
|
||||
{
|
||||
self.finishedTransitionIn();
|
||||
self.finishedTransitionIn = nil;
|
||||
}
|
||||
|
||||
[self _finishedTransitionInWithView:transitionView];
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -99,6 +99,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
||||
|
||||
bool _appeared;
|
||||
bool _skipEntitiesSetup;
|
||||
bool _entitiesReady;
|
||||
|
||||
TGPhotoPaintFont *_selectedTextFont;
|
||||
TGPhotoPaintTextEntityStyle _selectedTextStyle;
|
||||
@ -268,7 +269,9 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
||||
|
||||
[strongSelf updateSettingsButton];
|
||||
};
|
||||
[_contentWrapperView addSubview:_entitiesContainerView];
|
||||
if (!_skipEntitiesSetup) {
|
||||
[_contentWrapperView addSubview:_entitiesContainerView];
|
||||
}
|
||||
_undoManager.entitiesContainer = _entitiesContainerView;
|
||||
|
||||
_dimView = [[UIView alloc] init];
|
||||
@ -1816,7 +1819,6 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
||||
|
||||
if (self.presentedForAvatarCreation) {
|
||||
_canvasView.hidden = true;
|
||||
_entitiesContainerView.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1865,7 +1867,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
||||
|
||||
[self setupCanvas];
|
||||
_entitiesContainerView.hidden = false;
|
||||
|
||||
|
||||
TGPhotoEditorPreviewView *previewView = _previewView;
|
||||
[previewView setPaintingHidden:true];
|
||||
previewView.hidden = false;
|
||||
@ -1887,8 +1889,10 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
||||
CGPoint boundsCenter = TGPaintCenterOfRect(_contentWrapperView.bounds);
|
||||
_entitiesContainerView.center = TGPaintAddPoints(boundsCenter, offset);
|
||||
|
||||
[_contentWrapperView addSubview:_entitiesContainerView];
|
||||
|
||||
if (!_skipEntitiesSetup || _entitiesReady) {
|
||||
[_contentWrapperView addSubview:_entitiesContainerView];
|
||||
}
|
||||
_entitiesReady = true;
|
||||
[self resetScrollView];
|
||||
}
|
||||
|
||||
@ -2322,6 +2326,13 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
||||
|
||||
previewView.frame = previewFrame;
|
||||
|
||||
if ([self presentedForAvatarCreation]) {
|
||||
CGAffineTransform transform = CGAffineTransformMakeRotation(TGRotationForOrientation(photoEditor.cropOrientation));
|
||||
if (photoEditor.cropMirrored)
|
||||
transform = CGAffineTransformScale(transform, -1.0f, 1.0f);
|
||||
previewView.transform = transform;
|
||||
}
|
||||
|
||||
CGSize fittedOriginalSize = CGSizeMake(originalSize.width * ratio, originalSize.height * ratio);
|
||||
CGSize rotatedSize = TGRotatedContentSize(fittedOriginalSize, rotation);
|
||||
CGPoint centerPoint = CGPointMake(rotatedSize.width / 2.0f, rotatedSize.height / 2.0f);
|
||||
|
@ -35,6 +35,7 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
||||
bool _appeared;
|
||||
bool _scheduledTransitionIn;
|
||||
CGFloat _cellWidth;
|
||||
int _entitiesReady;
|
||||
|
||||
NSArray *_allTools;
|
||||
NSArray *_simpleTools;
|
||||
@ -107,26 +108,27 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
||||
}
|
||||
|
||||
- (void)layoutEntitiesView {
|
||||
CGSize fittedContentSize = [TGPhotoPaintController fittedContentSize:_photoEditor.cropRect orientation:_photoEditor.cropOrientation originalSize:_photoEditor.originalSize];
|
||||
CGRect fittedCropRect = [TGPhotoPaintController fittedCropRect:_photoEditor.cropRect originalSize:_photoEditor.originalSize keepOriginalSize:false];
|
||||
_entitiesWrapperView.frame = CGRectMake(0.0f, 0.0f, fittedContentSize.width, fittedContentSize.height);
|
||||
if (_entitiesReady < 2 || _dismissing)
|
||||
return;
|
||||
|
||||
CGRect rect = [TGPhotoPaintController fittedCropRect:self.photoEditor.cropRect originalSize:self.photoEditor.originalSize keepOriginalSize:true];
|
||||
_entitiesView.frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
|
||||
_entitiesView.transform = CGAffineTransformMakeRotation(_photoEditor.cropRotation);
|
||||
_entitiesWrapperView.transform = CGAffineTransformIdentity;
|
||||
_entitiesWrapperView.frame = CGRectMake(0.0, 0.0, _entitiesView.frame.size.width, _entitiesView.frame.size.height);
|
||||
[_entitiesWrapperView addSubview:_entitiesView];
|
||||
|
||||
CGSize fittedOriginalSize = TGScaleToSize(_photoEditor.originalSize, [TGPhotoPaintController maximumPaintingSize]);
|
||||
CGSize rotatedSize = TGRotatedContentSize(fittedOriginalSize, _photoEditor.cropRotation);
|
||||
CGPoint centerPoint = CGPointMake(rotatedSize.width / 2.0f, rotatedSize.height / 2.0f);
|
||||
CGFloat paintingScale = _entitiesView.frame.size.width / _photoEditor.originalSize.width;
|
||||
_entitiesView.frame = CGRectMake(-_photoEditor.cropRect.origin.x * paintingScale, -_photoEditor.cropRect.origin.y * paintingScale, _entitiesView.frame.size.width, _entitiesView.frame.size.height);
|
||||
|
||||
CGFloat scale = fittedOriginalSize.width / _photoEditor.originalSize.width;
|
||||
CGPoint offset = TGPaintSubtractPoints(centerPoint, [TGPhotoPaintController fittedCropRect:_photoEditor.cropRect centerScale:scale]);
|
||||
|
||||
CGPoint boundsCenter = TGPaintCenterOfRect(_entitiesWrapperView.bounds);
|
||||
_entitiesView.center = TGPaintAddPoints(boundsCenter, offset);
|
||||
if (_entitiesView.superview != _entitiesWrapperView) {
|
||||
[_entitiesWrapperView addSubview:_entitiesView];
|
||||
CGFloat cropScale = 1.0;
|
||||
if (_photoEditor.originalSize.width > _photoEditor.originalSize.height) {
|
||||
cropScale = _photoEditor.originalSize.height / _photoEditor.cropRect.size.height;
|
||||
} else {
|
||||
cropScale = _photoEditor.originalSize.width / _photoEditor.cropRect.size.width;
|
||||
}
|
||||
|
||||
CGFloat scale = _previewView.frame.size.width / _entitiesView.frame.size.width;
|
||||
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(TGRotationForOrientation(_photoEditor.cropOrientation));
|
||||
_entitiesWrapperView.transform = CGAffineTransformScale(rotationTransform, scale * cropScale, scale * cropScale);
|
||||
_entitiesWrapperView.frame = [_previewView convertRect:_previewView.bounds toView:_entitiesWrapperView.superview];
|
||||
}
|
||||
|
||||
- (void)loadView
|
||||
@ -507,6 +509,9 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
||||
TGPhotoEditorPreviewView *previewView = _previewView;
|
||||
previewView.hidden = false;
|
||||
[previewView performTransitionInIfNeeded];
|
||||
|
||||
_entitiesReady++;
|
||||
[self layoutEntitiesView];
|
||||
}
|
||||
|
||||
- (void)prepareForCustomTransitionOut
|
||||
|
@ -268,7 +268,7 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
if video != previousVideoRepresentations?.last {
|
||||
let mediaManager = self.context.sharedContext.mediaManager
|
||||
let videoFileReference = FileMediaReference.avatarList(peer: peerReference, media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.representation.resource, previewRepresentations: representations.map { $0.representation }, videoThumbnails: [], immediateThumbnailData: entry.immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.representation.dimensions, flags: [])]))
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(id, category), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.representation.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: true, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear)
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(id, category), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.representation.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: true, useLargeThumbnail: true, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear)
|
||||
let videoNode = UniversalVideoNode(postbox: self.context.account.postbox, audioSession: mediaManager.audioSession, manager: mediaManager.universalVideoManager, decoration: GalleryVideoDecoration(), content: videoContent, priority: .overlay)
|
||||
videoNode.isUserInteractionEnabled = false
|
||||
videoNode.isHidden = true
|
||||
|
@ -326,14 +326,14 @@ private func chatMessageImageFileThumbnailDatas(account: Account, fileReference:
|
||||
return signal
|
||||
}
|
||||
|
||||
private func chatMessageVideoDatas(postbox: Postbox, fileReference: FileMediaReference, thumbnailSize: Bool = false, onlyFullSize: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false) -> Signal<Tuple3<Data?, Tuple2<Data, String>?, Bool>, NoError> {
|
||||
private func chatMessageVideoDatas(postbox: Postbox, fileReference: FileMediaReference, thumbnailSize: Bool = false, onlyFullSize: Bool = false, useLargeThumbnail: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false) -> Signal<Tuple3<Data?, Tuple2<Data, String>?, Bool>, NoError> {
|
||||
let fullSizeResource = fileReference.media.resource
|
||||
var reducedSizeResource: MediaResource?
|
||||
if let videoThumbnail = fileReference.media.videoThumbnails.first {
|
||||
reducedSizeResource = videoThumbnail.resource
|
||||
}
|
||||
|
||||
let thumbnailRepresentation = smallestImageRepresentation(fileReference.media.previewRepresentations)
|
||||
let thumbnailRepresentation = useLargeThumbnail ? largestImageRepresentation(fileReference.media.previewRepresentations) : smallestImageRepresentation(fileReference.media.previewRepresentations)
|
||||
let thumbnailResource = thumbnailRepresentation?.resource
|
||||
|
||||
let maybeFullSize = postbox.mediaBox.cachedResourceRepresentation(fullSizeResource, representation: thumbnailSize ? CachedScaledVideoFirstFrameRepresentation(size: CGSize(width: 160.0, height: 160.0)) : CachedVideoFirstFrameRepresentation(), complete: false, fetch: false, attemptSynchronously: synchronousLoad)
|
||||
@ -1320,14 +1320,14 @@ public func gifPaneVideoThumbnail(account: Account, videoReference: FileMediaRef
|
||||
}
|
||||
}
|
||||
|
||||
public func mediaGridMessageVideo(postbox: Postbox, videoReference: FileMediaReference, onlyFullSize: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false, overlayColor: UIColor? = nil, nilForEmptyResult: Bool = false, useMiniThumbnailIfAvailable: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||
return internalMediaGridMessageVideo(postbox: postbox, videoReference: videoReference, onlyFullSize: onlyFullSize, synchronousLoad: synchronousLoad, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail, overlayColor: overlayColor, nilForEmptyResult: nilForEmptyResult, useMiniThumbnailIfAvailable: useMiniThumbnailIfAvailable)
|
||||
public func mediaGridMessageVideo(postbox: Postbox, videoReference: FileMediaReference, onlyFullSize: Bool = false, useLargeThumbnail: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false, overlayColor: UIColor? = nil, nilForEmptyResult: Bool = false, useMiniThumbnailIfAvailable: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||
return internalMediaGridMessageVideo(postbox: postbox, videoReference: videoReference, onlyFullSize: onlyFullSize, useLargeThumbnail: useLargeThumbnail, synchronousLoad: synchronousLoad, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail, overlayColor: overlayColor, nilForEmptyResult: nilForEmptyResult, useMiniThumbnailIfAvailable: useMiniThumbnailIfAvailable)
|
||||
|> map {
|
||||
return $0.1
|
||||
}
|
||||
}
|
||||
|
||||
public func internalMediaGridMessageVideo(postbox: Postbox, videoReference: FileMediaReference, imageReference: ImageMediaReference? = nil, onlyFullSize: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false, overlayColor: UIColor? = nil, nilForEmptyResult: Bool = false, useMiniThumbnailIfAvailable: Bool = false) -> Signal<(() -> CGSize?, (TransformImageArguments) -> DrawingContext?), NoError> {
|
||||
public func internalMediaGridMessageVideo(postbox: Postbox, videoReference: FileMediaReference, imageReference: ImageMediaReference? = nil, onlyFullSize: Bool = false, useLargeThumbnail: Bool = false, synchronousLoad: Bool = false, autoFetchFullSizeThumbnail: Bool = false, overlayColor: UIColor? = nil, nilForEmptyResult: Bool = false, useMiniThumbnailIfAvailable: Bool = false) -> Signal<(() -> CGSize?, (TransformImageArguments) -> DrawingContext?), NoError> {
|
||||
let signal: Signal<Tuple3<Data?, Tuple2<Data, String>?, Bool>, NoError>
|
||||
if let imageReference = imageReference {
|
||||
signal = chatMessagePhotoDatas(postbox: postbox, photoReference: imageReference, tryAdditionalRepresentations: true, synchronousLoad: synchronousLoad)
|
||||
@ -1338,7 +1338,7 @@ public func internalMediaGridMessageVideo(postbox: Postbox, videoReference: File
|
||||
return Tuple(thumbnailData, fullSizeData.flatMap({ Tuple($0, "") }), fullSizeComplete)
|
||||
}
|
||||
} else {
|
||||
signal = chatMessageVideoDatas(postbox: postbox, fileReference: videoReference, onlyFullSize: onlyFullSize, synchronousLoad: synchronousLoad, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail)
|
||||
signal = chatMessageVideoDatas(postbox: postbox, fileReference: videoReference, onlyFullSize: onlyFullSize, useLargeThumbnail: useLargeThumbnail, synchronousLoad: synchronousLoad, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail)
|
||||
}
|
||||
|
||||
return signal
|
||||
|
@ -351,7 +351,7 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
|
||||
if let video = videoRepresentations.last, let peerReference = PeerReference(self.peer) {
|
||||
let videoFileReference = FileMediaReference.avatarList(peer: peerReference, media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.representation.resource, previewRepresentations: representations.map { $0.representation }, videoThumbnails: [], immediateThumbnailData: immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.representation.dimensions, flags: [])]))
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(id, nil), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.representation.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, autoFetchFullSizeThumbnail: true, startTimestamp: video.representation.startTimestamp, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear)
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(id, nil), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.representation.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, useLargeThumbnail: true, autoFetchFullSizeThumbnail: true, startTimestamp: video.representation.startTimestamp, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear)
|
||||
|
||||
if videoContent.id != self.videoContent?.id {
|
||||
self.videoContent = videoContent
|
||||
@ -1278,7 +1278,7 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
|
||||
if let video = videoRepresentations.last, let peerReference = PeerReference(peer) {
|
||||
let videoFileReference = FileMediaReference.avatarList(peer: peerReference, media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.representation.resource, previewRepresentations: representations.map { $0.representation }, videoThumbnails: [], immediateThumbnailData: immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.representation.dimensions, flags: [])]))
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(id, nil), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.representation.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, autoFetchFullSizeThumbnail: true, startTimestamp: video.representation.startTimestamp, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear)
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(id, nil), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.representation.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, useLargeThumbnail: true, autoFetchFullSizeThumbnail: true, startTimestamp: video.representation.startTimestamp, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear)
|
||||
if videoContent.id != self.videoContent?.id {
|
||||
self.videoNode?.removeFromSupernode()
|
||||
|
||||
@ -1564,7 +1564,7 @@ final class PeerInfoEditingAvatarNode: ASDisplayNode {
|
||||
|
||||
if let video = videoRepresentations.last, let peerReference = PeerReference(peer) {
|
||||
let videoFileReference = FileMediaReference.avatarList(peer: peerReference, media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.representation.resource, previewRepresentations: representations.map { $0.representation }, videoThumbnails: [], immediateThumbnailData: immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.representation.dimensions, flags: [])]))
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(id, nil), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.representation.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, autoFetchFullSizeThumbnail: true, startTimestamp: video.representation.startTimestamp, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear)
|
||||
let videoContent = NativeVideoContent(id: .profileVideo(id, nil), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.representation.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, useLargeThumbnail: true, autoFetchFullSizeThumbnail: true, startTimestamp: video.representation.startTimestamp, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear)
|
||||
if videoContent.id != self.videoContent?.id {
|
||||
self.videoNode?.removeFromSupernode()
|
||||
|
||||
|
@ -31,13 +31,14 @@ public final class NativeVideoContent: UniversalVideoContent {
|
||||
public let baseRate: Double
|
||||
let fetchAutomatically: Bool
|
||||
let onlyFullSizeThumbnail: Bool
|
||||
let useLargeThumbnail: Bool
|
||||
let autoFetchFullSizeThumbnail: Bool
|
||||
let startTimestamp: Double?
|
||||
let continuePlayingWithoutSoundOnLostAudioSession: Bool
|
||||
let placeholderColor: UIColor
|
||||
let tempFilePath: String?
|
||||
|
||||
public init(id: NativeVideoContentId, fileReference: FileMediaReference, imageReference: ImageMediaReference? = nil, streamVideo: MediaPlayerStreaming = .none, loopVideo: Bool = false, enableSound: Bool = true, baseRate: Double = 1.0, fetchAutomatically: Bool = true, onlyFullSizeThumbnail: Bool = false, autoFetchFullSizeThumbnail: Bool = false, startTimestamp: Double? = nil, continuePlayingWithoutSoundOnLostAudioSession: Bool = false, placeholderColor: UIColor = .white, tempFilePath: String? = nil) {
|
||||
public init(id: NativeVideoContentId, fileReference: FileMediaReference, imageReference: ImageMediaReference? = nil, streamVideo: MediaPlayerStreaming = .none, loopVideo: Bool = false, enableSound: Bool = true, baseRate: Double = 1.0, fetchAutomatically: Bool = true, onlyFullSizeThumbnail: Bool = false, useLargeThumbnail: Bool = false, autoFetchFullSizeThumbnail: Bool = false, startTimestamp: Double? = nil, continuePlayingWithoutSoundOnLostAudioSession: Bool = false, placeholderColor: UIColor = .white, tempFilePath: String? = nil) {
|
||||
self.id = id
|
||||
self.nativeId = id
|
||||
self.fileReference = fileReference
|
||||
@ -62,6 +63,7 @@ public final class NativeVideoContent: UniversalVideoContent {
|
||||
self.baseRate = baseRate
|
||||
self.fetchAutomatically = fetchAutomatically
|
||||
self.onlyFullSizeThumbnail = onlyFullSizeThumbnail
|
||||
self.useLargeThumbnail = useLargeThumbnail
|
||||
self.autoFetchFullSizeThumbnail = autoFetchFullSizeThumbnail
|
||||
self.startTimestamp = startTimestamp
|
||||
self.continuePlayingWithoutSoundOnLostAudioSession = continuePlayingWithoutSoundOnLostAudioSession
|
||||
@ -70,7 +72,7 @@ public final class NativeVideoContent: UniversalVideoContent {
|
||||
}
|
||||
|
||||
public func makeContentNode(postbox: Postbox, audioSession: ManagedAudioSession) -> UniversalVideoContentNode & ASDisplayNode {
|
||||
return NativeVideoContentNode(postbox: postbox, audioSessionManager: audioSession, fileReference: self.fileReference, imageReference: self.imageReference, streamVideo: self.streamVideo, loopVideo: self.loopVideo, enableSound: self.enableSound, baseRate: self.baseRate, fetchAutomatically: self.fetchAutomatically, onlyFullSizeThumbnail: self.onlyFullSizeThumbnail, autoFetchFullSizeThumbnail: self.autoFetchFullSizeThumbnail, startTimestamp: self.startTimestamp, continuePlayingWithoutSoundOnLostAudioSession: self.continuePlayingWithoutSoundOnLostAudioSession, placeholderColor: self.placeholderColor, tempFilePath: self.tempFilePath)
|
||||
return NativeVideoContentNode(postbox: postbox, audioSessionManager: audioSession, fileReference: self.fileReference, imageReference: self.imageReference, streamVideo: self.streamVideo, loopVideo: self.loopVideo, enableSound: self.enableSound, baseRate: self.baseRate, fetchAutomatically: self.fetchAutomatically, onlyFullSizeThumbnail: self.onlyFullSizeThumbnail, useLargeThumbnail: self.useLargeThumbnail, autoFetchFullSizeThumbnail: self.autoFetchFullSizeThumbnail, startTimestamp: self.startTimestamp, continuePlayingWithoutSoundOnLostAudioSession: self.continuePlayingWithoutSoundOnLostAudioSession, placeholderColor: self.placeholderColor, tempFilePath: self.tempFilePath)
|
||||
}
|
||||
|
||||
public func isEqual(to other: UniversalVideoContent) -> Bool {
|
||||
@ -143,7 +145,7 @@ private final class NativeVideoContentNode: ASDisplayNode, UniversalVideoContent
|
||||
|
||||
private var shouldPlay: Bool = false
|
||||
|
||||
init(postbox: Postbox, audioSessionManager: ManagedAudioSession, fileReference: FileMediaReference, imageReference: ImageMediaReference?, streamVideo: MediaPlayerStreaming, loopVideo: Bool, enableSound: Bool, baseRate: Double, fetchAutomatically: Bool, onlyFullSizeThumbnail: Bool, autoFetchFullSizeThumbnail: Bool, startTimestamp: Double?, continuePlayingWithoutSoundOnLostAudioSession: Bool = false, placeholderColor: UIColor, tempFilePath: String?) {
|
||||
init(postbox: Postbox, audioSessionManager: ManagedAudioSession, fileReference: FileMediaReference, imageReference: ImageMediaReference?, streamVideo: MediaPlayerStreaming, loopVideo: Bool, enableSound: Bool, baseRate: Double, fetchAutomatically: Bool, onlyFullSizeThumbnail: Bool, useLargeThumbnail: Bool, autoFetchFullSizeThumbnail: Bool, startTimestamp: Double?, continuePlayingWithoutSoundOnLostAudioSession: Bool = false, placeholderColor: UIColor, tempFilePath: String?) {
|
||||
self.postbox = postbox
|
||||
self.fileReference = fileReference
|
||||
self.placeholderColor = placeholderColor
|
||||
@ -180,7 +182,7 @@ private final class NativeVideoContentNode: ASDisplayNode, UniversalVideoContent
|
||||
self?.performActionAtEnd()
|
||||
}
|
||||
|
||||
self.imageNode.setSignal(internalMediaGridMessageVideo(postbox: postbox, videoReference: fileReference, imageReference: imageReference, onlyFullSize: onlyFullSizeThumbnail, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail || fileReference.media.isInstantVideo) |> map { [weak self] getSize, getData in
|
||||
self.imageNode.setSignal(internalMediaGridMessageVideo(postbox: postbox, videoReference: fileReference, imageReference: imageReference, onlyFullSize: onlyFullSizeThumbnail, useLargeThumbnail: useLargeThumbnail, autoFetchFullSizeThumbnail: autoFetchFullSizeThumbnail || fileReference.media.isInstantVideo) |> map { [weak self] getSize, getData in
|
||||
Queue.mainQueue().async {
|
||||
if let strongSelf = self, strongSelf.dimensions == nil {
|
||||
if let dimensions = getSize() {
|
||||
|
@ -43,7 +43,6 @@ private final class ProfileDataPhotoPreloadContext {
|
||||
|
||||
let disposable: Disposable
|
||||
var value: Any?
|
||||
var skipNext = false
|
||||
var emptyTimer: SwiftSignalKit.Timer?
|
||||
|
||||
init(disposable: Disposable) {
|
||||
@ -211,9 +210,6 @@ private final class PeerChannelMemberCategoriesContextsManagerImpl {
|
||||
let context: ProfileDataPhotoPreloadContext
|
||||
if let current = self.profileDataPhotoPreloadContexts[peerId] {
|
||||
context = current
|
||||
if let _ = context.value {
|
||||
context.skipNext = true
|
||||
}
|
||||
} else {
|
||||
let disposable = MetaDisposable()
|
||||
context = ProfileDataPhotoPreloadContext(disposable: disposable)
|
||||
@ -223,10 +219,6 @@ private final class PeerChannelMemberCategoriesContextsManagerImpl {
|
||||
guard let context = context else {
|
||||
return
|
||||
}
|
||||
if context.skipNext {
|
||||
context.skipNext = false
|
||||
return
|
||||
}
|
||||
context.value = value
|
||||
for f in context.subscribers.copyItems() {
|
||||
f(value)
|
||||
|
Loading…
x
Reference in New Issue
Block a user