mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit 'c339bc8701bdc21a24598886445bf5bbf54165fe' into beta
This commit is contained in:
commit
f520588045
@ -34,7 +34,7 @@ typedef enum {
|
||||
|
||||
@property (nonatomic, copy) UIView *(^beginTransitionIn)(CGRect *referenceFrame, UIView **parentView);
|
||||
@property (nonatomic, copy) void (^finishedTransitionIn)(void);
|
||||
@property (nonatomic, copy) UIView *(^beginTransitionOut)(CGRect *referenceFrame, UIView **parentView);
|
||||
@property (nonatomic, copy) UIView *(^beginTransitionOut)(CGRect *referenceFrame, UIView **parentView, bool saving);
|
||||
@property (nonatomic, copy) void (^finishedTransitionOut)(bool saved);
|
||||
|
||||
@property (nonatomic, copy) void (^onDismiss)();
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
@property (nonatomic, copy) UIView *(^beginTransitionIn)(CGRect *referenceFrame, UIView **parentView, bool *noTransitionView);
|
||||
@property (nonatomic, copy) void(^finishedTransitionIn)(void);
|
||||
@property (nonatomic, copy) UIView *(^beginTransitionOut)(CGRect *referenceFrame, UIView **parentView);
|
||||
@property (nonatomic, copy) UIView *(^beginTransitionOut)(CGRect *referenceFrame, UIView **parentView, bool saving);
|
||||
@property (nonatomic, copy) void(^finishedTransitionOut)(void);
|
||||
|
||||
@property (nonatomic, copy) void (^valuesChanged)(void);
|
||||
|
@ -6,6 +6,6 @@
|
||||
|
||||
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSAttributedString *)caption withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item paint:(bool)paint adjustments:(bool)adjustments recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext fromRect:(CGRect)fromRect mainSnapshot:(UIView *)mainSnapshot snapshots:(NSArray *)snapshots immediate:(bool)immediate appeared:(void (^)(void))appeared completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed;
|
||||
|
||||
+ (void)presentEditorWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller withItem:(id<TGMediaEditableItem>)item cropRect:(CGRect)cropRect adjustments:(id<TGMediaEditAdjustments>)adjustments referenceView:(UIView *)referenceView completion:(void (^)(UIImage *, id<TGMediaEditAdjustments>))completion fullSizeCompletion:(void (^)(UIImage *))fullSizeCompletion beginTransitionOut:(void (^)())beginTransitionOut finishTransitionOut:(void (^)())finishTransitionOut;
|
||||
+ (void)presentEditorWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller withItem:(id<TGMediaEditableItem>)item cropRect:(CGRect)cropRect adjustments:(id<TGMediaEditAdjustments>)adjustments referenceView:(UIView *)referenceView completion:(void (^)(UIImage *, id<TGMediaEditAdjustments>))completion fullSizeCompletion:(void (^)(UIImage *))fullSizeCompletion beginTransitionOut:(void (^)(bool))beginTransitionOut finishTransitionOut:(void (^)())finishTransitionOut;
|
||||
|
||||
@end
|
||||
|
@ -2030,7 +2030,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
||||
return imageView;
|
||||
};
|
||||
|
||||
controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView)
|
||||
controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView, __unused bool saving)
|
||||
{
|
||||
__strong TGCameraController *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
|
@ -516,7 +516,7 @@
|
||||
[zoomableItemView reset];
|
||||
};
|
||||
|
||||
controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView)
|
||||
controller.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView, __unused bool saving)
|
||||
{
|
||||
__strong TGMediaPickerGalleryModel *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
|
@ -389,7 +389,7 @@ NSString * const TGPhotoCropOriginalAspectRatio = @"original";
|
||||
UIView *parentView = nil;
|
||||
|
||||
if (self.beginTransitionOut != nil)
|
||||
referenceView = self.beginTransitionOut(&referenceFrame, &parentView);
|
||||
referenceView = self.beginTransitionOut(&referenceFrame, &parentView, saving);
|
||||
|
||||
UIView *toTransitionView = nil;
|
||||
CGRect targetFrame = CGRectZero;
|
||||
|
@ -274,7 +274,7 @@ const CGFloat TGPhotoEditorToolbarSize = 49.0f;
|
||||
}
|
||||
|
||||
if (self.beginTransitionOut != nil)
|
||||
referenceView = self.beginTransitionOut(&referenceFrame, &parentView);
|
||||
referenceView = self.beginTransitionOut(&referenceFrame, &parentView, saving);
|
||||
|
||||
if (parentView == nil)
|
||||
parentView = referenceView.superview.superview;
|
||||
|
@ -283,7 +283,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)presentEditorWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller withItem:(id<TGMediaEditableItem>)item cropRect:(CGRect)cropRect adjustments:(id<TGMediaEditAdjustments>)adjustments referenceView:(UIView *)referenceView completion:(void (^)(UIImage *, id<TGMediaEditAdjustments>))completion fullSizeCompletion:(void (^)(UIImage *))fullSizeCompletion beginTransitionOut:(void (^)())beginTransitionOut finishTransitionOut:(void (^)())finishTransitionOut;
|
||||
+ (void)presentEditorWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller withItem:(id<TGMediaEditableItem>)item cropRect:(CGRect)cropRect adjustments:(id<TGMediaEditAdjustments>)adjustments referenceView:(UIView *)referenceView completion:(void (^)(UIImage *, id<TGMediaEditAdjustments>))completion fullSizeCompletion:(void (^)(UIImage *))fullSizeCompletion beginTransitionOut:(void (^)(bool))beginTransitionOut finishTransitionOut:(void (^)())finishTransitionOut;
|
||||
{
|
||||
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
|
||||
|
||||
@ -304,18 +304,16 @@
|
||||
editorController.dontHideStatusBar = true;
|
||||
editorController.ignoreCropForResult = true;
|
||||
|
||||
CGRect fromRect = referenceView.frame;// [referenceView convertRect:referenceView.bounds toView:nil];
|
||||
CGRect fromRect = referenceView.frame;
|
||||
editorController.beginTransitionIn = ^UIView *(CGRect *referenceFrame, UIView **parentView)
|
||||
{
|
||||
*referenceFrame = fromRect;
|
||||
*parentView = referenceView.superview;
|
||||
//UIImageView *imageView = [[UIImageView alloc] initWithFrame:fromRect];
|
||||
//imageView.image = image;
|
||||
|
||||
return referenceView;
|
||||
};
|
||||
|
||||
editorController.beginTransitionOut = ^UIView *(CGRect *referenceFrame, UIView **parentView)
|
||||
editorController.beginTransitionOut = ^UIView *(CGRect *referenceFrame, UIView **parentView, bool saving)
|
||||
{
|
||||
CGRect startFrame = CGRectZero;
|
||||
if (referenceFrame != NULL)
|
||||
@ -326,7 +324,7 @@
|
||||
}
|
||||
|
||||
if (beginTransitionOut) {
|
||||
beginTransitionOut();
|
||||
beginTransitionOut(saving);
|
||||
}
|
||||
|
||||
return referenceView;
|
||||
@ -382,126 +380,6 @@
|
||||
TGOverlayControllerWindow *controllerWindow = [[TGOverlayControllerWindow alloc] initWithManager:windowManager parentController:controller contentController:editorController];
|
||||
controllerWindow.hidden = false;
|
||||
controller.view.clipsToBounds = true;
|
||||
|
||||
// TGModernGalleryController *galleryController = [[TGModernGalleryController alloc] initWithContext:windowContext];
|
||||
// galleryController.adjustsStatusBarVisibility = true;
|
||||
// galleryController.animateTransition = false;
|
||||
// galleryController.finishedTransitionIn = ^(id<TGModernGalleryItem> item, TGModernGalleryItemView *itemView) {
|
||||
// appeared();
|
||||
// };
|
||||
// //galleryController.hasFadeOutTransition = true;
|
||||
//
|
||||
// id<TGModernGalleryEditableItem> galleryItem = nil;
|
||||
// if (item.isVideo)
|
||||
// galleryItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:item];
|
||||
// else
|
||||
// galleryItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:item];
|
||||
// galleryItem.editingContext = editingContext;
|
||||
// galleryItem.stickersContext = stickersContext;
|
||||
//
|
||||
// TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:windowContext items:@[galleryItem] focusItem:galleryItem selectionContext:nil editingContext:editingContext hasCaptions:true allowCaptionEntities:true hasTimer:false onlyCrop:false inhibitDocumentCaptions:false hasSelectionPanel:false hasCamera:false recipientName:recipientName];
|
||||
// model.controller = galleryController;
|
||||
// model.stickersContext = stickersContext;
|
||||
//
|
||||
// model.willFinishEditingItem = ^(id<TGMediaEditableItem> editableItem, id<TGMediaEditAdjustments> adjustments, id representation, bool hasChanges)
|
||||
// {
|
||||
// if (hasChanges)
|
||||
// {
|
||||
// [editingContext setAdjustments:adjustments forItem:editableItem];
|
||||
// [editingContext setTemporaryRep:representation forItem:editableItem];
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// model.didFinishEditingItem = ^(id<TGMediaEditableItem> editableItem, __unused id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, UIImage *thumbnailImage)
|
||||
// {
|
||||
// [editingContext setImage:resultImage thumbnailImage:thumbnailImage forItem:editableItem synchronous:false];
|
||||
// };
|
||||
//
|
||||
// model.saveItemCaption = ^(id<TGMediaEditableItem> editableItem, NSAttributedString *caption)
|
||||
// {
|
||||
// [editingContext setCaption:caption forItem:editableItem];
|
||||
// };
|
||||
//
|
||||
// model.didFinishRenderingFullSizeImage = ^(id<TGMediaEditableItem> editableItem, UIImage *resultImage)
|
||||
// {
|
||||
// [editingContext setFullSizeImage:resultImage forItem:editableItem];
|
||||
// };
|
||||
//
|
||||
// model.interfaceView.hasSwipeGesture = false;
|
||||
// galleryController.model = model;
|
||||
//
|
||||
// __weak TGModernGalleryController *weakGalleryController = galleryController;
|
||||
//
|
||||
// [model.interfaceView updateSelectionInterface:1 counterVisible:false animated:false];
|
||||
// model.interfaceView.thumbnailSignalForItem = ^SSignal *(id item)
|
||||
// {
|
||||
// return nil;
|
||||
// };
|
||||
// model.interfaceView.donePressed = ^(TGMediaPickerGalleryItem *item)
|
||||
// {
|
||||
// __strong TGModernGalleryController *strongController = weakGalleryController;
|
||||
// if (strongController == nil)
|
||||
// return;
|
||||
//
|
||||
// if ([item isKindOfClass:[TGMediaPickerGalleryVideoItem class]])
|
||||
// {
|
||||
// TGMediaPickerGalleryVideoItemView *itemView = (TGMediaPickerGalleryVideoItemView *)[strongController itemViewForItem:item];
|
||||
// [itemView stop];
|
||||
// [itemView setPlayButtonHidden:true animated:true];
|
||||
// }
|
||||
//
|
||||
// if (completion != nil)
|
||||
// completion(item.asset, editingContext);
|
||||
//
|
||||
// [strongController dismissWhenReadyAnimated:true];
|
||||
// };
|
||||
//
|
||||
// galleryController.beginTransitionIn = ^UIView *(__unused TGMediaPickerGalleryItem *item, __unused TGModernGalleryItemView *itemView)
|
||||
// {
|
||||
// return nil;
|
||||
// };
|
||||
//
|
||||
// galleryController.beginTransitionOut = ^UIView *(__unused TGMediaPickerGalleryItem *item, __unused TGModernGalleryItemView *itemView)
|
||||
// {
|
||||
// return nil;
|
||||
// };
|
||||
//
|
||||
// galleryController.completedTransitionOut = ^
|
||||
// {
|
||||
// TGModernGalleryController *strongGalleryController = weakGalleryController;
|
||||
// if (strongGalleryController != nil && strongGalleryController.overlayWindow == nil)
|
||||
// {
|
||||
// TGNavigationController *navigationController = (TGNavigationController *)strongGalleryController.navigationController;
|
||||
// TGOverlayControllerWindow *window = (TGOverlayControllerWindow *)navigationController.view.window;
|
||||
// if ([window isKindOfClass:[TGOverlayControllerWindow class]])
|
||||
// [window dismiss];
|
||||
// }
|
||||
// if (dismissed) {
|
||||
// dismissed();
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// if (paint || adjustments) {
|
||||
// [model.interfaceView immediateEditorTransitionIn];
|
||||
// }
|
||||
//
|
||||
// for (UIView *view in snapshots) {
|
||||
// [galleryController.view addSubview:view];
|
||||
// }
|
||||
//
|
||||
// TGOverlayControllerWindow *controllerWindow = [[TGOverlayControllerWindow alloc] initWithManager:windowManager parentController:controller contentController:galleryController];
|
||||
// controllerWindow.hidden = false;
|
||||
// galleryController.view.clipsToBounds = true;
|
||||
//
|
||||
// if (paint) {
|
||||
// TGDispatchAfter(0.05, dispatch_get_main_queue(), ^{
|
||||
// [model presentPhotoEditorForItem:galleryItem tab:TGPhotoEditorPaintTab snapshots:snapshots fromRect:fromRect];
|
||||
// });
|
||||
// } else if (adjustments) {
|
||||
// TGDispatchAfter(0.05, dispatch_get_main_queue(), ^{
|
||||
// [model presentPhotoEditorForItem:galleryItem tab:TGPhotoEditorToolsTab snapshots:snapshots fromRect:fromRect];
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,7 +64,7 @@ public enum LegacyMediaEditorMode {
|
||||
}
|
||||
|
||||
|
||||
public func legacyWallpaperEditor(context: AccountContext, item: TGMediaEditableItem, cropRect: CGRect, adjustments: TGMediaEditAdjustments?, referenceView: UIView, beginTransitionOut: (() -> Void)?, finishTransitionOut: (() -> Void)?, completion: @escaping (UIImage?, TGMediaEditAdjustments?) -> Void, fullSizeCompletion: @escaping (UIImage?) -> Void, present: @escaping (ViewController, Any?) -> Void) {
|
||||
public func legacyWallpaperEditor(context: AccountContext, item: TGMediaEditableItem, cropRect: CGRect, adjustments: TGMediaEditAdjustments?, referenceView: UIView, beginTransitionOut: ((Bool) -> Void)?, finishTransitionOut: (() -> Void)?, completion: @escaping (UIImage?, TGMediaEditAdjustments?) -> Void, fullSizeCompletion: @escaping (UIImage?) -> Void, present: @escaping (ViewController, Any?) -> Void) {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme, initialLayout: nil)
|
||||
legacyController.blocksBackgroundWhenInOverlay = true
|
||||
@ -90,8 +90,8 @@ public func legacyWallpaperEditor(context: AccountContext, item: TGMediaEditable
|
||||
Queue.mainQueue().async {
|
||||
fullSizeCompletion(image)
|
||||
}
|
||||
}, beginTransitionOut: {
|
||||
beginTransitionOut?()
|
||||
}, beginTransitionOut: { saving in
|
||||
beginTransitionOut?(saving)
|
||||
}, finishTransitionOut: { [weak legacyController] in
|
||||
legacyController?.dismiss()
|
||||
finishTransitionOut?()
|
||||
|
@ -284,11 +284,7 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa
|
||||
finalCropRect = CGRect(x: (image.size.width - fittedSize.width) / 2.0, y: (image.size.height - fittedSize.height) / 2.0, width: fittedSize.width, height: fittedSize.height)
|
||||
}
|
||||
croppedImage = TGPhotoEditorCrop(image, nil, .up, 0.0, finalCropRect, false, CGSize(width: 1440.0, height: 2960.0), image.size, true)
|
||||
|
||||
if mode.contains(.blur) {
|
||||
croppedImage = blurredImage(croppedImage, radius: 30.0)!
|
||||
}
|
||||
|
||||
|
||||
let thumbnailDimensions = finalCropRect.size.fitted(CGSize(width: 320.0, height: 320.0))
|
||||
let thumbnailImage = generateScaledImage(image: croppedImage, size: thumbnailDimensions, scale: 1.0)
|
||||
|
||||
@ -301,19 +297,23 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa
|
||||
context.sharedContext.accountManager.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||
context.account.postbox.mediaBox.storeResourceData(resource.id, data: data, synchronous: true)
|
||||
|
||||
let _ = context.sharedContext.accountManager.mediaBox.cachedResourceRepresentation(resource, representation: CachedBlurredWallpaperRepresentation(), complete: true, fetch: true).start()
|
||||
|
||||
var intensity: Int32?
|
||||
if let brightness {
|
||||
intensity = max(0, min(100, Int32(brightness * 100.0)))
|
||||
}
|
||||
|
||||
let settings = WallpaperSettings(blur: mode.contains(.blur), motion: mode.contains(.motion), colors: [], intensity: intensity)
|
||||
let temporaryWallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false), TelegramMediaImageRepresentation(dimensions: PixelDimensions(croppedImage.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)], settings)
|
||||
|
||||
Queue.mainQueue().async {
|
||||
completion()
|
||||
Queue.mainQueue().after(0.05) {
|
||||
let settings = WallpaperSettings(blur: mode.contains(.blur), motion: mode.contains(.motion), colors: [], intensity: intensity)
|
||||
let temporaryWallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false), TelegramMediaImageRepresentation(dimensions: PixelDimensions(croppedImage.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)], settings)
|
||||
|
||||
context.account.pendingPeerMediaUploadManager.add(peerId: peerId, content: .wallpaper(temporaryWallpaper))
|
||||
|
||||
Queue.mainQueue().async {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
|
||||
context.account.pendingPeerMediaUploadManager.add(peerId: peerId, content: .wallpaper(temporaryWallpaper))
|
||||
}
|
||||
return croppedImage
|
||||
}).start()
|
||||
|
@ -142,18 +142,28 @@ public final class ThemeGridController: ViewController {
|
||||
}
|
||||
}, presentGallery: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let dismissControllers = { [weak self] in
|
||||
if let self, let navigationController = self.navigationController as? NavigationController {
|
||||
let controllers = navigationController.viewControllers.filter({ controller in
|
||||
if controller is WallpaperGalleryController || controller is MediaPickerScreen {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
navigationController.setViewControllers(controllers, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
let controller = MediaPickerScreen(context: strongSelf.context, peer: nil, threadTitle: nil, chatLocation: nil, bannedSendPhotos: nil, bannedSendVideos: nil, subject: .assets(nil, .wallpaper))
|
||||
controller.customSelection = { [weak self] asset in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset))
|
||||
controller.apply = { [weak self, weak controller] wallpaper, options, editedImage, cropRect, brightness in
|
||||
if let strongSelf = self, let controller = controller {
|
||||
uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: { [weak controller] in
|
||||
if let controller = controller {
|
||||
controller.dismiss(forceAway: true)
|
||||
}
|
||||
controller.apply = { [weak self] wallpaper, options, editedImage, cropRect, brightness in
|
||||
if let strongSelf = self {
|
||||
uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: {
|
||||
dismissControllers()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -169,10 +169,10 @@ private func updatedFileWallpaper(id: Int64? = nil, accessHash: Int64? = nil, sl
|
||||
class WallpaperGalleryInteraction {
|
||||
let editMedia: (PHAsset, UIImage, CGRect, TGMediaEditAdjustments?, UIView, @escaping (UIImage?, TGMediaEditAdjustments?) -> Void, @escaping (UIImage?) -> Void) -> Void
|
||||
let beginTransitionToEditor: () -> Void
|
||||
let beginTransitionFromEditor: () -> Void
|
||||
let beginTransitionFromEditor: (Bool) -> Void
|
||||
let finishTransitionFromEditor: () -> Void
|
||||
|
||||
init(editMedia: @escaping (PHAsset, UIImage, CGRect, TGMediaEditAdjustments?, UIView, @escaping (UIImage?, TGMediaEditAdjustments?) -> Void, @escaping (UIImage?) -> Void) -> Void, beginTransitionToEditor: @escaping () -> Void, beginTransitionFromEditor: @escaping () -> Void, finishTransitionFromEditor: @escaping () -> Void) {
|
||||
init(editMedia: @escaping (PHAsset, UIImage, CGRect, TGMediaEditAdjustments?, UIView, @escaping (UIImage?, TGMediaEditAdjustments?) -> Void, @escaping (UIImage?) -> Void) -> Void, beginTransitionToEditor: @escaping () -> Void, beginTransitionFromEditor: @escaping (Bool) -> Void, finishTransitionFromEditor: @escaping () -> Void) {
|
||||
self.editMedia = editMedia
|
||||
self.beginTransitionToEditor = beginTransitionToEditor
|
||||
self.beginTransitionFromEditor = beginTransitionFromEditor
|
||||
@ -253,8 +253,8 @@ public class WallpaperGalleryController: ViewController {
|
||||
return
|
||||
}
|
||||
let item = LegacyWallpaperItem(asset: asset, screenImage: image, dimensions: CGSize(width: asset.pixelWidth, height: asset.pixelHeight))
|
||||
legacyWallpaperEditor(context: context, item: item, cropRect: cropRect, adjustments: adjustments, referenceView: referenceView, beginTransitionOut: { [weak self] in
|
||||
self?.interaction?.beginTransitionFromEditor()
|
||||
legacyWallpaperEditor(context: context, item: item, cropRect: cropRect, adjustments: adjustments, referenceView: referenceView, beginTransitionOut: { [weak self] saving in
|
||||
self?.interaction?.beginTransitionFromEditor(saving)
|
||||
}, finishTransitionOut: { [weak self] in
|
||||
self?.interaction?.finishTransitionFromEditor()
|
||||
}, completion: { image, adjustments in
|
||||
@ -274,7 +274,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
if let toolbarNode = self.toolbarNode {
|
||||
transition.updateAlpha(node: toolbarNode, alpha: 0.0)
|
||||
}
|
||||
}, beginTransitionFromEditor: { [weak self] in
|
||||
}, beginTransitionFromEditor: { [weak self] saving in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -283,7 +283,7 @@ public class WallpaperGalleryController: ViewController {
|
||||
transition.updateAlpha(node: toolbarNode, alpha: 1.0)
|
||||
}
|
||||
if let centralItemNode = self.galleryNode.pager.centralItemNode() as? WallpaperGalleryItemNode {
|
||||
centralItemNode.beginTransitionFromEditor()
|
||||
centralItemNode.beginTransitionFromEditor(saving: saving)
|
||||
}
|
||||
}, finishTransitionFromEditor: { [weak self] in
|
||||
guard let self else {
|
||||
|
@ -506,10 +506,13 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
return context
|
||||
}))
|
||||
|
||||
self.temporaryImageNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, delay: 0.2, removeOnCompletion: false, completion: { [weak self] _ in
|
||||
self?.temporaryImageNode.image = nil
|
||||
self?.temporaryImageNode.layer.removeAllAnimations()
|
||||
})
|
||||
Queue.mainQueue().after(0.1) {
|
||||
self.brightnessNode.isHidden = false
|
||||
self.temporaryImageNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, delay: 0.2, removeOnCompletion: false, completion: { [weak self] _ in
|
||||
self?.temporaryImageNode.image = nil
|
||||
self?.temporaryImageNode.layer.removeAllAnimations()
|
||||
})
|
||||
}
|
||||
}, { [weak self] image in
|
||||
guard let self else {
|
||||
return
|
||||
@ -532,13 +535,38 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
public private(set) var editedFullSizeImage: UIImage?
|
||||
private var currentAdjustments: TGMediaEditAdjustments?
|
||||
|
||||
func beginTransitionToEditor() {
|
||||
self.cropNode.isHidden = true
|
||||
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)
|
||||
transition.updateAlpha(node: self.messagesContainerNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.buttonsContainerNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.serviceBackgroundNode, alpha: 0.0)
|
||||
|
||||
self.interaction?.beginTransitionToEditor()
|
||||
}
|
||||
|
||||
func beginTransitionFromEditor(saving: Bool) {
|
||||
if saving {
|
||||
self.brightnessNode.isHidden = true
|
||||
}
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)
|
||||
transition.updateAlpha(node: self.messagesContainerNode, alpha: 1.0)
|
||||
transition.updateAlpha(node: self.buttonsContainerNode, alpha: 1.0)
|
||||
transition.updateAlpha(node: self.serviceBackgroundNode, alpha: 1.0)
|
||||
}
|
||||
|
||||
func finishTransitionFromEditor() {
|
||||
self.cropNode.isHidden = false
|
||||
self.temporaryImageNode.alpha = 1.0
|
||||
}
|
||||
|
||||
private func animateIntensityChange(delay: Double) {
|
||||
let targetValue: CGFloat = self.sliderNode.value
|
||||
self.sliderNode.internalUpdateLayout(size: self.sliderNode.frame.size, value: 1.0)
|
||||
self.sliderNode.ignoreUpdates = true
|
||||
Queue.mainQueue().after(delay, {
|
||||
self.brightnessNode.backgroundColor = UIColor(rgb: 0x000000)
|
||||
self.brightnessNode.layer.compositingFilter = nil
|
||||
|
||||
self.sliderNode.ignoreUpdates = false
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .easeInOut)
|
||||
@ -551,37 +579,12 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
let value = self.isDarkAppearance ? self.sliderNode.value : 1.0
|
||||
if value < 1.0 {
|
||||
self.brightnessNode.backgroundColor = UIColor(rgb: 0x000000)
|
||||
self.brightnessNode.layer.compositingFilter = nil
|
||||
transition.updateAlpha(node: self.brightnessNode, alpha: 1.0 - value)
|
||||
} else {
|
||||
self.brightnessNode.layer.compositingFilter = nil
|
||||
transition.updateAlpha(node: self.brightnessNode, alpha: 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
func beginTransitionToEditor() {
|
||||
self.cropNode.isHidden = true
|
||||
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)
|
||||
transition.updateAlpha(node: self.messagesContainerNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.buttonsContainerNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.serviceBackgroundNode, alpha: 0.0)
|
||||
|
||||
self.interaction?.beginTransitionToEditor()
|
||||
}
|
||||
|
||||
func beginTransitionFromEditor() {
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.3, curve: .easeInOut)
|
||||
transition.updateAlpha(node: self.messagesContainerNode, alpha: 1.0)
|
||||
transition.updateAlpha(node: self.buttonsContainerNode, alpha: 1.0)
|
||||
transition.updateAlpha(node: self.serviceBackgroundNode, alpha: 1.0)
|
||||
}
|
||||
|
||||
func finishTransitionFromEditor() {
|
||||
self.cropNode.isHidden = false
|
||||
self.temporaryImageNode.alpha = 1.0
|
||||
}
|
||||
|
||||
@objc private func cancelPressed() {
|
||||
self.dismiss()
|
||||
}
|
||||
@ -668,6 +671,21 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
self.patternButtonNode.isSelected = false
|
||||
self.playButtonNode.setIcon(self.playButtonRotateImage)
|
||||
}
|
||||
|
||||
if let settings = wallpaper.settings {
|
||||
if settings.blur {
|
||||
self.blurButtonNode.setSelected(true, animated: false)
|
||||
self.setBlurEnabled(true, animated: false)
|
||||
}
|
||||
if settings.motion {
|
||||
self.motionButtonNode.setSelected(true, animated: false)
|
||||
self.setMotionEnabled(true, animated: false)
|
||||
}
|
||||
if case let .file(file) = wallpaper, !file.isPattern, let intensity = file.settings.intensity {
|
||||
self.sliderNode.value = (1.0 - CGFloat(intensity) / 100.0)
|
||||
self.updateIntensity(transition: .immediate)
|
||||
}
|
||||
}
|
||||
case .asset:
|
||||
self.nativeNode._internalUpdateIsSettingUpWallpaper()
|
||||
self.nativeNode.isHidden = true
|
||||
|
@ -212,8 +212,8 @@ func mediaContentToUpload(network: Network, postbox: Postbox, auxiliaryMethods:
|
||||
let inputPoll = Api.InputMedia.inputMediaPoll(flags: pollMediaFlags, poll: Api.Poll.poll(id: 0, flags: pollFlags, question: poll.text, answers: poll.options.map({ $0.apiOption }), closePeriod: poll.deadlineTimeout, closeDate: nil), correctAnswers: correctAnswers, solution: mappedSolution, solutionEntities: mappedSolutionEntities)
|
||||
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(inputPoll, text), reuploadInfo: nil, cacheReferenceKey: nil)))
|
||||
} else if let media = media as? TelegramMediaDice {
|
||||
let input = Api.InputMedia.inputMediaDice(emoticon: media.emoji)
|
||||
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(input, text), reuploadInfo: nil, cacheReferenceKey: nil)))
|
||||
let inputDice = Api.InputMedia.inputMediaDice(emoticon: media.emoji)
|
||||
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(inputDice, text), reuploadInfo: nil, cacheReferenceKey: nil)))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ public final class PeerMediaUploadingItem: Equatable {
|
||||
|
||||
public enum Error {
|
||||
case generic
|
||||
case flood
|
||||
}
|
||||
|
||||
public enum Content: Equatable {
|
||||
@ -69,7 +70,14 @@ private func uploadPeerMedia(postbox: Postbox, network: Network, stateManager: A
|
||||
}
|
||||
}
|
||||
return _internal_setChatWallpaper(postbox: postbox, network: network, stateManager: stateManager, peerId: peerId, wallpaper: result, applyUpdates: false)
|
||||
|> castError(PeerMediaUploadingItem.Error.self)
|
||||
|> mapError { error -> PeerMediaUploadingItem.Error in
|
||||
switch error {
|
||||
case .generic:
|
||||
return .generic
|
||||
case .flood:
|
||||
return .flood
|
||||
}
|
||||
}
|
||||
|> map { updates -> PeerMediaUploadingItem.ProgressValue in
|
||||
return .done(updates)
|
||||
}
|
||||
@ -78,7 +86,14 @@ private func uploadPeerMedia(postbox: Postbox, network: Network, stateManager: A
|
||||
}
|
||||
} else {
|
||||
return _internal_setChatWallpaper(postbox: postbox, network: network, stateManager: stateManager, peerId: peerId, wallpaper: wallpaper, applyUpdates: false)
|
||||
|> castError(PeerMediaUploadingItem.Error.self)
|
||||
|> mapError { error -> PeerMediaUploadingItem.Error in
|
||||
switch error {
|
||||
case .generic:
|
||||
return .generic
|
||||
case .flood:
|
||||
return .flood
|
||||
}
|
||||
}
|
||||
|> map { updates -> PeerMediaUploadingItem.ProgressValue in
|
||||
return .done(updates)
|
||||
}
|
||||
@ -265,7 +280,15 @@ private final class PendingPeerMediaUploadManagerImpl {
|
||||
}
|
||||
if let context = strongSelf.contexts[peerId], context === initialContext {
|
||||
strongSelf.contexts.removeValue(forKey: peerId)
|
||||
context.disposable.dispose()
|
||||
|
||||
if let messageId = context.value.messageId {
|
||||
context.disposable.set(strongSelf.postbox.transaction({ transaction in
|
||||
transaction.deleteMessages([messageId], forEachMedia: nil)
|
||||
}).start())
|
||||
} else {
|
||||
context.disposable.dispose()
|
||||
}
|
||||
|
||||
strongSelf.updateValues()
|
||||
}
|
||||
}))
|
||||
|
@ -118,13 +118,19 @@ func managedChatThemesUpdates(accountManager: AccountManager<TelegramAccountMana
|
||||
return (poll |> then(.complete() |> suspendAwareDelay(1.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
||||
}
|
||||
|
||||
func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, wallpaper: TelegramWallpaper?, applyUpdates: Bool = true) -> Signal<Api.Updates, NoError> {
|
||||
public enum SetChatWallpaperError {
|
||||
case generic
|
||||
case flood
|
||||
}
|
||||
|
||||
func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, wallpaper: TelegramWallpaper?, applyUpdates: Bool = true) -> Signal<Api.Updates, SetChatWallpaperError> {
|
||||
return postbox.loadedPeerWithId(peerId)
|
||||
|> castError(SetChatWallpaperError.self)
|
||||
|> mapToSignal { peer in
|
||||
guard let inputPeer = apiInputPeer(peer) else {
|
||||
return .complete()
|
||||
}
|
||||
return postbox.transaction { transaction -> Signal<Api.Updates, NoError> in
|
||||
return postbox.transaction { transaction -> Signal<Api.Updates, SetChatWallpaperError> in
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
|
||||
if let current = current as? CachedUserData {
|
||||
return current.withUpdatedWallpaper(wallpaper)
|
||||
@ -143,16 +149,22 @@ func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager
|
||||
inputSettings = inputWallpaperAndInputSettings.1
|
||||
}
|
||||
return network.request(Api.functions.messages.setChatWallPaper(flags: flags, peer: inputPeer, wallpaper: inputWallpaper, settings: inputSettings, id: nil), automaticFloodWait: false)
|
||||
|> `catch` { error in
|
||||
return .complete()
|
||||
|> mapError { error -> SetChatWallpaperError in
|
||||
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||
return .flood
|
||||
} else {
|
||||
return .generic
|
||||
}
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<Api.Updates, NoError> in
|
||||
|> mapToSignal { updates -> Signal<Api.Updates, SetChatWallpaperError> in
|
||||
if applyUpdates {
|
||||
stateManager.addUpdates(updates)
|
||||
}
|
||||
return .single(updates)
|
||||
}
|
||||
} |> switchToLatest
|
||||
}
|
||||
|> castError(SetChatWallpaperError.self)
|
||||
|> switchToLatest
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ public extension TelegramEngine {
|
||||
return _internal_setChatTheme(account: self.account, peerId: peerId, emoticon: emoticon)
|
||||
}
|
||||
|
||||
public func setChatWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?) -> Signal<Never, NoError> {
|
||||
public func setChatWallpaper(peerId: PeerId, wallpaper: TelegramWallpaper?) -> Signal<Never, SetChatWallpaperError> {
|
||||
return _internal_setChatWallpaper(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, peerId: peerId, wallpaper: wallpaper)
|
||||
|> ignoreValues
|
||||
}
|
||||
|
@ -857,7 +857,20 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return true
|
||||
}
|
||||
strongSelf.chatDisplayNode.dismissInput()
|
||||
let wallpaperPreviewController = WallpaperGalleryController(context: strongSelf.context, source: .wallpaper(wallpaper, nil, [], nil, nil, nil), mode: .peer(EnginePeer(peer), true))
|
||||
var options = WallpaperPresentationOptions()
|
||||
var intensity: Int32?
|
||||
if let settings = wallpaper.settings {
|
||||
if settings.blur {
|
||||
options.insert(.blur)
|
||||
}
|
||||
if settings.motion {
|
||||
options.insert(.motion)
|
||||
}
|
||||
if case let .file(file) = wallpaper, !file.isPattern {
|
||||
intensity = settings.intensity
|
||||
}
|
||||
}
|
||||
let wallpaperPreviewController = WallpaperGalleryController(context: strongSelf.context, source: .wallpaper(wallpaper, options, [], intensity, nil, nil), mode: .peer(EnginePeer(peer), true))
|
||||
wallpaperPreviewController.apply = { [weak wallpaperPreviewController] entry, options, _, _, brightness in
|
||||
var settings: WallpaperSettings?
|
||||
if case let .wallpaper(wallpaper, _) = entry {
|
||||
|
@ -328,13 +328,13 @@ class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
if let dimensions = file.dimensions?.cgSize {
|
||||
imageSize = dimensions.aspectFilled(boundingSize)
|
||||
}
|
||||
updateImageSignal = wallpaperImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, fileReference: FileMediaReference.message(message: MessageReference(item.message), media: file), representations: representations, alwaysShowThumbnailFirst: true, thumbnail: true, autoFetchFullSize: true)
|
||||
updateImageSignal = wallpaperImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, fileReference: FileMediaReference.message(message: MessageReference(item.message), media: file), representations: representations, alwaysShowThumbnailFirst: true, thumbnail: true, autoFetchFullSize: true, blurred: wallpaper?.settings?.blur == true)
|
||||
}
|
||||
case let .image(representations):
|
||||
if let dimensions = representations.last?.dimensions.cgSize {
|
||||
imageSize = dimensions.aspectFilled(boundingSize)
|
||||
}
|
||||
updateImageSignal = wallpaperImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, fileReference: nil, representations: representations.map({ ImageRepresentationWithReference(representation: $0, reference: .standalone(resource: $0.resource)) }), alwaysShowThumbnailFirst: true, thumbnail: true, autoFetchFullSize: true)
|
||||
updateImageSignal = wallpaperImage(account: item.context.account, accountManager: item.context.sharedContext.accountManager, fileReference: nil, representations: representations.map({ ImageRepresentationWithReference(representation: $0, reference: .standalone(resource: $0.resource)) }), alwaysShowThumbnailFirst: true, thumbnail: true, autoFetchFullSize: true, blurred: wallpaper?.settings?.blur == true)
|
||||
case let .color(color):
|
||||
updateImageSignal = solidColorImage(color)
|
||||
case let .gradient(colors, rotation):
|
||||
|
@ -2311,7 +2311,7 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
var emojiStatusPackDisposable = MetaDisposable()
|
||||
var emojiStatusFileAndPackTitle = Promise<(TelegramMediaFile, LoadedStickerPack)?>()
|
||||
|
||||
private var validWidth: CGFloat?
|
||||
private var validLayout: (width: CGFloat, deviceMetrics: DeviceMetrics)?
|
||||
|
||||
init(context: AccountContext, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, isMediaOnly: Bool, isSettings: Bool, forumTopicThreadId: Int64?, chatLocation: ChatLocation) {
|
||||
self.context = context
|
||||
@ -2577,7 +2577,9 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
self.peer = peer
|
||||
self.threadData = threadData
|
||||
self.avatarListNode.listContainerNode.peer = peer
|
||||
self.validWidth = width
|
||||
|
||||
let isFirstTime = self.validLayout == nil
|
||||
self.validLayout = (width, deviceMetrics)
|
||||
|
||||
let previousPanelStatusData = self.currentPanelStatusData
|
||||
self.currentPanelStatusData = panelStatusData.0
|
||||
@ -3628,6 +3630,10 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
transition.updateFrame(node: self.separatorNode, frame: separatorFrame)
|
||||
}
|
||||
|
||||
if isFirstTime {
|
||||
self.updateAvatarMask(transition: .immediate)
|
||||
}
|
||||
|
||||
return resolvedHeight
|
||||
}
|
||||
|
||||
@ -3690,17 +3696,22 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
self.avatarListNode.animateAvatarCollapse(transition: transition)
|
||||
}
|
||||
|
||||
if let width = self.validWidth {
|
||||
let maskScale: CGFloat = isAvatarExpanded ? width / 100.0 : 1.0
|
||||
transition.updateTransformScale(layer: self.avatarListNode.maskNode.layer, scale: maskScale)
|
||||
transition.updateTransformScale(layer: self.avatarListNode.bottomCoverNode.layer, scale: maskScale)
|
||||
transition.updateTransformScale(layer: self.avatarListNode.topCoverNode.layer, scale: maskScale)
|
||||
|
||||
let maskAnchorPoint = CGPoint(x: 0.5, y: isAvatarExpanded ? 0.37 : 0.5)
|
||||
transition.updateAnchorPoint(layer: self.avatarListNode.maskNode.layer, anchorPoint: maskAnchorPoint)
|
||||
}
|
||||
self.updateAvatarMask(transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateAvatarMask(transition: ContainedViewLayoutTransition) {
|
||||
guard let (width, deviceMetrics) = self.validLayout, deviceMetrics.hasDynamicIsland else {
|
||||
return
|
||||
}
|
||||
let maskScale: CGFloat = isAvatarExpanded ? width / 100.0 : 1.0
|
||||
transition.updateTransformScale(layer: self.avatarListNode.maskNode.layer, scale: maskScale)
|
||||
transition.updateTransformScale(layer: self.avatarListNode.bottomCoverNode.layer, scale: maskScale)
|
||||
transition.updateTransformScale(layer: self.avatarListNode.topCoverNode.layer, scale: maskScale)
|
||||
|
||||
let maskAnchorPoint = CGPoint(x: 0.5, y: isAvatarExpanded ? 0.37 : 0.5)
|
||||
transition.updateAnchorPoint(layer: self.avatarListNode.maskNode.layer, anchorPoint: maskAnchorPoint)
|
||||
}
|
||||
}
|
||||
|
||||
private class DynamicIslandMaskNode: ASDisplayNode {
|
||||
|
Loading…
x
Reference in New Issue
Block a user