mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-05 19:28:46 +02:00
Various improvements
This commit is contained in:
parent
1fa0c7991c
commit
d88a29b378
44 changed files with 477 additions and 226 deletions
|
|
@ -16199,3 +16199,8 @@ Error: %8$@";
|
||||||
"Chat.Poll.Restriction.Country.CountriesLastDelimiter" = " and ";
|
"Chat.Poll.Restriction.Country.CountriesLastDelimiter" = " and ";
|
||||||
|
|
||||||
"Conversation.MessageGuestChatForUser" = "for %@";
|
"Conversation.MessageGuestChatForUser" = "for %@";
|
||||||
|
|
||||||
|
"Settings.About.PrivacyHelpEmpty" = "A few words about you.";
|
||||||
|
"Settings.About.PrivacyHelpEveryone" = "Everyone can see your bio. [Change >]()";
|
||||||
|
"Settings.About.PrivacyHelpContacts" = "Only uour contacts can see your bio. [Change >]()";
|
||||||
|
"Settings.About.PrivacyHelpNobody" = "Nobody can see your bio. [Change >]()";
|
||||||
|
|
|
||||||
|
|
@ -479,7 +479,9 @@ final class AttachmentContainer: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||||
if self.isDismissed {
|
if self.isDismissed {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.bottomClipNode.cornerRadius = layout.deviceMetrics.screenCornerRadius - 2.0
|
|
||||||
|
let containerCornerRadius = max(24.0, layout.deviceMetrics.screenCornerRadius)
|
||||||
|
self.bottomClipNode.cornerRadius = containerCornerRadius - 2.0
|
||||||
|
|
||||||
self.isUpdatingState = true
|
self.isUpdatingState = true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1174,7 +1174,8 @@ public class AttachmentController: ViewController, MinimizableController {
|
||||||
localGlassView.contentView.addSubview(buttonIcon)
|
localGlassView.contentView.addSubview(buttonIcon)
|
||||||
ComponentTransition(buttonTransition).animateBlur(layer: buttonIcon.layer, fromRadius: 0.0, toRadius: 10.0)
|
ComponentTransition(buttonTransition).animateBlur(layer: buttonIcon.layer, fromRadius: 0.0, toRadius: 10.0)
|
||||||
|
|
||||||
containerView.update(bounds: CGRect(origin: .zero, size: targetFrame.size), topCornerRadius: 38.0, bottomCornerRadius: layout.deviceMetrics.screenCornerRadius - 2.0, boundsTransition: scaleTransition, cornersTransition: cornersTransition)
|
let containerCornerRadius = max(24.0, layout.deviceMetrics.screenCornerRadius)
|
||||||
|
containerView.update(bounds: CGRect(origin: .zero, size: targetFrame.size), topCornerRadius: 38.0, bottomCornerRadius: containerCornerRadius - 2.0, boundsTransition: scaleTransition, cornersTransition: cornersTransition)
|
||||||
scaleTransition.animateBounds(layer: containerView.layer, from: CGRect(origin: .zero, size: CGSize(width: targetFrame.width, height: targetFrame.width)))
|
scaleTransition.animateBounds(layer: containerView.layer, from: CGRect(origin: .zero, size: CGSize(width: targetFrame.width, height: targetFrame.width)))
|
||||||
scaleTransition.animateTransformScale(view: containerView, from: sourceButtonScale)
|
scaleTransition.animateTransformScale(view: containerView, from: sourceButtonScale)
|
||||||
positionTransition.animatePosition(layer: containerView.layer, from: sourceButtonFrame.center, to: containerView.center, completion: { _ in
|
positionTransition.animatePosition(layer: containerView.layer, from: sourceButtonFrame.center, to: containerView.center, completion: { _ in
|
||||||
|
|
@ -1242,7 +1243,9 @@ public class AttachmentController: ViewController, MinimizableController {
|
||||||
if let sourceGlassView = findParentGlassBackgroundView(attachmentButton), let glassParams = sourceGlassView.params {
|
if let sourceGlassView = findParentGlassBackgroundView(attachmentButton), let glassParams = sourceGlassView.params {
|
||||||
let containerView = ClipContainerView()
|
let containerView = ClipContainerView()
|
||||||
containerView.frame = initialFrame
|
containerView.frame = initialFrame
|
||||||
containerView.update(bounds: CGRect(origin: .zero, size: initialFrame.size), topCornerRadius: 38.0, bottomCornerRadius: layout.deviceMetrics.screenCornerRadius - 2.0, boundsTransition: .immediate, cornersTransition: .immediate)
|
|
||||||
|
let containerCornerRadius = max(24.0, layout.deviceMetrics.screenCornerRadius)
|
||||||
|
containerView.update(bounds: CGRect(origin: .zero, size: initialFrame.size), topCornerRadius: 38.0, bottomCornerRadius: containerCornerRadius - 2.0, boundsTransition: .immediate, cornersTransition: .immediate)
|
||||||
self.view.addSubview(containerView)
|
self.view.addSubview(containerView)
|
||||||
|
|
||||||
let localGlassView = GlassBackgroundView()
|
let localGlassView = GlassBackgroundView()
|
||||||
|
|
|
||||||
|
|
@ -7287,7 +7287,7 @@ private final class ChatListLocationContext {
|
||||||
dateTimeFormat: presentationData.dateTimeFormat,
|
dateTimeFormat: presentationData.dateTimeFormat,
|
||||||
nameDisplayOrder: presentationData.nameDisplayOrder,
|
nameDisplayOrder: presentationData.nameDisplayOrder,
|
||||||
displayBackground: false,
|
displayBackground: false,
|
||||||
content: .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: nil, customSubtitle: nil, onlineMemberCount: onlineMemberCount, isScheduledMessages: false, isMuted: nil, customMessageCount: nil, isEnabled: true),
|
content: .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: nil, customSubtitle: nil, onlineMemberCount: onlineMemberCount, isScheduledMessages: false, isMuted: nil, customMessageCount: nil, hidePeerStatus: false, isEnabled: true),
|
||||||
activities: nil,
|
activities: nil,
|
||||||
networkState: nil,
|
networkState: nil,
|
||||||
tapped: { [weak self] in
|
tapped: { [weak self] in
|
||||||
|
|
|
||||||
|
|
@ -1986,6 +1986,9 @@ final class ChatListControllerNode: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||||
contentNode.dismissSearch = { [weak self] in
|
contentNode.dismissSearch = { [weak self] in
|
||||||
self?.dismissSearch?()
|
self?.dismissSearch?()
|
||||||
}
|
}
|
||||||
|
contentNode.dismissSearchImmediately = { [weak self] in
|
||||||
|
self?.controller?.deactivateSearch(animated: false)
|
||||||
|
}
|
||||||
contentNode.openAdInfo = { [weak self] node, adPeer in
|
contentNode.openAdInfo = { [weak self] node, adPeer in
|
||||||
self?.controller?.openAdInfo(node: node, adPeer: adPeer)
|
self?.controller?.openAdInfo(node: node, adPeer: adPeer)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||||
private let navigationController: NavigationController?
|
private let navigationController: NavigationController?
|
||||||
|
|
||||||
var dismissSearch: (() -> Void)?
|
var dismissSearch: (() -> Void)?
|
||||||
|
var dismissSearchImmediately: (() -> Void)?
|
||||||
var openAdInfo: ((ASDisplayNode, AdPeer) -> Void)?
|
var openAdInfo: ((ASDisplayNode, AdPeer) -> Void)?
|
||||||
|
|
||||||
private let edgeEffectView: EdgeEffectView
|
private let edgeEffectView: EdgeEffectView
|
||||||
|
|
@ -1657,7 +1658,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let proceed: (ChatController) -> Void = { chatController in
|
let proceed: (ChatController) -> Void = { chatController in
|
||||||
chatController.purposefulAction = { [weak self] in
|
chatController.purposefulAction = { [weak self] in
|
||||||
self?.cancel?()
|
self?.dismissSearchImmediately?()
|
||||||
}
|
}
|
||||||
if let navigationController = strongSelf.navigationController {
|
if let navigationController = strongSelf.navigationController {
|
||||||
var viewControllers = navigationController.viewControllers
|
var viewControllers = navigationController.viewControllers
|
||||||
|
|
|
||||||
|
|
@ -792,9 +792,10 @@ public final class ResizableSheetComponent<ChildEnvironmentType: Sendable & Equa
|
||||||
let scrollContentHeight = max(topInset + contentHeight + containerInset, availableSize.height - containerInset)
|
let scrollContentHeight = max(topInset + contentHeight + containerInset, availableSize.height - containerInset)
|
||||||
|
|
||||||
self.scrollContentClippingView.layer.cornerRadius = 38.0
|
self.scrollContentClippingView.layer.cornerRadius = 38.0
|
||||||
|
|
||||||
self.itemLayout = ItemLayout(containerSize: availableSize, containerInset: containerInset, containerCornerRadius: sheetEnvironment.deviceMetrics.screenCornerRadius, bottomInset: sheetEnvironment.safeInsets.bottom, topInset: topInset, fillingSize: fillingSize, isTablet: sheetEnvironment.metrics.isTablet)
|
let containerCornerRadius = max(22.0, sheetEnvironment.deviceMetrics.screenCornerRadius)
|
||||||
|
self.itemLayout = ItemLayout(containerSize: availableSize, containerInset: containerInset, containerCornerRadius: containerCornerRadius, bottomInset: sheetEnvironment.safeInsets.bottom, topInset: topInset, fillingSize: fillingSize, isTablet: sheetEnvironment.metrics.isTablet)
|
||||||
|
|
||||||
transition.setFrame(view: self.scrollContentView, frame: CGRect(origin: CGPoint(x: 0.0, y: topInset + containerInset), size: CGSize(width: availableSize.width, height: contentHeight)))
|
transition.setFrame(view: self.scrollContentView, frame: CGRect(origin: CGPoint(x: 0.0, y: topInset + containerInset), size: CGSize(width: availableSize.width, height: contentHeight)))
|
||||||
|
|
||||||
transition.setPosition(layer: self.backgroundLayer, position: CGPoint(x: availableSize.width / 2.0, y: availableSize.height / 2.0))
|
transition.setPosition(layer: self.backgroundLayer, position: CGPoint(x: availableSize.width / 2.0, y: availableSize.height / 2.0))
|
||||||
|
|
|
||||||
|
|
@ -403,7 +403,8 @@ public final class SheetComponent<ChildEnvironmentType: Sendable & Equatable>: C
|
||||||
if availableSize.width < availableSize.height {
|
if availableSize.width < availableSize.height {
|
||||||
glassInset = 6.0
|
glassInset = 6.0
|
||||||
}
|
}
|
||||||
bottomCornerRadius = sheetEnvironment.deviceMetrics.screenCornerRadius - glassInset
|
let containerCornerRadius = max(24.0, sheetEnvironment.deviceMetrics.screenCornerRadius)
|
||||||
|
bottomCornerRadius = containerCornerRadius - 2.0
|
||||||
case .legacy:
|
case .legacy:
|
||||||
topCornerRadius = 12.0
|
topCornerRadius = 12.0
|
||||||
bottomCornerRadius = 12.0
|
bottomCornerRadius = 12.0
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,20 @@
|
||||||
#import <LegacyComponents/TGMediaEditingContext.h>
|
#import <LegacyComponents/TGMediaEditingContext.h>
|
||||||
#import <LegacyComponents/TGMediaSelectionContext.h>
|
#import <LegacyComponents/TGMediaSelectionContext.h>
|
||||||
|
|
||||||
|
@class TGModernGalleryController;
|
||||||
|
|
||||||
|
typedef void (^ _Nonnull TGPhotoVideoEditorSchedulePickerCompletion)(int32_t time);
|
||||||
|
typedef void (^ _Nonnull TGPhotoVideoEditorSchedulePicker)(bool media, TGPhotoVideoEditorSchedulePickerCompletion _Nonnull done);
|
||||||
|
typedef void (^ _Nonnull TGPhotoVideoEditorCompletion)(id<TGMediaEditableItem> _Nonnull item, TGMediaEditingContext * _Nonnull editingContext, bool silentPosting, int32_t scheduleTime);
|
||||||
|
|
||||||
@interface TGPhotoVideoEditor : NSObject
|
@interface TGPhotoVideoEditor : NSObject
|
||||||
|
|
||||||
+ (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> _Nonnull)context parentController:(TGViewController * _Nonnull)parentController image:(UIImage * _Nullable)image video:(NSURL * _Nullable)video stickersContext:(id<TGPhotoPaintStickersContext> _Nullable)stickersContext transitionView:(UIView * _Nullable)transitionView senderName:(NSString * _Nullable)senderName didFinishWithImage:(void (^ _Nullable)(UIImage * _Nonnull image))didFinishWithImage didFinishWithVideo:(void (^ _Nullable)(UIImage * _Nonnull image, NSURL * _Nonnull url, TGVideoEditAdjustments * _Nullable adjustments))didFinishWithVideo dismissed:(void (^ _Nonnull)(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 activateInput:(bool)activateInput isGif:(bool)isGif appeared:(void (^)(void))appeared completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed;
|
+ (TGModernGalleryController * _Nonnull)controllerWithContext:(id<LegacyComponentsContext> _Nonnull)context caption:(NSAttributedString * _Nonnull)caption withItem:(id<TGMediaEditableItem, TGMediaSelectableItem> _Nonnull)item paint:(bool)paint adjustments:(bool)adjustments recipientName:(NSString * _Nonnull)recipientName stickersContext:(id<TGPhotoPaintStickersContext> _Nullable)stickersContext fromRect:(CGRect)fromRect mainSnapshot:(UIView * _Nullable)mainSnapshot snapshots:(NSArray * _Nonnull)snapshots immediate:(bool)immediate activateInput:(bool)activateInput isGif:(bool)isGif hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder presentSchedulePicker:(TGPhotoVideoEditorSchedulePicker _Nonnull)presentSchedulePicker appeared:(void (^ _Nonnull)(void))appeared completion:(TGPhotoVideoEditorCompletion _Nonnull)completion dismissed:(void (^ _Nonnull)(void))dismissed;
|
||||||
|
|
||||||
+ (void)presentEditorWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller withItem:(id<TGMediaEditableItem>)item cropRect:(CGRect)cropRect adjustments:(id<TGMediaEditAdjustments>)adjustments referenceView:(UIView *)referenceView completion:(void (^)(UIImage *, id<TGMediaEditAdjustments>))completion fullSizeCompletion:(void (^)(UIImage *))fullSizeCompletion beginTransitionOut:(void (^)(bool))beginTransitionOut finishTransitionOut:(void (^)())finishTransitionOut;
|
+ (void)presentWithContext:(id<LegacyComponentsContext> _Nonnull)context controller:(TGViewController * _Nonnull)controller caption:(NSAttributedString * _Nonnull)caption withItem:(id<TGMediaEditableItem, TGMediaSelectableItem> _Nonnull)item paint:(bool)paint adjustments:(bool)adjustments recipientName:(NSString * _Nonnull)recipientName stickersContext:(id<TGPhotoPaintStickersContext> _Nullable)stickersContext fromRect:(CGRect)fromRect mainSnapshot:(UIView * _Nullable)mainSnapshot snapshots:(NSArray * _Nonnull)snapshots immediate:(bool)immediate activateInput:(bool)activateInput isGif:(bool)isGif hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder presentSchedulePicker:(TGPhotoVideoEditorSchedulePicker _Nonnull)presentSchedulePicker appeared:(void (^ _Nonnull)(void))appeared completion:(TGPhotoVideoEditorCompletion _Nonnull)completion dismissed:(void (^ _Nonnull)(void))dismissed;
|
||||||
|
|
||||||
|
+ (void)presentEditorWithContext:(id<LegacyComponentsContext> _Nonnull)context controller:(TGViewController * _Nonnull)controller withItem:(id<TGMediaEditableItem> _Nonnull)item cropRect:(CGRect)cropRect adjustments:(id<TGMediaEditAdjustments> _Nullable)adjustments referenceView:(UIView * _Nonnull)referenceView completion:(void (^ _Nonnull)(UIImage * _Nonnull image, id<TGMediaEditAdjustments> _Nullable adjustments))completion fullSizeCompletion:(void (^ _Nonnull)(UIImage * _Nonnull image))fullSizeCompletion beginTransitionOut:(void (^ _Nullable)(bool saving))beginTransitionOut finishTransitionOut:(void (^ _Nullable)(void))finishTransitionOut;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#import <LegacyComponents/TGMediaPickerGalleryModel.h>
|
#import <LegacyComponents/TGMediaPickerGalleryModel.h>
|
||||||
#import <LegacyComponents/TGMediaPickerGalleryPhotoItem.h>
|
#import <LegacyComponents/TGMediaPickerGalleryPhotoItem.h>
|
||||||
|
#import <LegacyComponents/TGMediaPickerSendActionSheetController.h>
|
||||||
#import <LegacyComponents/TGMediaPickerGalleryVideoItem.h>
|
#import <LegacyComponents/TGMediaPickerGalleryVideoItem.h>
|
||||||
|
|
||||||
#import <LegacyComponents/TGMediaPickerGalleryVideoItemView.h>
|
#import <LegacyComponents/TGMediaPickerGalleryVideoItemView.h>
|
||||||
|
|
@ -156,21 +157,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (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 activateInput:(bool)activateInput isGif:(bool)isGif appeared:(void (^)(void))appeared completion:(void (^)(id<TGMediaEditableItem>, TGMediaEditingContext *))completion dismissed:(void (^)())dismissed
|
+ (TGModernGalleryController *)_configuredControllerWithContext:(id<LegacyComponentsContext> _Nonnull)context caption:(NSAttributedString * _Nonnull)caption withItem:(id<TGMediaEditableItem, TGMediaSelectableItem> _Nonnull)item paint:(bool)paint adjustments:(bool)adjustments recipientName:(NSString * _Nonnull)recipientName stickersContext:(id<TGPhotoPaintStickersContext> _Nullable)stickersContext fromRect:(CGRect)fromRect mainSnapshot:(UIView * _Nullable)__unused mainSnapshot snapshots:(NSArray * _Nonnull)snapshots immediate:(bool)immediate activateInput:(bool)activateInput isGif:(bool)isGif hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder presentSchedulePicker:(TGPhotoVideoEditorSchedulePicker _Nonnull)presentSchedulePicker appeared:(void (^ _Nonnull)(void))appeared completion:(TGPhotoVideoEditorCompletion _Nonnull)completion completedDismiss:(void (^ _Nullable)(void))completedDismiss customDismiss:(void (^ _Nullable)(void))customDismiss
|
||||||
{
|
{
|
||||||
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
|
|
||||||
id<LegacyComponentsContext> windowContext = [windowManager context];
|
|
||||||
|
|
||||||
TGMediaEditingContext *editingContext = [[TGMediaEditingContext alloc] init];
|
TGMediaEditingContext *editingContext = [[TGMediaEditingContext alloc] init];
|
||||||
[editingContext setForcedCaption:caption];
|
[editingContext setForcedCaption:caption];
|
||||||
|
|
||||||
TGModernGalleryController *galleryController = [[TGModernGalleryController alloc] initWithContext:windowContext];
|
TGModernGalleryController *galleryController = [[TGModernGalleryController alloc] initWithContext:context];
|
||||||
galleryController.adjustsStatusBarVisibility = true;
|
galleryController.adjustsStatusBarVisibility = true;
|
||||||
galleryController.animateTransition = !immediate;
|
galleryController.animateTransition = !immediate;
|
||||||
galleryController.finishedTransitionIn = ^(id<TGModernGalleryItem> item, TGModernGalleryItemView *itemView) {
|
galleryController.finishedTransitionIn = ^(id<TGModernGalleryItem> item, TGModernGalleryItemView *itemView) {
|
||||||
appeared();
|
appeared();
|
||||||
};
|
};
|
||||||
//galleryController.hasFadeOutTransition = true;
|
galleryController.customDismissBlock = customDismiss;
|
||||||
|
|
||||||
id<TGModernGalleryEditableItem> galleryItem = nil;
|
id<TGModernGalleryEditableItem> galleryItem = nil;
|
||||||
if (item.isVideo) {
|
if (item.isVideo) {
|
||||||
|
|
@ -181,7 +179,7 @@
|
||||||
galleryItem.editingContext = editingContext;
|
galleryItem.editingContext = editingContext;
|
||||||
galleryItem.stickersContext = stickersContext;
|
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 isScheduledMessages:false hasCoverButton:false];
|
TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:context items:@[galleryItem] focusItem:galleryItem selectionContext:nil editingContext:editingContext hasCaptions:true allowCaptionEntities:true hasTimer:false onlyCrop:false inhibitDocumentCaptions:false hasSelectionPanel:false hasCamera:false recipientName:recipientName isScheduledMessages:false hasCoverButton:false];
|
||||||
model.controller = galleryController;
|
model.controller = galleryController;
|
||||||
model.stickersContext = stickersContext;
|
model.stickersContext = stickersContext;
|
||||||
|
|
||||||
|
|
@ -213,6 +211,7 @@
|
||||||
galleryController.model = model;
|
galleryController.model = model;
|
||||||
|
|
||||||
__weak TGModernGalleryController *weakGalleryController = galleryController;
|
__weak TGModernGalleryController *weakGalleryController = galleryController;
|
||||||
|
__weak TGMediaPickerGalleryModel *weakModel = model;
|
||||||
|
|
||||||
[model.interfaceView updateSelectionInterface:1 counterVisible:false animated:false];
|
[model.interfaceView updateSelectionInterface:1 counterVisible:false animated:false];
|
||||||
model.interfaceView.thumbnailSignalForItem = ^SSignal *(id item)
|
model.interfaceView.thumbnailSignalForItem = ^SSignal *(id item)
|
||||||
|
|
@ -233,10 +232,62 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (completion != nil)
|
if (completion != nil)
|
||||||
completion(item.asset, editingContext);
|
completion(item.asset, editingContext, false, 0);
|
||||||
|
|
||||||
[strongController dismissWhenReadyAnimated:true];
|
[strongController dismissWhenReadyAnimated:true];
|
||||||
};
|
};
|
||||||
|
model.interfaceView.doneLongPressed = ^(TGMediaPickerGalleryItem *item)
|
||||||
|
{
|
||||||
|
__strong TGModernGalleryController *strongController = weakGalleryController;
|
||||||
|
__strong TGMediaPickerGalleryModel *strongModel = weakModel;
|
||||||
|
if (strongController == nil || strongModel == nil || !(hasSilentPosting || hasSchedule))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (iosMajorVersion() >= 10) {
|
||||||
|
UIImpactFeedbackGenerator *generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium];
|
||||||
|
[generator impactOccurred];
|
||||||
|
}
|
||||||
|
|
||||||
|
TGMediaPickerSendActionSheetController *sendController = [[TGMediaPickerSendActionSheetController alloc] initWithContext:context isDark:true sendButtonFrame:strongModel.interfaceView.doneButtonFrame canSendSilently:hasSilentPosting canSendWhenOnline:hasSchedule canSchedule:hasSchedule reminder:reminder hasTimer:false];
|
||||||
|
sendController.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
||||||
|
sendController.customDismissBlock = ^{
|
||||||
|
__strong TGModernGalleryController *strongController = weakGalleryController;
|
||||||
|
[strongController dismissViewControllerAnimated:false completion:nil];
|
||||||
|
};
|
||||||
|
void (^complete)(bool, int32_t) = ^(bool silentPosting, int32_t scheduleTime)
|
||||||
|
{
|
||||||
|
__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, silentPosting, scheduleTime);
|
||||||
|
|
||||||
|
[strongController dismissWhenReadyAnimated:true];
|
||||||
|
};
|
||||||
|
sendController.send = ^{
|
||||||
|
complete(false, 0);
|
||||||
|
};
|
||||||
|
sendController.sendSilently = ^{
|
||||||
|
complete(true, 0);
|
||||||
|
};
|
||||||
|
sendController.sendWhenOnline = ^{
|
||||||
|
complete(false, 0x7ffffffe);
|
||||||
|
};
|
||||||
|
sendController.schedule = ^{
|
||||||
|
presentSchedulePicker(true, ^(int32_t time) {
|
||||||
|
complete(false, time);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
[strongController presentViewController:sendController animated:false completion:nil];
|
||||||
|
};
|
||||||
|
|
||||||
galleryController.beginTransitionIn = ^UIView *(__unused TGMediaPickerGalleryItem *item, __unused TGModernGalleryItemView *itemView)
|
galleryController.beginTransitionIn = ^UIView *(__unused TGMediaPickerGalleryItem *item, __unused TGModernGalleryItemView *itemView)
|
||||||
{
|
{
|
||||||
|
|
@ -247,21 +298,12 @@
|
||||||
{
|
{
|
||||||
return nil;
|
return nil;
|
||||||
};
|
};
|
||||||
|
if (completedDismiss != nil) {
|
||||||
galleryController.completedTransitionOut = ^
|
galleryController.completedTransitionOut = ^
|
||||||
{
|
|
||||||
TGModernGalleryController *strongGalleryController = weakGalleryController;
|
|
||||||
if (strongGalleryController != nil && strongGalleryController.overlayWindow == nil)
|
|
||||||
{
|
{
|
||||||
TGNavigationController *navigationController = (TGNavigationController *)strongGalleryController.navigationController;
|
completedDismiss();
|
||||||
TGOverlayControllerWindow *window = (TGOverlayControllerWindow *)navigationController.view.window;
|
};
|
||||||
if ([window isKindOfClass:[TGOverlayControllerWindow class]])
|
}
|
||||||
[window dismiss];
|
|
||||||
}
|
|
||||||
if (dismissed) {
|
|
||||||
dismissed();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (paint || adjustments) {
|
if (paint || adjustments) {
|
||||||
[model.interfaceView immediateEditorTransitionIn];
|
[model.interfaceView immediateEditorTransitionIn];
|
||||||
|
|
@ -271,8 +313,6 @@
|
||||||
[galleryController.view addSubview:view];
|
[galleryController.view addSubview:view];
|
||||||
}
|
}
|
||||||
|
|
||||||
TGOverlayControllerWindow *controllerWindow = [[TGOverlayControllerWindow alloc] initWithManager:windowManager parentController:controller contentController:galleryController];
|
|
||||||
controllerWindow.hidden = false;
|
|
||||||
galleryController.view.clipsToBounds = true;
|
galleryController.view.clipsToBounds = true;
|
||||||
|
|
||||||
if (isGif) {
|
if (isGif) {
|
||||||
|
|
@ -292,9 +332,33 @@
|
||||||
[model beginEditingCaption];
|
[model beginEditingCaption];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return galleryController;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)presentEditorWithContext:(id<LegacyComponentsContext>)context controller:(TGViewController *)controller withItem:(id<TGMediaEditableItem>)item cropRect:(CGRect)cropRect adjustments:(id<TGMediaEditAdjustments>)adjustments referenceView:(UIView *)referenceView completion:(void (^)(UIImage *, id<TGMediaEditAdjustments>))completion fullSizeCompletion:(void (^)(UIImage *))fullSizeCompletion beginTransitionOut:(void (^)(bool))beginTransitionOut finishTransitionOut:(void (^)())finishTransitionOut;
|
+ (TGModernGalleryController * _Nonnull)controllerWithContext:(id<LegacyComponentsContext> _Nonnull)context caption:(NSAttributedString * _Nonnull)caption withItem:(id<TGMediaEditableItem, TGMediaSelectableItem> _Nonnull)item paint:(bool)paint adjustments:(bool)adjustments recipientName:(NSString * _Nonnull)recipientName stickersContext:(id<TGPhotoPaintStickersContext> _Nullable)stickersContext fromRect:(CGRect)fromRect mainSnapshot:(UIView * _Nullable)mainSnapshot snapshots:(NSArray * _Nonnull)snapshots immediate:(bool)immediate activateInput:(bool)activateInput isGif:(bool)isGif hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder presentSchedulePicker:(TGPhotoVideoEditorSchedulePicker _Nonnull)presentSchedulePicker appeared:(void (^ _Nonnull)(void))appeared completion:(TGPhotoVideoEditorCompletion _Nonnull)completion dismissed:(void (^ _Nonnull)(void))dismissed
|
||||||
|
{
|
||||||
|
TGModernGalleryController *galleryController = [self _configuredControllerWithContext:context caption:caption withItem:item paint:paint adjustments:adjustments recipientName:recipientName stickersContext:stickersContext fromRect:fromRect mainSnapshot:mainSnapshot snapshots:snapshots immediate:immediate activateInput:activateInput isGif:isGif hasSilentPosting:hasSilentPosting hasSchedule:hasSchedule reminder:reminder presentSchedulePicker:presentSchedulePicker appeared:appeared completion:completion completedDismiss:dismissed customDismiss:nil];
|
||||||
|
galleryController.asyncTransitionIn = true;
|
||||||
|
return galleryController;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)presentWithContext:(id<LegacyComponentsContext> _Nonnull)context controller:(TGViewController * _Nonnull)controller caption:(NSAttributedString * _Nonnull)caption withItem:(id<TGMediaEditableItem, TGMediaSelectableItem> _Nonnull)item paint:(bool)paint adjustments:(bool)adjustments recipientName:(NSString * _Nonnull)recipientName stickersContext:(id<TGPhotoPaintStickersContext> _Nullable)stickersContext fromRect:(CGRect)fromRect mainSnapshot:(UIView * _Nullable)mainSnapshot snapshots:(NSArray * _Nonnull)snapshots immediate:(bool)immediate activateInput:(bool)activateInput isGif:(bool)isGif hasSilentPosting:(bool)hasSilentPosting hasSchedule:(bool)hasSchedule reminder:(bool)reminder presentSchedulePicker:(TGPhotoVideoEditorSchedulePicker _Nonnull)presentSchedulePicker appeared:(void (^ _Nonnull)(void))appeared completion:(TGPhotoVideoEditorCompletion _Nonnull)completion dismissed:(void (^ _Nonnull)(void))dismissed
|
||||||
|
{
|
||||||
|
__weak TGViewController *weakController = controller;
|
||||||
|
TGModernGalleryController *galleryController = [self _configuredControllerWithContext:context caption:caption withItem:item paint:paint adjustments:adjustments recipientName:recipientName stickersContext:stickersContext fromRect:fromRect mainSnapshot:mainSnapshot snapshots:snapshots immediate:immediate activateInput:activateInput isGif:isGif hasSilentPosting:hasSilentPosting hasSchedule:hasSchedule reminder:reminder presentSchedulePicker:presentSchedulePicker appeared:appeared completion:completion completedDismiss:nil customDismiss:^{
|
||||||
|
__strong TGViewController *strongController = weakController;
|
||||||
|
[strongController dismissViewControllerAnimated:false completion:^{
|
||||||
|
if (dismissed) {
|
||||||
|
dismissed();
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}];
|
||||||
|
galleryController.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||||
|
[controller presentViewController:galleryController animated:false completion:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)presentEditorWithContext:(id<LegacyComponentsContext> _Nonnull)context controller:(TGViewController * _Nonnull)controller withItem:(id<TGMediaEditableItem> _Nonnull)item cropRect:(CGRect)cropRect adjustments:(id<TGMediaEditAdjustments> _Nullable)adjustments referenceView:(UIView * _Nonnull)referenceView completion:(void (^ _Nonnull)(UIImage * _Nonnull image, id<TGMediaEditAdjustments> _Nullable adjustments))completion fullSizeCompletion:(void (^ _Nonnull)(UIImage * _Nonnull image))fullSizeCompletion beginTransitionOut:(void (^ _Nullable)(bool saving))beginTransitionOut finishTransitionOut:(void (^ _Nullable)(void))finishTransitionOut
|
||||||
{
|
{
|
||||||
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
|
id<LegacyComponentsOverlayWindowManager> windowManager = [context makeOverlayWindowManager];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,12 +131,12 @@ public func legacyStoryMediaEditor(context: AccountContext, item: TGMediaEditabl
|
||||||
|
|
||||||
present(legacyController, nil)
|
present(legacyController, nil)
|
||||||
|
|
||||||
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, caption: NSAttributedString(), withItem: item, paint: false, adjustments: false, recipientName: "", stickersContext: paintStickersContext, from: .zero, mainSnapshot: nil, snapshots: [] as [Any], immediate: true, activateInput: false, isGif: false, appeared: {
|
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, caption: NSAttributedString(), withItem: item, paint: false, adjustments: false, recipientName: "", stickersContext: paintStickersContext, from: .zero, mainSnapshot: nil, snapshots: [] as [Any], immediate: true, activateInput: false, isGif: false, hasSilentPosting: false, hasSchedule: false, reminder: false, presentSchedulePicker: { _, _ in }, appeared: {
|
||||||
|
|
||||||
}, completion: { result, editingContext in
|
}, completion: { result, editingContext, _, _ in
|
||||||
var completionResult: Signal<StoryMediaEditorResult, NoError>
|
var completionResult: Signal<StoryMediaEditorResult, NoError>
|
||||||
if let photo = result as? TGCameraCapturedPhoto {
|
if let photo = result as? TGCameraCapturedPhoto {
|
||||||
if let _ = editingContext?.adjustments(for: result) {
|
if let _ = editingContext.adjustments(for: result) {
|
||||||
completionResult = .single(.image(photo.existingImage))
|
completionResult = .single(.image(photo.existingImage))
|
||||||
} else {
|
} else {
|
||||||
completionResult = .single(.image(photo.existingImage))
|
completionResult = .single(.image(photo.existingImage))
|
||||||
|
|
@ -167,6 +167,10 @@ public func legacyMediaEditor(
|
||||||
snapshots: [UIView],
|
snapshots: [UIView],
|
||||||
transitionCompletion: (() -> Void)?,
|
transitionCompletion: (() -> Void)?,
|
||||||
getCaptionPanelView: @escaping () -> TGCaptionPanelView?,
|
getCaptionPanelView: @escaping () -> TGCaptionPanelView?,
|
||||||
|
hasSilentPosting: Bool = false,
|
||||||
|
hasSchedule: Bool = false,
|
||||||
|
reminder: Bool = false,
|
||||||
|
presentSchedulePicker: @escaping (Bool, @escaping (Int32) -> Void) -> Void = { _, _ in },
|
||||||
sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32, Bool) -> Void,
|
sendMessagesWithSignals: @escaping ([Any]?, Bool, Int32, Bool) -> Void,
|
||||||
present: @escaping (ViewController, Any?) -> Void
|
present: @escaping (ViewController, Any?) -> Void
|
||||||
) {
|
) {
|
||||||
|
|
@ -209,32 +213,87 @@ public func legacyMediaEditor(
|
||||||
legacyController?.view.disablesInteractiveTransitionGestureRecognizer = true
|
legacyController?.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let emptyController = LegacyEmptyController(context: legacyController.context)!
|
let schedulePicker: (Bool, @escaping (Int32) -> Void) -> Void = { media, done in
|
||||||
emptyController.navigationBarShouldBeHidden = true
|
presentSchedulePicker(media, done)
|
||||||
let navigationController = makeLegacyNavigationController(rootController: emptyController)
|
}
|
||||||
navigationController.setNavigationBarHidden(true, animated: false)
|
let appeared: () -> Void = {
|
||||||
legacyController.bind(controller: navigationController)
|
|
||||||
|
|
||||||
legacyController.enableSizeClassSignal = true
|
|
||||||
|
|
||||||
present(legacyController, nil)
|
|
||||||
|
|
||||||
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, activateInput: mode == .caption, isGif: isGif, appeared: {
|
|
||||||
transitionCompletion?()
|
transitionCompletion?()
|
||||||
}, completion: { result, editingContext in
|
}
|
||||||
|
let completion: (TGMediaEditableItem, TGMediaEditingContext, Bool, Int32) -> Void = { result, editingContext, silentPosting, scheduleTime in
|
||||||
let nativeGenerator = legacyAssetPickerItemGenerator()
|
let nativeGenerator = legacyAssetPickerItemGenerator()
|
||||||
var selectableResult: TGMediaSelectableItem?
|
var selectableResult: TGMediaSelectableItem?
|
||||||
if let result = result {
|
selectableResult = unsafeDowncast(result, to: TGMediaSelectableItem.self)
|
||||||
selectableResult = unsafeDowncast(result, to: TGMediaSelectableItem.self)
|
|
||||||
}
|
|
||||||
let signals = TGCameraController.resultSignals(for: nil, editingContext: editingContext, currentItem: selectableResult, storeAssets: false, saveEditedPhotos: false, descriptionGenerator: { _1, _2, _3 in
|
let signals = TGCameraController.resultSignals(for: nil, editingContext: editingContext, currentItem: selectableResult, storeAssets: false, saveEditedPhotos: false, descriptionGenerator: { _1, _2, _3 in
|
||||||
nativeGenerator(_1, _2, _3, nil)
|
nativeGenerator(_1, _2, _3, nil)
|
||||||
})
|
})
|
||||||
let isCaptionAbove = editingContext?.isCaptionAbove() ?? false
|
let isCaptionAbove = editingContext.isCaptionAbove()
|
||||||
sendMessagesWithSignals(signals, false, 0, isCaptionAbove)
|
sendMessagesWithSignals(signals, silentPosting, scheduleTime, isCaptionAbove)
|
||||||
}, dismissed: { [weak legacyController] in
|
}
|
||||||
|
let dismissed: () -> Void = { [weak legacyController] in
|
||||||
legacyController?.dismiss()
|
legacyController?.dismiss()
|
||||||
})
|
}
|
||||||
|
|
||||||
|
legacyController.enableSizeClassSignal = true
|
||||||
|
|
||||||
|
if isGif {
|
||||||
|
let galleryController = TGPhotoVideoEditor.controller(
|
||||||
|
with: legacyController.context,
|
||||||
|
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,
|
||||||
|
activateInput: mode == .caption,
|
||||||
|
isGif: true,
|
||||||
|
hasSilentPosting: hasSilentPosting,
|
||||||
|
hasSchedule: hasSchedule,
|
||||||
|
reminder: reminder,
|
||||||
|
presentSchedulePicker: schedulePicker,
|
||||||
|
appeared: appeared,
|
||||||
|
completion: completion,
|
||||||
|
dismissed: dismissed
|
||||||
|
)
|
||||||
|
legacyController.bind(controller: galleryController)
|
||||||
|
present(legacyController, nil)
|
||||||
|
} else {
|
||||||
|
let emptyController = LegacyEmptyController(context: legacyController.context)!
|
||||||
|
emptyController.navigationBarShouldBeHidden = true
|
||||||
|
let navigationController = makeLegacyNavigationController(rootController: emptyController)
|
||||||
|
navigationController.setNavigationBarHidden(true, animated: false)
|
||||||
|
legacyController.bind(controller: navigationController)
|
||||||
|
|
||||||
|
present(legacyController, nil)
|
||||||
|
|
||||||
|
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,
|
||||||
|
activateInput: mode == .caption,
|
||||||
|
isGif: false,
|
||||||
|
hasSilentPosting: hasSilentPosting,
|
||||||
|
hasSchedule: hasSchedule,
|
||||||
|
reminder: reminder,
|
||||||
|
presentSchedulePicker: schedulePicker,
|
||||||
|
appeared: appeared,
|
||||||
|
completion: completion,
|
||||||
|
dismissed: dismissed
|
||||||
|
)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -530,13 +589,11 @@ public func legacyAttachmentMenu(
|
||||||
|
|
||||||
present(legacyController, nil)
|
present(legacyController, nil)
|
||||||
|
|
||||||
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, caption: initialCaption, withItem: item, paint: false, adjustments: false, recipientName: recipientName, stickersContext: paintStickersContext, from: .zero, mainSnapshot: nil, snapshots: [], immediate: false, activateInput: false, isGif: false, appeared: {
|
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, caption: initialCaption, withItem: item, paint: false, adjustments: false, recipientName: recipientName, stickersContext: paintStickersContext, from: .zero, mainSnapshot: nil, snapshots: [], immediate: false, activateInput: false, isGif: false, hasSilentPosting: false, hasSchedule: false, reminder: false, presentSchedulePicker: { _, _ in }, appeared: {
|
||||||
}, completion: { result, editingContext in
|
}, completion: { result, editingContext, _, _ in
|
||||||
let nativeGenerator = legacyAssetPickerItemGenerator()
|
let nativeGenerator = legacyAssetPickerItemGenerator()
|
||||||
var selectableResult: TGMediaSelectableItem?
|
let selectableResult: TGMediaSelectableItem? = unsafeDowncast(result, to: TGMediaSelectableItem.self)
|
||||||
if let result = result {
|
|
||||||
selectableResult = unsafeDowncast(result, to: TGMediaSelectableItem.self)
|
|
||||||
}
|
|
||||||
let signals = TGCameraController.resultSignals(for: nil, editingContext: editingContext, currentItem: selectableResult, storeAssets: false, saveEditedPhotos: false, descriptionGenerator: { _1, _2, _3 in
|
let signals = TGCameraController.resultSignals(for: nil, editingContext: editingContext, currentItem: selectableResult, storeAssets: false, saveEditedPhotos: false, descriptionGenerator: { _1, _2, _3 in
|
||||||
nativeGenerator(_1, _2, _3, nil)
|
nativeGenerator(_1, _2, _3, nil)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -108,11 +108,9 @@ public func legacyAvatarEditor(context: AccountContext, media: AnyMediaReference
|
||||||
present(legacyController, nil)
|
present(legacyController, nil)
|
||||||
|
|
||||||
TGPhotoVideoEditor.present(with: legacyController.context, parentController: emptyController, image: image.0, video: video.0, stickersContext: paintStickersContext, transitionView: transitionView, senderName: senderName, didFinishWithImage: { image in
|
TGPhotoVideoEditor.present(with: legacyController.context, parentController: emptyController, image: image.0, video: video.0, stickersContext: paintStickersContext, transitionView: transitionView, senderName: senderName, didFinishWithImage: { image in
|
||||||
if let image = image {
|
imageCompletion(image)
|
||||||
imageCompletion(image)
|
|
||||||
}
|
|
||||||
}, didFinishWithVideo: { image, url, adjustments in
|
}, didFinishWithVideo: { image, url, adjustments in
|
||||||
if let image = image, let url = url, let adjustments = adjustments {
|
if let adjustments = adjustments {
|
||||||
videoCompletion(image, url, adjustments)
|
videoCompletion(image, url, adjustments)
|
||||||
}
|
}
|
||||||
}, dismissed: { [weak legacyController] in
|
}, dismissed: { [weak legacyController] in
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,11 @@ public final class SearchDisplayController {
|
||||||
if let searchBar = self.searchBar {
|
if let searchBar = self.searchBar {
|
||||||
searchBar.deactivate(clear: false)
|
searchBar.deactivate(clear: false)
|
||||||
}
|
}
|
||||||
|
if !self.searchBarIsExternal, let searchBar = self.searchBar {
|
||||||
|
searchBar.isUserInteractionEnabled = false
|
||||||
|
}
|
||||||
|
self.backgroundNode.isUserInteractionEnabled = false
|
||||||
|
self.contentNode.isUserInteractionEnabled = false
|
||||||
|
|
||||||
if !self.searchBarIsExternal, let searchBar = self.searchBar {
|
if !self.searchBarIsExternal, let searchBar = self.searchBar {
|
||||||
if let placeholder = placeholder {
|
if let placeholder = placeholder {
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,10 @@ public struct PresentationResourcesSettings {
|
||||||
public static let business = renderSettingsIcon(name: "Item List/Icons/Business", backgroundColors: [UIColor(rgb: 0xA95CE3), UIColor(rgb: 0xF16B80)])
|
public static let business = renderSettingsIcon(name: "Item List/Icons/Business", backgroundColors: [UIColor(rgb: 0xA95CE3), UIColor(rgb: 0xF16B80)])
|
||||||
public static let myProfile = renderSettingsIcon(name: "Item List/Icons/Profile", backgroundColors: [colorRed])
|
public static let myProfile = renderSettingsIcon(name: "Item List/Icons/Profile", backgroundColors: [colorRed])
|
||||||
|
|
||||||
|
public static let birthday = renderSettingsIcon(name: "Item List/Icons/Cake", backgroundColors: [colorBlue])
|
||||||
|
public static let aiTools = renderSettingsIcon(name: "Item List/Icons/AITools", backgroundColors: [colorPurple])
|
||||||
|
public static let yourColor = renderSettingsIcon(name: "Item List/Icons/Brush", backgroundColors: [colorLightBlue])
|
||||||
|
|
||||||
public static let storageUsage = renderSettingsIcon(name: "Item List/Icons/Pie", backgroundColors: [colorOrange])
|
public static let storageUsage = renderSettingsIcon(name: "Item List/Icons/Pie", backgroundColors: [colorOrange])
|
||||||
public static let dataUsage = renderSettingsIcon(name: "Item List/Icons/Stats", backgroundColors: [colorPurple])
|
public static let dataUsage = renderSettingsIcon(name: "Item List/Icons/Stats", backgroundColors: [colorPurple])
|
||||||
|
|
||||||
|
|
@ -213,48 +217,7 @@ public struct PresentationResourcesSettings {
|
||||||
})
|
})
|
||||||
|
|
||||||
public static let ton = renderSettingsIcon(name: "Ads/TonAbout", backgroundColors: [UIColor(rgb: 0x32ade6)])
|
public static let ton = renderSettingsIcon(name: "Ads/TonAbout", backgroundColors: [UIColor(rgb: 0x32ade6)])
|
||||||
|
|
||||||
// generateImage(CGSize(width: 30.0, height: 30.0), contextGenerator: { size, context in
|
|
||||||
// let bounds = CGRect(origin: CGPoint(), size: size)
|
|
||||||
// context.clear(bounds)
|
|
||||||
//
|
|
||||||
// context.setFillColor(UIColor(rgb: 0x32ade6).cgColor)
|
|
||||||
// context.fill(bounds)
|
|
||||||
//
|
|
||||||
// if let gradientImage, let cgImage = gradientImage.cgImage {
|
|
||||||
// context.saveGState()
|
|
||||||
// context.setBlendMode(.plusLighter)
|
|
||||||
// context.draw(cgImage, in: CGRect(origin: .zero, size: size))
|
|
||||||
// context.restoreGState()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if let backdropImage, let cgImage = backdropImage.cgImage {
|
|
||||||
// context.saveGState()
|
|
||||||
// context.setBlendMode(.overlay)
|
|
||||||
// context.draw(cgImage, in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: size))
|
|
||||||
// context.restoreGState()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// context.setBlendMode(.normal)
|
|
||||||
//
|
|
||||||
// if let image = generateTintedImage(image: UIImage(bundleImageName: "Ads/TonAbout"), color: UIColor(rgb: 0xffffff)), let cgImage = image.cgImage {
|
|
||||||
// context.draw(cgImage, in: CGRect(origin: CGPoint(x: floorToScreenPixels((bounds.width - image.size.width) / 2.0), y: floorToScreenPixels((bounds.height - image.size.height) / 2.0)), size: image.size))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let outerPath = UIBezierPath(rect: CGRect(origin: .zero, size: size))
|
|
||||||
// let innerPath = UIBezierPath(roundedRect: CGRect(origin: .zero, size: size), cornerRadius: 8.0)
|
|
||||||
// outerPath.append(innerPath)
|
|
||||||
//
|
|
||||||
// context.saveGState()
|
|
||||||
// outerPath.usesEvenOddFillRule = true
|
|
||||||
// context.addPath(outerPath.cgPath)
|
|
||||||
// context.clip(using: .evenOdd)
|
|
||||||
//
|
|
||||||
// context.setBlendMode(.clear)
|
|
||||||
// context.fill(CGRect(origin: .zero, size: size))
|
|
||||||
// context.restoreGState()
|
|
||||||
// })
|
|
||||||
|
|
||||||
public static let stars = generateImage(CGSize(width: 30.0, height: 30.0), contextGenerator: { size, context in
|
public static let stars = generateImage(CGSize(width: 30.0, height: 30.0), contextGenerator: { size, context in
|
||||||
let bounds = CGRect(origin: CGPoint(), size: size)
|
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||||
context.clear(bounds)
|
context.clear(bounds)
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ public final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
||||||
|
|
||||||
private var presentationInterfaceState: ChatPresentationInterfaceState?
|
private var presentationInterfaceState: ChatPresentationInterfaceState?
|
||||||
|
|
||||||
private var layoutData: (CGFloat, CGFloat, CGFloat, CGFloat, UIEdgeInsets, CGFloat, CGFloat, Bool, LayoutMetrics)?
|
private var layoutData: (CGFloat, CGFloat, CGFloat, CGFloat, UIEdgeInsets, CGFloat, CGFloat, Bool, LayoutMetrics, DeviceMetrics)?
|
||||||
|
|
||||||
public override init() {
|
public override init() {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
@ -214,8 +214,8 @@ public final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
||||||
switch action {
|
switch action {
|
||||||
case .join, .joinGroup, .applyToJoin:
|
case .join, .joinGroup, .applyToJoin:
|
||||||
self.isJoining = true
|
self.isJoining = true
|
||||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, isSecondary, metrics) = self.layoutData, let presentationInterfaceState = self.presentationInterfaceState {
|
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, isSecondary, metrics, deviceMetrics) = self.layoutData, let presentationInterfaceState = self.presentationInterfaceState {
|
||||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: presentationInterfaceState, metrics: metrics, force: true)
|
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: presentationInterfaceState, metrics: metrics, deviceMetrics: deviceMetrics, force: true)
|
||||||
}
|
}
|
||||||
self.actionDisposable.set((context.peerChannelMemberCategoriesContextsManager.join(engine: context.engine, peerId: peer.id, hash: nil)
|
self.actionDisposable.set((context.peerChannelMemberCategoriesContextsManager.join(engine: context.engine, peerId: peer.id, hash: nil)
|
||||||
|> afterDisposed { [weak self] in
|
|> afterDisposed { [weak self] in
|
||||||
|
|
@ -292,8 +292,8 @@ public final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
override public func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
return self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: transition, interfaceState: interfaceState, metrics: metrics, force: false)
|
return self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: transition, interfaceState: interfaceState, metrics: metrics, deviceMetrics: deviceMetrics, force: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var displayedGiftOrSuggestTooltip = false
|
private var displayedGiftOrSuggestTooltip = false
|
||||||
|
|
@ -389,9 +389,9 @@ public final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, force: Bool) -> CGFloat {
|
private func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, force: Bool) -> CGFloat {
|
||||||
let isFirstTime = self.layoutData == nil
|
let isFirstTime = self.layoutData == nil
|
||||||
self.layoutData = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, isSecondary, metrics)
|
self.layoutData = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, isSecondary, metrics, deviceMetrics)
|
||||||
|
|
||||||
var transition = transition
|
var transition = transition
|
||||||
if !isFirstTime && !transition.isAnimated {
|
if !isFirstTime && !transition.isAnimated {
|
||||||
|
|
@ -433,10 +433,9 @@ public final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
||||||
|
|
||||||
var leftInset = leftInset + 8.0
|
var leftInset = leftInset + 8.0
|
||||||
var rightInset = rightInset + 8.0
|
var rightInset = rightInset + 8.0
|
||||||
if bottomInset <= 32.0 {
|
let compactBottomSideInset = self.compactBottomSideInset(bottomInset: bottomInset, deviceMetrics: deviceMetrics)
|
||||||
leftInset += 18.0
|
leftInset += compactBottomSideInset
|
||||||
rightInset += 18.0
|
rightInset += compactBottomSideInset
|
||||||
}
|
|
||||||
|
|
||||||
var leftPanelItems: [GlassControlGroupComponent.Item] = []
|
var leftPanelItems: [GlassControlGroupComponent.Item] = []
|
||||||
if displaySuggestPost {
|
if displaySuggestPost {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,15 @@ open class ChatInputPanelNode: ASDisplayNode {
|
||||||
open func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition) {
|
open func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
open func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
public final func compactBottomSideInset(bottomInset: CGFloat, deviceMetrics: DeviceMetrics) -> CGFloat {
|
||||||
|
if bottomInset <= 32.0 && deviceMetrics.screenCornerRadius > 0.0 {
|
||||||
|
return 18.0
|
||||||
|
} else {
|
||||||
|
return 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
return 0.0
|
return 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -202,7 +202,7 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
||||||
|
|
||||||
private let reactionOverlayContainer: ChatMessageSelectionInputPanelNodeViewForOverlayContent
|
private let reactionOverlayContainer: ChatMessageSelectionInputPanelNodeViewForOverlayContent
|
||||||
|
|
||||||
private var validLayout: (width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, metrics: LayoutMetrics, isSecondary: Bool, isMediaInputExpanded: Bool)?
|
private var validLayout: (width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, metrics: LayoutMetrics, isSecondary: Bool, isMediaInputExpanded: Bool, deviceMetrics: DeviceMetrics)?
|
||||||
private var presentationInterfaceState: ChatPresentationInterfaceState?
|
private var presentationInterfaceState: ChatPresentationInterfaceState?
|
||||||
private var actions: ChatAvailableMessageActions?
|
private var actions: ChatAvailableMessageActions?
|
||||||
|
|
||||||
|
|
@ -288,8 +288,8 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
||||||
|
|
||||||
if self.selectedMessages.isEmpty {
|
if self.selectedMessages.isEmpty {
|
||||||
self.actions = nil
|
self.actions = nil
|
||||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = self.validLayout, let interfaceState = self.presentationInterfaceState {
|
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded, deviceMetrics) = self.validLayout, let interfaceState = self.presentationInterfaceState {
|
||||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: interfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded)
|
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: interfaceState, metrics: metrics, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||||
}
|
}
|
||||||
self.canDeleteMessagesDisposable.set(nil)
|
self.canDeleteMessagesDisposable.set(nil)
|
||||||
} else if let context = self.context {
|
} else if let context = self.context {
|
||||||
|
|
@ -297,8 +297,8 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
||||||
|> deliverOnMainQueue).startStrict(next: { [weak self] actions in
|
|> deliverOnMainQueue).startStrict(next: { [weak self] actions in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.actions = actions
|
strongSelf.actions = actions
|
||||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight: maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = strongSelf.validLayout, let interfaceState = strongSelf.presentationInterfaceState {
|
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight: maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded, deviceMetrics) = strongSelf.validLayout, let interfaceState = strongSelf.presentationInterfaceState {
|
||||||
let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: interfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded)
|
let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: interfaceState, metrics: metrics, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
@ -456,21 +456,20 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func update(transition: ContainedViewLayoutTransition) {
|
private func update(transition: ContainedViewLayoutTransition) {
|
||||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = self.validLayout, let interfaceState = self.presentationInterfaceState {
|
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded, deviceMetrics) = self.validLayout, let interfaceState = self.presentationInterfaceState {
|
||||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: transition, interfaceState: interfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded)
|
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: transition, interfaceState: interfaceState, metrics: metrics, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
override public func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
self.validLayout = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded)
|
self.validLayout = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded, deviceMetrics)
|
||||||
|
|
||||||
var leftInset = leftInset + 8.0
|
var leftInset = leftInset + 8.0
|
||||||
var rightInset = rightInset + 8.0
|
var rightInset = rightInset + 8.0
|
||||||
|
|
||||||
if bottomInset <= 32.0 {
|
let compactBottomSideInset = self.compactBottomSideInset(bottomInset: bottomInset, deviceMetrics: deviceMetrics)
|
||||||
leftInset += 18.0
|
leftInset += compactBottomSideInset
|
||||||
rightInset += 18.0
|
rightInset += compactBottomSideInset
|
||||||
}
|
|
||||||
|
|
||||||
let panelHeight = defaultHeight(metrics: metrics)
|
let panelHeight = defaultHeight(metrics: metrics)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -392,7 +392,7 @@ public final class ChatRecordingPreviewInputPanelNodeImpl: ChatInputPanelNode {
|
||||||
})*/
|
})*/
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
override public func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
let waveformBackgroundFrame = CGRect(origin: CGPoint(x: 3.0, y: 3.0), size: CGSize(width: width - 3.0 * 2.0, height: 40.0 - 3.0 * 2.0))
|
let waveformBackgroundFrame = CGRect(origin: CGPoint(x: 3.0, y: 3.0), size: CGSize(width: width - 3.0 * 2.0, height: 40.0 - 3.0 * 2.0))
|
||||||
|
|
||||||
if self.presentationInterfaceState != interfaceState {
|
if self.presentationInterfaceState != interfaceState {
|
||||||
|
|
|
||||||
|
|
@ -1052,6 +1052,7 @@ public final class ChatTextInputPanelComponent: Component {
|
||||||
transition: transition.containedViewLayoutTransition,
|
transition: transition.containedViewLayoutTransition,
|
||||||
interfaceState: presentationInterfaceState,
|
interfaceState: presentationInterfaceState,
|
||||||
metrics: LayoutMetrics(widthClass: .compact, heightClass: .compact, orientation: nil),
|
metrics: LayoutMetrics(widthClass: .compact, heightClass: .compact, orientation: nil),
|
||||||
|
deviceMetrics: DeviceMetrics.iPhone16Pro,
|
||||||
isMediaInputExpanded: false
|
isMediaInputExpanded: false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||||
|
|
||||||
private var accessoryItemButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButton)] = []
|
private var accessoryItemButtons: [(ChatTextInputAccessoryItem, AccessoryItemIconButton)] = []
|
||||||
|
|
||||||
private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, UIEdgeInsets, CGFloat, CGFloat, LayoutMetrics, Bool, Bool)?
|
private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, UIEdgeInsets, CGFloat, CGFloat, LayoutMetrics, Bool, Bool, DeviceMetrics)?
|
||||||
private var leftMenuInset: CGFloat = 0.0
|
private var leftMenuInset: CGFloat = 0.0
|
||||||
private var rightSlowModeInset: CGFloat = 0.0
|
private var rightSlowModeInset: CGFloat = 0.0
|
||||||
private var currentTextInputBackgroundWidthOffset: CGFloat = 0.0
|
private var currentTextInputBackgroundWidthOffset: CGFloat = 0.0
|
||||||
|
|
@ -872,15 +872,15 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||||
}
|
}
|
||||||
self.mediaActionButtons.micButton.offsetRecordingControls = { [weak self] in
|
self.mediaActionButtons.micButton.offsetRecordingControls = { [weak self] in
|
||||||
if let strongSelf = self, let presentationInterfaceState = strongSelf.presentationInterfaceState {
|
if let strongSelf = self, let presentationInterfaceState = strongSelf.presentationInterfaceState {
|
||||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = strongSelf.validLayout {
|
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded, deviceMetrics) = strongSelf.validLayout {
|
||||||
let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: presentationInterfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded)
|
let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: presentationInterfaceState, metrics: metrics, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.mediaActionButtons.micButton.updateCancelTranslation = { [weak self] in
|
self.mediaActionButtons.micButton.updateCancelTranslation = { [weak self] in
|
||||||
if let strongSelf = self, let presentationInterfaceState = strongSelf.presentationInterfaceState {
|
if let strongSelf = self, let presentationInterfaceState = strongSelf.presentationInterfaceState {
|
||||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = strongSelf.validLayout {
|
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded, deviceMetrics) = strongSelf.validLayout {
|
||||||
let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: presentationInterfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded)
|
let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: presentationInterfaceState, metrics: metrics, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1412,10 +1412,10 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||||
}
|
}
|
||||||
|
|
||||||
public func requestLayout(transition: ContainedViewLayoutTransition = .immediate) {
|
public func requestLayout(transition: ContainedViewLayoutTransition = .immediate) {
|
||||||
guard let presentationInterfaceState = self.presentationInterfaceState, let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = self.validLayout else {
|
guard let presentationInterfaceState = self.presentationInterfaceState, let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded, deviceMetrics) = self.validLayout else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: transition, interfaceState: presentationInterfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded)
|
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, transition: transition, interfaceState: presentationInterfaceState, metrics: metrics, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func updateLayout(
|
override public func updateLayout(
|
||||||
|
|
@ -1430,12 +1430,13 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||||
transition: ContainedViewLayoutTransition,
|
transition: ContainedViewLayoutTransition,
|
||||||
interfaceState: ChatPresentationInterfaceState,
|
interfaceState: ChatPresentationInterfaceState,
|
||||||
metrics: LayoutMetrics,
|
metrics: LayoutMetrics,
|
||||||
|
deviceMetrics: DeviceMetrics,
|
||||||
isMediaInputExpanded: Bool
|
isMediaInputExpanded: Bool
|
||||||
) -> CGFloat {
|
) -> CGFloat {
|
||||||
let isFirstTime = self.validLayout == nil
|
let isFirstTime = self.validLayout == nil
|
||||||
|
|
||||||
let previousAdditionalSideInsets = self.validLayout?.4
|
let previousAdditionalSideInsets = self.validLayout?.4
|
||||||
self.validLayout = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded)
|
self.validLayout = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded, deviceMetrics)
|
||||||
|
|
||||||
let defaultGlassTintColor: GlassBackgroundView.TintColor
|
let defaultGlassTintColor: GlassBackgroundView.TintColor
|
||||||
let defaultGlassTintWithInnerColor: GlassBackgroundView.TintColor
|
let defaultGlassTintWithInnerColor: GlassBackgroundView.TintColor
|
||||||
|
|
@ -1450,10 +1451,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||||
var leftInset = leftInset
|
var leftInset = leftInset
|
||||||
var rightInset = rightInset
|
var rightInset = rightInset
|
||||||
|
|
||||||
if bottomInset <= 32.0 {
|
let compactBottomSideInset = self.compactBottomSideInset(bottomInset: bottomInset, deviceMetrics: deviceMetrics)
|
||||||
leftInset += 18.0
|
leftInset += compactBottomSideInset
|
||||||
rightInset += 18.0
|
rightInset += compactBottomSideInset
|
||||||
}
|
|
||||||
|
|
||||||
let placeholderColor: UIColor = interfaceState.theme.chat.inputPanel.inputPlaceholderColor
|
let placeholderColor: UIColor = interfaceState.theme.chat.inputPanel.inputPlaceholderColor
|
||||||
|
|
||||||
|
|
@ -2897,7 +2897,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||||
transition.updateAlpha(layer: mediaPreviewPanelNode.tintMaskView.layer, alpha: 1.0)
|
transition.updateAlpha(layer: mediaPreviewPanelNode.tintMaskView.layer, alpha: 1.0)
|
||||||
transition.updateFrame(view: mediaPreviewPanelNode.tintMaskView, frame: mediaPreviewPanelFrame)
|
transition.updateFrame(view: mediaPreviewPanelNode.tintMaskView, frame: mediaPreviewPanelFrame)
|
||||||
|
|
||||||
let _ = mediaPreviewPanelNode.updateLayout(width: mediaPreviewPanelFrame.width, leftInset: 0.0, rightInset: 0.0, bottomInset: 0.0, additionalSideInsets: UIEdgeInsets(), maxHeight: 40.0, maxOverlayHeight: 40.0, isSecondary: false, transition: mediaPreviewPanelTransition, interfaceState: interfaceState, metrics: metrics, isMediaInputExpanded: false)
|
let _ = mediaPreviewPanelNode.updateLayout(width: mediaPreviewPanelFrame.width, leftInset: 0.0, rightInset: 0.0, bottomInset: 0.0, additionalSideInsets: UIEdgeInsets(), maxHeight: 40.0, maxOverlayHeight: 40.0, isSecondary: false, transition: mediaPreviewPanelTransition, interfaceState: interfaceState, metrics: metrics, deviceMetrics: deviceMetrics, isMediaInputExpanded: false)
|
||||||
} else if let mediaPreviewPanelNode = self.mediaPreviewPanelNode {
|
} else if let mediaPreviewPanelNode = self.mediaPreviewPanelNode {
|
||||||
self.mediaPreviewPanelNode = nil
|
self.mediaPreviewPanelNode = nil
|
||||||
let mediaPreviewPanelView = mediaPreviewPanelNode.view
|
let mediaPreviewPanelView = mediaPreviewPanelNode.view
|
||||||
|
|
@ -4653,13 +4653,12 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateTextHeight(animated: Bool) {
|
private func updateTextHeight(animated: Bool) {
|
||||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, _, metrics, _, _) = self.validLayout, let interfaceState = self.presentationInterfaceState {
|
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, _, metrics, _, _, deviceMetrics) = self.validLayout, let interfaceState = self.presentationInterfaceState {
|
||||||
var leftInset = leftInset
|
var leftInset = leftInset
|
||||||
var rightInset = rightInset
|
var rightInset = rightInset
|
||||||
if bottomInset <= 32.0 {
|
let compactBottomSideInset = self.compactBottomSideInset(bottomInset: bottomInset, deviceMetrics: deviceMetrics)
|
||||||
leftInset += 18.0
|
leftInset += compactBottomSideInset
|
||||||
rightInset += 18.0
|
rightInset += compactBottomSideInset
|
||||||
}
|
|
||||||
|
|
||||||
let baseWidth = width - leftInset - self.leftMenuInset - rightInset - self.rightSlowModeInset + self.currentTextInputBackgroundWidthOffset - additionalSideInsets.right
|
let baseWidth = width - leftInset - self.leftMenuInset - rightInset - self.rightSlowModeInset + self.currentTextInputBackgroundWidthOffset - additionalSideInsets.right
|
||||||
let (_, textFieldHeight, _) = self.calculateTextFieldMetrics(width: baseWidth, sendActionControlsWidth: self.sendActionButtons.bounds.width, maxHeight: maxHeight, metrics: metrics, bottomInset: bottomInset, interfaceState: interfaceState)
|
let (_, textFieldHeight, _) = self.calculateTextFieldMetrics(width: baseWidth, sendActionControlsWidth: self.sendActionButtons.bounds.width, maxHeight: maxHeight, metrics: metrics, bottomInset: bottomInset, interfaceState: interfaceState)
|
||||||
|
|
|
||||||
|
|
@ -376,7 +376,7 @@ public final class ChatTitleComponent: Component {
|
||||||
var titleStatusIcon: ChatTitleCredibilityIcon = .none
|
var titleStatusIcon: ChatTitleCredibilityIcon = .none
|
||||||
var isEnabled = true
|
var isEnabled = true
|
||||||
switch component.content {
|
switch component.content {
|
||||||
case let .peer(peerView, customTitle, _, _, isScheduledMessages, isMuted, _, isEnabledValue):
|
case let .peer(peerView, customTitle, _, _, isScheduledMessages, isMuted, _, hidePeerStatus, isEnabledValue):
|
||||||
if peerView.peerId.isReplies {
|
if peerView.peerId.isReplies {
|
||||||
titleSegments = [AnimatedTextComponent.Item(
|
titleSegments = [AnimatedTextComponent.Item(
|
||||||
id: AnyHashable(0),
|
id: AnyHashable(0),
|
||||||
|
|
@ -448,7 +448,7 @@ public final class ChatTitleComponent: Component {
|
||||||
titleCredibilityIcon = .fake
|
titleCredibilityIcon = .fake
|
||||||
} else if peer.isScam {
|
} else if peer.isScam {
|
||||||
titleCredibilityIcon = .scam
|
titleCredibilityIcon = .scam
|
||||||
} else if let emojiStatus = peer.emojiStatus {
|
} else if !hidePeerStatus, let emojiStatus = peer.emojiStatus {
|
||||||
titleStatusIcon = .emojiStatus(emojiStatus)
|
titleStatusIcon = .emojiStatus(emojiStatus)
|
||||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||||
titleCredibilityIcon = .premium
|
titleCredibilityIcon = .premium
|
||||||
|
|
@ -612,7 +612,7 @@ public final class ChatTitleComponent: Component {
|
||||||
|
|
||||||
var inputActivitiesAllowed = true
|
var inputActivitiesAllowed = true
|
||||||
switch component.content {
|
switch component.content {
|
||||||
case let .peer(peerView, _, _, _, isScheduledMessages, _, _, _):
|
case let .peer(peerView, _, _, _, isScheduledMessages, _, _, _, _):
|
||||||
if let peer = peerView.peer {
|
if let peer = peerView.peer {
|
||||||
if peer.id == component.context.account.peerId || isScheduledMessages || peer.id.isRepliesOrVerificationCodes {
|
if peer.id == component.context.account.peerId || isScheduledMessages || peer.id.isRepliesOrVerificationCodes {
|
||||||
inputActivitiesAllowed = false
|
inputActivitiesAllowed = false
|
||||||
|
|
@ -710,7 +710,7 @@ public final class ChatTitleComponent: Component {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch component.content {
|
switch component.content {
|
||||||
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, _, customMessageCount, _):
|
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, _, customMessageCount, _, _):
|
||||||
if let customSubtitle {
|
if let customSubtitle {
|
||||||
let string = NSAttributedString(string: customSubtitle, font: subtitleFont, textColor: component.theme.chat.inputPanel.inputControlColor)
|
let string = NSAttributedString(string: customSubtitle, font: subtitleFont, textColor: component.theme.chat.inputPanel.inputControlColor)
|
||||||
state = .info(string, .generic)
|
state = .info(string, .generic)
|
||||||
|
|
|
||||||
|
|
@ -110,14 +110,14 @@ public enum ChatTitleContent: Equatable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case peer(peerView: PeerData, customTitle: String?, customSubtitle: String?, onlineMemberCount: (total: Int32?, recent: Int32?), isScheduledMessages: Bool, isMuted: Bool?, customMessageCount: Int?, isEnabled: Bool)
|
case peer(peerView: PeerData, customTitle: String?, customSubtitle: String?, onlineMemberCount: (total: Int32?, recent: Int32?), isScheduledMessages: Bool, isMuted: Bool?, customMessageCount: Int?, hidePeerStatus: Bool, isEnabled: Bool)
|
||||||
case replyThread(type: ReplyThreadType, count: Int)
|
case replyThread(type: ReplyThreadType, count: Int)
|
||||||
case custom(title: [TitleTextItem], subtitle: String?, isEnabled: Bool)
|
case custom(title: [TitleTextItem], subtitle: String?, isEnabled: Bool)
|
||||||
|
|
||||||
public static func ==(lhs: ChatTitleContent, rhs: ChatTitleContent) -> Bool {
|
public static func ==(lhs: ChatTitleContent, rhs: ChatTitleContent) -> Bool {
|
||||||
switch lhs {
|
switch lhs {
|
||||||
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, isMuted, customMessageCount, isEnabled):
|
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, isMuted, customMessageCount, hidePeerStatus, isEnabled):
|
||||||
if case let .peer(rhsPeerView, rhsCustomTitle, rhsCustomSubtitle, rhsOnlineMemberCount, rhsIsScheduledMessages, rhsIsMuted, rhsCustomMessageCount, rhsIsEnabled) = rhs {
|
if case let .peer(rhsPeerView, rhsCustomTitle, rhsCustomSubtitle, rhsOnlineMemberCount, rhsIsScheduledMessages, rhsIsMuted, rhsCustomMessageCount, rhsHidePeerStatus, rhsIsEnabled) = rhs {
|
||||||
if peerView != rhsPeerView {
|
if peerView != rhsPeerView {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -139,6 +139,9 @@ public enum ChatTitleContent: Equatable {
|
||||||
if customMessageCount != rhsCustomMessageCount {
|
if customMessageCount != rhsCustomMessageCount {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if hidePeerStatus != rhsHidePeerStatus {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if isEnabled != rhsIsEnabled {
|
if isEnabled != rhsIsEnabled {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -269,7 +272,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
||||||
var titleStatusIcon: ChatTitleCredibilityIcon = .none
|
var titleStatusIcon: ChatTitleCredibilityIcon = .none
|
||||||
var isEnabled = true
|
var isEnabled = true
|
||||||
switch titleContent {
|
switch titleContent {
|
||||||
case let .peer(peerView, customTitle, _, _, isScheduledMessages, isMuted, _, isEnabledValue):
|
case let .peer(peerView, customTitle, _, _, isScheduledMessages, isMuted, _, hidePeerStatus, isEnabledValue):
|
||||||
if peerView.peerId.isReplies {
|
if peerView.peerId.isReplies {
|
||||||
let typeText: String = self.strings.DialogList_Replies
|
let typeText: String = self.strings.DialogList_Replies
|
||||||
segments = [.text(0, NSAttributedString(string: typeText, font: titleFont, textColor: titleTheme.rootController.navigationBar.primaryTextColor))]
|
segments = [.text(0, NSAttributedString(string: typeText, font: titleFont, textColor: titleTheme.rootController.navigationBar.primaryTextColor))]
|
||||||
|
|
@ -306,7 +309,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
||||||
titleCredibilityIcon = .fake
|
titleCredibilityIcon = .fake
|
||||||
} else if peer.isScam {
|
} else if peer.isScam {
|
||||||
titleCredibilityIcon = .scam
|
titleCredibilityIcon = .scam
|
||||||
} else if let emojiStatus = peer.emojiStatus {
|
} else if !hidePeerStatus, let emojiStatus = peer.emojiStatus {
|
||||||
titleStatusIcon = .emojiStatus(emojiStatus)
|
titleStatusIcon = .emojiStatus(emojiStatus)
|
||||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||||
titleCredibilityIcon = .premium
|
titleCredibilityIcon = .premium
|
||||||
|
|
@ -476,8 +479,8 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
||||||
|
|
||||||
var enableAnimation = false
|
var enableAnimation = false
|
||||||
switch titleContent {
|
switch titleContent {
|
||||||
case let .peer(_, customTitle, _, _, _, _, _, _):
|
case let .peer(_, customTitle, _, _, _, _, _, _, _):
|
||||||
if case let .peer(_, previousCustomTitle, _, _, _, _, _, _) = oldValue {
|
if case let .peer(_, previousCustomTitle, _, _, _, _, _, _, _) = oldValue {
|
||||||
if customTitle != previousCustomTitle {
|
if customTitle != previousCustomTitle {
|
||||||
enableAnimation = false
|
enableAnimation = false
|
||||||
}
|
}
|
||||||
|
|
@ -503,7 +506,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
||||||
var inputActivitiesAllowed = true
|
var inputActivitiesAllowed = true
|
||||||
if let titleContent = self.titleContent {
|
if let titleContent = self.titleContent {
|
||||||
switch titleContent {
|
switch titleContent {
|
||||||
case let .peer(peerView, _, _, _, isScheduledMessages, _, _, _):
|
case let .peer(peerView, _, _, _, isScheduledMessages, _, _, _, _):
|
||||||
if let peer = peerView.peer {
|
if let peer = peerView.peer {
|
||||||
if peer.id == self.context.account.peerId || isScheduledMessages || peer.id.isRepliesOrVerificationCodes {
|
if peer.id == self.context.account.peerId || isScheduledMessages || peer.id.isRepliesOrVerificationCodes {
|
||||||
inputActivitiesAllowed = false
|
inputActivitiesAllowed = false
|
||||||
|
|
@ -604,7 +607,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
||||||
} else {
|
} else {
|
||||||
if let titleContent = self.titleContent {
|
if let titleContent = self.titleContent {
|
||||||
switch titleContent {
|
switch titleContent {
|
||||||
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, _, customMessageCount, _):
|
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, _, customMessageCount, _, _):
|
||||||
if let customSubtitle {
|
if let customSubtitle {
|
||||||
let string = NSAttributedString(string: customSubtitle, font: subtitleFont, textColor: titleTheme.rootController.navigationBar.secondaryTextColor)
|
let string = NSAttributedString(string: customSubtitle, font: subtitleFont, textColor: titleTheme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(string, .generic)
|
state = .info(string, .generic)
|
||||||
|
|
|
||||||
|
|
@ -425,6 +425,7 @@ final class PeerInfoScreenData {
|
||||||
let savedMusicContext: ProfileSavedMusicContext?
|
let savedMusicContext: ProfileSavedMusicContext?
|
||||||
let savedMusicState: ProfileSavedMusicContext.State?
|
let savedMusicState: ProfileSavedMusicContext.State?
|
||||||
let managedByBot: EnginePeer?
|
let managedByBot: EnginePeer?
|
||||||
|
let businessConnectedBot: EnginePeer?
|
||||||
|
|
||||||
let _isContact: Bool
|
let _isContact: Bool
|
||||||
var forceIsContact: Bool = false
|
var forceIsContact: Bool = false
|
||||||
|
|
@ -480,7 +481,8 @@ final class PeerInfoScreenData {
|
||||||
webAppPermissions: WebAppPermissionsState?,
|
webAppPermissions: WebAppPermissionsState?,
|
||||||
savedMusicContext: ProfileSavedMusicContext?,
|
savedMusicContext: ProfileSavedMusicContext?,
|
||||||
savedMusicState: ProfileSavedMusicContext.State?,
|
savedMusicState: ProfileSavedMusicContext.State?,
|
||||||
managedByBot: EnginePeer?
|
managedByBot: EnginePeer?,
|
||||||
|
businessConnectedBot: EnginePeer?
|
||||||
) {
|
) {
|
||||||
self.peer = peer
|
self.peer = peer
|
||||||
self.chatPeer = chatPeer
|
self.chatPeer = chatPeer
|
||||||
|
|
@ -525,6 +527,7 @@ final class PeerInfoScreenData {
|
||||||
self.savedMusicContext = savedMusicContext
|
self.savedMusicContext = savedMusicContext
|
||||||
self.savedMusicState = savedMusicState
|
self.savedMusicState = savedMusicState
|
||||||
self.managedByBot = managedByBot
|
self.managedByBot = managedByBot
|
||||||
|
self.businessConnectedBot = businessConnectedBot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -931,6 +934,20 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
||||||
|
|
||||||
let profileGiftsContext = ProfileGiftsContext(account: context.account, peerId: peerId)
|
let profileGiftsContext = ProfileGiftsContext(account: context.account, peerId: peerId)
|
||||||
|
|
||||||
|
let businessConnectedBot = context.engine.data.subscribe(
|
||||||
|
TelegramEngine.EngineData.Item.Peer.BusinessConnectedBot(id: context.account.peerId)
|
||||||
|
)
|
||||||
|
|> map { bot -> EnginePeer.Id? in
|
||||||
|
return bot?.id
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
|> mapToSignal { botPeerId -> Signal<EnginePeer?, NoError> in
|
||||||
|
guard let botPeerId else {
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: botPeerId))
|
||||||
|
}
|
||||||
|
|
||||||
return combineLatest(
|
return combineLatest(
|
||||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||||
accountsAndPeers,
|
accountsAndPeers,
|
||||||
|
|
@ -956,9 +973,10 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
||||||
bots,
|
bots,
|
||||||
peerInfoPersonalOrLinkedChannel(context: context, peerId: peerId, isSettings: true),
|
peerInfoPersonalOrLinkedChannel(context: context, peerId: peerId, isSettings: true),
|
||||||
starsState,
|
starsState,
|
||||||
tonState
|
tonState,
|
||||||
|
businessConnectedBot
|
||||||
)
|
)
|
||||||
|> map { peerView, accountsAndPeers, accountSessions, privacySettings, sharedPreferences, notifications, stickerPacks, hasPassport, accountPreferences, suggestions, limits, hasPassword, isPowerSavingEnabled, hasStories, bots, personalChannel, starsState, tonState -> PeerInfoScreenData in
|
|> map { peerView, accountsAndPeers, accountSessions, privacySettings, sharedPreferences, notifications, stickerPacks, hasPassport, accountPreferences, suggestions, limits, hasPassword, isPowerSavingEnabled, hasStories, bots, personalChannel, starsState, tonState, businessConnectedBot -> PeerInfoScreenData in
|
||||||
let (notificationExceptions, notificationsAuthorizationStatus, notificationsWarningSuppressed) = notifications
|
let (notificationExceptions, notificationsAuthorizationStatus, notificationsWarningSuppressed) = notifications
|
||||||
let (featuredStickerPacks, archivedStickerPacks) = stickerPacks
|
let (featuredStickerPacks, archivedStickerPacks) = stickerPacks
|
||||||
|
|
||||||
|
|
@ -1048,7 +1066,8 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
||||||
webAppPermissions: nil,
|
webAppPermissions: nil,
|
||||||
savedMusicContext: nil,
|
savedMusicContext: nil,
|
||||||
savedMusicState: nil,
|
savedMusicState: nil,
|
||||||
managedByBot: nil
|
managedByBot: nil,
|
||||||
|
businessConnectedBot: businessConnectedBot
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1120,7 +1139,8 @@ func peerInfoScreenData(
|
||||||
webAppPermissions: nil,
|
webAppPermissions: nil,
|
||||||
savedMusicContext: nil,
|
savedMusicContext: nil,
|
||||||
savedMusicState: nil,
|
savedMusicState: nil,
|
||||||
managedByBot: nil
|
managedByBot: nil,
|
||||||
|
businessConnectedBot: nil
|
||||||
))
|
))
|
||||||
case let .user(userPeerId, secretChatId, kind):
|
case let .user(userPeerId, secretChatId, kind):
|
||||||
let groupsInCommon: GroupsInCommonContext?
|
let groupsInCommon: GroupsInCommonContext?
|
||||||
|
|
@ -1446,7 +1466,26 @@ func peerInfoScreenData(
|
||||||
}
|
}
|
||||||
|
|
||||||
let savedMusicContext = ProfileSavedMusicContext(account: context.account, peerId: peerId)
|
let savedMusicContext = ProfileSavedMusicContext(account: context.account, peerId: peerId)
|
||||||
|
|
||||||
|
let businessConnectedBot: Signal<EnginePeer?, NoError>
|
||||||
|
if isMyProfile {
|
||||||
|
businessConnectedBot = context.engine.data.subscribe(
|
||||||
|
TelegramEngine.EngineData.Item.Peer.BusinessConnectedBot(id: context.account.peerId)
|
||||||
|
)
|
||||||
|
|> map { bot -> EnginePeer.Id? in
|
||||||
|
return bot?.id
|
||||||
|
}
|
||||||
|
|> distinctUntilChanged
|
||||||
|
|> mapToSignal { botPeerId -> Signal<EnginePeer?, NoError> in
|
||||||
|
guard let botPeerId else {
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
|
return context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: botPeerId))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
businessConnectedBot = .single(nil)
|
||||||
|
}
|
||||||
|
|
||||||
return combineLatest(
|
return combineLatest(
|
||||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||||
peerInfoAvailableMediaPanes(context: context, peerId: peerId, chatLocation: chatLocation, isMyProfile: isMyProfile, chatLocationContextHolder: chatLocationContextHolder, sharedMediaFromForumTopic: sharedMediaFromForumTopic),
|
peerInfoAvailableMediaPanes(context: context, peerId: peerId, chatLocation: chatLocation, isMyProfile: isMyProfile, chatLocationContextHolder: chatLocationContextHolder, sharedMediaFromForumTopic: sharedMediaFromForumTopic),
|
||||||
|
|
@ -1468,9 +1507,10 @@ func peerInfoScreenData(
|
||||||
revenueContextAndState,
|
revenueContextAndState,
|
||||||
premiumGiftOptions,
|
premiumGiftOptions,
|
||||||
webAppPermissions,
|
webAppPermissions,
|
||||||
savedMusicContext.state
|
savedMusicContext.state,
|
||||||
|
businessConnectedBot
|
||||||
)
|
)
|
||||||
|> map { peerView, availablePanes, globalNotificationSettings, encryptionKeyFingerprint, status, hasStories, hasStoryArchive, recommendedBots, accountIsPremium, savedMessagesPeer, hasSavedMessagesChats, hasSavedMessages, hasSavedMessageTags, hasBotPreviewItems, personalChannel, privacySettings, starsRevenueContextAndState, revenueContextAndState, premiumGiftOptions, webAppPermissions, savedMusicState -> PeerInfoScreenData in
|
|> map { peerView, availablePanes, globalNotificationSettings, encryptionKeyFingerprint, status, hasStories, hasStoryArchive, recommendedBots, accountIsPremium, savedMessagesPeer, hasSavedMessagesChats, hasSavedMessages, hasSavedMessageTags, hasBotPreviewItems, personalChannel, privacySettings, starsRevenueContextAndState, revenueContextAndState, premiumGiftOptions, webAppPermissions, savedMusicState, businessConnectedBot -> PeerInfoScreenData in
|
||||||
var availablePanes = availablePanes
|
var availablePanes = availablePanes
|
||||||
if isMyProfile {
|
if isMyProfile {
|
||||||
availablePanes?.insert(.stories, at: 0)
|
availablePanes?.insert(.stories, at: 0)
|
||||||
|
|
@ -1616,7 +1656,8 @@ func peerInfoScreenData(
|
||||||
webAppPermissions: webAppPermissions,
|
webAppPermissions: webAppPermissions,
|
||||||
savedMusicContext: savedMusicContext,
|
savedMusicContext: savedMusicContext,
|
||||||
savedMusicState: savedMusicState,
|
savedMusicState: savedMusicState,
|
||||||
managedByBot: managedByBot
|
managedByBot: managedByBot,
|
||||||
|
businessConnectedBot: businessConnectedBot
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case .channel:
|
case .channel:
|
||||||
|
|
@ -1862,7 +1903,8 @@ func peerInfoScreenData(
|
||||||
webAppPermissions: nil,
|
webAppPermissions: nil,
|
||||||
savedMusicContext: nil,
|
savedMusicContext: nil,
|
||||||
savedMusicState: nil,
|
savedMusicState: nil,
|
||||||
managedByBot: nil
|
managedByBot: nil,
|
||||||
|
businessConnectedBot: nil
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
case let .group(groupId):
|
case let .group(groupId):
|
||||||
|
|
@ -2199,7 +2241,8 @@ func peerInfoScreenData(
|
||||||
webAppPermissions: nil,
|
webAppPermissions: nil,
|
||||||
savedMusicContext: nil,
|
savedMusicContext: nil,
|
||||||
savedMusicState: nil,
|
savedMusicState: nil,
|
||||||
managedByBot: nil
|
managedByBot: nil,
|
||||||
|
businessConnectedBot: nil
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ final class PeerInfoInteraction {
|
||||||
let editingOpenVerifyAccounts: () -> Void
|
let editingOpenVerifyAccounts: () -> Void
|
||||||
let editingToggleAutoTranslate: (Bool) -> Void
|
let editingToggleAutoTranslate: (Bool) -> Void
|
||||||
let displayAutoTranslateLocked: () -> Void
|
let displayAutoTranslateLocked: () -> Void
|
||||||
|
let editingOpenBusinessChatBots: () -> Void
|
||||||
let getController: () -> ViewController?
|
let getController: () -> ViewController?
|
||||||
|
|
||||||
init(
|
init(
|
||||||
|
|
@ -160,6 +161,7 @@ final class PeerInfoInteraction {
|
||||||
editingOpenVerifyAccounts: @escaping () -> Void,
|
editingOpenVerifyAccounts: @escaping () -> Void,
|
||||||
editingToggleAutoTranslate: @escaping (Bool) -> Void,
|
editingToggleAutoTranslate: @escaping (Bool) -> Void,
|
||||||
displayAutoTranslateLocked: @escaping () -> Void,
|
displayAutoTranslateLocked: @escaping () -> Void,
|
||||||
|
editingOpenBusinessChatBots: @escaping () -> Void,
|
||||||
getController: @escaping () -> ViewController?
|
getController: @escaping () -> ViewController?
|
||||||
) {
|
) {
|
||||||
self.openUsername = openUsername
|
self.openUsername = openUsername
|
||||||
|
|
@ -236,6 +238,7 @@ final class PeerInfoInteraction {
|
||||||
self.editingOpenVerifyAccounts = editingOpenVerifyAccounts
|
self.editingOpenVerifyAccounts = editingOpenVerifyAccounts
|
||||||
self.editingToggleAutoTranslate = editingToggleAutoTranslate
|
self.editingToggleAutoTranslate = editingToggleAutoTranslate
|
||||||
self.displayAutoTranslateLocked = displayAutoTranslateLocked
|
self.displayAutoTranslateLocked = displayAutoTranslateLocked
|
||||||
|
self.editingOpenBusinessChatBots = editingOpenBusinessChatBots
|
||||||
self.getController = getController
|
self.getController = getController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -682,6 +682,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.displayAutoTranslateLocked()
|
self.displayAutoTranslateLocked()
|
||||||
|
}, editingOpenBusinessChatBots: { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.editingOpenBusinessChatBots()
|
||||||
},
|
},
|
||||||
getController: { [weak self] in
|
getController: { [weak self] in
|
||||||
return self?.controller
|
return self?.controller
|
||||||
|
|
@ -3986,6 +3991,17 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func editingOpenBusinessChatBots() {
|
||||||
|
let _ = (self.context.sharedContext.makeChatbotSetupScreenInitialData(context: self.context)
|
||||||
|
|> take(1)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] initialData in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.controller?.push(self.context.sharedContext.makeChatbotSetupScreen(context: self.context, initialData: initialData))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private func editingOpenInviteLinksSetup() {
|
private func editingOpenInviteLinksSetup() {
|
||||||
self.controller?.push(inviteLinkListController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: self.peerId, admin: nil))
|
self.controller?.push(inviteLinkListController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: self.peerId, admin: nil))
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ final class PeerInfoSelectionPanelNode: ASDisplayNode {
|
||||||
self.separatorNode.backgroundColor = presentationData.theme.rootController.navigationBar.separatorColor
|
self.separatorNode.backgroundColor = presentationData.theme.rootController.navigationBar.separatorColor
|
||||||
|
|
||||||
let interfaceState = ChatPresentationInterfaceState(chatWallpaper: .color(0), theme: presentationData.theme, preferredGlassType: .default, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, limitsConfiguration: .defaultValue, fontSize: .regular, bubbleCorners: PresentationChatBubbleCorners(mainRadius: 16.0, auxiliaryRadius: 8.0, mergeBubbleCorners: true), accountPeerId: self.context.account.peerId, mode: .standard(.default), chatLocation: .peer(id: self.peerId), subject: nil, peerNearbyData: nil, greetingData: nil, pendingUnpinnedAllMessages: false, activeGroupCallInfo: nil, hasActiveGroupCall: false, threadData: nil, isGeneralThreadClosed: nil, replyMessage: nil, accountPeerColor: nil, businessIntro: nil)
|
let interfaceState = ChatPresentationInterfaceState(chatWallpaper: .color(0), theme: presentationData.theme, preferredGlassType: .default, strings: presentationData.strings, dateTimeFormat: presentationData.dateTimeFormat, nameDisplayOrder: presentationData.nameDisplayOrder, limitsConfiguration: .defaultValue, fontSize: .regular, bubbleCorners: PresentationChatBubbleCorners(mainRadius: 16.0, auxiliaryRadius: 8.0, mergeBubbleCorners: true), accountPeerId: self.context.account.peerId, mode: .standard(.default), chatLocation: .peer(id: self.peerId), subject: nil, peerNearbyData: nil, greetingData: nil, pendingUnpinnedAllMessages: false, activeGroupCallInfo: nil, hasActiveGroupCall: false, threadData: nil, isGeneralThreadClosed: nil, replyMessage: nil, accountPeerColor: nil, businessIntro: nil)
|
||||||
let panelHeight = self.selectionPanel.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: layout.intrinsicInsets.bottom, additionalSideInsets: UIEdgeInsets(), maxHeight: layout.size.height, maxOverlayHeight: layout.size.height, isSecondary: false, transition: transition, interfaceState: interfaceState, metrics: layout.metrics, isMediaInputExpanded: false)
|
let panelHeight = self.selectionPanel.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: layout.intrinsicInsets.bottom, additionalSideInsets: UIEdgeInsets(), maxHeight: layout.size.height, maxOverlayHeight: layout.size.height, isSecondary: false, transition: transition, interfaceState: interfaceState, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, isMediaInputExpanded: false)
|
||||||
|
|
||||||
transition.updateFrame(node: self.selectionPanel, frame: CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: panelHeight)))
|
transition.updateFrame(node: self.selectionPanel, frame: CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: panelHeight)))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -370,6 +370,8 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
||||||
let ItemBirthdayRemove = 11
|
let ItemBirthdayRemove = 11
|
||||||
let ItemBirthdayHelp = 12
|
let ItemBirthdayHelp = 12
|
||||||
let ItemPeerPersonalChannel = 13
|
let ItemPeerPersonalChannel = 13
|
||||||
|
let ItemPeerChatAutomation = 14
|
||||||
|
let ItemPeerChatAutomationHelp = 15
|
||||||
|
|
||||||
items[.help]!.append(PeerInfoScreenCommentItem(id: ItemNameHelp, text: presentationData.strings.EditProfile_NameAndPhotoOrVideoHelp))
|
items[.help]!.append(PeerInfoScreenCommentItem(id: ItemNameHelp, text: presentationData.strings.EditProfile_NameAndPhotoOrVideoHelp))
|
||||||
|
|
||||||
|
|
@ -400,7 +402,7 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
||||||
}
|
}
|
||||||
|
|
||||||
let isEditingBirthDate = state.isEditingBirthDate
|
let isEditingBirthDate = state.isEditingBirthDate
|
||||||
items[.birthday]!.append(PeerInfoScreenDisclosureItem(id: ItemBirthday, label: .coloredText(birthDateString, isEditingBirthDate ? .accent : .generic), text: presentationData.strings.Settings_Birthday, icon: nil, hasArrow: false, action: {
|
items[.birthday]!.append(PeerInfoScreenDisclosureItem(id: ItemBirthday, label: .coloredText(birthDateString, isEditingBirthDate ? .accent : .generic), text: presentationData.strings.Settings_Birthday, icon: PresentationResourcesSettings.birthday, hasArrow: false, action: {
|
||||||
interaction.updateIsEditingBirthdate(!isEditingBirthDate)
|
interaction.updateIsEditingBirthdate(!isEditingBirthDate)
|
||||||
}))
|
}))
|
||||||
if isEditingBirthDate, let birthday {
|
if isEditingBirthDate, let birthday {
|
||||||
|
|
@ -423,7 +425,7 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
||||||
}))
|
}))
|
||||||
|
|
||||||
if let user = data.peer as? TelegramUser {
|
if let user = data.peer as? TelegramUser {
|
||||||
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPhoneNumber, label: .text(user.phone.flatMap({ formatPhoneNumber(context: context, number: $0) }) ?? ""), text: presentationData.strings.Settings_PhoneNumber, action: {
|
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPhoneNumber, label: .text(user.phone.flatMap({ formatPhoneNumber(context: context, number: $0) }) ?? ""), text: presentationData.strings.Settings_PhoneNumber, icon: PresentationResourcesSettings.recentCalls, action: {
|
||||||
interaction.openSettings(.phoneNumber)
|
interaction.openSettings(.phoneNumber)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
@ -431,7 +433,7 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
||||||
if let addressName = data.peer?.addressName, !addressName.isEmpty {
|
if let addressName = data.peer?.addressName, !addressName.isEmpty {
|
||||||
username = "@\(addressName)"
|
username = "@\(addressName)"
|
||||||
}
|
}
|
||||||
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemUsername, label: .text(username), text: presentationData.strings.Settings_Username, action: {
|
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemUsername, label: .text(username), text: presentationData.strings.Settings_Username, icon: PresentationResourcesSettings.email, action: {
|
||||||
interaction.openSettings(.username)
|
interaction.openSettings(.username)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
@ -452,7 +454,7 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
||||||
}
|
}
|
||||||
let colorImage = generateSettingsMenuPeerColorsLabelIcon(colors: colors)
|
let colorImage = generateSettingsMenuPeerColorsLabelIcon(colors: colors)
|
||||||
|
|
||||||
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerColor, label: .image(colorImage, colorImage.size), text: presentationData.strings.Settings_YourColor, icon: nil, action: {
|
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerColor, label: .image(colorImage, colorImage.size), text: presentationData.strings.Settings_YourColor, icon: PresentationResourcesSettings.yourColor, action: {
|
||||||
interaction.editingOpenNameColorSetup()
|
interaction.editingOpenNameColorSetup()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
@ -468,12 +470,26 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
||||||
personalChannelTitle = peer.compactDisplayTitle
|
personalChannelTitle = peer.compactDisplayTitle
|
||||||
}
|
}
|
||||||
|
|
||||||
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerPersonalChannel, label: .text(personalChannelTitle ?? presentationData.strings.Settings_PersonalChannelEmptyValue), text: presentationData.strings.Settings_PersonalChannelItem, icon: nil, action: {
|
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerPersonalChannel, label: .text(personalChannelTitle ?? presentationData.strings.Settings_PersonalChannelEmptyValue), text: presentationData.strings.Settings_PersonalChannelItem, icon: PresentationResourcesSettings.channels, action: {
|
||||||
interaction.editingOpenPersonalChannel()
|
interaction.editingOpenPersonalChannel()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if "".isEmpty {
|
||||||
|
//TODO:localize
|
||||||
|
let automationBotTitle: String
|
||||||
|
if let botPeer = data.businessConnectedBot {
|
||||||
|
automationBotTitle = "@\(botPeer.compactDisplayTitle)"
|
||||||
|
} else {
|
||||||
|
automationBotTitle = "Off"
|
||||||
|
}
|
||||||
|
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerChatAutomation, label: .text(automationBotTitle), text: "Chat Automation", icon: PresentationResourcesSettings.aiTools, action: {
|
||||||
|
interaction.editingOpenBusinessChatBots()
|
||||||
|
}))
|
||||||
|
items[.info]!.append(PeerInfoScreenCommentItem(id: ItemPeerChatAutomationHelp, text: "Add a bot to reply to messages on your behalf."))
|
||||||
|
}
|
||||||
|
|
||||||
items[.account]!.append(PeerInfoScreenActionItem(id: ItemAddAccount, text: presentationData.strings.Settings_AddAnotherAccount, alignment: .center, action: {
|
items[.account]!.append(PeerInfoScreenActionItem(id: ItemAddAccount, text: presentationData.strings.Settings_AddAnotherAccount, alignment: .center, action: {
|
||||||
interaction.openSettings(.addAccount)
|
interaction.openSettings(.addAccount)
|
||||||
}))
|
}))
|
||||||
|
|
|
||||||
|
|
@ -645,13 +645,13 @@ final class ChatbotSetupScreenComponent: Component {
|
||||||
let navigationTitleSize = self.navigationTitle.update(
|
let navigationTitleSize = self.navigationTitle.update(
|
||||||
transition: transition,
|
transition: transition,
|
||||||
component: AnyComponent(MultilineTextComponent(
|
component: AnyComponent(MultilineTextComponent(
|
||||||
text: .plain(NSAttributedString(string: environment.strings.ChatbotSetup_TitleItem, font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
text: .plain(NSAttributedString(string: environment.strings.ChatbotSetup_TitleItem, font: Font.bold(24.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
||||||
horizontalAlignment: .center
|
horizontalAlignment: .center
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: availableSize.width, height: 100.0)
|
containerSize: CGSize(width: availableSize.width, height: 100.0)
|
||||||
)
|
)
|
||||||
let navigationTitleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - navigationTitleSize.width) / 2.0), y: environment.statusBarHeight + floor((environment.navigationHeight - environment.statusBarHeight - navigationTitleSize.height) / 2.0)), size: navigationTitleSize)
|
let navigationTitleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - navigationTitleSize.width) / 2.0), y: environment.navigationHeight + 76.0), size: navigationTitleSize)
|
||||||
if let navigationTitleView = self.navigationTitle.view {
|
if let navigationTitleView = self.navigationTitle.view {
|
||||||
if navigationTitleView.superview == nil {
|
if navigationTitleView.superview == nil {
|
||||||
if let controller = self.environment?.controller(), let navigationBar = controller.navigationBar {
|
if let controller = self.environment?.controller(), let navigationBar = controller.navigationBar {
|
||||||
|
|
@ -681,7 +681,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: 100.0, height: 100.0)
|
containerSize: CGSize(width: 100.0, height: 100.0)
|
||||||
)
|
)
|
||||||
let iconFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - iconSize.width) * 0.5), y: contentHeight + 8.0), size: iconSize)
|
let iconFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - iconSize.width) * 0.5), y: contentHeight - 30.0), size: iconSize)
|
||||||
if let iconView = self.icon.view as? LottieComponent.View {
|
if let iconView = self.icon.view as? LottieComponent.View {
|
||||||
if iconView.superview == nil {
|
if iconView.superview == nil {
|
||||||
self.scrollView.addSubview(iconView)
|
self.scrollView.addSubview(iconView)
|
||||||
|
|
@ -691,11 +691,11 @@ final class ChatbotSetupScreenComponent: Component {
|
||||||
iconView.bounds = CGRect(origin: CGPoint(), size: iconFrame.size)
|
iconView.bounds = CGRect(origin: CGPoint(), size: iconFrame.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
contentHeight += 129.0
|
contentHeight += 115.0
|
||||||
|
|
||||||
let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.ChatbotSetup_Text, attributes: MarkdownAttributes(
|
let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.ChatbotSetup_Text, attributes: MarkdownAttributes(
|
||||||
body: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.freeTextColor),
|
body: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemPrimaryTextColor),
|
||||||
bold: MarkdownAttributeSet(font: Font.semibold(15.0), textColor: environment.theme.list.freeTextColor),
|
bold: MarkdownAttributeSet(font: Font.semibold(15.0), textColor: environment.theme.list.itemPrimaryTextColor),
|
||||||
link: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemAccentColor),
|
link: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemAccentColor),
|
||||||
linkAttribute: { attributes in
|
linkAttribute: { attributes in
|
||||||
return ("URL", "")
|
return ("URL", "")
|
||||||
|
|
@ -732,7 +732,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 1000.0)
|
containerSize: CGSize(width: availableSize.width - sideInset * 2.0 - 64.0, height: 1000.0)
|
||||||
)
|
)
|
||||||
let subtitleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - subtitleSize.width) * 0.5), y: contentHeight), size: subtitleSize)
|
let subtitleFrame = CGRect(origin: CGPoint(x: floor((availableSize.width - subtitleSize.width) * 0.5), y: contentHeight), size: subtitleSize)
|
||||||
if let subtitleView = self.subtitle.view {
|
if let subtitleView = self.subtitle.view {
|
||||||
|
|
|
||||||
12
submodules/TelegramUI/Images.xcassets/Item List/Icons/Cake.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Item List/Icons/Cake.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "birthday.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
submodules/TelegramUI/Images.xcassets/Item List/Icons/Cake.imageset/birthday.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Item List/Icons/Cake.imageset/birthday.pdf
vendored
Normal file
Binary file not shown.
|
|
@ -14,6 +14,8 @@ extension ChatControllerImpl {
|
||||||
guard let peer = self.presentationInterfaceState.renderedPeer?.peer else {
|
guard let peer = self.presentationInterfaceState.renderedPeer?.peer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let hasSilentPosting = peer.id != self.context.account.peerId
|
||||||
|
let hasSchedule = self.presentationInterfaceState.subject != .scheduledMessages && peer.id.namespace != Namespaces.Peer.SecretChat && self.presentationInterfaceState.sendPaidMessageStars == nil
|
||||||
legacyMediaEditor(
|
legacyMediaEditor(
|
||||||
context: self.context,
|
context: self.context,
|
||||||
peer: peer,
|
peer: peer,
|
||||||
|
|
@ -27,7 +29,24 @@ extension ChatControllerImpl {
|
||||||
getCaptionPanelView: { [weak self] in
|
getCaptionPanelView: { [weak self] in
|
||||||
return self?.getCaptionPanelView(isFile: false, hasTimer: false)
|
return self?.getCaptionPanelView(isFile: false, hasTimer: false)
|
||||||
},
|
},
|
||||||
sendMessagesWithSignals: { [weak self] signals, _, _, isCaptionAbove in
|
hasSilentPosting: hasSilentPosting,
|
||||||
|
hasSchedule: hasSchedule,
|
||||||
|
reminder: peer.id == self.context.account.peerId,
|
||||||
|
presentSchedulePicker: { [weak self] _, done in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.presentScheduleTimePicker(style: .media, completion: { [weak self] time, _ in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
done(time)
|
||||||
|
if self.presentationInterfaceState.subject != .scheduledMessages && time != scheduleWhenOnlineTimestamp {
|
||||||
|
self.openScheduledMessages()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
sendMessagesWithSignals: { [weak self] signals, silentPosting, scheduleTime, isCaptionAbove in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -39,8 +58,8 @@ extension ChatControllerImpl {
|
||||||
fromGallery: false,
|
fromGallery: false,
|
||||||
signals: signals,
|
signals: signals,
|
||||||
originalMediaReference: file.abstract,
|
originalMediaReference: file.abstract,
|
||||||
silentPosting: false,
|
silentPosting: silentPosting,
|
||||||
scheduleTime: nil,
|
scheduleTime: scheduleTime == 0 ? nil : scheduleTime,
|
||||||
replyToSubject: nil,
|
replyToSubject: nil,
|
||||||
parameters: parameters,
|
parameters: parameters,
|
||||||
getAnimatedTransitionSource: nil,
|
getAnimatedTransitionSource: nil,
|
||||||
|
|
@ -48,7 +67,8 @@ extension ChatControllerImpl {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
present: { [weak self] c, a in
|
present: { [weak self] c, a in
|
||||||
self?.present(c, in: .window(.root), with: a)
|
c.navigationPresentation = .flatModal
|
||||||
|
self?.push(c)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ extension ChatControllerImpl {
|
||||||
if strongSelf.presentationInterfaceState.interfaceState.postSuggestionState != nil {
|
if strongSelf.presentationInterfaceState.interfaceState.postSuggestionState != nil {
|
||||||
enableMultiselection = false
|
enableMultiselection = false
|
||||||
}
|
}
|
||||||
|
let inputText = strongSelf.presentationInterfaceState.interfaceState.effectiveInputState.inputText
|
||||||
|
|
||||||
strongSelf.chatDisplayNode.dismissInput()
|
strongSelf.chatDisplayNode.dismissInput()
|
||||||
let controller = mediaPasteboardScreen(
|
let controller = mediaPasteboardScreen(
|
||||||
|
|
@ -32,7 +33,15 @@ extension ChatControllerImpl {
|
||||||
subjects: subjects,
|
subjects: subjects,
|
||||||
presentMediaPicker: { [weak self] subject, saveEditedPhotos, bannedSendPhotos, bannedSendVideos, present in
|
presentMediaPicker: { [weak self] subject, saveEditedPhotos, bannedSendPhotos, bannedSendVideos, present in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.presentMediaPicker(subject: subject, saveEditedPhotos: saveEditedPhotos, bannedSendPhotos: bannedSendPhotos, bannedSendVideos: bannedSendVideos, enableMultiselection: enableMultiselection, present: present, updateMediaPickerContext: { _ in }, completion: { [weak self] fromGallery, signals, silentPosting, scheduleTime, parameters, getAnimatedTransitionSource, completion in
|
strongSelf.presentMediaPicker(subject: subject, saveEditedPhotos: saveEditedPhotos, bannedSendPhotos: bannedSendPhotos, bannedSendVideos: bannedSendVideos, enableMultiselection: enableMultiselection, present: { controller, mediaPickerContext in
|
||||||
|
if !inputText.string.isEmpty {
|
||||||
|
mediaPickerContext?.setCaption(inputText)
|
||||||
|
}
|
||||||
|
present(controller, mediaPickerContext)
|
||||||
|
}, updateMediaPickerContext: { _ in }, completion: { [weak self] fromGallery, signals, silentPosting, scheduleTime, parameters, getAnimatedTransitionSource, completion in
|
||||||
|
if !inputText.string.isEmpty {
|
||||||
|
self?.clearInputText()
|
||||||
|
}
|
||||||
self?.enqueueMediaMessages(fromGallery: fromGallery, signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime, parameters: parameters, getAnimatedTransitionSource: getAnimatedTransitionSource, completion: completion)
|
self?.enqueueMediaMessages(fromGallery: fromGallery, signals: signals, silentPosting: silentPosting, scheduleTime: scheduleTime, parameters: parameters, getAnimatedTransitionSource: getAnimatedTransitionSource, completion: completion)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -602,7 +602,7 @@ extension ChatControllerImpl {
|
||||||
notificationSettings: nil,
|
notificationSettings: nil,
|
||||||
peerPresences: [:],
|
peerPresences: [:],
|
||||||
cachedData: nil
|
cachedData: nil
|
||||||
), customTitle: nil, customSubtitle: strings.Chat_Monoforum_Subtitle, onlineMemberCount: (nil, nil), isScheduledMessages: false, isMuted: nil, customMessageCount: nil, isEnabled: true)
|
), customTitle: nil, customSubtitle: strings.Chat_Monoforum_Subtitle, onlineMemberCount: (nil, nil), isScheduledMessages: false, isMuted: nil, customMessageCount: nil, hidePeerStatus: false, isEnabled: true)
|
||||||
} else {
|
} else {
|
||||||
strongSelf.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(channel.debugDisplayTitle))], subtitle: nil, isEnabled: true)
|
strongSelf.state.chatTitleContent = .custom(title: [ChatTitleContent.TitleTextItem(id: AnyHashable(0), content: .text(channel.debugDisplayTitle))], subtitle: nil, isEnabled: true)
|
||||||
}
|
}
|
||||||
|
|
@ -613,7 +613,7 @@ extension ChatControllerImpl {
|
||||||
customSubtitle = "Tap to view as chats"
|
customSubtitle = "Tap to view as chats"
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.state.chatTitleContent = .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: nil, customSubtitle: customSubtitle, onlineMemberCount: onlineMemberCount, isScheduledMessages: isScheduledMessages, isMuted: nil, customMessageCount: nil, isEnabled: hasPeerInfo)
|
strongSelf.state.chatTitleContent = .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: nil, customSubtitle: customSubtitle, onlineMemberCount: onlineMemberCount, isScheduledMessages: isScheduledMessages, isMuted: nil, customMessageCount: nil, hidePeerStatus: false, isEnabled: hasPeerInfo)
|
||||||
|
|
||||||
let imageOverride: AvatarNodeImageOverride?
|
let imageOverride: AvatarNodeImageOverride?
|
||||||
if context.account.peerId == peer.id {
|
if context.account.peerId == peer.id {
|
||||||
|
|
@ -1519,7 +1519,7 @@ extension ChatControllerImpl {
|
||||||
customMessageCount = savedMessagesPeer?.messageCount ?? 0
|
customMessageCount = savedMessagesPeer?.messageCount ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.state.chatTitleContent = .peer(peerView: mappedPeerData, customTitle: nil, customSubtitle: customSubtitle, onlineMemberCount: (nil, nil), isScheduledMessages: false, isMuted: false, customMessageCount: customMessageCount, isEnabled: true)
|
strongSelf.state.chatTitleContent = .peer(peerView: mappedPeerData, customTitle: nil, customSubtitle: customSubtitle, onlineMemberCount: (nil, nil), isScheduledMessages: false, isMuted: false, customMessageCount: customMessageCount, hidePeerStatus: false, isEnabled: true)
|
||||||
|
|
||||||
strongSelf.state.peerView = peerView
|
strongSelf.state.peerView = peerView
|
||||||
|
|
||||||
|
|
@ -1613,7 +1613,7 @@ extension ChatControllerImpl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.state.chatTitleContent = .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: threadInfo.title, customSubtitle: customSubtitle, onlineMemberCount: onlineMemberCount, isScheduledMessages: false, isMuted: peerIsMuted, customMessageCount: messageAndTopic.messageCount == 0 ? nil : messageAndTopic.messageCount, isEnabled: true)
|
strongSelf.state.chatTitleContent = .peer(peerView: ChatTitleContent.PeerData(peerView: peerView), customTitle: threadInfo.title, customSubtitle: customSubtitle, onlineMemberCount: onlineMemberCount, isScheduledMessages: false, isMuted: peerIsMuted, customMessageCount: messageAndTopic.messageCount == 0 ? nil : messageAndTopic.messageCount, hidePeerStatus: true, isEnabled: true)
|
||||||
|
|
||||||
let avatarContent: EmojiStatusComponent.Content
|
let avatarContent: EmojiStatusComponent.Content
|
||||||
if chatLocation.threadId == 1 {
|
if chatLocation.threadId == 1 {
|
||||||
|
|
|
||||||
|
|
@ -1763,7 +1763,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||||
if inputTextPanelNode.isFocused {
|
if inputTextPanelNode.isFocused {
|
||||||
self.context.sharedContext.mainWindow?.simulateKeyboardDismiss(transition: .animated(duration: 0.5, curve: .spring))
|
self.context.sharedContext.mainWindow?.simulateKeyboardDismiss(transition: .animated(duration: 0.5, curve: .spring))
|
||||||
}
|
}
|
||||||
let _ = inputTextPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: inputPanelBottomInset, additionalSideInsets: layout.additionalInsets, maxHeight: layout.size.height - insets.top - inputPanelBottomInset, maxOverlayHeight: layout.size.height - insets.top - inputPanelBottomInset, isSecondary: false, transition: transition, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics, isMediaInputExpanded: self.inputPanelContainerNode.expansionFraction == 1.0)
|
let _ = inputTextPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: inputPanelBottomInset, additionalSideInsets: layout.additionalInsets, maxHeight: layout.size.height - insets.top - inputPanelBottomInset, maxOverlayHeight: layout.size.height - insets.top - inputPanelBottomInset, isSecondary: false, transition: transition, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, isMediaInputExpanded: self.inputPanelContainerNode.expansionFraction == 1.0)
|
||||||
}
|
}
|
||||||
if let prevInputPanelNode = self.inputPanelNode, inputPanelNode.canHandleTransition(from: prevInputPanelNode) {
|
if let prevInputPanelNode = self.inputPanelNode, inputPanelNode.canHandleTransition(from: prevInputPanelNode) {
|
||||||
inputPanelNodeHandlesTransition = true
|
inputPanelNodeHandlesTransition = true
|
||||||
|
|
@ -1775,7 +1775,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||||
} else {
|
} else {
|
||||||
dismissedInputPanelNode = self.inputPanelNode
|
dismissedInputPanelNode = self.inputPanelNode
|
||||||
}
|
}
|
||||||
let inputPanelHeight = inputPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: inputPanelBottomInset, additionalSideInsets: layout.additionalInsets, maxHeight: layout.size.height - insets.top - inputPanelBottomInset, maxOverlayHeight: layout.size.height - insets.top - inputPanelBottomInset, isSecondary: false, transition: inputPanelNode.supernode !== self ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics, isMediaInputExpanded: self.inputPanelContainerNode.expansionFraction == 1.0)
|
let inputPanelHeight = inputPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: inputPanelBottomInset, additionalSideInsets: layout.additionalInsets, maxHeight: layout.size.height - insets.top - inputPanelBottomInset, maxOverlayHeight: layout.size.height - insets.top - inputPanelBottomInset, isSecondary: false, transition: inputPanelNode.supernode !== self ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, isMediaInputExpanded: self.inputPanelContainerNode.expansionFraction == 1.0)
|
||||||
inputPanelSize = CGSize(width: layout.size.width, height: inputPanelHeight)
|
inputPanelSize = CGSize(width: layout.size.width, height: inputPanelHeight)
|
||||||
self.inputPanelNode = inputPanelNode
|
self.inputPanelNode = inputPanelNode
|
||||||
if inputPanelNode.supernode !== self {
|
if inputPanelNode.supernode !== self {
|
||||||
|
|
@ -1786,7 +1786,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||||
self.inputPanelOverlayNode.view.addSubview(viewForOverlayContent)
|
self.inputPanelOverlayNode.view.addSubview(viewForOverlayContent)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let inputPanelHeight = inputPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: inputPanelBottomInset, additionalSideInsets: layout.additionalInsets, maxHeight: layout.size.height - insets.top - inputPanelBottomInset - 120.0, maxOverlayHeight: layout.size.height - insets.top - inputPanelBottomInset, isSecondary: false, transition: transition, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics, isMediaInputExpanded: self.inputPanelContainerNode.expansionFraction == 1.0)
|
let inputPanelHeight = inputPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: inputPanelBottomInset, additionalSideInsets: layout.additionalInsets, maxHeight: layout.size.height - insets.top - inputPanelBottomInset - 120.0, maxOverlayHeight: layout.size.height - insets.top - inputPanelBottomInset, isSecondary: false, transition: transition, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, isMediaInputExpanded: self.inputPanelContainerNode.expansionFraction == 1.0)
|
||||||
inputPanelSize = CGSize(width: layout.size.width, height: inputPanelHeight)
|
inputPanelSize = CGSize(width: layout.size.width, height: inputPanelHeight)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1797,7 +1797,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||||
if let secondaryInputPanelNode = inputPanelNodes.secondary, !previewing {
|
if let secondaryInputPanelNode = inputPanelNodes.secondary, !previewing {
|
||||||
if secondaryInputPanelNode !== self.secondaryInputPanelNode {
|
if secondaryInputPanelNode !== self.secondaryInputPanelNode {
|
||||||
dismissedSecondaryInputPanelNode = self.secondaryInputPanelNode
|
dismissedSecondaryInputPanelNode = self.secondaryInputPanelNode
|
||||||
let inputPanelHeight = secondaryInputPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: inputPanelBottomInset, additionalSideInsets: layout.additionalInsets, maxHeight: layout.size.height - insets.top - inputPanelBottomInset, maxOverlayHeight: layout.size.height - insets.top - inputPanelBottomInset, isSecondary: true, transition: .immediate, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics, isMediaInputExpanded: self.inputPanelContainerNode.expansionFraction == 1.0)
|
let inputPanelHeight = secondaryInputPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: inputPanelBottomInset, additionalSideInsets: layout.additionalInsets, maxHeight: layout.size.height - insets.top - inputPanelBottomInset, maxOverlayHeight: layout.size.height - insets.top - inputPanelBottomInset, isSecondary: true, transition: .immediate, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, isMediaInputExpanded: self.inputPanelContainerNode.expansionFraction == 1.0)
|
||||||
secondaryInputPanelSize = CGSize(width: layout.size.width, height: inputPanelHeight)
|
secondaryInputPanelSize = CGSize(width: layout.size.width, height: inputPanelHeight)
|
||||||
self.secondaryInputPanelNode = secondaryInputPanelNode
|
self.secondaryInputPanelNode = secondaryInputPanelNode
|
||||||
if secondaryInputPanelNode.supernode == nil {
|
if secondaryInputPanelNode.supernode == nil {
|
||||||
|
|
@ -1808,7 +1808,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||||
self.inputPanelOverlayNode.view.addSubview(viewForOverlayContent)
|
self.inputPanelOverlayNode.view.addSubview(viewForOverlayContent)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let inputPanelHeight = secondaryInputPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: inputPanelBottomInset, additionalSideInsets: layout.additionalInsets, maxHeight: layout.size.height - insets.top - inputPanelBottomInset, maxOverlayHeight: layout.size.height - insets.top - inputPanelBottomInset, isSecondary: true, transition: transition, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics, isMediaInputExpanded: self.inputPanelContainerNode.expansionFraction == 1.0)
|
let inputPanelHeight = secondaryInputPanelNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: inputPanelBottomInset, additionalSideInsets: layout.additionalInsets, maxHeight: layout.size.height - insets.top - inputPanelBottomInset, maxOverlayHeight: layout.size.height - insets.top - inputPanelBottomInset, isSecondary: true, transition: transition, interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, isMediaInputExpanded: self.inputPanelContainerNode.expansionFraction == 1.0)
|
||||||
secondaryInputPanelSize = CGSize(width: layout.size.width, height: inputPanelHeight)
|
secondaryInputPanelSize = CGSize(width: layout.size.width, height: inputPanelHeight)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -3362,6 +3362,11 @@ public final class ChatHistoryListNodeImpl: ListViewImpl, ChatHistoryNode, ChatH
|
||||||
if self.chatHistoryLocationValue?.content != locationInput {
|
if self.chatHistoryLocationValue?.content != locationInput {
|
||||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: locationInput, id: self.takeNextHistoryLocationId())
|
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: locationInput, id: self.takeNextHistoryLocationId())
|
||||||
}
|
}
|
||||||
|
} else if historyView.originalView.holeEarlier, case let .custom(_, _, _, _, _, loadMore) = self.source, let loadMore {
|
||||||
|
if self.chatHistoryLocationValue?.content != locationInput {
|
||||||
|
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: locationInput, id: self.takeNextHistoryLocationId())
|
||||||
|
loadMore()
|
||||||
|
}
|
||||||
} else if case let .customChatContents(customChatContents) = self.subject, case .hashTagSearch = customChatContents.kind {
|
} else if case let .customChatContents(customChatContents) = self.subject, case .hashTagSearch = customChatContents.kind {
|
||||||
if self.chatHistoryLocationValue?.content != locationInput {
|
if self.chatHistoryLocationValue?.content != locationInput {
|
||||||
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: locationInput, id: self.takeNextHistoryLocationId())
|
self.chatHistoryLocationValue = ChatHistoryLocationInput(content: locationInput, id: self.takeNextHistoryLocationId())
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ final class ChatMessageReportInputPanelNode: ChatInputPanelNode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
if self.presentationInterfaceState != interfaceState {
|
if self.presentationInterfaceState != interfaceState {
|
||||||
self.presentationInterfaceState = interfaceState
|
self.presentationInterfaceState = interfaceState
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,10 @@ final class ChatPremiumRequiredInputPanelNode: ChatInputPanelNode {
|
||||||
var isSecondary: Bool
|
var isSecondary: Bool
|
||||||
var interfaceState: ChatPresentationInterfaceState
|
var interfaceState: ChatPresentationInterfaceState
|
||||||
var metrics: LayoutMetrics
|
var metrics: LayoutMetrics
|
||||||
|
var deviceMetrics: DeviceMetrics
|
||||||
var isMediaInputExpanded: Bool
|
var isMediaInputExpanded: Bool
|
||||||
|
|
||||||
init(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) {
|
init(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) {
|
||||||
self.width = width
|
self.width = width
|
||||||
self.leftInset = leftInset
|
self.leftInset = leftInset
|
||||||
self.rightInset = rightInset
|
self.rightInset = rightInset
|
||||||
|
|
@ -43,6 +44,7 @@ final class ChatPremiumRequiredInputPanelNode: ChatInputPanelNode {
|
||||||
self.isSecondary = isSecondary
|
self.isSecondary = isSecondary
|
||||||
self.interfaceState = interfaceState
|
self.interfaceState = interfaceState
|
||||||
self.metrics = metrics
|
self.metrics = metrics
|
||||||
|
self.deviceMetrics = deviceMetrics
|
||||||
self.isMediaInputExpanded = isMediaInputExpanded
|
self.isMediaInputExpanded = isMediaInputExpanded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -74,8 +76,8 @@ final class ChatPremiumRequiredInputPanelNode: ChatInputPanelNode {
|
||||||
deinit {
|
deinit {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
let params = Params(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, interfaceState: interfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded)
|
let params = Params(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, interfaceState: interfaceState, metrics: metrics, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||||
if let currentLayout = self.currentLayout, currentLayout.params == params {
|
if let currentLayout = self.currentLayout, currentLayout.params == params {
|
||||||
return currentLayout.height
|
return currentLayout.height
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
|
||||||
self.interfaceInteraction?.openBoostToUnrestrict()
|
self.interfaceInteraction?.openBoostToUnrestrict()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
if self.presentationInterfaceState != interfaceState {
|
if self.presentationInterfaceState != interfaceState {
|
||||||
self.presentationInterfaceState = interfaceState
|
self.presentationInterfaceState = interfaceState
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,10 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode {
|
||||||
var isSecondary: Bool
|
var isSecondary: Bool
|
||||||
var interfaceState: ChatPresentationInterfaceState
|
var interfaceState: ChatPresentationInterfaceState
|
||||||
var metrics: LayoutMetrics
|
var metrics: LayoutMetrics
|
||||||
|
var deviceMetrics: DeviceMetrics
|
||||||
var isMediaInputExpanded: Bool
|
var isMediaInputExpanded: Bool
|
||||||
|
|
||||||
init(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) {
|
init(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) {
|
||||||
self.width = width
|
self.width = width
|
||||||
self.leftInset = leftInset
|
self.leftInset = leftInset
|
||||||
self.rightInset = rightInset
|
self.rightInset = rightInset
|
||||||
|
|
@ -45,6 +46,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode {
|
||||||
self.isSecondary = isSecondary
|
self.isSecondary = isSecondary
|
||||||
self.interfaceState = interfaceState
|
self.interfaceState = interfaceState
|
||||||
self.metrics = metrics
|
self.metrics = metrics
|
||||||
|
self.deviceMetrics = deviceMetrics
|
||||||
self.isMediaInputExpanded = isMediaInputExpanded
|
self.isMediaInputExpanded = isMediaInputExpanded
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -110,16 +112,15 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode {
|
||||||
self.totalMessageCountDisposable?.dispose()
|
self.totalMessageCountDisposable?.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
var leftInset = leftInset + 8.0
|
var leftInset = leftInset + 8.0
|
||||||
var rightInset = rightInset + 8.0
|
var rightInset = rightInset + 8.0
|
||||||
|
|
||||||
if bottomInset <= 32.0 {
|
let compactBottomSideInset = self.compactBottomSideInset(bottomInset: bottomInset, deviceMetrics: deviceMetrics)
|
||||||
leftInset += 18.0
|
leftInset += compactBottomSideInset
|
||||||
rightInset += 18.0
|
rightInset += compactBottomSideInset
|
||||||
}
|
|
||||||
|
|
||||||
let params = Params(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, interfaceState: interfaceState, metrics: metrics, isMediaInputExpanded: isMediaInputExpanded)
|
let params = Params(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, additionalSideInsets: additionalSideInsets, maxHeight: maxHeight, maxOverlayHeight: maxOverlayHeight, isSecondary: isSecondary, interfaceState: interfaceState, metrics: metrics, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||||
if let currentLayout = self.currentLayout, currentLayout.params == params {
|
if let currentLayout = self.currentLayout, currentLayout.params == params {
|
||||||
return currentLayout.height
|
return currentLayout.height
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ final class ChatUnblockInputPanelNode: ChatInputPanelNode {
|
||||||
self.interfaceInteraction?.unblockPeer()
|
self.interfaceInteraction?.unblockPeer()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
if self.presentationInterfaceState != interfaceState {
|
if self.presentationInterfaceState != interfaceState {
|
||||||
self.presentationInterfaceState = interfaceState
|
self.presentationInterfaceState = interfaceState
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ final class DeleteChatInputPanelNode: ChatInputPanelNode {
|
||||||
self.interfaceInteraction?.deleteChat()
|
self.interfaceInteraction?.deleteChat()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
if self.presentationInterfaceState != interfaceState {
|
if self.presentationInterfaceState != interfaceState {
|
||||||
self.presentationInterfaceState = interfaceState
|
self.presentationInterfaceState = interfaceState
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -840,7 +840,9 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
|
||||||
containerTransform = CATransform3DScale(containerTransform, scale, scale, scale)
|
containerTransform = CATransform3DScale(containerTransform, scale, scale, scale)
|
||||||
|
|
||||||
transition.updateTransform(layer: self.containerContainingNode.layer, transform: containerTransform)
|
transition.updateTransform(layer: self.containerContainingNode.layer, transform: containerTransform)
|
||||||
transition.updateCornerRadius(node: self.containerContainingNode, cornerRadius: layout.deviceMetrics.screenCornerRadius)
|
|
||||||
|
let containerCornerRadius = max(22.0, layout.deviceMetrics.screenCornerRadius)
|
||||||
|
transition.updateCornerRadius(node: self.containerContainingNode, cornerRadius: containerCornerRadius)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var effectiveHeaderHeight: CGFloat {
|
private var effectiveHeaderHeight: CGFloat {
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ final class SecretChatHandshakeStatusInputPanelNode: ChatInputPanelNode {
|
||||||
self.interfaceInteraction?.unblockPeer()
|
self.interfaceInteraction?.unblockPeer()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||||
self.presentationInterfaceState = interfaceState
|
self.presentationInterfaceState = interfaceState
|
||||||
|
|
||||||
var text: String?
|
var text: String?
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,15 @@ import UndoUI
|
||||||
import BrowserUI
|
import BrowserUI
|
||||||
|
|
||||||
func handleTextLinkActionImpl(context: AccountContext, peerId: EnginePeer.Id?, navigateDisposable: MetaDisposable, controller: ViewController, action: TextLinkItemActionType, itemLink: TextLinkItem) {
|
func handleTextLinkActionImpl(context: AccountContext, peerId: EnginePeer.Id?, navigateDisposable: MetaDisposable, controller: ViewController, action: TextLinkItemActionType, itemLink: TextLinkItem) {
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with({ $0 })
|
||||||
|
|
||||||
let presentImpl: (ViewController, Any?) -> Void = { controllerToPresent, _ in
|
let presentImpl: (ViewController, Any?) -> Void = { controllerToPresent, _ in
|
||||||
controller.present(controllerToPresent, in: .window(.root))
|
controller.present(controllerToPresent, in: .window(.root))
|
||||||
}
|
}
|
||||||
|
|
||||||
let openResolvedPeerImpl: (EnginePeer?, ChatControllerInteractionNavigateToPeer) -> Void = { [weak controller] peer, navigation in
|
let openResolvedPeerImpl: (EnginePeer?, ChatControllerInteractionNavigateToPeer) -> Void = { [weak controller] peer, navigation in
|
||||||
guard let peer = peer else {
|
guard let peer else {
|
||||||
|
controller?.present(textAlertController(context: context, updatedPresentationData: nil, title: nil, text: presentationData.strings.Resolve_ErrorNotFound, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
context.sharedContext.openResolvedUrl(.peer(peer._asPeer(), navigation), context: context, urlContext: .generic, navigationController: (controller?.navigationController as? NavigationController), forceExternal: false, forceUpdate: false, openPeer: { (peer, navigation) in
|
context.sharedContext.openResolvedUrl(.peer(peer._asPeer(), navigation), context: context, urlContext: .generic, navigationController: (controller?.navigationController as? NavigationController), forceExternal: false, forceUpdate: false, openPeer: { (peer, navigation) in
|
||||||
|
|
@ -73,7 +76,7 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: EnginePeer.Id?, n
|
||||||
if let controller = controller {
|
if let controller = controller {
|
||||||
switch result {
|
switch result {
|
||||||
case let .externalUrl(url):
|
case let .externalUrl(url):
|
||||||
context.sharedContext.openExternalUrl(context: context, urlContext: .generic, url: url, forceExternal: false, presentationData: context.sharedContext.currentPresentationData.with({ $0 }), navigationController: controller.navigationController as? NavigationController, dismissInput: {
|
context.sharedContext.openExternalUrl(context: context, urlContext: .generic, url: url, forceExternal: false, presentationData: presentationData, navigationController: controller.navigationController as? NavigationController, dismissInput: {
|
||||||
})
|
})
|
||||||
case let .peer(peer, navigation):
|
case let .peer(peer, navigation):
|
||||||
openResolvedPeerImpl(peer.flatMap(EnginePeer.init), navigation)
|
openResolvedPeerImpl(peer.flatMap(EnginePeer.init), navigation)
|
||||||
|
|
@ -100,7 +103,7 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: EnginePeer.Id?, n
|
||||||
let sourceLocation = InstantPageSourceLocation(userLocation: peerId.flatMap(MediaResourceUserLocation.peer) ?? .other, peerType: .group)
|
let sourceLocation = InstantPageSourceLocation(userLocation: peerId.flatMap(MediaResourceUserLocation.peer) ?? .other, peerType: .group)
|
||||||
let browserController = context.sharedContext.makeInstantPageController(context: context, webPage: webPage, anchor: anchor, sourceLocation: sourceLocation)
|
let browserController = context.sharedContext.makeInstantPageController(context: context, webPage: webPage, anchor: anchor, sourceLocation: sourceLocation)
|
||||||
(controller.navigationController as? NavigationController)?.pushViewController(browserController, animated: true)
|
(controller.navigationController as? NavigationController)?.pushViewController(browserController, animated: true)
|
||||||
case .boost, .chatFolder, .join, .invoice:
|
case .boost, .chatFolder, .join, .invoice, .proxy:
|
||||||
if let navigationController = controller.navigationController as? NavigationController {
|
if let navigationController = controller.navigationController as? NavigationController {
|
||||||
openResolvedUrlImpl(result, context: context, urlContext: peerId.flatMap { .chat(peerId: $0, message: nil, updatedPresentationData: nil) } ?? .generic, navigationController: navigationController, forceExternal: false, forceUpdate: false, openPeer: { peer, navigateToPeer in
|
openResolvedUrlImpl(result, context: context, urlContext: peerId.flatMap { .chat(peerId: $0, message: nil, updatedPresentationData: nil) } ?? .generic, navigationController: navigationController, forceExternal: false, forceUpdate: false, openPeer: { peer, navigateToPeer in
|
||||||
openResolvedPeerImpl(peer, navigateToPeer)
|
openResolvedPeerImpl(peer, navigateToPeer)
|
||||||
|
|
@ -128,7 +131,6 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: EnginePeer.Id?, n
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
||||||
switch action {
|
switch action {
|
||||||
case .tap:
|
case .tap:
|
||||||
switch itemLink {
|
switch itemLink {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue