mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-31 23:47:01 +00:00
Merge commit '5e36741afa9f5f28e55af8fd13e718a300c98870'
This commit is contained in:
commit
9cd7e3a8f1
@ -312,6 +312,7 @@ public final class GalleryPagerNode: ASDisplayNode, UIScrollViewDelegate, UIGest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var updateOnReplacement = false
|
||||||
public func replaceItems(_ items: [GalleryItem], centralItemIndex: Int?, synchronous: Bool = false) {
|
public func replaceItems(_ items: [GalleryItem], centralItemIndex: Int?, synchronous: Bool = false) {
|
||||||
var updateItems: [GalleryPagerUpdateItem] = []
|
var updateItems: [GalleryPagerUpdateItem] = []
|
||||||
var deleteItems: [Int] = []
|
var deleteItems: [Int] = []
|
||||||
@ -326,14 +327,20 @@ public final class GalleryPagerNode: ASDisplayNode, UIScrollViewDelegate, UIGest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i in 0 ..< items.count {
|
if self.updateOnReplacement {
|
||||||
if i == previousIndexById[items[i].id] {
|
for i in 0 ..< items.count {
|
||||||
updateItems.append(GalleryPagerUpdateItem(index: i, previousIndex: i, item: items[i]))
|
if (previousIndexById[items[i].id] == nil) {
|
||||||
} else {
|
insertItems.append(GalleryPagerInsertItem(index: i, item: items[i], previousIndex: previousIndexById[items[i].id]))
|
||||||
|
} else {
|
||||||
|
updateItems.append(GalleryPagerUpdateItem(index: i, previousIndex: i, item: items[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i in 0 ..< items.count {
|
||||||
insertItems.append(GalleryPagerInsertItem(index: i, item: items[i], previousIndex: previousIndexById[items[i].id]))
|
insertItems.append(GalleryPagerInsertItem(index: i, item: items[i], previousIndex: previousIndexById[items[i].id]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.transaction(GalleryPagerTransaction(deleteItems: deleteItems, insertItems: insertItems, updateItems: updateItems, focusOnItem: centralItemIndex, synchronous: synchronous))
|
self.transaction(GalleryPagerTransaction(deleteItems: deleteItems, insertItems: insertItems, updateItems: updateItems, focusOnItem: centralItemIndex, synchronous: synchronous))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +411,7 @@ public final class GalleryPagerNode: ASDisplayNode, UIScrollViewDelegate, UIGest
|
|||||||
self.ignoreCentralItemIndexUpdate = true
|
self.ignoreCentralItemIndexUpdate = true
|
||||||
self.centralItemIndex = focusOnItem
|
self.centralItemIndex = focusOnItem
|
||||||
self.ignoreCentralItemIndexUpdate = false
|
self.ignoreCentralItemIndexUpdate = false
|
||||||
self.updateItemNodes(transition: .immediate, forceOffsetReset: true)
|
self.updateItemNodes(transition: .immediate, forceOffsetReset: true, synchronous: transaction.synchronous)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
- (void)closeCurtains;
|
- (void)closeCurtains;
|
||||||
- (void)openCurtains;
|
- (void)openCurtains;
|
||||||
|
|
||||||
|
- (void)flash:(void (^)(void))completion;
|
||||||
|
|
||||||
- (void)invalidateCropRect;
|
- (void)invalidateCropRect;
|
||||||
|
|
||||||
- (UIImage *)currentImage;
|
- (UIImage *)currentImage;
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
- (void)prepareTransitionOutSaving:(bool)saving;
|
- (void)prepareTransitionOutSaving:(bool)saving;
|
||||||
|
|
||||||
- (void)prepareForCustomTransitionOut;
|
- (void)prepareForCustomTransitionOut;
|
||||||
|
- (void)finishCustomTransitionOut;
|
||||||
|
|
||||||
- (void)animateTransitionIn;
|
- (void)animateTransitionIn;
|
||||||
- (CGRect)_targetFrameForTransitionInFromFrame:(CGRect)fromFrame;
|
- (CGRect)_targetFrameForTransitionInFromFrame:(CGRect)fromFrame;
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
@interface TGPhotoVideoEditor : NSObject
|
@interface TGPhotoVideoEditor : NSObject
|
||||||
|
|
||||||
|
+ (void)presentWithContext:(id<LegacyComponentsContext>)context parentController:(TGViewController *)parentController image:(UIImage *)image video:(NSURL *)video didFinishWithImage:(void (^)(UIImage *image))didFinishWithImage didFinishWithVideo:(void (^)(UIImage *image, NSURL *url, TGVideoEditAdjustments *adjustments))didFinishWithVideo;
|
||||||
|
|
||||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSString *)caption entities:(NSArray *)entities withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed;
|
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSString *)caption entities:(NSArray *)entities withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -484,7 +484,6 @@
|
|||||||
[_finalFilter addTarget:self.previewOutput.imageView];
|
[_finalFilter addTarget:self.previewOutput.imageView];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (_histogramGenerator != nil && !self.standalone) {
|
if (_histogramGenerator != nil && !self.standalone) {
|
||||||
[_finalFilter addTarget:_histogramGenerator];
|
[_finalFilter addTarget:_histogramGenerator];
|
||||||
|
@ -23,8 +23,12 @@
|
|||||||
|
|
||||||
#import <LegacyComponents/TGMenuView.h>
|
#import <LegacyComponents/TGMenuView.h>
|
||||||
|
|
||||||
|
#import "TGPaintFaceDetector.h"
|
||||||
|
|
||||||
@interface TGMediaPickerGalleryPhotoItemView ()
|
@interface TGMediaPickerGalleryPhotoItemView ()
|
||||||
{
|
{
|
||||||
|
SMetaDisposable *_facesDisposable;
|
||||||
|
|
||||||
UILabel *_fileInfoLabel;
|
UILabel *_fileInfoLabel;
|
||||||
|
|
||||||
TGMessageImageViewOverlayView *_progressView;
|
TGMessageImageViewOverlayView *_progressView;
|
||||||
@ -57,6 +61,8 @@
|
|||||||
self = [super initWithFrame:frame];
|
self = [super initWithFrame:frame];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
{
|
{
|
||||||
|
_facesDisposable = [[SMetaDisposable alloc] init];
|
||||||
|
|
||||||
__weak TGMediaPickerGalleryPhotoItemView *weakSelf = self;
|
__weak TGMediaPickerGalleryPhotoItemView *weakSelf = self;
|
||||||
_imageView = [[TGModernGalleryImageItemImageView alloc] init];
|
_imageView = [[TGModernGalleryImageItemImageView alloc] init];
|
||||||
_imageView.clipsToBounds = true;
|
_imageView.clipsToBounds = true;
|
||||||
@ -101,6 +107,7 @@
|
|||||||
{
|
{
|
||||||
[_adjustmentsDisposable dispose];
|
[_adjustmentsDisposable dispose];
|
||||||
[_attributesDisposable dispose];
|
[_attributesDisposable dispose];
|
||||||
|
[_facesDisposable dispose];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setHiddenAsBeingEdited:(bool)hidden
|
- (void)setHiddenAsBeingEdited:(bool)hidden
|
||||||
@ -226,8 +233,11 @@
|
|||||||
|
|
||||||
}]];
|
}]];
|
||||||
|
|
||||||
if (!item.asFile)
|
if (!item.asFile) {
|
||||||
|
[_facesDisposable setDisposable:[[TGPaintFaceDetector detectFacesInItem:item.editableMediaItem editingContext:item.editingContext] startWithNext:nil]];
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_fileInfoLabel.text = nil;
|
_fileInfoLabel.text = nil;
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#import <LegacyComponents/TGMenuView.h>
|
#import <LegacyComponents/TGMenuView.h>
|
||||||
|
|
||||||
#import "PGPhotoEditor.h"
|
#import "PGPhotoEditor.h"
|
||||||
|
#import "TGPaintFaceDetector.h"
|
||||||
|
|
||||||
@interface TGMediaPickerGalleryVideoItemView() <TGMediaPickerGalleryVideoScrubberDataSource, TGMediaPickerGalleryVideoScrubberDelegate>
|
@interface TGMediaPickerGalleryVideoItemView() <TGMediaPickerGalleryVideoScrubberDataSource, TGMediaPickerGalleryVideoScrubberDelegate>
|
||||||
{
|
{
|
||||||
@ -96,6 +97,7 @@
|
|||||||
SMetaDisposable *_adjustmentsDisposable;
|
SMetaDisposable *_adjustmentsDisposable;
|
||||||
SMetaDisposable *_attributesDisposable;
|
SMetaDisposable *_attributesDisposable;
|
||||||
SMetaDisposable *_downloadDisposable;
|
SMetaDisposable *_downloadDisposable;
|
||||||
|
SMetaDisposable *_facesDisposable;
|
||||||
SMetaDisposable *_currentAudioSession;
|
SMetaDisposable *_currentAudioSession;
|
||||||
|
|
||||||
SVariable *_editableItemVariable;
|
SVariable *_editableItemVariable;
|
||||||
@ -131,6 +133,7 @@
|
|||||||
|
|
||||||
_currentAudioSession = [[SMetaDisposable alloc] init];
|
_currentAudioSession = [[SMetaDisposable alloc] init];
|
||||||
_playerItemDisposable = [[SMetaDisposable alloc] init];
|
_playerItemDisposable = [[SMetaDisposable alloc] init];
|
||||||
|
_facesDisposable = [[SMetaDisposable alloc] init];
|
||||||
|
|
||||||
_videoDurationVar = [[SVariable alloc] init];
|
_videoDurationVar = [[SVariable alloc] init];
|
||||||
_videoDurationDisposable = [[SMetaDisposable alloc] init];
|
_videoDurationDisposable = [[SMetaDisposable alloc] init];
|
||||||
@ -251,6 +254,7 @@
|
|||||||
[_thumbnailsDisposable dispose];
|
[_thumbnailsDisposable dispose];
|
||||||
[_attributesDisposable dispose];
|
[_attributesDisposable dispose];
|
||||||
[_downloadDisposable dispose];
|
[_downloadDisposable dispose];
|
||||||
|
[_facesDisposable dispose];
|
||||||
[self stopPlayer];
|
[self stopPlayer];
|
||||||
|
|
||||||
[self releaseVolumeOverlay];
|
[self releaseVolumeOverlay];
|
||||||
@ -385,8 +389,13 @@
|
|||||||
|
|
||||||
[super setItem:item synchronously:synchronously];
|
[super setItem:item synchronously:synchronously];
|
||||||
|
|
||||||
if (itemChanged)
|
if (itemChanged) {
|
||||||
[self _playerCleanup];
|
[self _playerCleanup];
|
||||||
|
|
||||||
|
if (!item.asFile) {
|
||||||
|
[_facesDisposable setDisposable:[[TGPaintFaceDetector detectFacesInItem:item.editableMediaItem editingContext:item.editingContext] startWithNext:nil]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_scrubberView.allowsTrimming = false;
|
_scrubberView.allowsTrimming = false;
|
||||||
_videoDimensions = item.dimensions;
|
_videoDimensions = item.dimensions;
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#import <SSignalKit/SSignalKit.h>
|
#import <SSignalKit/SSignalKit.h>
|
||||||
|
|
||||||
|
@protocol TGMediaEditableItem;
|
||||||
|
@class TGMediaEditingContext;
|
||||||
|
|
||||||
@interface TGPaintFaceFeature : NSObject
|
@interface TGPaintFaceFeature : NSObject
|
||||||
{
|
{
|
||||||
CGPoint _position;
|
CGPoint _position;
|
||||||
@ -49,6 +52,8 @@
|
|||||||
|
|
||||||
+ (SSignal *)detectFacesInImage:(UIImage *)image originalSize:(CGSize)originalSize;
|
+ (SSignal *)detectFacesInImage:(UIImage *)image originalSize:(CGSize)originalSize;
|
||||||
|
|
||||||
|
+ (SSignal *)detectFacesInItem:(id<TGMediaEditableItem>)item editingContext:(TGMediaEditingContext *)editingContext;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#import <LegacyComponents/TGPaintUtils.h>
|
#import <LegacyComponents/TGPaintUtils.h>
|
||||||
#import <ImageIO/ImageIO.h>
|
#import <ImageIO/ImageIO.h>
|
||||||
|
|
||||||
|
#import "TGMediaEditingContext.h"
|
||||||
|
#import "UIImage+TG.h"
|
||||||
|
|
||||||
@interface TGPaintFace ()
|
@interface TGPaintFace ()
|
||||||
|
|
||||||
+ (instancetype)faceWithBounds:(CGRect)bounds angle:(CGFloat)angle leftEye:(TGPaintFaceEye *)leftEye rightEye:(TGPaintFaceEye *)rightEye mouth:(TGPaintFaceMouth *)mouth;
|
+ (instancetype)faceWithBounds:(CGRect)bounds angle:(CGFloat)angle leftEye:(TGPaintFaceEye *)leftEye rightEye:(TGPaintFaceEye *)rightEye mouth:(TGPaintFaceMouth *)mouth;
|
||||||
@ -26,6 +29,41 @@
|
|||||||
|
|
||||||
@implementation TGPaintFaceDetector
|
@implementation TGPaintFaceDetector
|
||||||
|
|
||||||
|
+ (SSignal *)detectFacesInItem:(id<TGMediaEditableItem>)item editingContext:(TGMediaEditingContext *)editingContext
|
||||||
|
{
|
||||||
|
CGSize originalSize = item.originalSize;
|
||||||
|
|
||||||
|
SSignal *cachedFaces = [editingContext facesForItem:item];
|
||||||
|
SSignal *cachedSignal = [cachedFaces mapToSignal:^SSignal *(id result)
|
||||||
|
{
|
||||||
|
if (result == nil)
|
||||||
|
return [SSignal fail:nil];
|
||||||
|
return [SSignal single:result];
|
||||||
|
}];
|
||||||
|
|
||||||
|
SSignal *imageSignal = [item screenImageSignal:0];
|
||||||
|
SSignal *detectSignal = [[[imageSignal filter:^bool(UIImage *image)
|
||||||
|
{
|
||||||
|
if (![image isKindOfClass:[UIImage class]])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (image.degraded)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}] take:1] mapToSignal:^SSignal *(UIImage *image) {
|
||||||
|
return [[TGPaintFaceDetector detectFacesInImage:image originalSize:originalSize] startOn:[SQueue concurrentDefaultQueue]];
|
||||||
|
}];
|
||||||
|
|
||||||
|
return [[[cachedSignal catch:^SSignal *(__unused id error)
|
||||||
|
{
|
||||||
|
return detectSignal;
|
||||||
|
}] deliverOn:[SQueue mainQueue]] onNext:^(NSArray *next)
|
||||||
|
{
|
||||||
|
[editingContext setFaces:next forItem:item];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
+ (SSignal *)detectFacesInImage:(UIImage *)image originalSize:(CGSize)originalSize
|
+ (SSignal *)detectFacesInImage:(UIImage *)image originalSize:(CGSize)originalSize
|
||||||
{
|
{
|
||||||
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
return [[SSignal alloc] initWithGenerator:^id<SDisposable>(SSubscriber *subscriber)
|
||||||
|
@ -26,6 +26,8 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200;
|
|||||||
UIView *_snapshotView;
|
UIView *_snapshotView;
|
||||||
CGSize _snapshotSize;
|
CGSize _snapshotSize;
|
||||||
|
|
||||||
|
UIView *_flashView;
|
||||||
|
|
||||||
UIView *_topOverlayView;
|
UIView *_topOverlayView;
|
||||||
UIView *_leftOverlayView;
|
UIView *_leftOverlayView;
|
||||||
UIView *_rightOverlayView;
|
UIView *_rightOverlayView;
|
||||||
@ -39,7 +41,7 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200;
|
|||||||
|
|
||||||
CGFloat _currentDiameter;
|
CGFloat _currentDiameter;
|
||||||
|
|
||||||
PGPhotoEditorView *_fullPreviewView;
|
__weak PGPhotoEditorView *_fullPreviewView;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@ -82,6 +84,12 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200;
|
|||||||
_fullPreviewView.userInteractionEnabled = false;
|
_fullPreviewView.userInteractionEnabled = false;
|
||||||
[_wrapperView addSubview:_fullPreviewView];
|
[_wrapperView addSubview:_fullPreviewView];
|
||||||
|
|
||||||
|
_flashView = [[UIView alloc] init];
|
||||||
|
_flashView.alpha = 0.0;
|
||||||
|
_flashView.backgroundColor = [UIColor whiteColor];
|
||||||
|
_flashView.userInteractionEnabled = false;
|
||||||
|
[self addSubview:_flashView];
|
||||||
|
|
||||||
_topCurtainView = [[UIView alloc] initWithFrame:CGRectZero];
|
_topCurtainView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||||
_topCurtainView.backgroundColor = [UIColor blackColor];
|
_topCurtainView.backgroundColor = [UIColor blackColor];
|
||||||
[self addSubview:_topCurtainView];
|
[self addSubview:_topCurtainView];
|
||||||
@ -122,6 +130,11 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200;
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
_scrollView.delegate = nil;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer {
|
- (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer {
|
||||||
if (self.tapped != nil)
|
if (self.tapped != nil)
|
||||||
self.tapped();
|
self.tapped();
|
||||||
@ -611,6 +624,8 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200;
|
|||||||
{
|
{
|
||||||
[self _layoutOverlayViews];
|
[self _layoutOverlayViews];
|
||||||
|
|
||||||
|
_flashView.frame = self.bounds;
|
||||||
|
|
||||||
if (_scrollView.superview == nil)
|
if (_scrollView.superview == nil)
|
||||||
{
|
{
|
||||||
_scrollView.frame = self.bounds;
|
_scrollView.frame = self.bounds;
|
||||||
@ -647,4 +662,16 @@ const CGFloat TGPhotoAvatarCropViewCurtainMargin = 200;
|
|||||||
return CGSizeMake(20, 20);
|
return CGSizeMake(20, 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)flash:(void (^)(void))completion {
|
||||||
|
[UIView animateWithDuration:0.12 animations:^{
|
||||||
|
_flashView.alpha = 1.0f;
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
[UIView animateWithDuration:0.2 animations:^{
|
||||||
|
_flashView.alpha = 0.0f;
|
||||||
|
} completion:^(BOOL finished) {
|
||||||
|
completion();
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -15,7 +15,12 @@
|
|||||||
@property (nonatomic, copy) void (^croppingChanged)(void);
|
@property (nonatomic, copy) void (^croppingChanged)(void);
|
||||||
@property (nonatomic, copy) void (^togglePlayback)(void);
|
@property (nonatomic, copy) void (^togglePlayback)(void);
|
||||||
|
|
||||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context photoEditor:(PGPhotoEditor *)photoEditor previewView:(TGPhotoEditorPreviewView *)previewView scrubberView:(TGMediaPickerGalleryVideoScrubber *)scrubberView dotImageView:(UIView *)dotImageView fullPreviewView:(PGPhotoEditorView *)fullPreviewView;
|
@property (nonatomic, weak) UIView *dotImageView;
|
||||||
|
@property (nonatomic, weak) UIView *dotMarkerView;
|
||||||
|
@property (nonatomic, weak) PGPhotoEditorView *fullPreviewView;
|
||||||
|
@property (nonatomic, weak) TGMediaPickerGalleryVideoScrubber *scrubberView;
|
||||||
|
|
||||||
|
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context photoEditor:(PGPhotoEditor *)photoEditor previewView:(TGPhotoEditorPreviewView *)previewView;
|
||||||
|
|
||||||
- (void)setImage:(UIImage *)image;
|
- (void)setImage:(UIImage *)image;
|
||||||
- (void)setSnapshotImage:(UIImage *)snapshotImage;
|
- (void)setSnapshotImage:(UIImage *)snapshotImage;
|
||||||
|
@ -32,18 +32,13 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
|
|
||||||
UIView *_wrapperView;
|
UIView *_wrapperView;
|
||||||
|
|
||||||
TGPhotoAvatarCropView *_cropView;
|
__weak TGPhotoAvatarCropView *_cropView;
|
||||||
PGPhotoEditorView *_fullPreviewView;
|
|
||||||
|
|
||||||
UIView *_portraitToolsWrapperView;
|
UIView *_portraitToolsWrapperView;
|
||||||
UIView *_landscapeToolsWrapperView;
|
UIView *_landscapeToolsWrapperView;
|
||||||
UIView *_portraitWrapperBackgroundView;
|
UIView *_portraitWrapperBackgroundView;
|
||||||
UIView *_landscapeWrapperBackgroundView;
|
UIView *_landscapeWrapperBackgroundView;
|
||||||
|
|
||||||
TGMediaPickerGalleryVideoScrubber *_scrubberView;
|
|
||||||
UIView *_dotImageView;
|
|
||||||
UIView *_videoAreaView;
|
|
||||||
UIView *_flashView;
|
|
||||||
UIView *_portraitToolControlView;
|
UIView *_portraitToolControlView;
|
||||||
UIView *_landscapeToolControlView;
|
UIView *_landscapeToolControlView;
|
||||||
UILabel *_coverLabel;
|
UILabel *_coverLabel;
|
||||||
@ -58,21 +53,20 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
|
|
||||||
@implementation TGPhotoAvatarPreviewController
|
@implementation TGPhotoAvatarPreviewController
|
||||||
|
|
||||||
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context photoEditor:(PGPhotoEditor *)photoEditor previewView:(TGPhotoEditorPreviewView *)previewView scrubberView:(TGMediaPickerGalleryVideoScrubber *)scrubberView dotImageView:(UIView *)dotImageView fullPreviewView:(PGPhotoEditorView *)fullPreviewView
|
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context photoEditor:(PGPhotoEditor *)photoEditor previewView:(TGPhotoEditorPreviewView *)previewView {
|
||||||
{
|
|
||||||
self = [super initWithContext:context];
|
self = [super initWithContext:context];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
{
|
{
|
||||||
self.photoEditor = photoEditor;
|
self.photoEditor = photoEditor;
|
||||||
self.previewView = previewView;
|
self.previewView = previewView;
|
||||||
_fullPreviewView = fullPreviewView;
|
|
||||||
_scrubberView = scrubberView;
|
|
||||||
|
|
||||||
_dotImageView = dotImageView;
|
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
NSLog(@"");
|
||||||
|
}
|
||||||
|
|
||||||
- (void)loadView
|
- (void)loadView
|
||||||
{
|
{
|
||||||
[super loadView];
|
[super loadView];
|
||||||
@ -90,7 +84,7 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
if (strongSelf == nil)
|
if (strongSelf == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
self.controlVideoPlayback(false);
|
strongSelf.controlVideoPlayback(false);
|
||||||
};
|
};
|
||||||
void(^interactionEnded)(void) = ^
|
void(^interactionEnded)(void) = ^
|
||||||
{
|
{
|
||||||
@ -101,11 +95,12 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
if ([strongSelf shouldAutorotate])
|
if ([strongSelf shouldAutorotate])
|
||||||
[TGViewController attemptAutorotation];
|
[TGViewController attemptAutorotation];
|
||||||
|
|
||||||
self.controlVideoPlayback(true);
|
strongSelf.controlVideoPlayback(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
PGPhotoEditor *photoEditor = self.photoEditor;
|
PGPhotoEditor *photoEditor = self.photoEditor;
|
||||||
_cropView = [[TGPhotoAvatarCropView alloc] initWithOriginalSize:photoEditor.originalSize screenSize:[self referenceViewSize] fullPreviewView:_fullPreviewView];
|
TGPhotoAvatarCropView *cropView = [[TGPhotoAvatarCropView alloc] initWithOriginalSize:photoEditor.originalSize screenSize:[self referenceViewSize] fullPreviewView:_fullPreviewView];
|
||||||
|
_cropView = cropView;
|
||||||
[_cropView setCropRect:photoEditor.cropRect];
|
[_cropView setCropRect:photoEditor.cropRect];
|
||||||
[_cropView setCropOrientation:photoEditor.cropOrientation];
|
[_cropView setCropOrientation:photoEditor.cropOrientation];
|
||||||
[_cropView setCropMirrored:photoEditor.cropMirrored];
|
[_cropView setCropMirrored:photoEditor.cropMirrored];
|
||||||
@ -142,7 +137,7 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
}
|
}
|
||||||
_cropView.interactionBegan = interactionBegan;
|
_cropView.interactionBegan = interactionBegan;
|
||||||
_cropView.interactionEnded = interactionEnded;
|
_cropView.interactionEnded = interactionEnded;
|
||||||
[_wrapperView addSubview:_cropView];
|
[_wrapperView addSubview:cropView];
|
||||||
|
|
||||||
_portraitToolsWrapperView = [[UIView alloc] initWithFrame:CGRectZero];
|
_portraitToolsWrapperView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||||
[_wrapperView addSubview:_portraitToolsWrapperView];
|
[_wrapperView addSubview:_portraitToolsWrapperView];
|
||||||
@ -162,18 +157,9 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
_landscapeWrapperBackgroundView.backgroundColor = [TGPhotoEditorInterfaceAssets toolbarTransparentBackgroundColor];
|
_landscapeWrapperBackgroundView.backgroundColor = [TGPhotoEditorInterfaceAssets toolbarTransparentBackgroundColor];
|
||||||
_landscapeWrapperBackgroundView.userInteractionEnabled = false;
|
_landscapeWrapperBackgroundView.userInteractionEnabled = false;
|
||||||
[_landscapeToolsWrapperView addSubview:_landscapeWrapperBackgroundView];
|
[_landscapeToolsWrapperView addSubview:_landscapeWrapperBackgroundView];
|
||||||
|
|
||||||
_videoAreaView = [[UIView alloc] init];
|
|
||||||
[self.view insertSubview:_videoAreaView belowSubview:_wrapperView];
|
|
||||||
|
|
||||||
[_portraitToolsWrapperView addSubview:_scrubberView];
|
[_portraitToolsWrapperView addSubview:_scrubberView];
|
||||||
|
|
||||||
_flashView = [[UIView alloc] init];
|
|
||||||
_flashView.alpha = 0.0;
|
|
||||||
_flashView.backgroundColor = [UIColor whiteColor];
|
|
||||||
_flashView.userInteractionEnabled = false;
|
|
||||||
[_videoAreaView addSubview:_flashView];
|
|
||||||
|
|
||||||
_coverLabel = [[UILabel alloc] init];
|
_coverLabel = [[UILabel alloc] init];
|
||||||
_coverLabel.alpha = 0.7f;
|
_coverLabel.alpha = 0.7f;
|
||||||
_coverLabel.backgroundColor = [UIColor clearColor];
|
_coverLabel.backgroundColor = [UIColor clearColor];
|
||||||
@ -183,7 +169,6 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
[_coverLabel sizeToFit];
|
[_coverLabel sizeToFit];
|
||||||
[_portraitToolsWrapperView addSubview:_coverLabel];
|
[_portraitToolsWrapperView addSubview:_coverLabel];
|
||||||
|
|
||||||
_dotImageView.alpha = 1.0f;
|
|
||||||
[_wrapperView addSubview:_dotImageView];
|
[_wrapperView addSubview:_dotImageView];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,7 +248,9 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
- (void)prepareTransitionInWithReferenceView:(UIView *)referenceView referenceFrame:(CGRect)referenceFrame parentView:(UIView *)parentView noTransitionView:(bool)noTransitionView
|
- (void)prepareTransitionInWithReferenceView:(UIView *)referenceView referenceFrame:(CGRect)referenceFrame parentView:(UIView *)parentView noTransitionView:(bool)noTransitionView
|
||||||
{
|
{
|
||||||
[super prepareTransitionInWithReferenceView:referenceView referenceFrame:referenceFrame parentView:parentView noTransitionView:noTransitionView];
|
[super prepareTransitionInWithReferenceView:referenceView referenceFrame:referenceFrame parentView:parentView noTransitionView:noTransitionView];
|
||||||
[self.view insertSubview:_transitionView belowSubview:_wrapperView];
|
|
||||||
|
if (self.initialAppearance && self.fromCamera)
|
||||||
|
[self.view insertSubview:_transitionView belowSubview:_wrapperView];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)transitionIn
|
- (void)transitionIn
|
||||||
@ -282,6 +269,8 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
{
|
{
|
||||||
_portraitToolsWrapperView.alpha = 1.0f;
|
_portraitToolsWrapperView.alpha = 1.0f;
|
||||||
_landscapeToolsWrapperView.alpha = 1.0f;
|
_landscapeToolsWrapperView.alpha = 1.0f;
|
||||||
|
_dotImageView.alpha = 1.0f;
|
||||||
|
_dotMarkerView.alpha = 1.0f;
|
||||||
} completion:^(BOOL finished) {
|
} completion:^(BOOL finished) {
|
||||||
_scrubberView.layer.shouldRasterize = false;
|
_scrubberView.layer.shouldRasterize = false;
|
||||||
}];
|
}];
|
||||||
@ -387,6 +376,7 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
_cropView.transform = CGAffineTransformMakeScale(targetCropViewScale, targetCropViewScale);
|
_cropView.transform = CGAffineTransformMakeScale(targetCropViewScale, targetCropViewScale);
|
||||||
} completion:^(__unused BOOL finished)
|
} completion:^(__unused BOOL finished)
|
||||||
{
|
{
|
||||||
|
[_cropView removeFromSuperview];
|
||||||
_previewView.alpha = 1.0;
|
_previewView.alpha = 1.0;
|
||||||
if (self.finishedTransitionOut != nil)
|
if (self.finishedTransitionOut != nil)
|
||||||
self.finishedTransitionOut();
|
self.finishedTransitionOut();
|
||||||
@ -394,8 +384,9 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
if (completion != nil)
|
if (completion != nil)
|
||||||
completion();
|
completion();
|
||||||
}];
|
}];
|
||||||
} else if (self.fromCamera) {
|
} else {
|
||||||
_previewView.alpha = 0.0f;
|
if (self.fromCamera)
|
||||||
|
_previewView.alpha = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (self.effectiveOrientation)
|
switch (self.effectiveOrientation)
|
||||||
@ -438,9 +429,11 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
_portraitToolsWrapperView.alpha = 0.0f;
|
_portraitToolsWrapperView.alpha = 0.0f;
|
||||||
_landscapeToolsWrapperView.alpha = 0.0f;
|
_landscapeToolsWrapperView.alpha = 0.0f;
|
||||||
_dotImageView.alpha = 0.0f;
|
_dotImageView.alpha = 0.0f;
|
||||||
|
_dotMarkerView.alpha = 0.0f;
|
||||||
} completion:^(__unused BOOL finished)
|
} completion:^(__unused BOOL finished)
|
||||||
{
|
{
|
||||||
if (!switching) {
|
if (!switching) {
|
||||||
|
[_cropView removeFromSuperview];
|
||||||
if (completion != nil)
|
if (completion != nil)
|
||||||
completion();
|
completion();
|
||||||
}
|
}
|
||||||
@ -544,17 +537,21 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
{
|
{
|
||||||
_portraitToolsWrapperView.alpha = 0.0f;
|
_portraitToolsWrapperView.alpha = 0.0f;
|
||||||
_landscapeToolsWrapperView.alpha = 0.0f;
|
_landscapeToolsWrapperView.alpha = 0.0f;
|
||||||
_videoAreaView.alpha = 0.0f;
|
|
||||||
_dotImageView.alpha = 0.0f;
|
_dotImageView.alpha = 0.0f;
|
||||||
} completion:nil];
|
} completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)finishCustomTransitionOut
|
||||||
|
{
|
||||||
|
[_cropView removeFromSuperview];
|
||||||
|
}
|
||||||
|
|
||||||
- (CGRect)transitionOutReferenceFrame
|
- (CGRect)transitionOutReferenceFrame
|
||||||
{
|
{
|
||||||
if (_dismissingToCamera) {
|
if (_dismissingToCamera) {
|
||||||
return _fullPreviewView.frame;
|
return [_fullPreviewView.superview convertRect:_fullPreviewView.frame toView:self.view];
|
||||||
} else {
|
} else {
|
||||||
return _previewView.frame;
|
return [_wrapperView convertRect:_cropView.frame toView:self.view];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -735,12 +732,6 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
CGRect containerFrame = [TGPhotoAvatarPreviewController photoContainerFrameForParentViewFrame:CGRectMake(0, 0, referenceSize.width, referenceSize.height) toolbarLandscapeSize:self.toolbarLandscapeSize orientation:self.effectiveOrientation panelSize:0 hasOnScreenNavigation:self.hasOnScreenNavigation];
|
CGRect containerFrame = [TGPhotoAvatarPreviewController photoContainerFrameForParentViewFrame:CGRectMake(0, 0, referenceSize.width, referenceSize.height) toolbarLandscapeSize:self.toolbarLandscapeSize orientation:self.effectiveOrientation panelSize:0 hasOnScreenNavigation:self.hasOnScreenNavigation];
|
||||||
CGSize fittedSize = TGScaleToSize(photoEditor.rotatedCropSize, containerFrame.size);
|
CGSize fittedSize = TGScaleToSize(photoEditor.rotatedCropSize, containerFrame.size);
|
||||||
previewView.frame = CGRectMake(containerFrame.origin.x + (containerFrame.size.width - fittedSize.width) / 2, containerFrame.origin.y + (containerFrame.size.height - fittedSize.height) / 2, fittedSize.width, fittedSize.height);
|
previewView.frame = CGRectMake(containerFrame.origin.x + (containerFrame.size.width - fittedSize.width) / 2, containerFrame.origin.y + (containerFrame.size.height - fittedSize.height) / 2, fittedSize.width, fittedSize.height);
|
||||||
|
|
||||||
[UIView performWithoutAnimation:^
|
|
||||||
{
|
|
||||||
_videoAreaView.frame = _previewView.frame;
|
|
||||||
_flashView.frame = _videoAreaView.bounds;
|
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateLayout:(UIInterfaceOrientation)orientation
|
- (void)updateLayout:(UIInterfaceOrientation)orientation
|
||||||
@ -826,29 +817,24 @@ const CGFloat TGPhotoAvatarPreviewLandscapePanelSize = TGPhotoAvatarPreviewPanel
|
|||||||
|
|
||||||
- (void)beginScrubbing:(bool)flash
|
- (void)beginScrubbing:(bool)flash
|
||||||
{
|
{
|
||||||
if (flash)
|
if (flash) {
|
||||||
_coverLabel.alpha = 1.0f;
|
_coverLabel.alpha = 1.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)endScrubbing:(bool)flash completion:(bool (^)(void))completion
|
- (void)endScrubbing:(bool)flash completion:(bool (^)(void))completion
|
||||||
{
|
{
|
||||||
if (flash) {
|
if (flash) {
|
||||||
[UIView animateWithDuration:0.12 animations:^{
|
[_cropView flash:^{
|
||||||
_flashView.alpha = 1.0f;
|
TGDispatchAfter(1.0, dispatch_get_main_queue(), ^{
|
||||||
} completion:^(BOOL finished) {
|
if (completion()) {
|
||||||
[UIView animateWithDuration:0.2 animations:^{
|
[UIView animateWithDuration:0.2 animations:^{
|
||||||
_flashView.alpha = 0.0f;
|
_coverLabel.alpha = 0.7f;
|
||||||
} completion:^(BOOL finished) {
|
}];
|
||||||
TGDispatchAfter(1.0, dispatch_get_main_queue(), ^{
|
|
||||||
if (completion()) {
|
self.controlVideoPlayback(true);
|
||||||
[UIView animateWithDuration:0.2 animations:^{
|
}
|
||||||
_coverLabel.alpha = 0.7f;
|
});
|
||||||
}];
|
|
||||||
|
|
||||||
self.controlVideoPlayback(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}];
|
|
||||||
}];
|
}];
|
||||||
} else {
|
} else {
|
||||||
TGDispatchAfter(1.32, dispatch_get_main_queue(), ^{
|
TGDispatchAfter(1.32, dispatch_get_main_queue(), ^{
|
||||||
|
@ -59,6 +59,8 @@
|
|||||||
TGPhotoEditorTab _currentTab;
|
TGPhotoEditorTab _currentTab;
|
||||||
TGPhotoEditorTabController *_currentTabController;
|
TGPhotoEditorTabController *_currentTabController;
|
||||||
|
|
||||||
|
TGMediaEditingContext *_standaloneEditingContext;
|
||||||
|
|
||||||
UIView *_backgroundView;
|
UIView *_backgroundView;
|
||||||
UIView *_containerView;
|
UIView *_containerView;
|
||||||
UIView *_wrapperView;
|
UIView *_wrapperView;
|
||||||
@ -140,6 +142,7 @@
|
|||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_actionHandle = [[ASHandle alloc] initWithDelegate:self releaseOnMainThread:true];
|
_actionHandle = [[ASHandle alloc] initWithDelegate:self releaseOnMainThread:true];
|
||||||
|
_standaloneEditingContext = [[TGMediaEditingContext alloc] init];
|
||||||
|
|
||||||
self.automaticallyManageScrollViewInsets = false;
|
self.automaticallyManageScrollViewInsets = false;
|
||||||
self.autoManageStatusBarBackground = false;
|
self.autoManageStatusBarBackground = false;
|
||||||
@ -561,6 +564,9 @@
|
|||||||
|
|
||||||
if (strongSelf->_ignoreDefaultPreviewViewTransitionIn)
|
if (strongSelf->_ignoreDefaultPreviewViewTransitionIn)
|
||||||
{
|
{
|
||||||
|
__strong TGPhotoEditorController *strongSelf = weakSelf;
|
||||||
|
if (strongSelf == nil)
|
||||||
|
return;
|
||||||
TGDispatchOnMainThread(^
|
TGDispatchOnMainThread(^
|
||||||
{
|
{
|
||||||
if (strongSelf->_dismissed)
|
if (strongSelf->_dismissed)
|
||||||
@ -575,6 +581,9 @@
|
|||||||
{
|
{
|
||||||
[photoEditor processAnimated:false completion:^
|
[photoEditor processAnimated:false completion:^
|
||||||
{
|
{
|
||||||
|
__strong TGPhotoEditorController *strongSelf = weakSelf;
|
||||||
|
if (strongSelf == nil)
|
||||||
|
return;
|
||||||
TGDispatchOnMainThread(^
|
TGDispatchOnMainThread(^
|
||||||
{
|
{
|
||||||
if (strongSelf->_dismissed)
|
if (strongSelf->_dismissed)
|
||||||
@ -1090,7 +1099,13 @@
|
|||||||
rep = imageView;
|
rep = imageView;
|
||||||
}
|
}
|
||||||
[_currentTabController prepareForCustomTransitionOut];
|
[_currentTabController prepareForCustomTransitionOut];
|
||||||
self.beginCustomTransitionOut([_currentTabController transitionOutReferenceFrame], rep, completion);
|
|
||||||
|
TGPhotoEditorTabController *tabController = _currentTabController;
|
||||||
|
self.beginCustomTransitionOut([_currentTabController transitionOutReferenceFrame], rep, ^{
|
||||||
|
[tabController finishCustomTransitionOut];
|
||||||
|
if (completion)
|
||||||
|
completion();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1125,6 +1140,8 @@
|
|||||||
{
|
{
|
||||||
if (![currentController isDismissAllowed])
|
if (![currentController isDismissAllowed])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
[self savePaintingData];
|
||||||
|
|
||||||
currentController.switchingToTab = tab;
|
currentController.switchingToTab = tab;
|
||||||
[currentController transitionOutSwitching:true completion:^
|
[currentController transitionOutSwitching:true completion:^
|
||||||
@ -1203,7 +1220,11 @@
|
|||||||
{
|
{
|
||||||
bool skipInitialTransition = (![self presentedFromCamera] && self.navigationController != nil) || self.skipInitialTransition;
|
bool skipInitialTransition = (![self presentedFromCamera] && self.navigationController != nil) || self.skipInitialTransition;
|
||||||
|
|
||||||
TGPhotoAvatarPreviewController *cropController = [[TGPhotoAvatarPreviewController alloc] initWithContext:_context photoEditor:_photoEditor previewView:_previewView scrubberView:_scrubberView dotImageView:_dotImageView fullPreviewView:_fullPreviewView];
|
TGPhotoAvatarPreviewController *cropController = [[TGPhotoAvatarPreviewController alloc] initWithContext:_context photoEditor:_photoEditor previewView:_previewView];
|
||||||
|
cropController.scrubberView = _scrubberView;
|
||||||
|
cropController.dotImageView = _dotImageView;
|
||||||
|
cropController.dotMarkerView = _dotMarkerView;
|
||||||
|
cropController.fullPreviewView = _fullPreviewView;
|
||||||
cropController.fromCamera = [self presentedFromCamera];
|
cropController.fromCamera = [self presentedFromCamera];
|
||||||
cropController.skipTransitionIn = skipInitialTransition;
|
cropController.skipTransitionIn = skipInitialTransition;
|
||||||
if (snapshotImage != nil)
|
if (snapshotImage != nil)
|
||||||
@ -1636,6 +1657,7 @@
|
|||||||
self.view.frame = targetFrame;
|
self.view.frame = targetFrame;
|
||||||
} completion:^(__unused BOOL finished)
|
} completion:^(__unused BOOL finished)
|
||||||
{
|
{
|
||||||
|
[_currentTabController finishCustomTransitionOut];
|
||||||
if (self.navigationController != nil) {
|
if (self.navigationController != nil) {
|
||||||
[self.navigationController popViewControllerAnimated:false];
|
[self.navigationController popViewControllerAnimated:false];
|
||||||
} else {
|
} else {
|
||||||
@ -1646,6 +1668,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (self.navigationController != nil) {
|
if (self.navigationController != nil) {
|
||||||
|
[_currentTabController finishCustomTransitionOut];
|
||||||
[self.navigationController popViewControllerAnimated:false];
|
[self.navigationController popViewControllerAnimated:false];
|
||||||
} else {
|
} else {
|
||||||
[self dismiss];
|
[self dismiss];
|
||||||
@ -1760,6 +1783,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)savePaintingData {
|
||||||
|
if (![_currentTabController isKindOfClass:[TGPhotoPaintController class]])
|
||||||
|
return;
|
||||||
|
|
||||||
|
TGPhotoPaintController *paintController = (TGPhotoPaintController *)_currentTabController;
|
||||||
|
TGPaintingData *paintingData = [paintController paintingData];
|
||||||
|
_photoEditor.paintingData = paintingData;
|
||||||
|
|
||||||
|
if (paintingData != nil)
|
||||||
|
[TGPaintingData storePaintingData:paintingData inContext:self.editingContext forItem:_item forVideo:(_intent == TGPhotoEditorControllerVideoIntent)];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)applyEditor
|
- (void)applyEditor
|
||||||
{
|
{
|
||||||
if (![_currentTabController isDismissAllowed])
|
if (![_currentTabController isDismissAllowed])
|
||||||
@ -1768,8 +1803,6 @@
|
|||||||
self.view.userInteractionEnabled = false;
|
self.view.userInteractionEnabled = false;
|
||||||
[_currentTabController prepareTransitionOutSaving:true];
|
[_currentTabController prepareTransitionOutSaving:true];
|
||||||
|
|
||||||
TGPaintingData *paintingData = _photoEditor.paintingData;
|
|
||||||
|
|
||||||
bool saving = true;
|
bool saving = true;
|
||||||
NSTimeInterval videoStartValue = 0.0;
|
NSTimeInterval videoStartValue = 0.0;
|
||||||
NSTimeInterval trimStartValue = 0.0;
|
NSTimeInterval trimStartValue = 0.0;
|
||||||
@ -1777,12 +1810,7 @@
|
|||||||
|
|
||||||
if ([_currentTabController isKindOfClass:[TGPhotoPaintController class]])
|
if ([_currentTabController isKindOfClass:[TGPhotoPaintController class]])
|
||||||
{
|
{
|
||||||
TGPhotoPaintController *paintController = (TGPhotoPaintController *)_currentTabController;
|
[self savePaintingData];
|
||||||
paintingData = [paintController paintingData];
|
|
||||||
_photoEditor.paintingData = paintingData;
|
|
||||||
|
|
||||||
if (paintingData != nil)
|
|
||||||
[TGPaintingData storePaintingData:paintingData inContext:_editingContext forItem:_item forVideo:(_intent == TGPhotoEditorControllerVideoIntent)];
|
|
||||||
}
|
}
|
||||||
else if ([_currentTabController isKindOfClass:[TGPhotoQualityController class]])
|
else if ([_currentTabController isKindOfClass:[TGPhotoQualityController class]])
|
||||||
{
|
{
|
||||||
@ -1800,6 +1828,7 @@
|
|||||||
|
|
||||||
[self stopVideoPlayback:true];
|
[self stopVideoPlayback:true];
|
||||||
|
|
||||||
|
TGPaintingData *paintingData = _photoEditor.paintingData;
|
||||||
TGVideoEditAdjustments *adjustments = [_photoEditor exportAdjustmentsWithPaintingData:paintingData];
|
TGVideoEditAdjustments *adjustments = [_photoEditor exportAdjustmentsWithPaintingData:paintingData];
|
||||||
if ([self presentedForAvatarCreation] && _item.isVideo) {
|
if ([self presentedForAvatarCreation] && _item.isVideo) {
|
||||||
[[SQueue concurrentDefaultQueue] dispatch:^
|
[[SQueue concurrentDefaultQueue] dispatch:^
|
||||||
@ -1968,7 +1997,7 @@
|
|||||||
thumbnailImage = UIGraphicsGetImageFromCurrentImageContext();
|
thumbnailImage = UIGraphicsGetImageFromCurrentImageContext();
|
||||||
UIGraphicsEndImageContext();
|
UIGraphicsEndImageContext();
|
||||||
|
|
||||||
[_editingContext setImage:fullImage thumbnailImage:thumbnailImage forItem:_item synchronous:true];
|
[self.editingContext setImage:fullImage thumbnailImage:thumbnailImage forItem:_item synchronous:true];
|
||||||
}];
|
}];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
@ -1990,6 +2019,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (TGMediaEditingContext *)editingContext
|
||||||
|
{
|
||||||
|
if (_editingContext)
|
||||||
|
return _editingContext;
|
||||||
|
else
|
||||||
|
return _standaloneEditingContext;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)doneButtonLongPressed:(UIButton *)sender
|
- (void)doneButtonLongPressed:(UIButton *)sender
|
||||||
{
|
{
|
||||||
if (_intent == TGPhotoEditorControllerVideoIntent)
|
if (_intent == TGPhotoEditorControllerVideoIntent)
|
||||||
@ -2591,7 +2628,7 @@
|
|||||||
return !strongSelf->_scrubberView.isScrubbing;
|
return !strongSelf->_scrubberView.isScrubbing;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
TGDispatchAfter(0.16, dispatch_get_main_queue(), ^{
|
||||||
[self updateDotImage:true];
|
[self updateDotImage:true];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -215,6 +215,11 @@ const CGFloat TGPhotoEditorToolbarSize = 49.0f;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)finishCustomTransitionOut
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
- (void)transitionOutSwitching:(bool)__unused switching completion:(void (^)(void))__unused completion
|
- (void)transitionOutSwitching:(bool)__unused switching completion:(void (^)(void))__unused completion
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1842,7 +1842,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||||||
_appeared = true;
|
_appeared = true;
|
||||||
|
|
||||||
if ([transitionView isKindOfClass:[TGPhotoEditorPreviewView class]]) {
|
if ([transitionView isKindOfClass:[TGPhotoEditorPreviewView class]]) {
|
||||||
[_containerView insertSubview:transitionView belowSubview:_paintingWrapperView];
|
|
||||||
} else {
|
} else {
|
||||||
[transitionView removeFromSuperview];
|
[transitionView removeFromSuperview];
|
||||||
}
|
}
|
||||||
@ -1853,6 +1853,7 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||||||
[previewView setPaintingHidden:true];
|
[previewView setPaintingHidden:true];
|
||||||
previewView.hidden = false;
|
previewView.hidden = false;
|
||||||
[_containerView insertSubview:previewView belowSubview:_paintingWrapperView];
|
[_containerView insertSubview:previewView belowSubview:_paintingWrapperView];
|
||||||
|
[self updateContentViewLayout];
|
||||||
[previewView performTransitionInIfNeeded];
|
[previewView performTransitionInIfNeeded];
|
||||||
|
|
||||||
CGRect rect = [self fittedCropRect:true];
|
CGRect rect = [self fittedCropRect:true];
|
||||||
@ -2142,6 +2143,14 @@ const CGFloat TGPhotoPaintStickerKeyboardSize = 260.0f;
|
|||||||
[self updateLayout:toInterfaceOrientation];
|
[self updateLayout:toInterfaceOrientation];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)updateContentViewLayout
|
||||||
|
{
|
||||||
|
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(TGRotationForOrientation(_photoEditor.cropOrientation));
|
||||||
|
_contentView.transform = rotationTransform;
|
||||||
|
_contentView.frame = self.previewView.frame;
|
||||||
|
[self resetScrollView];
|
||||||
|
}
|
||||||
|
|
||||||
- (void)updateLayout:(UIInterfaceOrientation)orientation
|
- (void)updateLayout:(UIInterfaceOrientation)orientation
|
||||||
{
|
{
|
||||||
if ([self inFormSheet] || [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
|
if ([self inFormSheet] || [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
|
||||||
|
@ -160,8 +160,9 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
|||||||
if (strongSelf != nil) {
|
if (strongSelf != nil) {
|
||||||
[strongSelf->_hudView setText:nil];
|
[strongSelf->_hudView setText:nil];
|
||||||
|
|
||||||
if (forVideo) {
|
strongSelf->_photoEditor.disableAll = false;
|
||||||
strongSelf->_photoEditor.disableAll = false;
|
if (!forVideo) {
|
||||||
|
[strongSelf->_photoEditor processAnimated:false completion:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -171,8 +172,9 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
|
|||||||
if (strongSelf != nil) {
|
if (strongSelf != nil) {
|
||||||
[strongSelf->_hudView setText:TGLocalized(@"PhotoEditor.Original")];
|
[strongSelf->_hudView setText:TGLocalized(@"PhotoEditor.Original")];
|
||||||
|
|
||||||
if (forVideo) {
|
strongSelf->_photoEditor.disableAll = true;
|
||||||
strongSelf->_photoEditor.disableAll = true;
|
if (!forVideo) {
|
||||||
|
[strongSelf->_photoEditor processAnimated:false completion:nil];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -10,6 +10,59 @@
|
|||||||
|
|
||||||
@implementation TGPhotoVideoEditor
|
@implementation TGPhotoVideoEditor
|
||||||
|
|
||||||
|
+ (void)presentWithContext:(id<LegacyComponentsContext>)context parentController:(TGViewController *)parentController image:(UIImage *)image video:(NSURL *)video didFinishWithImage:(void (^)(UIImage *image))didFinishWithImage didFinishWithVideo:(void (^)(UIImage *image, NSURL *url, TGVideoEditAdjustments *adjustments))didFinishWithVideo
|
||||||
|
{
|
||||||
|
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
|
||||||
|
|
||||||
|
id<TGMediaEditableItem> editableItem;
|
||||||
|
if (image != nil) {
|
||||||
|
editableItem = image;
|
||||||
|
} else if (video != nil) {
|
||||||
|
editableItem = [[TGCameraCapturedVideo alloc] initWithURL:video];
|
||||||
|
}
|
||||||
|
|
||||||
|
TGPhotoEditorController *controller = [[TGPhotoEditorController alloc] initWithContext:[windowManager context] item:editableItem intent:TGPhotoEditorControllerAvatarIntent adjustments:nil caption:nil screenImage:nil availableTabs:[TGPhotoEditorController defaultTabsForAvatarIntent] selectedTab:TGPhotoEditorCropTab];
|
||||||
|
// controller.stickersContext = _stickersContext;
|
||||||
|
controller.dontHideStatusBar = true;
|
||||||
|
controller.didFinishEditing = ^(__unused id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, __unused bool hasChanges)
|
||||||
|
{
|
||||||
|
if (didFinishWithImage != nil)
|
||||||
|
didFinishWithImage(resultImage);
|
||||||
|
};
|
||||||
|
controller.didFinishEditingVideo = ^(NSURL *url, id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, UIImage *thumbnailImage, bool hasChanges) {
|
||||||
|
if (didFinishWithVideo != nil)
|
||||||
|
didFinishWithVideo(resultImage, url, adjustments);
|
||||||
|
};
|
||||||
|
controller.requestThumbnailImage = ^(id<TGMediaEditableItem> editableItem)
|
||||||
|
{
|
||||||
|
return [editableItem thumbnailImageSignal];
|
||||||
|
};
|
||||||
|
|
||||||
|
controller.requestOriginalScreenSizeImage = ^(id<TGMediaEditableItem> editableItem, NSTimeInterval position)
|
||||||
|
{
|
||||||
|
return [editableItem screenImageSignal:position];
|
||||||
|
};
|
||||||
|
|
||||||
|
controller.requestOriginalFullSizeImage = ^(id<TGMediaEditableItem> editableItem, NSTimeInterval position)
|
||||||
|
{
|
||||||
|
if (editableItem.isVideo) {
|
||||||
|
if ([editableItem isKindOfClass:[TGMediaAsset class]]) {
|
||||||
|
return [TGMediaAssetImageSignals avAssetForVideoAsset:(TGMediaAsset *)editableItem allowNetworkAccess:true];
|
||||||
|
} else if ([editableItem isKindOfClass:[TGCameraCapturedVideo class]]) {
|
||||||
|
return ((TGCameraCapturedVideo *)editableItem).avAsset;
|
||||||
|
} else {
|
||||||
|
return [editableItem originalImageSignal:position];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return [editableItem originalImageSignal:position];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TGOverlayControllerWindow *controllerWindow = [[TGOverlayControllerWindow alloc] initWithManager:windowManager parentController:controller contentController:controller];
|
||||||
|
controllerWindow.hidden = false;
|
||||||
|
controller.view.clipsToBounds = true;
|
||||||
|
}
|
||||||
|
|
||||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSString *)caption entities:(NSArray *)entities withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed
|
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSString *)caption entities:(NSArray *)entities withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed
|
||||||
{
|
{
|
||||||
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
|
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
|
||||||
|
@ -6,6 +6,30 @@ import LegacyComponents
|
|||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import LegacyUI
|
import LegacyUI
|
||||||
|
|
||||||
|
public func presentLegacyAvatarEditor(theme: PresentationTheme, image: UIImage?, video: URL?, present: (ViewController, Any?) -> Void, imageCompletion: @escaping (UIImage) -> Void, videoCompletion: @escaping (UIImage, URL, TGVideoEditAdjustments?) -> Void) {
|
||||||
|
let legacyController = LegacyController(presentation: .custom, theme: theme)
|
||||||
|
legacyController.statusBar.statusBarStyle = .Ignore
|
||||||
|
|
||||||
|
let emptyController = LegacyEmptyController(context: legacyController.context)!
|
||||||
|
let navigationController = makeLegacyNavigationController(rootController: emptyController)
|
||||||
|
navigationController.setNavigationBarHidden(true, animated: false)
|
||||||
|
navigationController.navigationBar.transform = CGAffineTransform(translationX: -1000.0, y: 0.0)
|
||||||
|
|
||||||
|
legacyController.bind(controller: navigationController)
|
||||||
|
|
||||||
|
present(legacyController, nil)
|
||||||
|
|
||||||
|
TGPhotoVideoEditor.present(with: legacyController.context, parentController: emptyController, image: image, video: video, didFinishWithImage: { image in
|
||||||
|
if let image = image {
|
||||||
|
imageCompletion(image)
|
||||||
|
}
|
||||||
|
}, didFinishWithVideo: { image, url, adjustments in
|
||||||
|
if let image = image, let url = url {
|
||||||
|
videoCompletion(image, url, adjustments)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public func presentLegacyAvatarPicker(holder: Atomic<NSObject?>, signup: Bool, theme: PresentationTheme, present: (ViewController, Any?) -> Void, openCurrent: (() -> Void)?, completion: @escaping (UIImage) -> Void) {
|
public func presentLegacyAvatarPicker(holder: Atomic<NSObject?>, signup: Bool, theme: PresentationTheme, present: (ViewController, Any?) -> Void, openCurrent: (() -> Void)?, completion: @escaping (UIImage) -> Void) {
|
||||||
let legacyController = LegacyController(presentation: .custom, theme: theme)
|
let legacyController = LegacyController(presentation: .custom, theme: theme)
|
||||||
legacyController.statusBar.statusBarStyle = .Ignore
|
legacyController.statusBar.statusBarStyle = .Ignore
|
||||||
|
@ -161,7 +161,7 @@ public final class MediaTrackFrameBuffer {
|
|||||||
if self.endOfStream, let decodedFrame = self.decoder.takeRemainingFrame() {
|
if self.endOfStream, let decodedFrame = self.decoder.takeRemainingFrame() {
|
||||||
return .frame(decodedFrame)
|
return .frame(decodedFrame)
|
||||||
} else {
|
} else {
|
||||||
if let bufferedUntilTime = bufferedUntilTime {
|
if let bufferedUntilTime = self.bufferedUntilTime {
|
||||||
if CMTimeCompare(bufferedUntilTime, self.duration) >= 0 || self.endOfStream {
|
if CMTimeCompare(bufferedUntilTime, self.duration) >= 0 || self.endOfStream {
|
||||||
return .finished
|
return .finished
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ static_library(
|
|||||||
"//submodules/RadialStatusNode:RadialStatusNode",
|
"//submodules/RadialStatusNode:RadialStatusNode",
|
||||||
"//submodules/ShareController:ShareController",
|
"//submodules/ShareController:ShareController",
|
||||||
"//submodules/AppBundle:AppBundle",
|
"//submodules/AppBundle:AppBundle",
|
||||||
|
"//submodules/LegacyMediaPickerUI:LegacyMediaPickerUI",
|
||||||
|
"//submodules/SaveToCameraRoll:SaveToCameraRoll",
|
||||||
],
|
],
|
||||||
frameworks = [
|
frameworks = [
|
||||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||||
|
@ -22,6 +22,8 @@ swift_library(
|
|||||||
"//submodules/RadialStatusNode:RadialStatusNode",
|
"//submodules/RadialStatusNode:RadialStatusNode",
|
||||||
"//submodules/ShareController:ShareController",
|
"//submodules/ShareController:ShareController",
|
||||||
"//submodules/AppBundle:AppBundle",
|
"//submodules/AppBundle:AppBundle",
|
||||||
|
"//submodules/LegacyMediaPickerUI:LegacyMediaPickerUI",
|
||||||
|
"//submodules/SaveToCameraRoll:SaveToCameraRoll",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -10,6 +10,8 @@ import SyncCore
|
|||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
import AccountContext
|
import AccountContext
|
||||||
import GalleryUI
|
import GalleryUI
|
||||||
|
import LegacyMediaPickerUI
|
||||||
|
import SaveToCameraRoll
|
||||||
|
|
||||||
public enum AvatarGalleryEntryId: Hashable {
|
public enum AvatarGalleryEntryId: Hashable {
|
||||||
case topImage
|
case topImage
|
||||||
@ -192,6 +194,8 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
|
|||||||
|
|
||||||
private let replaceRootController: (ViewController, Promise<Bool>?) -> Void
|
private let replaceRootController: (ViewController, Promise<Bool>?) -> Void
|
||||||
|
|
||||||
|
private let editDisposable = MetaDisposable ()
|
||||||
|
|
||||||
public init(context: AccountContext, peer: Peer, sourceHasRoundCorners: Bool = true, remoteEntries: Promise<[AvatarGalleryEntry]>? = nil, centralEntryIndex: Int? = nil, replaceRootController: @escaping (ViewController, Promise<Bool>?) -> Void, synchronousLoad: Bool = false) {
|
public init(context: AccountContext, peer: Peer, sourceHasRoundCorners: Bool = true, remoteEntries: Promise<[AvatarGalleryEntry]>? = nil, centralEntryIndex: Int? = nil, replaceRootController: @escaping (ViewController, Promise<Bool>?) -> Void, synchronousLoad: Bool = false) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.peer = peer
|
self.peer = peer
|
||||||
@ -265,7 +269,9 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
|
|||||||
self?.deleteEntry(entry)
|
self?.deleteEntry(entry)
|
||||||
} : nil, setMain: { [weak self] in
|
} : nil, setMain: { [weak self] in
|
||||||
self?.setMainEntry(entry)
|
self?.setMainEntry(entry)
|
||||||
})
|
}, edit: { [weak self] in
|
||||||
|
self?.editEntry(entry)
|
||||||
|
})
|
||||||
}), centralItemIndex: strongSelf.centralEntryIndex, synchronous: !isFirstTime)
|
}), centralItemIndex: strongSelf.centralEntryIndex, synchronous: !isFirstTime)
|
||||||
|
|
||||||
let ready = strongSelf.galleryNode.pager.ready() |> timeout(2.0, queue: Queue.mainQueue(), alternate: .single(Void())) |> afterNext { [weak strongSelf] _ in
|
let ready = strongSelf.galleryNode.pager.ready() |> timeout(2.0, queue: Queue.mainQueue(), alternate: .single(Void())) |> afterNext { [weak strongSelf] _ in
|
||||||
@ -332,6 +338,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
|
|||||||
deinit {
|
deinit {
|
||||||
self.disposable.dispose()
|
self.disposable.dispose()
|
||||||
self.centralItemAttributesDisposable.dispose()
|
self.centralItemAttributesDisposable.dispose()
|
||||||
|
self.editDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func donePressed() {
|
@objc func donePressed() {
|
||||||
@ -384,6 +391,7 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
|
|||||||
self.displayNode = GalleryControllerNode(controllerInteraction: controllerInteraction)
|
self.displayNode = GalleryControllerNode(controllerInteraction: controllerInteraction)
|
||||||
self.displayNodeDidLoad()
|
self.displayNodeDidLoad()
|
||||||
|
|
||||||
|
self.galleryNode.pager.updateOnReplacement = true
|
||||||
self.galleryNode.statusBar = self.statusBar
|
self.galleryNode.statusBar = self.statusBar
|
||||||
self.galleryNode.navigationBar = self.navigationBar
|
self.galleryNode.navigationBar = self.navigationBar
|
||||||
|
|
||||||
@ -426,6 +434,8 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
|
|||||||
self?.deleteEntry(entry)
|
self?.deleteEntry(entry)
|
||||||
} : nil, setMain: { [weak self] in
|
} : nil, setMain: { [weak self] in
|
||||||
self?.setMainEntry(entry)
|
self?.setMainEntry(entry)
|
||||||
|
}, edit: { [weak self] in
|
||||||
|
self?.editEntry(entry)
|
||||||
}) }), centralItemIndex: self.centralEntryIndex)
|
}) }), centralItemIndex: self.centralEntryIndex)
|
||||||
|
|
||||||
self.galleryNode.pager.centralItemIndexUpdated = { [weak self] index in
|
self.galleryNode.pager.centralItemIndexUpdated = { [weak self] index in
|
||||||
@ -584,7 +594,9 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
|
|||||||
self?.deleteEntry(entry)
|
self?.deleteEntry(entry)
|
||||||
} : nil, setMain: { [weak self] in
|
} : nil, setMain: { [weak self] in
|
||||||
self?.setMainEntry(entry)
|
self?.setMainEntry(entry)
|
||||||
}) }), centralItemIndex: 0)
|
}, edit: { [weak self] in
|
||||||
|
self?.editEntry(entry)
|
||||||
|
}) }), centralItemIndex: 0, synchronous: true)
|
||||||
self.entries = entries
|
self.entries = entries
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -605,6 +617,50 @@ public class AvatarGalleryController: ViewController, StandalonePresentableContr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func editEntry(_ rawEntry: AvatarGalleryEntry) {
|
||||||
|
let mediaReference: AnyMediaReference
|
||||||
|
if let video = rawEntry.videoRepresentations.last {
|
||||||
|
mediaReference = .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.resource, previewRepresentations: [], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.dimensions, flags: [])]))
|
||||||
|
} else {
|
||||||
|
let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: rawEntry.representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
|
mediaReference = .standalone(media: media)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.editDisposable.set((fetchMediaData(context: self.context, postbox: self.context.account.postbox, mediaReference: mediaReference)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] state, isImage in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch state {
|
||||||
|
case let .progress(value):
|
||||||
|
break
|
||||||
|
case let .data(data):
|
||||||
|
let image: UIImage?
|
||||||
|
let video: URL?
|
||||||
|
if isImage {
|
||||||
|
if let fileData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) {
|
||||||
|
image = UIImage(data: fileData)
|
||||||
|
} else {
|
||||||
|
image = nil
|
||||||
|
}
|
||||||
|
video = nil
|
||||||
|
} else {
|
||||||
|
image = nil
|
||||||
|
video = URL(fileURLWithPath: data.path)
|
||||||
|
}
|
||||||
|
presentLegacyAvatarEditor(theme: strongSelf.presentationData.theme, image: image, video: video, present: { [weak self] c, a in
|
||||||
|
if let strongSelf = self {
|
||||||
|
strongSelf.present(c, in: .window(.root), with: a, blockInteraction: true)
|
||||||
|
}
|
||||||
|
}, imageCompletion: { [weak self] image in
|
||||||
|
|
||||||
|
}, videoCompletion: { [weak self] image, url, adjustments in
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
private func deleteEntry(_ rawEntry: AvatarGalleryEntry) {
|
private func deleteEntry(_ rawEntry: AvatarGalleryEntry) {
|
||||||
var entry = rawEntry
|
var entry = rawEntry
|
||||||
if case .topImage = entry, !self.entries.isEmpty {
|
if case .topImage = entry, !self.entries.isEmpty {
|
||||||
|
@ -54,8 +54,9 @@ class PeerAvatarImageGalleryItem: GalleryItem {
|
|||||||
let sourceHasRoundCorners: Bool
|
let sourceHasRoundCorners: Bool
|
||||||
let delete: (() -> Void)?
|
let delete: (() -> Void)?
|
||||||
let setMain: (() -> Void)?
|
let setMain: (() -> Void)?
|
||||||
|
let edit: (() -> Void)?
|
||||||
|
|
||||||
init(context: AccountContext, peer: Peer, presentationData: PresentationData, entry: AvatarGalleryEntry, sourceHasRoundCorners: Bool, delete: (() -> Void)?, setMain: (() -> Void)?) {
|
init(context: AccountContext, peer: Peer, presentationData: PresentationData, entry: AvatarGalleryEntry, sourceHasRoundCorners: Bool, delete: (() -> Void)?, setMain: (() -> Void)?, edit: (() -> Void)?) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.peer = peer
|
self.peer = peer
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
@ -63,6 +64,7 @@ class PeerAvatarImageGalleryItem: GalleryItem {
|
|||||||
self.sourceHasRoundCorners = sourceHasRoundCorners
|
self.sourceHasRoundCorners = sourceHasRoundCorners
|
||||||
self.delete = delete
|
self.delete = delete
|
||||||
self.setMain = setMain
|
self.setMain = setMain
|
||||||
|
self.edit = edit
|
||||||
}
|
}
|
||||||
|
|
||||||
func node(synchronous: Bool) -> GalleryItemNode {
|
func node(synchronous: Bool) -> GalleryItemNode {
|
||||||
@ -75,6 +77,7 @@ class PeerAvatarImageGalleryItem: GalleryItem {
|
|||||||
node.setEntry(self.entry, synchronous: synchronous)
|
node.setEntry(self.entry, synchronous: synchronous)
|
||||||
node.footerContentNode.delete = self.delete
|
node.footerContentNode.delete = self.delete
|
||||||
node.footerContentNode.setMain = self.setMain
|
node.footerContentNode.setMain = self.setMain
|
||||||
|
node.edit = self.edit
|
||||||
|
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
@ -84,10 +87,17 @@ class PeerAvatarImageGalleryItem: GalleryItem {
|
|||||||
if let indexData = self.entry.indexData {
|
if let indexData = self.entry.indexData {
|
||||||
node._title.set(.single(self.presentationData.strings.Items_NOfM("\(indexData.position + 1)", "\(indexData.totalCount)").0))
|
node._title.set(.single(self.presentationData.strings.Items_NOfM("\(indexData.position + 1)", "\(indexData.totalCount)").0))
|
||||||
}
|
}
|
||||||
|
let previousContentAnimations = node.imageNode.contentAnimations
|
||||||
|
if synchronous {
|
||||||
|
node.imageNode.contentAnimations = []
|
||||||
|
}
|
||||||
node.setEntry(self.entry, synchronous: synchronous)
|
node.setEntry(self.entry, synchronous: synchronous)
|
||||||
|
if synchronous {
|
||||||
|
node.imageNode.contentAnimations = previousContentAnimations
|
||||||
|
}
|
||||||
node.footerContentNode.delete = self.delete
|
node.footerContentNode.delete = self.delete
|
||||||
node.footerContentNode.setMain = self.setMain
|
node.footerContentNode.setMain = self.setMain
|
||||||
|
node.edit = self.edit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +135,7 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
private var entry: AvatarGalleryEntry?
|
private var entry: AvatarGalleryEntry?
|
||||||
|
|
||||||
private let contentNode: PeerAvatarImageGalleryContentNode
|
private let contentNode: PeerAvatarImageGalleryContentNode
|
||||||
private let imageNode: TransformImageNode
|
fileprivate let imageNode: TransformImageNode
|
||||||
private var videoNode: UniversalVideoNode?
|
private var videoNode: UniversalVideoNode?
|
||||||
private var videoContent: NativeVideoContent?
|
private var videoContent: NativeVideoContent?
|
||||||
|
|
||||||
@ -142,6 +152,8 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
private var status: MediaResourceStatus?
|
private var status: MediaResourceStatus?
|
||||||
private let playbackStatusDisposable = MetaDisposable()
|
private let playbackStatusDisposable = MetaDisposable()
|
||||||
|
|
||||||
|
fileprivate var edit: (() -> Void)?
|
||||||
|
|
||||||
init(context: AccountContext, presentationData: PresentationData, peer: Peer, sourceHasRoundCorners: Bool) {
|
init(context: AccountContext, presentationData: PresentationData, peer: Peer, sourceHasRoundCorners: Bool) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.presentationData = presentationData
|
self.presentationData = presentationData
|
||||||
@ -212,7 +224,7 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
var footerContent: AvatarGalleryItemFooterContent
|
var footerContent: AvatarGalleryItemFooterContent
|
||||||
if self.peer.id == self.context.account.peerId {
|
if self.peer.id == self.context.account.peerId {
|
||||||
footerContent = .own((entry.indexData?.position ?? 0) == 0)
|
footerContent = .own((entry.indexData?.position ?? 0) == 0)
|
||||||
let rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Settings_EditProfileMedia, style: .plain, target: self, action: #selector(editPressed))
|
let rightBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Settings_EditProfileMedia, style: .plain, target: self, action: #selector(self.editPressed))
|
||||||
barButtonItems.append(rightBarButtonItem)
|
barButtonItems.append(rightBarButtonItem)
|
||||||
} else {
|
} else {
|
||||||
footerContent = .info
|
footerContent = .info
|
||||||
@ -507,7 +519,7 @@ final class PeerAvatarImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc private func editPressed() {
|
@objc private func editPressed() {
|
||||||
|
self.edit?()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
|
override func footerContent() -> Signal<(GalleryFooterContentNode?, GalleryOverlayContentNode?), NoError> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user