Merge commit '62470a424f6be1d6d86fd838c8d7153c8ae9ed8f'

This commit is contained in:
Ali 2023-04-11 23:11:58 +04:00
commit 184f58d774
40 changed files with 997 additions and 187 deletions

View File

@ -255,8 +255,8 @@
"PUSH_MESSAGE_SUGGEST_USERPIC" = "%1$@|suggested you new profile photo";
"PUSH_MESSAGE_WALLPAPER" = "%1$@ set a new background for the chat with you";
"PUSH_MESSAGE_SAME_WALLPAPER" = "%1$@ set the same background for the chat with you";
"PUSH_MESSAGE_WALLPAPER" = "%1$@ set a new wallpaper for the chat with you";
"PUSH_MESSAGE_SAME_WALLPAPER" = "%1$@ set the same wallpaper for the chat with you";
"PUSH_REMINDER_TITLE" = "🗓 Reminder";
"PUSH_SENDER_YOU" = "📅 You";
@ -9121,12 +9121,13 @@ Sorry for the inconvenience.";
"Premium.GiftedTitle.Someone" = "Someone";
"Notification.ChangedWallpaper" = "%1$@ set a new background for this chat";
"Notification.YouChangedWallpaper" = "You set a new background for this chat";
"Notification.Wallpaper.View" = "View Background";
"Notification.ChangedWallpaper" = "%1$@ set a new wallpaper for this chat";
"Notification.YouChangedWallpaper" = "You set a new wallpaper for this chat";
"Notification.YouChangingWallpaper" = "Setting new wallpaper";
"Notification.Wallpaper.View" = "View Wallpaper";
"Notification.ChangedToSameWallpaper" = "%1$@ set the same background for this chat";
"Notification.YouChangedToSameWallpaper" = "You set the same background for this chat";
"Notification.ChangedToSameWallpaper" = "%1$@ set the same wallpaper for this chat";
"Notification.YouChangedToSameWallpaper" = "You set the same wallpaper for this chat";
"Channel.AdminLog.JoinedViaFolderInviteLink" = "%1$@ joined via invite link %2$@ (community)";
@ -9144,28 +9145,29 @@ Sorry for the inconvenience.";
"PeerInfo.Bot.ChangeSettings" = "Change Bot Settings";
"PeerInfo.Bot.BotFatherInfo" = "Use [@BotFather]() to manage this bot.";
"WallpaperPreview.NotAppliedInfo" = "Background will not be applied for **%@**";
"WallpaperPreview.ChatTopText" = "Apply the background in this chat.";
"WallpaperPreview.NotAppliedInfo" = "**%@** will be able to apply this wallpaper";
"WallpaperPreview.ChatTopText" = "Apply the wallpaper in this chat.";
"WallpaperPreview.ChatBottomText" = "Enjoy the view.";
"Conversation.Theme.SetPhotoWallpaper" = "Choose Background from Photos";
"Conversation.Theme.SetColorWallpaper" = "Set a Color as a Background";
"Conversation.Theme.OtherOptions" = "Other Options...";
"Conversation.Theme.SetPhotoWallpaper" = "Choose Wallpaper from Photos";
"Conversation.Theme.SetColorWallpaper" = "Set a Color as Wallpaper";
"Conversation.Theme.ChooseWallpaperTitle" = "Choose Background";
"Conversation.Theme.ResetWallpaper" = "Reset to Default Background";
"Conversation.Theme.ChooseWallpaperTitle" = "Choose Wallpaper";
"Conversation.Theme.ResetWallpaper" = "Remove Wallpaper";
"Conversation.Theme.ChooseColorTitle" = "Set a Color";
"Conversation.Theme.SetCustomColor" = "Set Custom";
"Appearance.ShowNextMediaOnTap" = "Show Next Media on Tap";
"Appearance.ShowNextMediaOnTapInfo" = "Tap near the edge of the screen while viewing media to navigate between photos.";
"WebApp.LaunchMoreInfo" = "More about this bot";
"WebApp.LaunchConfirmation" = "To launch this web app, you will connect to its website.";
"WallpaperPreview.PreviewInNightMode" = "Preview this background in night mode.";
"WallpaperPreview.PreviewInDayMode" = "Preview this background in day mode.";
"WallpaperPreview.PreviewInNightMode" = "Preview this wallpaper in night mode.";
"WallpaperPreview.PreviewInDayMode" = "Preview this wallpaper in day mode.";
"Conversation.Theme.ApplyBackground" = "Set as Background";
"PeerInfo.BotBlockedTitle" = "Bot Blocked";
"PeerInfo.BotBlockedText" = "This bot will not be able to message you.";
"ChatList.ContextMuteAll" = "Mute All";
"ChatList.ContextUnmuteAll" = "Unmute All";

View File

@ -49,6 +49,6 @@
- (instancetype)initWithContext:(id<LegacyComponentsContext>)context items:(NSArray *)items focusItem:(id<TGModernGalleryItem>)focusItem selectionContext:(TGMediaSelectionContext *)selectionContext editingContext:(TGMediaEditingContext *)editingContext hasCaptions:(bool)hasCaptions allowCaptionEntities:(bool)allowCaptionEntities hasTimer:(bool)hasTimer onlyCrop:(bool)onlyCrop inhibitDocumentCaptions:(bool)inhibitDocumentCaptions hasSelectionPanel:(bool)hasSelectionPanel hasCamera:(bool)hasCamera recipientName:(NSString *)recipientName;
- (void)presentPhotoEditorForItem:(id<TGModernGalleryEditableItem>)item tab:(TGPhotoEditorTab)tab;
- (void)presentPhotoEditorForItem:(id<TGModernGalleryEditableItem>)item tab:(TGPhotoEditorTab)tab snapshots:(NSArray *)snapshots;
- (void)presentPhotoEditorForItem:(id<TGModernGalleryEditableItem>)item tab:(TGPhotoEditorTab)tab snapshots:(NSArray *)snapshots fromRect:(CGRect)fromRect;
@end

View File

@ -48,6 +48,8 @@ typedef NS_ENUM(NSUInteger, TGModernGalleryScrollAnimationDirection) {
- (void)dismissWhenReady;
- (void)dismissWhenReadyAnimated:(bool)animated;
- (void)setScrollViewHidden:(bool)hidden;
- (bool)isFullyOpaque;
@end

View File

@ -23,7 +23,8 @@ typedef enum {
TGPhotoEditorControllerVideoIntent = (1 << 4),
TGPhotoEditorControllerForumAvatarIntent = (1 << 5),
TGPhotoEditorControllerSuggestedAvatarIntent = (1 << 6),
TGPhotoEditorControllerSuggestingAvatarIntent = (1 << 7)
TGPhotoEditorControllerSuggestingAvatarIntent = (1 << 7),
TGPhotoEditorControllerWallpaperIntent = (1 << 8)
} TGPhotoEditorControllerIntent;
@interface TGPhotoEditorController : TGOverlayController

View File

@ -4,6 +4,8 @@
+ (void)presentWithContext:(id<LegacyComponentsContext>)context parentController:(TGViewController *)parentController image:(UIImage *)image video:(NSURL *)video stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext transitionView:(UIView *)transitionView senderName:(NSString *)senderName didFinishWithImage:(void (^)(UIImage *image))didFinishWithImage didFinishWithVideo:(void (^)(UIImage *image, NSURL *url, TGVideoEditAdjustments *adjustments))didFinishWithVideo dismissed:(void (^)(void))dismissed;
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSAttributedString *)caption withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item paint:(bool)paint recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext snapshots:(NSArray *)snapshots immediate:(bool)immediate appeared:(void (^)(void))appeared completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed;
+ (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, TGMediaSelectableItem>)item fromRect:(CGRect)fromRect mainSnapshot:(UIView *)mainSnapshot snapshots:(NSArray *)snapshots completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed;
@end

View File

@ -218,6 +218,11 @@
return false;
}
- (bool)isRegional
{
return true;
}
- (bool)isAvialableForVideo
{
return false;

View File

@ -35,6 +35,7 @@ typedef enum
@property (nonatomic, readonly) NSInteger order;
@property (nonatomic, readonly) bool isHidden;
@property (nonatomic, readonly) bool isRegional;
@property (nonatomic, readonly) NSString *shaderString;
@property (nonatomic, readonly) NSString *ancillaryShaderString;

View File

@ -38,6 +38,11 @@
return true;
}
- (bool)isRegional
{
return false;
}
- (bool)isAvialableForVideo
{
return true;

View File

@ -38,6 +38,11 @@
return (ABS(((NSNumber *)self.displayValue).floatValue - (float)self.defaultValue) < FLT_EPSILON);
}
- (bool)isRegional
{
return true;
}
- (NSArray *)parameters
{
if (!_parameters)

View File

@ -338,10 +338,10 @@
- (void)presentPhotoEditorForItem:(id<TGModernGalleryEditableItem>)item tab:(TGPhotoEditorTab)tab
{
[self presentPhotoEditorForItem:item tab:tab snapshots:@[]];
[self presentPhotoEditorForItem:item tab:tab snapshots:@[] fromRect:CGRectZero];
}
- (void)presentPhotoEditorForItem:(id<TGModernGalleryEditableItem>)item tab:(TGPhotoEditorTab)tab snapshots:(NSArray *)snapshots
- (void)presentPhotoEditorForItem:(id<TGModernGalleryEditableItem>)item tab:(TGPhotoEditorTab)tab snapshots:(NSArray *)snapshots fromRect:(CGRect)fromRect
{
__weak TGMediaPickerGalleryModel *weakSelf = self;
@ -356,6 +356,9 @@
CGRect refFrame = CGRectZero;
UIView *editorReferenceView = [self referenceViewForItem:item frame:&refFrame];
if (!CGRectEqualToRect(fromRect, CGRectZero)) {
refFrame = fromRect;
}
UIView *referenceView = nil;
UIImage *screenImage = nil;
UIView *referenceParentView = nil;

View File

@ -166,6 +166,12 @@ static void adjustFrameRate(CAAnimation *animation) {
[self dismissWhenReadyAnimated:animated force:false];
}
- (void)setScrollViewHidden:(bool)hidden {
TGDispatchAfter(0.01, dispatch_get_main_queue(), ^{
_view.scrollView.hidden = hidden;
});
}
- (void)dismissWhenReadyAnimated:(bool)animated force:(bool)force
{
if (animated) {

View File

@ -6,7 +6,7 @@
#import <AVFoundation/AVFoundation.h>
#import <Accelerate/Accelerate.h>
const CGSize TGPhotoEditorResultImageMaxSize = { 1280, 1280 };
const CGSize TGPhotoEditorResultImageMaxSize = { 2560, 2560 };
const CGSize TGPhotoEditorScreenImageHardLimitSize = { 1280, 1280 };
const CGSize TGPhotoEditorScreenImageHardLimitLegacySize = { 750, 750 };

View File

@ -150,6 +150,9 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
}
if (!tool.isHidden)
{
if (tool.isRegional && self.intent == TGPhotoEditorControllerWallpaperIntent) {
continue;
}
[tools addObject:tool];
if (tool.isSimple)
[simpleTools addObject:tool];
@ -1020,6 +1023,8 @@ const CGFloat TGPhotoEditorToolsLandscapePanelSize = TGPhotoEditorToolsPanelSize
{
if (self.photoEditor.forVideo) {
return TGPhotoEditorToolsTab | TGPhotoEditorTintTab | TGPhotoEditorCurvesTab;
} else if (self.intent == TGPhotoEditorControllerWallpaperIntent) {
return TGPhotoEditorToolsTab | TGPhotoEditorTintTab | TGPhotoEditorCurvesTab;
} else {
return TGPhotoEditorToolsTab | TGPhotoEditorTintTab | TGPhotoEditorBlurTab | TGPhotoEditorCurvesTab;
}

View File

@ -154,7 +154,7 @@
}
}
+ (void)presentWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller caption:(NSAttributedString *)caption withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item paint:(bool)paint recipientName:(NSString *)recipientName stickersContext:(id<TGPhotoPaintStickersContext>)stickersContext snapshots:(NSArray *)snapshots immediate:(bool)immediate appeared:(void (^)(void))appeared completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed
+ (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
{
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
id<LegacyComponentsContext> windowContext = [windowManager context];
@ -201,6 +201,11 @@
[editingContext setCaption:caption forItem:editableItem];
};
model.didFinishRenderingFullSizeImage = ^(id<TGMediaEditableItem> editableItem, UIImage *resultImage)
{
[editingContext setFullSizeImage:resultImage forItem:editableItem];
};
model.interfaceView.hasSwipeGesture = false;
galleryController.model = model;
@ -255,7 +260,7 @@
}
};
if (paint) {
if (paint || adjustments) {
[model.interfaceView immediateEditorTransitionIn];
}
@ -269,9 +274,216 @@
if (paint) {
TGDispatchAfter(0.05, dispatch_get_main_queue(), ^{
[model presentPhotoEditorForItem:galleryItem tab:TGPhotoEditorPaintTab snapshots:snapshots];
[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];
});
}
}
+ (void)presentEditorWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller withItem:(id<TGMediaEditableItem, TGMediaSelectableItem>)item fromRect:(CGRect)fromRect mainSnapshot:(UIView *)mainSnapshot snapshots:(NSArray *)snapshots completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed
{
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
TGMediaEditingContext *editingContext = [[TGMediaEditingContext alloc] init];
UIImage *thumbnailImage;
TGPhotoEditorController *editorController = [[TGPhotoEditorController alloc] initWithContext:[windowManager context] item:item intent:TGPhotoEditorControllerWallpaperIntent adjustments:nil caption:nil screenImage:thumbnailImage availableTabs:TGPhotoEditorToolsTab selectedTab:TGPhotoEditorToolsTab];
editorController.editingContext = editingContext;
editorController.dontHideStatusBar = true;
editorController.beginTransitionIn = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView)
{
*referenceFrame = fromRect;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:fromRect];
//imageView.image = image;
return imageView;
};
editorController.beginTransitionOut = ^UIView *(CGRect *referenceFrame, __unused UIView **parentView)
{
CGRect startFrame = CGRectZero;
if (referenceFrame != NULL)
{
startFrame = *referenceFrame;
*referenceFrame = fromRect;
}
//[strongSelf transitionBackFromResultControllerWithReferenceFrame:startFrame];
return nil; //strongSelf->_previewView;
};
editorController.didFinishRenderingFullSizeImage = ^(UIImage *resultImage)
{
};
__weak TGPhotoEditorController *weakController = editorController;
editorController.didFinishEditing = ^(id<TGMediaEditAdjustments> adjustments, UIImage *resultImage, __unused UIImage *thumbnailImage, __unused bool hasChanges, void(^commit)(void))
{
if (!hasChanges)
return;
__strong TGPhotoEditorController *strongController = weakController;
if (strongController == nil)
return;
};
editorController.requestThumbnailImage = ^(id<TGMediaEditableItem> editableItem)
{
return [editableItem thumbnailImageSignal];
};
editorController.requestOriginalScreenSizeImage = ^(id<TGMediaEditableItem> editableItem, NSTimeInterval position)
{
return [editableItem screenImageSignal:position];
};
editorController.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: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];
// });
// }
}
@end

View File

@ -58,7 +58,48 @@ public enum LegacyAttachmentMenuMediaEditing {
case file
}
public func legacyMediaEditor(context: AccountContext, peer: Peer, threadTitle: String?, media: AnyMediaReference, initialCaption: NSAttributedString, snapshots: [UIView], transitionCompletion: (() -> Void)?, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, present: @escaping (ViewController, Any?) -> Void) {
public enum LegacyMediaEditorMode {
case draw
case adjustments
}
public func legacyWallpaperEditor(context: AccountContext, image: UIImage, fromRect: CGRect, mainSnapshot: UIView, snapshots: [UIView], transitionCompletion: (() -> Void)?, completion: @escaping (UIImage, TGMediaEditAdjustments?) -> Void, present: @escaping (ViewController, Any?) -> Void) {
let item = TGCameraCapturedPhoto(existing: image)
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let legacyController = LegacyController(presentation: .custom, theme: presentationData.theme, initialLayout: nil)
legacyController.blocksBackgroundWhenInOverlay = true
legacyController.acceptsFocusWhenInOverlay = true
legacyController.statusBar.statusBarStyle = .Ignore
legacyController.controllerLoaded = { [weak legacyController] in
legacyController?.view.disablesInteractiveTransitionGestureRecognizer = true
}
let emptyController = LegacyEmptyController(context: legacyController.context)!
emptyController.navigationBarShouldBeHidden = true
let navigationController = makeLegacyNavigationController(rootController: emptyController)
navigationController.setNavigationBarHidden(true, animated: false)
legacyController.bind(controller: navigationController)
legacyController.enableSizeClassSignal = true
present(legacyController, nil)
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, withItem: item, from: fromRect, mainSnapshot: mainSnapshot, snapshots: snapshots as [Any], completion: { item, editingContext in
let adjustments = editingContext?.adjustments(for: item)
if let imageSignal = editingContext?.fullSizeImageUrl(for: item) {
imageSignal.start(next: { value in
if let value = value as? NSURL, let data = try? Data(contentsOf: value as URL), let image = UIImage(data: data) {
completion(image, adjustments)
}
}, error: { _ in }, completed: {})
}
}, dismissed: { [weak legacyController] in
legacyController?.dismiss()
})
}
public func legacyMediaEditor(context: AccountContext, peer: Peer, threadTitle: String?, media: AnyMediaReference, mode: LegacyMediaEditorMode, initialCaption: NSAttributedString, snapshots: [UIView], transitionCompletion: (() -> Void)?, getCaptionPanelView: @escaping () -> TGCaptionPanelView?, sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32) -> Void, present: @escaping (ViewController, Any?) -> Void) {
let _ = (fetchMediaData(context: context, postbox: context.account.postbox, userLocation: .other, mediaReference: media)
|> deliverOnMainQueue).start(next: { (value, isImage) in
guard case let .data(data) = value, data.complete else {
@ -107,7 +148,7 @@ public func legacyMediaEditor(context: AccountContext, peer: Peer, threadTitle:
present(legacyController, nil)
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, caption: initialCaption, withItem: item, paint: true, recipientName: recipientName, stickersContext: paintStickersContext, snapshots: snapshots as [Any], immediate: transitionCompletion != nil, appeared: {
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, caption: initialCaption, withItem: item, paint: mode == .draw, adjustments: mode == .adjustments, recipientName: recipientName, stickersContext: paintStickersContext, from: .zero, mainSnapshot: nil, snapshots: snapshots as [Any], immediate: transitionCompletion != nil, appeared: {
transitionCompletion?()
}, completion: { result, editingContext in
let nativeGenerator = legacyAssetPickerItemGenerator()
@ -365,7 +406,7 @@ public func legacyAttachmentMenu(context: AccountContext, peer: Peer, threadTitl
present(legacyController, nil)
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, caption: NSAttributedString(), withItem: item, paint: false, recipientName: recipientName, stickersContext: paintStickersContext, snapshots: [], immediate: false, appeared: {
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, caption: NSAttributedString(), withItem: item, paint: false, adjustments: false, recipientName: recipientName, stickersContext: paintStickersContext, from: .zero, mainSnapshot: nil, snapshots: [], immediate: false, appeared: {
}, completion: { result, editingContext in
let nativeGenerator = legacyAssetPickerItemGenerator()
var selectableResult: TGMediaSelectableItem?

View File

@ -323,7 +323,14 @@ final class MediaPickerGridItemNode: GridItemNode {
strongSelf.updateHasSpoiler(hasSpoiler)
}))
if asset.mediaType == .video {
if asset.isFavorite {
self.typeIconNode.image = generateTintedImage(image: UIImage(bundleImageName: "Media Grid/Favorite"), color: .white)
if self.typeIconNode.supernode == nil {
self.addSubnode(self.gradientNode)
self.addSubnode(self.typeIconNode)
self.setNeedsLayout()
}
} else if asset.mediaType == .video {
if asset.mediaSubtypes.contains(.videoHighFrameRate) {
self.typeIconNode.image = UIImage(bundleImageName: "Media Editor/MediaSlomo")
} else if asset.mediaSubtypes.contains(.videoTimelapse) {

View File

@ -25,9 +25,9 @@ func presentCustomWallpaperPicker(context: AccountContext, present: @escaping (V
controller.selectionBlock = { [weak legacyController] asset, _ in
if let asset = asset {
let controller = WallpaperGalleryController(context: context, source: .asset(asset.backingAsset))
controller.apply = { [weak legacyController, weak controller] wallpaper, mode, cropRect, brightness in
controller.apply = { [weak legacyController, weak controller] wallpaper, mode, editedImage, cropRect, brightness in
if let legacyController = legacyController, let controller = controller {
uploadCustomWallpaper(context: context, wallpaper: wallpaper, mode: mode, cropRect: cropRect, brightness: brightness, completion: { [weak legacyController, weak controller] in
uploadCustomWallpaper(context: context, wallpaper: wallpaper, mode: mode, editedImage: nil, cropRect: cropRect, brightness: brightness, completion: { [weak legacyController, weak controller] in
if let legacyController = legacyController, let controller = controller {
legacyController.dismiss()
controller.dismiss(forceAway: true)
@ -47,8 +47,8 @@ func presentCustomWallpaperPicker(context: AccountContext, present: @escaping (V
})
}
func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryEntry, mode: WallpaperPresentationOptions, cropRect: CGRect?, brightness: CGFloat?, completion: @escaping () -> Void) {
let imageSignal: Signal<UIImage, NoError>
func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryEntry, mode: WallpaperPresentationOptions, editedImage: UIImage?, cropRect: CGRect?, brightness: CGFloat?, completion: @escaping () -> Void) {
var imageSignal: Signal<UIImage, NoError>
switch wallpaper {
case let .wallpaper(wallpaper, _):
switch wallpaper {
@ -112,6 +112,10 @@ func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryE
}
}
if let editedImage {
imageSignal = .single(editedImage)
}
let _ = (imageSignal
|> map { image -> UIImage in
var croppedImage = UIImage()
@ -196,7 +200,7 @@ func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryE
}).start()
}
public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: WallpaperGalleryEntry, mode: WallpaperPresentationOptions, cropRect: CGRect?, brightness: CGFloat?, peerId: PeerId, completion: @escaping () -> Void) {
public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: WallpaperGalleryEntry, mode: WallpaperPresentationOptions, editedImage: UIImage?, cropRect: CGRect?, brightness: CGFloat?, peerId: PeerId, completion: @escaping () -> Void) {
var imageSignal: Signal<UIImage, NoError>
switch wallpaper {
case let .wallpaper(wallpaper, _):
@ -263,6 +267,10 @@ public func uploadCustomPeerWallpaper(context: AccountContext, wallpaper: Wallpa
}
}
if let editedImage {
imageSignal = .single(editedImage)
}
let _ = (imageSignal
|> map { image -> UIImage in
var croppedImage = UIImage()

View File

@ -158,7 +158,7 @@ final class ThemeColorsGridControllerNode: ASDisplayNode {
}
controller.navigationPresentation = .modal
controller.apply = { [weak self] wallpaper, _, _, _ in
controller.apply = { [weak self] wallpaper, _, _, _, _ in
if let strongSelf = self, let mode = strongSelf.controller?.mode, case let .peer(peer) = mode, case let .wallpaper(wallpaperValue, _) = wallpaper {
let _ = (strongSelf.context.engine.themes.setChatWallpaper(peerId: peer.id, wallpaper: wallpaperValue)
|> deliverOnMainQueue).start(completed: {

View File

@ -120,9 +120,9 @@ public final class ThemeGridController: ViewController {
self.displayNode = ThemeGridControllerNode(context: self.context, presentationData: self.presentationData, presentPreviewController: { [weak self] source in
if let strongSelf = self {
let controller = WallpaperGalleryController(context: strongSelf.context, source: source)
controller.apply = { [weak self, weak controller] wallpaper, options, cropRect, brightness in
controller.apply = { [weak self, weak controller] wallpaper, options, editedImage, cropRect, brightness in
if let strongSelf = self {
uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, cropRect: cropRect, brightness: brightness, completion: { [weak self, weak controller] in
uploadCustomWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, completion: { [weak self, weak controller] in
if let strongSelf = self {
strongSelf.deactivateSearch(animated: false)
strongSelf.controllerNode.scrollToTop(animated: false)
@ -148,9 +148,9 @@ public final class ThemeGridController: ViewController {
return
}
let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset))
controller.apply = { [weak self, weak controller] wallpaper, options, cropRect, brightness in
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, cropRect: cropRect, brightness: brightness, completion: { [weak controller] in
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)
}

View File

@ -129,7 +129,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
case stickersAndEmoji
case otherHeader(PresentationTheme, String)
case showNextMediaOnTap(PresentationTheme, String, Bool)
case animationsInfo(PresentationTheme, String)
case showNextMediaOnTapInfo(PresentationTheme, String)
var section: ItemListSectionId {
switch self {
@ -143,7 +143,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
return ThemeSettingsControllerSection.icon.rawValue
case .powerSaving, .stickersAndEmoji:
return ThemeSettingsControllerSection.message.rawValue
case .otherHeader, .showNextMediaOnTap, .animationsInfo:
case .otherHeader, .showNextMediaOnTap, .showNextMediaOnTapInfo:
return ThemeSettingsControllerSection.other.rawValue
}
}
@ -180,7 +180,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
return 13
case .showNextMediaOnTap:
return 14
case .animationsInfo:
case .showNextMediaOnTapInfo:
return 15
}
}
@ -277,8 +277,8 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
} else {
return false
}
case let .animationsInfo(lhsTheme, lhsText):
if case let .animationsInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
case let .showNextMediaOnTapInfo(lhsTheme, lhsText):
if case let .showNextMediaOnTapInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
@ -347,7 +347,7 @@ private enum ThemeSettingsControllerEntry: ItemListNodeEntry {
return ItemListSwitchItem(presentationData: presentationData, title: title, value: value, sectionId: self.section, style: .blocks, updated: { value in
arguments.toggleShowNextMediaOnTap(value)
}, tag: ThemeSettingsEntryTag.animations)
case let .animationsInfo(_, text):
case let .showNextMediaOnTapInfo(_, text):
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
}
}
@ -405,6 +405,7 @@ private func themeSettingsControllerEntries(presentationData: PresentationData,
entries.append(.otherHeader(presentationData.theme, strings.Appearance_Other.uppercased()))
entries.append(.showNextMediaOnTap(presentationData.theme, strings.Appearance_ShowNextMediaOnTap, mediaSettings.showNextMediaOnTap))
entries.append(.showNextMediaOnTapInfo(presentationData.theme, strings.Appearance_ShowNextMediaOnTapInfo))
return entries
}

View File

@ -16,6 +16,8 @@ import GalleryUI
import HexColor
import CounterContollerTitleView
import UndoUI
import LegacyComponents
import LegacyMediaPickerUI
public enum WallpaperListType {
case wallpapers(WallpaperPresentationOptions?)
@ -164,6 +166,14 @@ private func updatedFileWallpaper(id: Int64? = nil, accessHash: Int64? = nil, sl
return .file(TelegramWallpaper.File(id: id ?? 0, accessHash: accessHash ?? 0, isCreator: false, isDefault: false, isPattern: isPattern, isDark: false, slug: slug, file: file, settings: WallpaperSettings(colors: colorValues, intensity: intensityValue, rotation: rotation)))
}
class WallpaperGalleryInteraction {
let editMedia: (UIImage, CGRect, UIView, [UIView], @escaping (UIImage, TGMediaEditAdjustments?) -> Void) -> Void
init(editMedia: @escaping (UIImage, CGRect, UIView, [UIView], @escaping (UIImage, TGMediaEditAdjustments?) -> Void) -> Void) {
self.editMedia = editMedia
}
}
public class WallpaperGalleryController: ViewController {
public enum Mode {
case `default`
@ -176,7 +186,9 @@ public class WallpaperGalleryController: ViewController {
private let context: AccountContext
private let source: WallpaperListSource
private let mode: Mode
public var apply: ((WallpaperGalleryEntry, WallpaperPresentationOptions, CGRect?, CGFloat?) -> Void)?
public var apply: ((WallpaperGalleryEntry, WallpaperPresentationOptions, UIImage?, CGRect?, CGFloat?) -> Void)?
private var interaction: WallpaperGalleryInteraction?
private let _ready = Promise<Bool>()
override public var ready: Promise<Bool> {
@ -230,9 +242,29 @@ public class WallpaperGalleryController: ViewController {
//self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
self.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .all, compactSize: .portrait)
self.interaction = WallpaperGalleryInteraction(editMedia: { [weak self] image, fromRect, mainSnapshot, snapshots, apply in
guard let self else {
return
}
var snapshots = snapshots
if let toolbarNode = self.toolbarNode, let snapshotView = toolbarNode.view.snapshotContentTree() {
snapshotView.frame = toolbarNode.view.convert(toolbarNode.view.bounds, to: nil)
snapshots.append(snapshotView)
}
legacyWallpaperEditor(context: context, image: image, fromRect: fromRect, mainSnapshot: mainSnapshot, snapshots: snapshots, transitionCompletion: {
}, completion: { image, adjustments in
apply(image, adjustments)
}, present: { [weak self] c, a in
if let self {
self.present(c, in: .window(.root))
}
})
})
var entries: [WallpaperGalleryEntry] = []
var centralEntryIndex: Int?
switch source {
case let .list(wallpapers, central, type):
entries = wallpapers.map { .wallpaper($0, nil) }
@ -350,7 +382,7 @@ public class WallpaperGalleryController: ViewController {
var i: Int = 0
var updateItems: [GalleryPagerUpdateItem] = []
for entry in entries {
let item = GalleryPagerUpdateItem(index: i, previousIndex: i, item: WallpaperGalleryItem(context: self.context, index: updateItems.count, entry: entry, arguments: arguments, source: self.source, mode: self.mode))
let item = GalleryPagerUpdateItem(index: i, previousIndex: i, item: WallpaperGalleryItem(context: self.context, index: updateItems.count, entry: entry, arguments: arguments, source: self.source, mode: self.mode, interaction: self.interaction!))
updateItems.append(item)
i += 1
}
@ -361,7 +393,7 @@ public class WallpaperGalleryController: ViewController {
var updateItems: [GalleryPagerUpdateItem] = []
for i in 0 ..< self.entries.count {
if i == index {
let item = GalleryPagerUpdateItem(index: index, previousIndex: index, item: WallpaperGalleryItem(context: self.context, index: index, entry: entry, arguments: arguments, source: self.source, mode: self.mode))
let item = GalleryPagerUpdateItem(index: index, previousIndex: index, item: WallpaperGalleryItem(context: self.context, index: index, entry: entry, arguments: arguments, source: self.source, mode: self.mode, interaction: self.interaction!))
updateItems.append(item)
}
}
@ -459,7 +491,7 @@ public class WallpaperGalleryController: ViewController {
let entry = strongSelf.entries[centralItemNode.index]
if case .peer = strongSelf.mode {
strongSelf.apply?(entry, options, centralItemNode.cropRect, centralItemNode.brightness)
strongSelf.apply?(entry, options, centralItemNode.editedImage, centralItemNode.cropRect, centralItemNode.brightness)
return
}
@ -617,7 +649,7 @@ public class WallpaperGalleryController: ViewController {
break
}
strongSelf.apply?(entry, options, centralItemNode.cropRect, centralItemNode.brightness)
strongSelf.apply?(entry, options, nil, centralItemNode.cropRect, centralItemNode.brightness)
}
}
}
@ -695,7 +727,7 @@ public class WallpaperGalleryController: ViewController {
break
}
}
strongSelf.containerLayoutUpdated(layout, transition: .animated(duration: 0.3, curve: .spring))
strongSelf.containerLayoutUpdated(layout, transition: .animated(duration: 0.4, curve: .spring))
}
}
@ -723,7 +755,7 @@ public class WallpaperGalleryController: ViewController {
itemNode.updateIsColorsPanelActive(strongSelf.colorsPanelEnabled, animated: true)
strongSelf.containerLayoutUpdated(layout, transition: .animated(duration: 0.3, curve: .spring))
strongSelf.containerLayoutUpdated(layout, transition: .animated(duration: 0.4, curve: .spring))
}
}
@ -960,7 +992,7 @@ public class WallpaperGalleryController: ViewController {
colors = true
}
self.galleryNode.pager.replaceItems(zip(0 ..< self.entries.count, self.entries).map({ WallpaperGalleryItem(context: self.context, index: $0, entry: $1, arguments: WallpaperGalleryItemArguments(isColorsList: colors), source: self.source, mode: self.mode) }), centralItemIndex: self.centralEntryIndex)
self.galleryNode.pager.replaceItems(zip(0 ..< self.entries.count, self.entries).map({ WallpaperGalleryItem(context: self.context, index: $0, entry: $1, arguments: WallpaperGalleryItemArguments(isColorsList: colors), source: self.source, mode: self.mode, interaction: self.interaction!) }), centralItemIndex: self.centralEntryIndex)
if let initialOptions = self.initialOptions, let itemNode = self.galleryNode.pager.centralItemNode() as? WallpaperGalleryItemNode {
itemNode.options = initialOptions

View File

@ -46,25 +46,27 @@ class WallpaperGalleryItem: GalleryItem {
let arguments: WallpaperGalleryItemArguments
let source: WallpaperListSource
let mode: WallpaperGalleryController.Mode
let interaction: WallpaperGalleryInteraction
init(context: AccountContext, index: Int, entry: WallpaperGalleryEntry, arguments: WallpaperGalleryItemArguments, source: WallpaperListSource, mode: WallpaperGalleryController.Mode) {
init(context: AccountContext, index: Int, entry: WallpaperGalleryEntry, arguments: WallpaperGalleryItemArguments, source: WallpaperListSource, mode: WallpaperGalleryController.Mode, interaction: WallpaperGalleryInteraction) {
self.context = context
self.index = index
self.entry = entry
self.arguments = arguments
self.source = source
self.mode = mode
self.interaction = interaction
}
func node(synchronous: Bool) -> GalleryItemNode {
let node = WallpaperGalleryItemNode(context: self.context)
node.setEntry(self.entry, arguments: self.arguments, source: self.source, mode: self.mode)
node.setEntry(self.entry, arguments: self.arguments, source: self.source, mode: self.mode, interaction: self.interaction)
return node
}
func updateNode(node: GalleryItemNode, synchronous: Bool) {
if let node = node as? WallpaperGalleryItemNode {
node.setEntry(self.entry, arguments: self.arguments, source: self.source, mode: self.mode)
node.setEntry(self.entry, arguments: self.arguments, source: self.source, mode: self.mode, interaction: self.interaction)
}
}
@ -93,6 +95,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
private var colorPreview: Bool = false
private var contentSize: CGSize?
private var arguments = WallpaperGalleryItemArguments()
private var interaction: WallpaperGalleryInteraction?
let wrapperNode: ASDisplayNode
let imageNode: TransformImageNode
@ -105,6 +108,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
private let cancelButtonNode: WallpaperNavigationButtonNode
private let shareButtonNode: WallpaperNavigationButtonNode
private let dayNightButtonNode: WallpaperNavigationButtonNode
private let editButtonNode: WallpaperNavigationButtonNode
private let blurButtonNode: WallpaperOptionButtonNode
private let motionButtonNode: WallpaperOptionButtonNode
@ -176,8 +180,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.patternButtonNode = WallpaperOptionButtonNode(title: self.presentationData.strings.WallpaperPreview_Pattern, value: .check(false))
self.patternButtonNode.setEnabled(false)
self.serviceBackgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0x333333, alpha: 0.45))
self.serviceBackgroundNode.isHidden = true
self.serviceBackgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0x333333, alpha: 0.35))
var sliderValueChangedImpl: ((CGFloat) -> Void)?
self.sliderNode = WallpaperSliderNode(minValue: 0.0, maxValue: 1.0, value: 0.7, valueChanged: { value, _ in
@ -192,6 +195,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.shareButtonNode.enableSaturation = true
self.dayNightButtonNode = WallpaperNavigationButtonNode(content: .dayNight(isNight: self.isDarkAppearance), dark: true)
self.dayNightButtonNode.enableSaturation = true
self.editButtonNode = WallpaperNavigationButtonNode(content: .icon(image: UIImage(bundleImageName: "Settings/WallpaperAdjustments"), size: CGSize(width: 28.0, height: 28.0)), dark: true)
self.editButtonNode.enableSaturation = true
self.playButtonPlayImage = generateImage(CGSize(width: 48.0, height: 48.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
@ -256,6 +261,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.addSubnode(self.cancelButtonNode)
self.addSubnode(self.shareButtonNode)
self.addSubnode(self.dayNightButtonNode)
self.addSubnode(self.editButtonNode)
self.imageNode.addSubnode(self.brightnessNode)
@ -267,6 +273,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.cancelButtonNode.addTarget(self, action: #selector(self.cancelPressed), forControlEvents: .touchUpInside)
self.shareButtonNode.addTarget(self, action: #selector(self.actionPressed), forControlEvents: .touchUpInside)
self.dayNightButtonNode.addTarget(self, action: #selector(self.dayNightPressed), forControlEvents: .touchUpInside)
self.editButtonNode.addTarget(self, action: #selector(self.editPressed), forControlEvents: .touchUpInside)
sliderValueChangedImpl = { [weak self] value in
if let self {
@ -288,7 +295,13 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
}
switch entry {
case .asset, .contextResult:
if let editedImage = self.editedImage {
let scale = editedImage.size.height / self.cropNode.cropRect.height
let cropRect = self.cropNode.cropRect
return CGRect(origin: CGPoint(x: cropRect.minX * scale, y: cropRect.minY * scale), size: CGSize(width: cropRect.width * scale, height: cropRect.height * scale))
} else {
return self.cropNode.cropRect
}
default:
return nil
}
@ -453,6 +466,70 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.switchTheme()
}
@objc private func editPressed() {
guard let image = self.imageNode.image else {
return
}
let originalImage = self.originalImage ?? image
var nodesToSnapshot = [
self.cancelButtonNode,
self.editButtonNode,
self.blurButtonNode,
self.motionButtonNode,
self.serviceBackgroundNode
]
if let messageNodes = self.messageNodes {
for node in messageNodes {
nodesToSnapshot.append(node)
}
}
var snapshots: [UIView] = []
for node in nodesToSnapshot {
if let snapshotView = node.view.snapshotContentTree() {
snapshotView.frame = node.view.convert(node.view.bounds, to: nil)
snapshots.append(snapshotView)
}
}
if let snapshotView = self.dayNightButtonNode.view.snapshotView(afterScreenUpdates: false) {
snapshotView.frame = self.dayNightButtonNode.view.convert(self.dayNightButtonNode.view.bounds, to: nil)
snapshots.append(snapshotView)
}
let mainSnapshotView: UIView
if let snapshotView = self.imageNode.view.snapshotView(afterScreenUpdates: false) {
snapshotView.frame = self.imageNode.view.convert(self.imageNode.view.bounds, to: nil)
mainSnapshotView = snapshotView
} else {
mainSnapshotView = UIView()
}
let fromRect = self.imageNode.view.convert(self.imageNode.bounds, to: nil)
self.interaction?.editMedia(originalImage, fromRect, mainSnapshotView, snapshots, { [weak self] result, adjustments in
self?.originalImage = originalImage
self?.editedImage = result
self?.currentAdjustments = adjustments
self?.imageNode.setSignal(.single({ arguments in
let context = DrawingContext(size: arguments.drawingSize, opaque: false)
context?.withFlippedContext({ context in
if let cgImage = result.cgImage {
context.draw(cgImage, in: CGRect(origin: .zero, size: arguments.drawingSize))
}
})
return context
}))
})
}
private var originalImage: UIImage?
public private(set) var editedImage: UIImage?
private var currentAdjustments: TGMediaEditAdjustments?
private func animateIntensityChange(delay: Double) {
let targetValue: CGFloat = self.sliderNode.value
self.sliderNode.internalUpdateLayout(size: self.sliderNode.frame.size, value: 1.0)
@ -484,11 +561,12 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.dismiss()
}
func setEntry(_ entry: WallpaperGalleryEntry, arguments: WallpaperGalleryItemArguments, source: WallpaperListSource, mode: WallpaperGalleryController.Mode) {
func setEntry(_ entry: WallpaperGalleryEntry, arguments: WallpaperGalleryItemArguments, source: WallpaperListSource, mode: WallpaperGalleryController.Mode, interaction: WallpaperGalleryInteraction) {
let previousArguments = self.arguments
self.arguments = arguments
self.source = source
self.mode = mode
self.interaction = interaction
if self.arguments.colorPreview != previousArguments.colorPreview {
if self.arguments.colorPreview {
@ -530,6 +608,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.nativeNode.updateBubbleTheme(bubbleTheme: presentationData.theme, bubbleCorners: presentationData.chatBubbleCorners)
var isColor = false
switch entry {
case let .wallpaper(wallpaper, _):
Queue.mainQueue().justDispatch {
@ -545,6 +624,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
} else {
self.playButtonNode.setIcon(self.playButtonRotateImage)
}
isColor = true
} else if case let .gradient(gradient) = wallpaper {
self.nativeNode.isHidden = false
self.nativeNode.update(wallpaper: wallpaper)
@ -555,10 +635,12 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
} else {
self.playButtonNode.setIcon(self.playButtonRotateImage)
}
isColor = true
} else if case .color = wallpaper {
self.nativeNode.isHidden = false
self.nativeNode.update(wallpaper: wallpaper)
self.patternButtonNode.isSelected = false
isColor = true
} else {
self.nativeNode._internalUpdateIsSettingUpWallpaper()
self.nativeNode.isHidden = true
@ -576,7 +658,20 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.playButtonNode.setIcon(self.playButtonRotateImage)
}
self.cancelButtonNode.enableSaturation = isColor
self.dayNightButtonNode.enableSaturation = isColor
self.editButtonNode.enableSaturation = isColor
self.shareButtonNode.enableSaturation = isColor
self.patternButtonNode.backgroundNode.enableSaturation = isColor
self.blurButtonNode.backgroundNode.enableSaturation = isColor
self.motionButtonNode.backgroundNode.enableSaturation = isColor
self.colorsButtonNode.backgroundNode.enableSaturation = isColor
self.playButtonNode.enableSaturation = isColor
var canShare = false
var canSwitchTheme = false
var canEdit = false
switch entry {
case let .wallpaper(wallpaper, message):
self.initialWallpaper = wallpaper
@ -749,7 +844,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
colorSignal = .single(UIColor(rgb: 0x000000, alpha: 0.3))
self.wrapperNode.addSubnode(self.cropNode)
showPreviewTooltip = true
self.serviceBackgroundNode.isHidden = false
canSwitchTheme = true
canEdit = true
case let .contextResult(result):
var imageDimensions: CGSize?
var imageResource: TelegramMediaResource?
@ -805,11 +901,24 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
subtitleSignal = .single(nil)
self.wrapperNode.addSubnode(self.cropNode)
showPreviewTooltip = true
self.serviceBackgroundNode.isHidden = false
canSwitchTheme = true
}
self.contentSize = contentSize
if case .wallpaper = source {
canSwitchTheme = true
} else if case let .list(_, _, type) = source, case .colors = type {
canSwitchTheme = true
}
if canSwitchTheme {
self.dayNightButtonNode.isHidden = false
self.shareButtonNode.isHidden = true
} else {
self.dayNightButtonNode.isHidden = true
self.shareButtonNode.isHidden = !canShare
}
self.editButtonNode.isHidden = !canEdit
if self.cropNode.supernode == nil {
self.imageNode.contentMode = .scaleAspectFill
@ -1157,16 +1266,22 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let alpha = 1.0 - min(1.0, max(0.0, abs(offset.y) / 50.0))
var additionalYOffset: CGFloat = 0.0
var canEditIntensity = false
if let source = self.source {
switch source {
case .asset, .contextResult:
if self.isDarkAppearance {
additionalYOffset -= 44.0
canEditIntensity = true
case let .wallpaper(wallpaper, _, _, _, _, _):
if case let .file(file) = wallpaper, !file.isPattern {
canEditIntensity = true
}
default:
break
}
}
if canEditIntensity && self.isDarkAppearance {
additionalYOffset -= 44.0
}
let buttonSpacing: CGFloat = 18.0
@ -1202,12 +1317,10 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
sliderFrame = sliderFrame.offsetBy(dx: 0.0, dy: 22.0)
}
var dayNightHidden = true
let cancelSize = self.cancelButtonNode.measure(layout.size)
let cancelFrame = CGRect(origin: CGPoint(x: 16.0 + offset.x, y: 16.0), size: cancelSize)
let shareFrame = CGRect(origin: CGPoint(x: layout.size.width - 16.0 - 28.0 + offset.x, y: 16.0), size: CGSize(width: 28.0, height: 28.0))
let editFrame = CGRect(origin: CGPoint(x: layout.size.width - 16.0 - 28.0 + offset.x - 46.0, y: 16.0), size: CGSize(width: 28.0, height: 28.0))
let centerOffset: CGFloat = 32.0
@ -1218,13 +1331,11 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
blurFrame = leftButtonFrame
motionAlpha = 1.0
motionFrame = rightButtonFrame
dayNightHidden = false
case .contextResult:
blurAlpha = 1.0
blurFrame = leftButtonFrame
motionAlpha = 1.0
motionFrame = rightButtonFrame
dayNightHidden = false
case let .wallpaper(wallpaper, _):
switch wallpaper {
case .builtin:
@ -1317,8 +1428,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
transition.updateFrame(node: self.cancelButtonNode, frame: cancelFrame)
transition.updateFrame(node: self.shareButtonNode, frame: shareFrame)
transition.updateFrame(node: self.dayNightButtonNode, frame: shareFrame)
self.dayNightButtonNode.isHidden = dayNightHidden
transition.updateFrame(node: self.editButtonNode, frame: editFrame)
}
private func updateMessagesLayout(layout: ContainerViewLayout, offset: CGPoint, transition: ContainedViewLayoutTransition) {
@ -1342,6 +1452,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
currentWallpaper = wallpaper
}
var canEditIntensity = false
if let source = self.source {
switch source {
case .slug, .wallpaper:
@ -1364,6 +1475,10 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
if hasAnimatableGradient {
bottomMessageText = presentationData.strings.WallpaperPreview_PreviewBottomTextAnimatable
}
if case let .wallpaper(wallpaper, _, _, _, _, _) = source, case let .file(file) = wallpaper, !file.isPattern {
canEditIntensity = true
}
case let .list(_, _, type):
switch type {
case .wallpapers:
@ -1393,9 +1508,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
case .asset, .contextResult:
topMessageText = presentationData.strings.WallpaperPreview_CropTopText
bottomMessageText = presentationData.strings.WallpaperPreview_CropBottomText
if self.isDarkAppearance {
bottomInset += 44.0
}
canEditIntensity = true
case .customColor:
topMessageText = presentationData.strings.WallpaperPreview_CustomColorTopText
bottomMessageText = presentationData.strings.WallpaperPreview_CustomColorBottomText
@ -1410,6 +1523,10 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
}
}
if canEditIntensity && self.isDarkAppearance {
bottomInset += 44.0
}
let theme = self.presentationData.theme
let message1 = Message(stableId: 2, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 2), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66001, flags: [], tags: [], globalTags: [], localTags: [], forwardInfo: nil, author: peers[otherPeerId], text: bottomMessageText, attributes: [], media: [], peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil)
@ -1567,7 +1684,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
if let strongSelf = self, (count < 2 && currentTimestamp > timestamp + 24 * 60 * 60) {
strongSelf.displayedPreviewTooltip = true
let controller = TooltipScreen(account: strongSelf.context.account, sharedContext: strongSelf.context.sharedContext, text: isDark ? strongSelf.presentationData.strings.WallpaperPreview_PreviewInDayMode : strongSelf.presentationData.strings.WallpaperPreview_PreviewInNightMode, style: .customBlur(UIColor(rgb: 0x333333, alpha: 0.45)), icon: nil, location: .point(frame.offsetBy(dx: 1.0, dy: 6.0), .bottom), displayDuration: .custom(3.0), inset: 3.0, shouldDismissOnTouch: { _ in
let controller = TooltipScreen(account: strongSelf.context.account, sharedContext: strongSelf.context.sharedContext, text: isDark ? strongSelf.presentationData.strings.WallpaperPreview_PreviewInDayMode : strongSelf.presentationData.strings.WallpaperPreview_PreviewInNightMode, style: .customBlur(UIColor(rgb: 0x333333, alpha: 0.35)), icon: nil, location: .point(frame.offsetBy(dx: 1.0, dy: 6.0), .bottom), displayDuration: .custom(3.0), inset: 3.0, shouldDismissOnTouch: { _ in
return .dismiss(consume: false)
})
strongSelf.galleryController()?.present(controller, in: .current)

View File

@ -41,7 +41,7 @@ final class WallpaperLightButtonBackgroundNode: ASDisplayNode {
private let lightNode: ASDisplayNode
override init() {
self.backgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0x333333, alpha: 0.45), enableBlur: true, enableSaturation: false)
self.backgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0x333333, alpha: 0.35), enableBlur: true, enableSaturation: false)
self.overlayNode = ASDisplayNode()
self.overlayNode.backgroundColor = UIColor(rgb: 0xffffff, alpha: 0.75)
self.overlayNode.layer.compositingFilter = "overlayBlendMode"
@ -71,8 +71,15 @@ final class WallpaperLightButtonBackgroundNode: ASDisplayNode {
final class WallpaperOptionBackgroundNode: ASDisplayNode {
private let backgroundNode: NavigationBackgroundNode
var enableSaturation: Bool {
didSet {
self.backgroundNode.updateColor(color: UIColor(rgb: 0x333333, alpha: 0.35), enableBlur: true, enableSaturation: self.enableSaturation, transition: .immediate)
}
}
init(enableSaturation: Bool = false) {
self.backgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0x333333, alpha: 0.45), enableBlur: true, enableSaturation: enableSaturation)
self.enableSaturation = enableSaturation
self.backgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0x333333, alpha: 0.35), enableBlur: true, enableSaturation: enableSaturation)
super.init()
@ -97,7 +104,13 @@ final class WallpaperNavigationButtonNode: HighlightTrackingButtonNode {
case dayNight(isNight: Bool)
}
var enableSaturation: Bool = false
var enableSaturation: Bool = false {
didSet {
if let backgroundNode = self.backgroundNode as? WallpaperOptionBackgroundNode {
backgroundNode.enableSaturation = self.enableSaturation
}
}
}
private let content: Content
var dark: Bool {
@ -128,7 +141,7 @@ final class WallpaperNavigationButtonNode: HighlightTrackingButtonNode {
self.dark = dark
if dark {
self.backgroundNode = WallpaperOptionBackgroundNode()
self.backgroundNode = WallpaperOptionBackgroundNode(enableSaturation: self.enableSaturation)
} else {
self.backgroundNode = WallpaperLightButtonBackgroundNode()
}
@ -252,7 +265,7 @@ final class WallpaperNavigationButtonNode: HighlightTrackingButtonNode {
final class WallpaperOptionButtonNode: HighlightTrackingButtonNode {
private let backgroundNode: WallpaperOptionBackgroundNode
let backgroundNode: WallpaperOptionBackgroundNode
private let checkNode: CheckNode
private let colorNode: ASImageNode
@ -488,7 +501,7 @@ final class WallpaperSliderNode: ASDisplayNode {
self.value = value
self.valueChanged = valueChanged
self.backgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0x333333, alpha: 0.45), enableBlur: true, enableSaturation: false)
self.backgroundNode = NavigationBackgroundNode(color: UIColor(rgb: 0x333333, alpha: 0.35), enableBlur: true, enableSaturation: false)
self.foregroundNode = ASDisplayNode()
self.foregroundNode.clipsToBounds = true

View File

@ -759,7 +759,7 @@ final class SparseItemGridScrollingIndicatorComponent: CombinedComponent {
let date = context.component.date
let components = date.0.components(separatedBy: " ")
let month = components.first ?? ""
let month = String(components.prefix(upTo: components.count - 1).joined(separator: " "))
let year = components.last ?? ""
var monthAnimation: RollingText.AnimationDirection?

View File

@ -124,18 +124,8 @@ func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager
guard let inputPeer = apiInputPeer(peer) else {
return .complete()
}
return postbox.transaction { transaction -> Signal<Api.Updates, NoError> in
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
if let current = current as? CachedUserData {
return current.withUpdatedWallpaper(wallpaper)
} else {
return current
}
})
var flags: Int32 = 0
var inputWallpaper: Api.InputWallPaper?
var inputSettings: Api.WallPaperSettings?
if let inputWallpaperAndInputSettings = wallpaper?.apiInputWallpaperAndSettings {
@ -149,10 +139,19 @@ func _internal_setChatWallpaper(postbox: Postbox, network: Network, stateManager
return .complete()
}
|> mapToSignal { updates -> Signal<Api.Updates, NoError> in
return postbox.transaction { transaction -> Api.Updates in
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in
if let current = current as? CachedUserData {
return current.withUpdatedWallpaper(wallpaper)
} else {
return current
}
})
if applyUpdates {
stateManager.addUpdates(updates)
}
return .single(updates)
return updates
}
}
} |> switchToLatest
}

View File

@ -20,6 +20,7 @@ swift_library(
"//submodules/StringPluralization:StringPluralization",
"//submodules/Sunrise:Sunrise",
"//submodules/TinyThumbnail:TinyThumbnail",
"//submodules/FastBlur:FastBlur",
"//Telegram:PresentationStrings",
],
visibility = [

View File

@ -8,6 +8,7 @@ import Postbox
import MediaResources
import AppBundle
import TinyThumbnail
import FastBlur
private var backgroundImageForWallpaper: (TelegramWallpaper, Bool, UIImage)?
@ -200,8 +201,25 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me
} else if !didOutputBlurred {
didOutputBlurred = true
if let immediateThumbnailData = file.file.immediateThumbnailData, let decodedData = decodeTinyThumbnail(data: immediateThumbnailData) {
if let image = UIImage(data: decodedData)?.precomposed() {
subscriber.putNext((image, false))
if let thumbnailImage = UIImage(data: decodedData)?.precomposed() {
let thumbnailContextSize = CGSize(width: thumbnailImage.size.width * 6.0, height: thumbnailImage.size.height * 6.0)
guard let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) else {
subscriber.putNext((thumbnailImage, false))
return
}
thumbnailContext.withFlippedContext { c in
if let image = thumbnailImage.cgImage {
c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContextSize))
}
}
telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
if let blurredThumbnailImage = thumbnailContext.generateImage() {
subscriber.putNext((blurredThumbnailImage, false))
} else {
subscriber.putNext((thumbnailImage, false))
}
}
}
}
@ -238,8 +256,25 @@ public func chatControllerBackgroundImageSignal(wallpaper: TelegramWallpaper, me
} else if !didOutputBlurred {
didOutputBlurred = true
if let immediateThumbnailData = file.file.immediateThumbnailData, let decodedData = decodeTinyThumbnail(data: immediateThumbnailData) {
if let image = UIImage(data: decodedData)?.precomposed() {
subscriber.putNext((image, false))
if let thumbnailImage = UIImage(data: decodedData)?.precomposed() {
let thumbnailContextSize = CGSize(width: thumbnailImage.size.width * 6.0, height: thumbnailImage.size.height * 6.0)
guard let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) else {
subscriber.putNext((thumbnailImage, false))
return
}
thumbnailContext.withFlippedContext { c in
if let image = thumbnailImage.cgImage {
c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContextSize))
}
}
telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
if let blurredThumbnailImage = thumbnailContext.generateImage() {
subscriber.putNext((blurredThumbnailImage, false))
} else {
subscriber.putNext((thumbnailImage, false))
}
}
}
}

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "heart_18.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,75 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 2.625000 2.815430 cm
0.000000 0.000000 0.000000 scn
6.375000 0.000042 m
6.539109 0.000042 6.772649 0.119967 6.962005 0.239893 c
10.490347 2.512170 12.750000 5.175784 12.750000 7.877269 c
12.750000 10.193728 11.153094 11.809570 9.139605 11.809570 c
7.883540 11.809570 6.943069 11.115263 6.375000 10.073803 c
5.819555 11.108952 4.872772 11.809570 3.616708 11.809570 c
1.603218 11.809570 0.000000 10.193728 0.000000 7.877269 c
0.000000 5.175784 2.259654 2.512170 5.787995 0.239893 c
5.983664 0.119967 6.217203 0.000042 6.375000 0.000042 c
h
f
n
Q
endstream
endobj
3 0 obj
611
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 18.000000 18.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000000701 00000 n
0000000723 00000 n
0000000896 00000 n
0000000970 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
1029
%%EOF

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "edit.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,101 @@
%PDF-1.7
1 0 obj
<< >>
endobj
2 0 obj
<< /Length 3 0 R >>
stream
/DeviceRGB CS
/DeviceRGB cs
q
1.000000 0.000000 -0.000000 1.000000 7.170227 6.170044 cm
1.000000 1.000000 1.000000 scn
4.830000 16.659882 m
5.288396 16.659882 5.660000 16.288279 5.660000 15.829882 c
5.660000 13.659912 l
14.830000 13.659912 l
15.288396 13.659912 15.660000 13.288309 15.660000 12.829912 c
15.660000 12.371515 15.288396 11.999912 14.830000 11.999912 c
5.660000 11.999912 l
5.660000 9.829882 l
5.660000 9.371485 5.288396 8.999882 4.830000 8.999882 c
4.371603 8.999882 4.000000 9.371485 4.000000 9.829882 c
4.000000 11.999912 l
0.830000 11.999912 l
0.371604 11.999912 0.000000 12.371515 0.000000 12.829912 c
0.000000 13.288309 0.371604 13.659912 0.830000 13.659912 c
4.000000 13.659912 l
4.000000 15.829882 l
4.000000 16.288279 4.371603 16.659882 4.830000 16.659882 c
h
14.830078 2.999956 m
15.288474 2.999956 15.660078 3.371560 15.660078 3.829956 c
15.660078 4.288352 15.288474 4.659956 14.830078 4.659956 c
11.660078 4.659956 l
11.660078 6.829987 l
11.660078 7.288383 11.288474 7.659986 10.830078 7.659986 c
10.371682 7.659986 10.000078 7.288383 10.000078 6.829987 c
10.000078 4.659956 l
0.830078 4.659956 l
0.371682 4.659956 0.000078 4.288352 0.000078 3.829956 c
0.000078 3.371560 0.371682 2.999956 0.830078 2.999956 c
10.000078 2.999956 l
10.000078 0.829987 l
10.000078 0.371590 10.371682 -0.000013 10.830078 -0.000013 c
11.288474 -0.000013 11.660078 0.371590 11.660078 0.829987 c
11.660078 2.999956 l
14.830078 2.999956 l
h
f*
n
Q
endstream
endobj
3 0 obj
1448
endobj
4 0 obj
<< /Annots []
/Type /Page
/MediaBox [ 0.000000 0.000000 30.000000 30.000000 ]
/Resources 1 0 R
/Contents 2 0 R
/Parent 5 0 R
>>
endobj
5 0 obj
<< /Kids [ 4 0 R ]
/Count 1
/Type /Pages
>>
endobj
6 0 obj
<< /Pages 5 0 R
/Type /Catalog
>>
endobj
xref
0 7
0000000000 65535 f
0000000010 00000 n
0000000034 00000 n
0000001538 00000 n
0000001561 00000 n
0000001734 00000 n
0000001808 00000 n
trailer
<< /ID [ (some) (id) ]
/Root 6 0 R
/Size 7
>>
startxref
1867
%%EOF

View File

@ -858,9 +858,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
strongSelf.chatDisplayNode.dismissInput()
let wallpaperPreviewController = WallpaperGalleryController(context: strongSelf.context, source: .wallpaper(wallpaper, nil, [], nil, nil, nil), mode: .peer(EnginePeer(peer), true))
wallpaperPreviewController.apply = { [weak wallpaperPreviewController] entry, options, _, _ in
wallpaperPreviewController.apply = { [weak wallpaperPreviewController] entry, options, _, _, _ in
if case let .wallpaper(wallpaper, _) = entry, case let .file(file) = wallpaper, !file.isPattern && options.contains(.blur) {
uploadCustomPeerWallpaper(context: strongSelf.context, wallpaper: entry, mode: options, cropRect: nil, brightness: nil, peerId: message.id.peerId, completion: {
uploadCustomPeerWallpaper(context: strongSelf.context, wallpaper: entry, mode: options, editedImage: nil, cropRect: nil, brightness: nil, peerId: message.id.peerId, completion: {
wallpaperPreviewController?.dismiss()
})
} else {
@ -1096,7 +1096,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, initialCaption: NSAttributedString(), snapshots: snapshots, transitionCompletion: {
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, mode: .draw, initialCaption: NSAttributedString(), snapshots: snapshots, transitionCompletion: {
transitionCompletion()
}, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView()
@ -3970,7 +3970,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
let inputText = strongSelf.presentationInterfaceState.interfaceState.effectiveInputState.inputText
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, initialCaption: inputText, snapshots: [], transitionCompletion: nil, getCaptionPanelView: { [weak self] in
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: strongSelf.threadInfo?.title, media: mediaReference, mode: .draw, initialCaption: inputText, snapshots: [], transitionCompletion: nil, getCaptionPanelView: { [weak self] in
return self?.getCaptionPanelView()
}, sendMessagesWithSignals: { [weak self] signals, _, _ in
if let strongSelf = self {
@ -5831,7 +5831,25 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let themeEmoticon: Signal<String?, NoError> = self.chatThemeEmoticonPromise.get()
|> distinctUntilChanged
let chatWallpaper: Signal<TelegramWallpaper?, NoError> = self.chatWallpaperPromise.get()
let uploadingChatWallpaper: Signal<TelegramWallpaper?, NoError>
if let peerId = self.chatLocation.peerId {
uploadingChatWallpaper = self.context.account.pendingPeerMediaUploadManager.uploadingPeerMedia
|> map { uploadingPeerMedia -> TelegramWallpaper? in
if let item = uploadingPeerMedia[peerId], case let .wallpaper(wallpaper) = item.content {
return wallpaper
} else {
return nil
}
}
|> distinctUntilChanged
} else {
uploadingChatWallpaper = .single(nil)
}
let chatWallpaper: Signal<TelegramWallpaper?, NoError> = combineLatest(self.chatWallpaperPromise.get(), uploadingChatWallpaper)
|> map { chatWallpaper, uploadingChatWallpaper in
return uploadingChatWallpaper ?? chatWallpaper
}
|> distinctUntilChanged
let themeSettings = context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationThemeSettings])
@ -18615,9 +18633,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
let controller = WallpaperGalleryController(context: strongSelf.context, source: .asset(asset), mode: .peer(EnginePeer(peer), false))
controller.navigationPresentation = .modal
controller.apply = { [weak self] wallpaper, options, cropRect, brightness in
controller.apply = { [weak self] wallpaper, options, editedImage, cropRect, brightness in
if let strongSelf = self {
uploadCustomPeerWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, cropRect: cropRect, brightness: brightness, peerId: peerId, completion: {
uploadCustomPeerWallpaper(context: strongSelf.context, wallpaper: wallpaper, mode: options, editedImage: editedImage, cropRect: cropRect, brightness: brightness, peerId: peerId, completion: {
dismissControllers()
})
}

View File

@ -101,6 +101,9 @@ func titlePanelForChatPresentationInterfaceState(_ chatPresentationInterfaceStat
displayActionsPanel = true
}
}
if peerStatusSettings.requestChatTitle != nil {
displayActionsPanel = true
}
}
if displayActionsPanel && (selectedContext == nil || selectedContext! <= .pinnedMessage) {

View File

@ -46,6 +46,7 @@ class ChatMessageProfilePhotoSuggestionContentNode: ChatMessageBubbleContentNode
self.subtitleNode.displaysAsynchronously = false
self.imageNode = TransformImageNode()
self.imageNode.contentAnimations = [.subsequentUpdates]
self.buttonNode = HighlightTrackingButtonNode()
self.buttonNode.clipsToBounds = true

View File

@ -16,12 +16,16 @@ import PhotoResources
import WallpaperResources
import Markdown
import RadialStatusNode
import ComponentFlow
import AudioTranscriptionPendingIndicatorComponent
class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
private var mediaBackgroundContent: WallpaperBubbleBackgroundNode?
private let mediaBackgroundNode: NavigationBackgroundNode
private let subtitleNode: TextNode
private let progressNode: ImmediateTextNode
private let imageNode: TransformImageNode
private var transcriptionPendingIndicator: ComponentHostView<Empty>?
private var statusOverlayNode: ASDisplayNode
private var statusNode: RadialStatusNode
@ -43,7 +47,12 @@ class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
self.subtitleNode.isUserInteractionEnabled = false
self.subtitleNode.displaysAsynchronously = false
self.progressNode = ImmediateTextNode()
self.progressNode.isUserInteractionEnabled = false
self.progressNode.displaysAsynchronously = false
self.imageNode = TransformImageNode()
self.imageNode.contentAnimations = [.subsequentUpdates]
self.buttonNode = HighlightTrackingButtonNode()
self.buttonNode.clipsToBounds = true
@ -66,6 +75,7 @@ class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
self.addSubnode(self.mediaBackgroundNode)
self.addSubnode(self.subtitleNode)
self.addSubnode(self.progressNode)
self.addSubnode(self.imageNode)
self.addSubnode(self.buttonNode)
@ -172,14 +182,25 @@ class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
}
private func updateProgress(_ progress: Float?) {
guard let item = self.item else {
return
}
let transition: ContainedViewLayoutTransition = .animated(duration: 0.2, curve: .easeInOut)
if let progress {
let progressValue = CGFloat(max(0.027, progress))
self.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: progressValue, cancelEnabled: true, animateRotation: true))
transition.updateAlpha(node: self.statusOverlayNode, alpha: 1.0)
let primaryTextColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper).primaryText
self.progressNode.attributedText = NSAttributedString(string: "\(Int(progress * 100.0))%", font: Font.semibold(13.0), textColor: primaryTextColor, paragraphAlignment: .center)
let progressSize = self.progressNode.updateLayout(CGSize(width: 100.0, height: 100.0))
let progressFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(self.subtitleNode.frame.midX - progressSize.width / 2.0), y: self.subtitleNode.frame.maxY + 1.0), size: progressSize)
self.progressNode.isHidden = false
self.progressNode.frame = progressFrame
} else {
self.statusNode.transitionToState(.none)
transition.updateAlpha(node: self.statusOverlayNode, alpha: 0.0)
self.progressNode.isHidden = true
}
}
@ -218,8 +239,14 @@ class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
let peerName = item.message.peers[item.message.id.peerId].flatMap { EnginePeer($0).compactDisplayTitle } ?? ""
let text: String
var displayTrailingAnimatedDots = false
if fromYou {
if item.message.id.namespace == Namespaces.Message.Local {
text = item.presentationData.strings.Notification_YouChangingWallpaper
displayTrailingAnimatedDots = true
} else {
text = item.presentationData.strings.Notification_YouChangedWallpaper
}
} else {
text = item.presentationData.strings.Notification_ChangedWallpaper(peerName).string
}
@ -227,15 +254,24 @@ class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
let body = MarkdownAttributeSet(font: Font.regular(13.0), textColor: primaryTextColor)
let bold = MarkdownAttributeSet(font: Font.semibold(13.0), textColor: primaryTextColor)
let subtitle = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in
var subtitle = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in
return nil
}), textAlignment: .center)
if displayTrailingAnimatedDots {
let modifiedString = NSMutableAttributedString(attributedString: subtitle)
modifiedString.append(NSAttributedString(string: "...", font: Font.regular(13.0), textColor: .clear))
subtitle = modifiedString
}
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: subtitle, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
let (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Notification_Wallpaper_View, font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
let backgroundSize = CGSize(width: width, height: subtitleLayout.size.height + 140.0 + (fromYou ? 0.0 : 42.0))
var textHeight = subtitleLayout.size.height
if displayTrailingAnimatedDots {
textHeight += subtitleLayout.size.height
}
let backgroundSize = CGSize(width: width, height: textHeight + 140.0 + (fromYou ? 0.0 : 42.0))
return (backgroundSize.width, { boundingWidth in
return (backgroundSize, { [weak self] animation, synchronousLoads, _ in
@ -324,6 +360,34 @@ class ChatMessageWallpaperBubbleContentNode: ChatMessageBubbleContentNode {
let subtitleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - subtitleLayout.size.width) / 2.0) , y: mediaBackgroundFrame.minY + 127.0), size: subtitleLayout.size)
strongSelf.subtitleNode.frame = subtitleFrame
if displayTrailingAnimatedDots {
let transcriptionPendingIndicator: ComponentHostView<Empty>
if let current = strongSelf.transcriptionPendingIndicator {
transcriptionPendingIndicator = current
} else {
transcriptionPendingIndicator = ComponentHostView<Empty>()
strongSelf.transcriptionPendingIndicator = transcriptionPendingIndicator
strongSelf.view.addSubview(transcriptionPendingIndicator)
}
let indicatorComponent: AnyComponent<Empty>
indicatorComponent = AnyComponent(AudioTranscriptionPendingLottieIndicatorComponent(color: primaryTextColor, font: Font.regular(13.0)))
let indicatorSize = transcriptionPendingIndicator.update(
transition: .immediate,
component: indicatorComponent,
environment: {},
containerSize: CGSize(width: 100.0, height: 100.0)
)
transcriptionPendingIndicator.frame = CGRect(origin: CGPoint(x: strongSelf.subtitleNode.frame.midX + subtitleLayout.trailingLineWidth / 2.0 - indicatorSize.width + 2.0 - UIScreenPixel, y: strongSelf.subtitleNode.frame.maxY - indicatorSize.height - 3.0 - UIScreenPixel), size: indicatorSize)
} else {
if let transcriptionPendingIndicator = strongSelf.transcriptionPendingIndicator {
strongSelf.transcriptionPendingIndicator = nil
transcriptionPendingIndicator.removeFromSuperview()
}
}
let buttonTitleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - buttonTitleLayout.size.width) / 2.0), y: subtitleFrame.maxY + 18.0), size: buttonTitleLayout.size)
strongSelf.buttonTitleNode.frame = buttonTitleFrame

View File

@ -20,27 +20,7 @@ import TooltipUI
import AnimatedStickerNode
import TelegramAnimatedStickerNode
import ShimmerEffect
private func closeButtonImage(theme: PresentationTheme) -> UIImage? {
return generateImage(CGSize(width: 30.0, height: 30.0), contextGenerator: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.setFillColor(UIColor(rgb: 0x808084, alpha: 0.1).cgColor)
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
context.setLineWidth(2.0)
context.setLineCap(.round)
context.setStrokeColor(theme.actionSheet.inputClearButtonColor.cgColor)
context.move(to: CGPoint(x: 10.0, y: 10.0))
context.addLine(to: CGPoint(x: 20.0, y: 20.0))
context.strokePath()
context.move(to: CGPoint(x: 20.0, y: 10.0))
context.addLine(to: CGPoint(x: 10.0, y: 20.0))
context.strokePath()
})
}
import WebUI
private struct ThemeSettingsThemeEntry: Comparable, Identifiable {
let index: Int
@ -745,7 +725,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
private let contentBackgroundNode: ASDisplayNode
private let titleNode: ASTextNode
private let textNode: ImmediateTextNode
private let cancelButton: HighlightableButtonNode
private let cancelButtonNode: WebAppCancelButtonNode
private let switchThemeButton: HighlightTrackingButtonNode
private let animationContainerNode: ASDisplayNode
private var animationNode: AnimationNode
@ -830,13 +810,13 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
self.contentBackgroundNode.backgroundColor = backgroundColor
self.titleNode = ASTextNode()
self.titleNode.attributedText = NSAttributedString(string: self.presentationData.strings.Conversation_Theme_Title, font: Font.semibold(16.0), textColor: textColor)
self.titleNode.attributedText = NSAttributedString(string: self.presentationData.strings.Conversation_Theme_Title, font: Font.semibold(17.0), textColor: textColor)
self.textNode = ImmediateTextNode()
self.textNode.attributedText = NSAttributedString(string: self.presentationData.strings.Conversation_Theme_Subtitle(peerName).string, font: Font.regular(12.0), textColor: secondaryTextColor)
self.textNode.attributedText = NSAttributedString(string: self.presentationData.strings.Conversation_Theme_Subtitle(peerName).string, font: Font.regular(15.0), textColor: secondaryTextColor)
self.textNode.isHidden = true
self.cancelButton = HighlightableButtonNode()
self.cancelButton.setImage(closeButtonImage(theme: self.presentationData.theme), for: .normal)
self.cancelButtonNode = WebAppCancelButtonNode(theme: self.presentationData.theme, strings: self.presentationData.strings)
self.switchThemeButton = HighlightTrackingButtonNode()
self.animationContainerNode = ASDisplayNode()
@ -845,7 +825,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
self.animationNode = AnimationNode(animation: self.isDarkAppearance ? "anim_sun_reverse" : "anim_sun", colors: iconColors(theme: self.presentationData.theme), scale: 1.0)
self.animationNode.isUserInteractionEnabled = false
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 52.0, cornerRadius: 11.0, gloss: false)
self.doneButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(theme: self.presentationData.theme), height: 50.0, cornerRadius: 11.0, gloss: false)
self.otherButton = HighlightableButtonNode()
@ -872,7 +852,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
self.backgroundNode.addSubnode(self.effectNode)
self.backgroundNode.addSubnode(self.contentBackgroundNode)
self.contentContainerNode.addSubnode(self.titleNode)
self.contentContainerNode.addSubnode(self.textNode)
self.buttonsContentContainerNode.addSubnode(self.textNode)
self.buttonsContentContainerNode.addSubnode(self.doneButton)
self.buttonsContentContainerNode.addSubnode(self.otherButton)
@ -880,10 +860,10 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
self.animationContainerNode.addSubnode(self.animationNode)
self.topContentContainerNode.addSubnode(self.switchThemeButton)
self.topContentContainerNode.addSubnode(self.listNode)
self.topContentContainerNode.addSubnode(self.cancelButton)
self.topContentContainerNode.addSubnode(self.cancelButtonNode)
self.switchThemeButton.addTarget(self, action: #selector(self.switchThemePressed), forControlEvents: .touchUpInside)
self.cancelButton.addTarget(self, action: #selector(self.cancelButtonPressed), forControlEvents: .touchUpInside)
self.cancelButtonNode.buttonNode.addTarget(self, action: #selector(self.cancelButtonPressed), forControlEvents: .touchUpInside)
self.doneButton.pressed = { [weak self] in
if let strongSelf = self {
strongSelf.doneButton.isUserInteractionEnabled = false
@ -970,6 +950,8 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
}
}
}
self.updateCancelButton()
}
private func enqueueTransition(_ transition: ThemeSettingsThemeItemNodeTransition) {
@ -1018,6 +1000,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
UIView.transition(with: self.buttonsContentContainerNode.view, duration: ChatThemeScreen.themeCrossfadeDuration, options: [.transitionCrossDissolve, .curveLinear]) {
self.updateButtons()
}
self.updateCancelButton()
self.skipButtonsUpdate = false
self.themeSelectionsCount += 1
@ -1027,23 +1010,17 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
}
private func updateButtons() {
let canResetWallpaper = self.controller?.canResetWallpaper ?? false
let doneButtonTitle: String
let otherButtonTitle: String
var accentButtonTheme = true
var destructiveOtherButton = false
var otherIsEnabled = false
if self.selectedEmoticon?.strippedEmoji == self.initiallySelectedEmoticon?.strippedEmoji {
doneButtonTitle = self.presentationData.strings.Conversation_Theme_SetPhotoWallpaper
otherButtonTitle = canResetWallpaper ? self.presentationData.strings.Conversation_Theme_ResetWallpaper : self.presentationData.strings.Common_Cancel
otherIsEnabled = self.controller?.canResetWallpaper == true
accentButtonTheme = false
destructiveOtherButton = canResetWallpaper
} else if self.selectedEmoticon == nil && self.initiallySelectedEmoticon != nil {
doneButtonTitle = self.presentationData.strings.Conversation_Theme_Reset
otherButtonTitle = self.presentationData.strings.Conversation_Theme_OtherOptions
} else {
doneButtonTitle = self.presentationData.strings.Conversation_Theme_ApplyBackground
otherButtonTitle = self.presentationData.strings.Conversation_Theme_OtherOptions
doneButtonTitle = self.presentationData.strings.Conversation_Theme_Apply
}
let buttonTheme: SolidRoundedButtonTheme
@ -1058,7 +1035,25 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
}
self.doneButton.updateTheme(buttonTheme)
self.otherButton.setTitle(otherButtonTitle, with: Font.regular(17.0), with: destructiveOtherButton ? self.presentationData.theme.actionSheet.destructiveActionTextColor : self.presentationData.theme.actionSheet.controlAccentColor, for: .normal)
self.otherButton.setTitle(self.presentationData.strings.Conversation_Theme_ResetWallpaper, with: Font.regular(17.0), with: self.presentationData.theme.actionSheet.destructiveActionTextColor, for: .normal)
self.otherButton.isHidden = !otherIsEnabled
self.textNode.isHidden = !accentButtonTheme || self.controller?.canResetWallpaper == false
if let (layout, navigationBarHeight) = self.containerLayout {
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
}
}
private func updateCancelButton() {
var cancelButtonState: WebAppCancelButtonNode.State = .cancel
if self.selectedEmoticon?.strippedEmoji == self.initiallySelectedEmoticon?.strippedEmoji {
} else if self.selectedEmoticon == nil && self.initiallySelectedEmoticon != nil {
cancelButtonState = .back
} else {
cancelButtonState = .back
}
self.cancelButtonNode.setState(cancelButtonState, animated: true)
}
private var switchThemeIconAnimator: DisplayLinkAnimator?
@ -1069,14 +1064,14 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
let previousTheme = self.presentationData.theme
self.presentationData = presentationData
self.titleNode.attributedText = NSAttributedString(string: self.titleNode.attributedText?.string ?? "", font: Font.semibold(16.0), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
self.textNode.attributedText = NSAttributedString(string: self.textNode.attributedText?.string ?? "", font: Font.regular(12.0), textColor: self.presentationData.theme.actionSheet.secondaryTextColor)
self.titleNode.attributedText = NSAttributedString(string: self.titleNode.attributedText?.string ?? "", font: Font.semibold(17.0), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
self.textNode.attributedText = NSAttributedString(string: self.textNode.attributedText?.string ?? "", font: Font.regular(15.0), textColor: self.presentationData.theme.actionSheet.secondaryTextColor)
if previousTheme !== presentationData.theme, let (layout, navigationBarHeight) = self.containerLayout {
self.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: .immediate)
}
self.cancelButton.setImage(closeButtonImage(theme: self.presentationData.theme), for: .normal)
self.cancelButtonNode.theme = presentationData.theme
let previousIconColors = iconColors(theme: previousTheme)
let newIconColors = iconColors(theme: self.presentationData.theme)
@ -1113,8 +1108,12 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
}
@objc func cancelButtonPressed() {
if self.cancelButtonNode.state == .back {
self.setEmoticon(self.initiallySelectedEmoticon)
} else {
self.cancel?()
}
}
@objc func otherButtonPressed() {
if self.selectedEmoticon?.strippedEmoji != self.initiallySelectedEmoticon?.strippedEmoji {
@ -1317,7 +1316,10 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
let bottomInset: CGFloat = 10.0 + cleanInsets.bottom
let titleHeight: CGFloat = 54.0
let contentHeight = titleHeight + bottomInset + 188.0 + 50.0
var contentHeight = titleHeight + bottomInset + 168.0
if self.controller?.canResetWallpaper == true {
contentHeight += 50.0
}
let width = horizontalContainerFillingSizeForLayout(layout: layout, sideInset: 0.0)
@ -1336,29 +1338,38 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
transition.updateFrame(node: self.dimNode, frame: CGRect(origin: CGPoint(), size: layout.size))
let titleSize = self.titleNode.measure(CGSize(width: width - 90.0, height: titleHeight))
let titleFrame = CGRect(origin: CGPoint(x: floor((contentFrame.width - titleSize.width) / 2.0), y: 11.0 + UIScreenPixel), size: titleSize)
let titleFrame = CGRect(origin: CGPoint(x: floor((contentFrame.width - titleSize.width) / 2.0), y: 18.0 + UIScreenPixel), size: titleSize)
transition.updateFrame(node: self.titleNode, frame: titleFrame)
let textSize = self.textNode.updateLayout(CGSize(width: width - 90.0, height: titleHeight))
let textFrame = CGRect(origin: CGPoint(x: floor((contentFrame.width - textSize.width) / 2.0), y: 31.0), size: textSize)
transition.updateFrame(node: self.textNode, frame: textFrame)
let switchThemeSize = CGSize(width: 44.0, height: 44.0)
let switchThemeFrame = CGRect(origin: CGPoint(x: 3.0, y: 6.0), size: switchThemeSize)
let switchThemeFrame = CGRect(origin: CGPoint(x: contentFrame.width - switchThemeSize.width - 3.0, y: 6.0), size: switchThemeSize)
transition.updateFrame(node: self.switchThemeButton, frame: switchThemeFrame)
transition.updateFrame(node: self.animationContainerNode, frame: switchThemeFrame.insetBy(dx: 9.0, dy: 9.0))
transition.updateFrameAsPositionAndBounds(node: self.animationNode, frame: CGRect(origin: .zero, size: self.animationContainerNode.frame.size))
let cancelSize = CGSize(width: 44.0, height: 44.0)
let cancelFrame = CGRect(origin: CGPoint(x: contentFrame.width - cancelSize.width - 3.0, y: 6.0), size: cancelSize)
transition.updateFrame(node: self.cancelButton, frame: cancelFrame)
let cancelSize = self.cancelButtonNode.calculateSizeThatFits(CGSize(width: layout.size.width, height: 56.0))
let cancelFrame = CGRect(origin: CGPoint(x: 16.0, y: 0.0), size: cancelSize)
transition.updateFrame(node: self.cancelButtonNode, frame: cancelFrame)
let buttonInset: CGFloat = 16.0
let doneButtonHeight = self.doneButton.updateLayout(width: contentFrame.width - buttonInset * 2.0, transition: transition)
transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: contentHeight - doneButtonHeight - 50.0 - insets.bottom - 6.0, width: contentFrame.width, height: doneButtonHeight))
var doneY = contentHeight - doneButtonHeight - 2.0 - insets.bottom
if self.controller?.canResetWallpaper == true {
doneY = contentHeight - doneButtonHeight - 52.0 - insets.bottom
}
transition.updateFrame(node: self.doneButton, frame: CGRect(x: buttonInset, y: doneY, width: contentFrame.width, height: doneButtonHeight))
let colorButtonSize = self.otherButton.measure(CGSize(width: contentFrame.width - buttonInset * 2.0, height: .greatestFiniteMagnitude))
transition.updateFrame(node: self.otherButton, frame: CGRect(origin: CGPoint(x: floor((contentFrame.width - colorButtonSize.width) / 2.0), y: contentHeight - colorButtonSize.height - insets.bottom - 6.0 - 9.0), size: colorButtonSize))
let otherButtonSize = self.otherButton.measure(CGSize(width: contentFrame.width - buttonInset * 2.0, height: .greatestFiniteMagnitude))
self.otherButton.frame = CGRect(origin: CGPoint(x: floor((contentFrame.width - otherButtonSize.width) / 2.0), y: contentHeight - otherButtonSize.height - insets.bottom - 15.0), size: otherButtonSize)
let textSize = self.textNode.updateLayout(CGSize(width: width - 90.0, height: titleHeight))
let textFrame: CGRect
if self.controller?.canResetWallpaper == true {
textFrame = CGRect(origin: CGPoint(x: floor((contentFrame.width - textSize.width) / 2.0), y: contentHeight - textSize.height - insets.bottom - 17.0), size: textSize)
} else {
textFrame = CGRect(origin: CGPoint(x: floor((contentFrame.width - textSize.width) / 2.0), y: contentHeight - textSize.height - insets.bottom - 15.0), size: textSize)
}
transition.updateFrame(node: self.textNode, frame: textFrame)
transition.updateFrame(node: self.contentContainerNode, frame: contentContainerFrame)
transition.updateFrame(node: self.topContentContainerNode, frame: contentContainerFrame)
@ -1371,7 +1382,7 @@ private class ChatThemeScreenNode: ViewControllerTracingNode, UIScrollViewDelega
let contentSize = CGSize(width: contentFrame.width, height: 120.0)
self.listNode.bounds = CGRect(x: 0.0, y: 0.0, width: contentSize.height, height: contentSize.width)
self.listNode.position = CGPoint(x: contentSize.width / 2.0, y: contentSize.height / 2.0 + titleHeight + 6.0)
self.listNode.position = CGPoint(x: contentSize.width / 2.0, y: contentSize.height / 2.0 + titleHeight - 4.0)
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: CGSize(width: contentSize.height, height: contentSize.width), insets: listInsets, duration: 0.0, curve: .Default(duration: nil)), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
}
}

View File

@ -3906,6 +3906,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
var previousAbout: String?
var currentAbout: String?
var previousIsBlocked: Bool?
var currentIsBlocked: Bool?
var previousPhotoIsPersonal: Bool?
var currentPhotoIsPersonal: Bool?
if let previousUser = previousData?.peer as? TelegramUser {
@ -3932,6 +3935,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
currentVideoCallsAvailable = cachedData.videoCallsAvailable
previousAbout = previousCachedData.about
currentAbout = cachedData.about
previousIsBlocked = previousCachedData.isBlocked
currentIsBlocked = cachedData.isBlocked
}
if self.isSettings {
@ -3954,6 +3959,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
if let previousPhotoIsPersonal, let currentPhotoIsPersonal, previousPhotoIsPersonal != currentPhotoIsPersonal {
infoUpdated = true
}
if let previousIsBlocked, let currentIsBlocked, previousIsBlocked != currentIsBlocked {
infoUpdated = true
}
self.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: self.didSetReady && (membersUpdated || infoUpdated) ? .animated(duration: 0.3, curve: .spring) : .immediate)
}
}
@ -4091,7 +4099,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}
if let mediaReference = mediaReference, let peer = message.peers[message.id.peerId] {
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: message.associatedThreadInfo?.title, media: mediaReference, initialCaption: NSAttributedString(), snapshots: snapshots, transitionCompletion: {
legacyMediaEditor(context: strongSelf.context, peer: peer, threadTitle: message.associatedThreadInfo?.title, media: mediaReference, mode: .draw, initialCaption: NSAttributedString(), snapshots: snapshots, transitionCompletion: {
transitionCompletion()
}, getCaptionPanelView: {
return nil
@ -5396,6 +5404,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
case .leave:
self.openLeavePeer(delete: false)
case .stop:
self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .universal(animation: "anim_banned", scale: 0.066, colors: [:], title: self.presentationData.strings.PeerInfo_BotBlockedTitle, text: self.presentationData.strings.PeerInfo_BotBlockedText, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
self.updateBlocked(block: true)
}
}

View File

@ -1030,6 +1030,7 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode
} else {
strongSelf.blurredBackgroundContents = nil
}
strongSelf.updateBubbles()
strongSelf._isReady.set(true)
}))
}

View File

@ -258,7 +258,7 @@ public func wallpaperImage(account: Account, accountManager: AccountManager<Tele
if let thumbnailImage = thumbnailImage {
let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height)
let initialThumbnailContextFittingSize = fittedSize.fitted(CGSize(width: 240.0, height: 240.0))
let initialThumbnailContextFittingSize = fittedSize.fitted(thumbnail ? CGSize(width: 240.0, height: 240.0) : CGSize(width: 320.0, height: 320.0))
let thumbnailContextSize = thumbnailSize.aspectFitted(initialThumbnailContextFittingSize)
guard let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) else {

View File

@ -26,26 +26,26 @@ import InstantPageUI
private let durgerKingBotIds: [Int64] = [5104055776, 2200339955]
private class CancelButtonNode: ASDisplayNode {
enum State {
public class WebAppCancelButtonNode: ASDisplayNode {
public enum State {
case cancel
case back
}
private let buttonNode: HighlightTrackingButtonNode
public let buttonNode: HighlightTrackingButtonNode
private let arrowNode: ASImageNode
private let labelNode: ImmediateTextNode
var state: State = .cancel
public var state: State = .cancel
var theme: PresentationTheme {
public var theme: PresentationTheme {
didSet {
self.setState(self.state, animated: false, force: true)
}
}
private let strings: PresentationStrings
init(theme: PresentationTheme, strings: PresentationStrings) {
public init(theme: PresentationTheme, strings: PresentationStrings) {
self.theme = theme
self.strings = strings
@ -82,7 +82,7 @@ private class CancelButtonNode: ASDisplayNode {
self.setState(.cancel, animated: false, force: true)
}
func setState(_ state: State, animated: Bool, force: Bool = false) {
public func setState(_ state: State, animated: Bool, force: Bool = false) {
guard self.state != state || force else {
return
}
@ -1049,7 +1049,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
}
private var titleView: CounterContollerTitleView?
private let cancelButtonNode: CancelButtonNode
private let cancelButtonNode: WebAppCancelButtonNode
private let moreButtonNode: MoreButtonNode
private let context: AccountContext
@ -1097,7 +1097,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
self.updatedPresentationData = updatedPresentationData
self.presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
self.cancelButtonNode = CancelButtonNode(theme: self.presentationData.theme, strings: self.presentationData.strings)
self.cancelButtonNode = WebAppCancelButtonNode(theme: self.presentationData.theme, strings: self.presentationData.strings)
self.moreButtonNode = MoreButtonNode(theme: self.presentationData.theme)
self.moreButtonNode.iconNode.enqueueState(.more, animated: false)