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 ";
|
||||
|
||||
"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 {
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -1174,7 +1174,8 @@ public class AttachmentController: ViewController, MinimizableController {
|
|||
localGlassView.contentView.addSubview(buttonIcon)
|
||||
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.animateTransformScale(view: containerView, from: sourceButtonScale)
|
||||
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 {
|
||||
let containerView = ClipContainerView()
|
||||
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)
|
||||
|
||||
let localGlassView = GlassBackgroundView()
|
||||
|
|
|
|||
|
|
@ -7287,7 +7287,7 @@ private final class ChatListLocationContext {
|
|||
dateTimeFormat: presentationData.dateTimeFormat,
|
||||
nameDisplayOrder: presentationData.nameDisplayOrder,
|
||||
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,
|
||||
networkState: nil,
|
||||
tapped: { [weak self] in
|
||||
|
|
|
|||
|
|
@ -1986,6 +1986,9 @@ final class ChatListControllerNode: ASDisplayNode, ASGestureRecognizerDelegate {
|
|||
contentNode.dismissSearch = { [weak self] in
|
||||
self?.dismissSearch?()
|
||||
}
|
||||
contentNode.dismissSearchImmediately = { [weak self] in
|
||||
self?.controller?.deactivateSearch(animated: false)
|
||||
}
|
||||
contentNode.openAdInfo = { [weak self] node, adPeer in
|
||||
self?.controller?.openAdInfo(node: node, adPeer: adPeer)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
|||
private let navigationController: NavigationController?
|
||||
|
||||
var dismissSearch: (() -> Void)?
|
||||
var dismissSearchImmediately: (() -> Void)?
|
||||
var openAdInfo: ((ASDisplayNode, AdPeer) -> Void)?
|
||||
|
||||
private let edgeEffectView: EdgeEffectView
|
||||
|
|
@ -1657,7 +1658,7 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
|||
if let strongSelf = self {
|
||||
let proceed: (ChatController) -> Void = { chatController in
|
||||
chatController.purposefulAction = { [weak self] in
|
||||
self?.cancel?()
|
||||
self?.dismissSearchImmediately?()
|
||||
}
|
||||
if let navigationController = strongSelf.navigationController {
|
||||
var viewControllers = navigationController.viewControllers
|
||||
|
|
|
|||
|
|
@ -792,9 +792,10 @@ public final class ResizableSheetComponent<ChildEnvironmentType: Sendable & Equa
|
|||
let scrollContentHeight = max(topInset + contentHeight + containerInset, availableSize.height - containerInset)
|
||||
|
||||
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.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 {
|
||||
glassInset = 6.0
|
||||
}
|
||||
bottomCornerRadius = sheetEnvironment.deviceMetrics.screenCornerRadius - glassInset
|
||||
let containerCornerRadius = max(24.0, sheetEnvironment.deviceMetrics.screenCornerRadius)
|
||||
bottomCornerRadius = containerCornerRadius - 2.0
|
||||
case .legacy:
|
||||
topCornerRadius = 12.0
|
||||
bottomCornerRadius = 12.0
|
||||
|
|
|
|||
|
|
@ -7,12 +7,20 @@
|
|||
#import <LegacyComponents/TGMediaEditingContext.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
|
||||
|
||||
+ (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
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#import <LegacyComponents/TGMediaPickerGalleryModel.h>
|
||||
#import <LegacyComponents/TGMediaPickerGalleryPhotoItem.h>
|
||||
#import <LegacyComponents/TGMediaPickerSendActionSheetController.h>
|
||||
#import <LegacyComponents/TGMediaPickerGalleryVideoItem.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];
|
||||
[editingContext setForcedCaption:caption];
|
||||
|
||||
TGModernGalleryController *galleryController = [[TGModernGalleryController alloc] initWithContext:windowContext];
|
||||
TGModernGalleryController *galleryController = [[TGModernGalleryController alloc] initWithContext:context];
|
||||
galleryController.adjustsStatusBarVisibility = true;
|
||||
galleryController.animateTransition = !immediate;
|
||||
galleryController.finishedTransitionIn = ^(id<TGModernGalleryItem> item, TGModernGalleryItemView *itemView) {
|
||||
appeared();
|
||||
};
|
||||
//galleryController.hasFadeOutTransition = true;
|
||||
galleryController.customDismissBlock = customDismiss;
|
||||
|
||||
id<TGModernGalleryEditableItem> galleryItem = nil;
|
||||
if (item.isVideo) {
|
||||
|
|
@ -181,7 +179,7 @@
|
|||
galleryItem.editingContext = editingContext;
|
||||
galleryItem.stickersContext = stickersContext;
|
||||
|
||||
TGMediaPickerGalleryModel *model = [[TGMediaPickerGalleryModel alloc] initWithContext:windowContext items:@[galleryItem] focusItem:galleryItem selectionContext:nil editingContext:editingContext hasCaptions:true allowCaptionEntities:true hasTimer:false onlyCrop:false inhibitDocumentCaptions:false hasSelectionPanel:false hasCamera:false recipientName:recipientName 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.stickersContext = stickersContext;
|
||||
|
||||
|
|
@ -213,6 +211,7 @@
|
|||
galleryController.model = model;
|
||||
|
||||
__weak TGModernGalleryController *weakGalleryController = galleryController;
|
||||
__weak TGMediaPickerGalleryModel *weakModel = model;
|
||||
|
||||
[model.interfaceView updateSelectionInterface:1 counterVisible:false animated:false];
|
||||
model.interfaceView.thumbnailSignalForItem = ^SSignal *(id item)
|
||||
|
|
@ -233,10 +232,62 @@
|
|||
}
|
||||
|
||||
if (completion != nil)
|
||||
completion(item.asset, editingContext);
|
||||
completion(item.asset, editingContext, false, 0);
|
||||
|
||||
[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)
|
||||
{
|
||||
|
|
@ -247,21 +298,12 @@
|
|||
{
|
||||
return nil;
|
||||
};
|
||||
|
||||
galleryController.completedTransitionOut = ^
|
||||
{
|
||||
TGModernGalleryController *strongGalleryController = weakGalleryController;
|
||||
if (strongGalleryController != nil && strongGalleryController.overlayWindow == nil)
|
||||
if (completedDismiss != nil) {
|
||||
galleryController.completedTransitionOut = ^
|
||||
{
|
||||
TGNavigationController *navigationController = (TGNavigationController *)strongGalleryController.navigationController;
|
||||
TGOverlayControllerWindow *window = (TGOverlayControllerWindow *)navigationController.view.window;
|
||||
if ([window isKindOfClass:[TGOverlayControllerWindow class]])
|
||||
[window dismiss];
|
||||
}
|
||||
if (dismissed) {
|
||||
dismissed();
|
||||
}
|
||||
};
|
||||
completedDismiss();
|
||||
};
|
||||
}
|
||||
|
||||
if (paint || adjustments) {
|
||||
[model.interfaceView immediateEditorTransitionIn];
|
||||
|
|
@ -271,8 +313,6 @@
|
|||
[galleryController.view addSubview:view];
|
||||
}
|
||||
|
||||
TGOverlayControllerWindow *controllerWindow = [[TGOverlayControllerWindow alloc] initWithManager:windowManager parentController:controller contentController:galleryController];
|
||||
controllerWindow.hidden = false;
|
||||
galleryController.view.clipsToBounds = true;
|
||||
|
||||
if (isGif) {
|
||||
|
|
@ -292,9 +332,33 @@
|
|||
[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];
|
||||
|
||||
|
|
|
|||
|
|
@ -131,12 +131,12 @@ public func legacyStoryMediaEditor(context: AccountContext, item: TGMediaEditabl
|
|||
|
||||
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>
|
||||
if let photo = result as? TGCameraCapturedPhoto {
|
||||
if let _ = editingContext?.adjustments(for: result) {
|
||||
if let _ = editingContext.adjustments(for: result) {
|
||||
completionResult = .single(.image(photo.existingImage))
|
||||
} else {
|
||||
completionResult = .single(.image(photo.existingImage))
|
||||
|
|
@ -167,6 +167,10 @@ public func legacyMediaEditor(
|
|||
snapshots: [UIView],
|
||||
transitionCompletion: (() -> Void)?,
|
||||
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,
|
||||
present: @escaping (ViewController, Any?) -> Void
|
||||
) {
|
||||
|
|
@ -209,32 +213,87 @@ public func legacyMediaEditor(
|
|||
legacyController?.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||
}
|
||||
|
||||
let emptyController = LegacyEmptyController(context: legacyController.context)!
|
||||
emptyController.navigationBarShouldBeHidden = true
|
||||
let navigationController = makeLegacyNavigationController(rootController: emptyController)
|
||||
navigationController.setNavigationBarHidden(true, animated: false)
|
||||
legacyController.bind(controller: navigationController)
|
||||
|
||||
legacyController.enableSizeClassSignal = true
|
||||
|
||||
present(legacyController, nil)
|
||||
|
||||
TGPhotoVideoEditor.present(with: legacyController.context, controller: emptyController, 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: {
|
||||
let schedulePicker: (Bool, @escaping (Int32) -> Void) -> Void = { media, done in
|
||||
presentSchedulePicker(media, done)
|
||||
}
|
||||
let appeared: () -> Void = {
|
||||
transitionCompletion?()
|
||||
}, completion: { result, editingContext in
|
||||
}
|
||||
let completion: (TGMediaEditableItem, TGMediaEditingContext, Bool, Int32) -> Void = { result, editingContext, silentPosting, scheduleTime in
|
||||
let nativeGenerator = legacyAssetPickerItemGenerator()
|
||||
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
|
||||
nativeGenerator(_1, _2, _3, nil)
|
||||
})
|
||||
let isCaptionAbove = editingContext?.isCaptionAbove() ?? false
|
||||
sendMessagesWithSignals(signals, false, 0, isCaptionAbove)
|
||||
}, dismissed: { [weak legacyController] in
|
||||
let isCaptionAbove = editingContext.isCaptionAbove()
|
||||
sendMessagesWithSignals(signals, silentPosting, scheduleTime, isCaptionAbove)
|
||||
}
|
||||
let dismissed: () -> Void = { [weak legacyController] in
|
||||
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)
|
||||
|
||||
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: {
|
||||
}, completion: { result, editingContext in
|
||||
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
|
||||
let nativeGenerator = legacyAssetPickerItemGenerator()
|
||||
var selectableResult: TGMediaSelectableItem?
|
||||
if let result = result {
|
||||
selectableResult = unsafeDowncast(result, to: TGMediaSelectableItem.self)
|
||||
}
|
||||
let selectableResult: TGMediaSelectableItem? = unsafeDowncast(result, to: TGMediaSelectableItem.self)
|
||||
|
||||
let signals = TGCameraController.resultSignals(for: nil, editingContext: editingContext, currentItem: selectableResult, storeAssets: false, saveEditedPhotos: false, descriptionGenerator: { _1, _2, _3 in
|
||||
nativeGenerator(_1, _2, _3, nil)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -108,11 +108,9 @@ public func legacyAvatarEditor(context: AccountContext, media: AnyMediaReference
|
|||
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
|
||||
if let image = image {
|
||||
imageCompletion(image)
|
||||
}
|
||||
imageCompletion(image)
|
||||
}, didFinishWithVideo: { image, url, adjustments in
|
||||
if let image = image, let url = url, let adjustments = adjustments {
|
||||
if let adjustments = adjustments {
|
||||
videoCompletion(image, url, adjustments)
|
||||
}
|
||||
}, dismissed: { [weak legacyController] in
|
||||
|
|
|
|||
|
|
@ -312,6 +312,11 @@ public final class SearchDisplayController {
|
|||
if let searchBar = self.searchBar {
|
||||
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 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 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 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)])
|
||||
|
||||
// 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
|
||||
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||
context.clear(bounds)
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ public final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
|||
|
||||
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() {
|
||||
super.init()
|
||||
|
|
@ -214,8 +214,8 @@ public final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
|||
switch action {
|
||||
case .join, .joinGroup, .applyToJoin:
|
||||
self.isJoining = true
|
||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, isSecondary, metrics) = 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)
|
||||
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, deviceMetrics: deviceMetrics, force: true)
|
||||
}
|
||||
self.actionDisposable.set((context.peerChannelMemberCategoriesContextsManager.join(engine: context.engine, peerId: peer.id, hash: nil)
|
||||
|> 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 {
|
||||
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)
|
||||
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, deviceMetrics: deviceMetrics, force: 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
|
||||
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
|
||||
if !isFirstTime && !transition.isAnimated {
|
||||
|
|
@ -433,10 +433,9 @@ public final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
|||
|
||||
var leftInset = leftInset + 8.0
|
||||
var rightInset = rightInset + 8.0
|
||||
if bottomInset <= 32.0 {
|
||||
leftInset += 18.0
|
||||
rightInset += 18.0
|
||||
}
|
||||
let compactBottomSideInset = self.compactBottomSideInset(bottomInset: bottomInset, deviceMetrics: deviceMetrics)
|
||||
leftInset += compactBottomSideInset
|
||||
rightInset += compactBottomSideInset
|
||||
|
||||
var leftPanelItems: [GlassControlGroupComponent.Item] = []
|
||||
if displaySuggestPost {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,15 @@ open class ChatInputPanelNode: ASDisplayNode {
|
|||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
|||
|
||||
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 actions: ChatAvailableMessageActions?
|
||||
|
||||
|
|
@ -288,8 +288,8 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
|||
|
||||
if self.selectedMessages.isEmpty {
|
||||
self.actions = nil
|
||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = 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)
|
||||
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, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||
}
|
||||
self.canDeleteMessagesDisposable.set(nil)
|
||||
} else if let context = self.context {
|
||||
|
|
@ -297,8 +297,8 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
|||
|> deliverOnMainQueue).startStrict(next: { [weak self] actions in
|
||||
if let strongSelf = self {
|
||||
strongSelf.actions = actions
|
||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight: maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = 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)
|
||||
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, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
|
@ -456,21 +456,20 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
|||
}
|
||||
|
||||
private func update(transition: ContainedViewLayoutTransition) {
|
||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = 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)
|
||||
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, 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 {
|
||||
self.validLayout = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, 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, deviceMetrics: DeviceMetrics, isMediaInputExpanded: Bool) -> CGFloat {
|
||||
self.validLayout = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded, deviceMetrics)
|
||||
|
||||
var leftInset = leftInset + 8.0
|
||||
var rightInset = rightInset + 8.0
|
||||
|
||||
if bottomInset <= 32.0 {
|
||||
leftInset += 18.0
|
||||
rightInset += 18.0
|
||||
}
|
||||
let compactBottomSideInset = self.compactBottomSideInset(bottomInset: bottomInset, deviceMetrics: deviceMetrics)
|
||||
leftInset += compactBottomSideInset
|
||||
rightInset += compactBottomSideInset
|
||||
|
||||
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))
|
||||
|
||||
if self.presentationInterfaceState != interfaceState {
|
||||
|
|
|
|||
|
|
@ -1052,6 +1052,7 @@ public final class ChatTextInputPanelComponent: Component {
|
|||
transition: transition.containedViewLayoutTransition,
|
||||
interfaceState: presentationInterfaceState,
|
||||
metrics: LayoutMetrics(widthClass: .compact, heightClass: .compact, orientation: nil),
|
||||
deviceMetrics: DeviceMetrics.iPhone16Pro,
|
||||
isMediaInputExpanded: false
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
|
||||
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 rightSlowModeInset: 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
|
||||
if let strongSelf = self, let presentationInterfaceState = strongSelf.presentationInterfaceState {
|
||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = 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)
|
||||
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, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||
}
|
||||
}
|
||||
}
|
||||
self.mediaActionButtons.micButton.updateCancelTranslation = { [weak self] in
|
||||
if let strongSelf = self, let presentationInterfaceState = strongSelf.presentationInterfaceState {
|
||||
if let (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded) = 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)
|
||||
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, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1412,10 +1412,10 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
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(
|
||||
|
|
@ -1430,12 +1430,13 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
transition: ContainedViewLayoutTransition,
|
||||
interfaceState: ChatPresentationInterfaceState,
|
||||
metrics: LayoutMetrics,
|
||||
deviceMetrics: DeviceMetrics,
|
||||
isMediaInputExpanded: Bool
|
||||
) -> CGFloat {
|
||||
let isFirstTime = self.validLayout == nil
|
||||
|
||||
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 defaultGlassTintWithInnerColor: GlassBackgroundView.TintColor
|
||||
|
|
@ -1450,10 +1451,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
var leftInset = leftInset
|
||||
var rightInset = rightInset
|
||||
|
||||
if bottomInset <= 32.0 {
|
||||
leftInset += 18.0
|
||||
rightInset += 18.0
|
||||
}
|
||||
let compactBottomSideInset = self.compactBottomSideInset(bottomInset: bottomInset, deviceMetrics: deviceMetrics)
|
||||
leftInset += compactBottomSideInset
|
||||
rightInset += compactBottomSideInset
|
||||
|
||||
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.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 {
|
||||
self.mediaPreviewPanelNode = nil
|
||||
let mediaPreviewPanelView = mediaPreviewPanelNode.view
|
||||
|
|
@ -4653,13 +4653,12 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
|
|||
}
|
||||
|
||||
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 rightInset = rightInset
|
||||
if bottomInset <= 32.0 {
|
||||
leftInset += 18.0
|
||||
rightInset += 18.0
|
||||
}
|
||||
let compactBottomSideInset = self.compactBottomSideInset(bottomInset: bottomInset, deviceMetrics: deviceMetrics)
|
||||
leftInset += compactBottomSideInset
|
||||
rightInset += compactBottomSideInset
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ public final class ChatTitleComponent: Component {
|
|||
var titleStatusIcon: ChatTitleCredibilityIcon = .none
|
||||
var isEnabled = true
|
||||
switch component.content {
|
||||
case let .peer(peerView, customTitle, _, _, isScheduledMessages, isMuted, _, isEnabledValue):
|
||||
case let .peer(peerView, customTitle, _, _, isScheduledMessages, isMuted, _, hidePeerStatus, isEnabledValue):
|
||||
if peerView.peerId.isReplies {
|
||||
titleSegments = [AnimatedTextComponent.Item(
|
||||
id: AnyHashable(0),
|
||||
|
|
@ -448,7 +448,7 @@ public final class ChatTitleComponent: Component {
|
|||
titleCredibilityIcon = .fake
|
||||
} else if peer.isScam {
|
||||
titleCredibilityIcon = .scam
|
||||
} else if let emojiStatus = peer.emojiStatus {
|
||||
} else if !hidePeerStatus, let emojiStatus = peer.emojiStatus {
|
||||
titleStatusIcon = .emojiStatus(emojiStatus)
|
||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||
titleCredibilityIcon = .premium
|
||||
|
|
@ -612,7 +612,7 @@ public final class ChatTitleComponent: Component {
|
|||
|
||||
var inputActivitiesAllowed = true
|
||||
switch component.content {
|
||||
case let .peer(peerView, _, _, _, isScheduledMessages, _, _, _):
|
||||
case let .peer(peerView, _, _, _, isScheduledMessages, _, _, _, _):
|
||||
if let peer = peerView.peer {
|
||||
if peer.id == component.context.account.peerId || isScheduledMessages || peer.id.isRepliesOrVerificationCodes {
|
||||
inputActivitiesAllowed = false
|
||||
|
|
@ -710,7 +710,7 @@ public final class ChatTitleComponent: Component {
|
|||
}
|
||||
} else {
|
||||
switch component.content {
|
||||
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, _, customMessageCount, _):
|
||||
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, _, customMessageCount, _, _):
|
||||
if let customSubtitle {
|
||||
let string = NSAttributedString(string: customSubtitle, font: subtitleFont, textColor: component.theme.chat.inputPanel.inputControlColor)
|
||||
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 custom(title: [TitleTextItem], subtitle: String?, isEnabled: Bool)
|
||||
|
||||
public static func ==(lhs: ChatTitleContent, rhs: ChatTitleContent) -> Bool {
|
||||
switch lhs {
|
||||
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, isMuted, customMessageCount, isEnabled):
|
||||
if case let .peer(rhsPeerView, rhsCustomTitle, rhsCustomSubtitle, rhsOnlineMemberCount, rhsIsScheduledMessages, rhsIsMuted, rhsCustomMessageCount, rhsIsEnabled) = rhs {
|
||||
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, isMuted, customMessageCount, hidePeerStatus, isEnabled):
|
||||
if case let .peer(rhsPeerView, rhsCustomTitle, rhsCustomSubtitle, rhsOnlineMemberCount, rhsIsScheduledMessages, rhsIsMuted, rhsCustomMessageCount, rhsHidePeerStatus, rhsIsEnabled) = rhs {
|
||||
if peerView != rhsPeerView {
|
||||
return false
|
||||
}
|
||||
|
|
@ -139,6 +139,9 @@ public enum ChatTitleContent: Equatable {
|
|||
if customMessageCount != rhsCustomMessageCount {
|
||||
return false
|
||||
}
|
||||
if hidePeerStatus != rhsHidePeerStatus {
|
||||
return false
|
||||
}
|
||||
if isEnabled != rhsIsEnabled {
|
||||
return false
|
||||
}
|
||||
|
|
@ -269,7 +272,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||
var titleStatusIcon: ChatTitleCredibilityIcon = .none
|
||||
var isEnabled = true
|
||||
switch titleContent {
|
||||
case let .peer(peerView, customTitle, _, _, isScheduledMessages, isMuted, _, isEnabledValue):
|
||||
case let .peer(peerView, customTitle, _, _, isScheduledMessages, isMuted, _, hidePeerStatus, isEnabledValue):
|
||||
if peerView.peerId.isReplies {
|
||||
let typeText: String = self.strings.DialogList_Replies
|
||||
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
|
||||
} else if peer.isScam {
|
||||
titleCredibilityIcon = .scam
|
||||
} else if let emojiStatus = peer.emojiStatus {
|
||||
} else if !hidePeerStatus, let emojiStatus = peer.emojiStatus {
|
||||
titleStatusIcon = .emojiStatus(emojiStatus)
|
||||
} else if peer.isPremium && !premiumConfiguration.isPremiumDisabled {
|
||||
titleCredibilityIcon = .premium
|
||||
|
|
@ -476,8 +479,8 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||
|
||||
var enableAnimation = false
|
||||
switch titleContent {
|
||||
case let .peer(_, customTitle, _, _, _, _, _, _):
|
||||
if case let .peer(_, previousCustomTitle, _, _, _, _, _, _) = oldValue {
|
||||
case let .peer(_, customTitle, _, _, _, _, _, _, _):
|
||||
if case let .peer(_, previousCustomTitle, _, _, _, _, _, _, _) = oldValue {
|
||||
if customTitle != previousCustomTitle {
|
||||
enableAnimation = false
|
||||
}
|
||||
|
|
@ -503,7 +506,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||
var inputActivitiesAllowed = true
|
||||
if let titleContent = self.titleContent {
|
||||
switch titleContent {
|
||||
case let .peer(peerView, _, _, _, isScheduledMessages, _, _, _):
|
||||
case let .peer(peerView, _, _, _, isScheduledMessages, _, _, _, _):
|
||||
if let peer = peerView.peer {
|
||||
if peer.id == self.context.account.peerId || isScheduledMessages || peer.id.isRepliesOrVerificationCodes {
|
||||
inputActivitiesAllowed = false
|
||||
|
|
@ -604,7 +607,7 @@ public final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||
} else {
|
||||
if let titleContent = self.titleContent {
|
||||
switch titleContent {
|
||||
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, _, customMessageCount, _):
|
||||
case let .peer(peerView, customTitle, customSubtitle, onlineMemberCount, isScheduledMessages, _, customMessageCount, _, _):
|
||||
if let customSubtitle {
|
||||
let string = NSAttributedString(string: customSubtitle, font: subtitleFont, textColor: titleTheme.rootController.navigationBar.secondaryTextColor)
|
||||
state = .info(string, .generic)
|
||||
|
|
|
|||
|
|
@ -425,6 +425,7 @@ final class PeerInfoScreenData {
|
|||
let savedMusicContext: ProfileSavedMusicContext?
|
||||
let savedMusicState: ProfileSavedMusicContext.State?
|
||||
let managedByBot: EnginePeer?
|
||||
let businessConnectedBot: EnginePeer?
|
||||
|
||||
let _isContact: Bool
|
||||
var forceIsContact: Bool = false
|
||||
|
|
@ -480,7 +481,8 @@ final class PeerInfoScreenData {
|
|||
webAppPermissions: WebAppPermissionsState?,
|
||||
savedMusicContext: ProfileSavedMusicContext?,
|
||||
savedMusicState: ProfileSavedMusicContext.State?,
|
||||
managedByBot: EnginePeer?
|
||||
managedByBot: EnginePeer?,
|
||||
businessConnectedBot: EnginePeer?
|
||||
) {
|
||||
self.peer = peer
|
||||
self.chatPeer = chatPeer
|
||||
|
|
@ -525,6 +527,7 @@ final class PeerInfoScreenData {
|
|||
self.savedMusicContext = savedMusicContext
|
||||
self.savedMusicState = savedMusicState
|
||||
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 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(
|
||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||
accountsAndPeers,
|
||||
|
|
@ -956,9 +973,10 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||
bots,
|
||||
peerInfoPersonalOrLinkedChannel(context: context, peerId: peerId, isSettings: true),
|
||||
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 (featuredStickerPacks, archivedStickerPacks) = stickerPacks
|
||||
|
||||
|
|
@ -1048,7 +1066,8 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
|||
webAppPermissions: nil,
|
||||
savedMusicContext: nil,
|
||||
savedMusicState: nil,
|
||||
managedByBot: nil
|
||||
managedByBot: nil,
|
||||
businessConnectedBot: businessConnectedBot
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1120,7 +1139,8 @@ func peerInfoScreenData(
|
|||
webAppPermissions: nil,
|
||||
savedMusicContext: nil,
|
||||
savedMusicState: nil,
|
||||
managedByBot: nil
|
||||
managedByBot: nil,
|
||||
businessConnectedBot: nil
|
||||
))
|
||||
case let .user(userPeerId, secretChatId, kind):
|
||||
let groupsInCommon: GroupsInCommonContext?
|
||||
|
|
@ -1446,7 +1466,26 @@ func peerInfoScreenData(
|
|||
}
|
||||
|
||||
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(
|
||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||
peerInfoAvailableMediaPanes(context: context, peerId: peerId, chatLocation: chatLocation, isMyProfile: isMyProfile, chatLocationContextHolder: chatLocationContextHolder, sharedMediaFromForumTopic: sharedMediaFromForumTopic),
|
||||
|
|
@ -1468,9 +1507,10 @@ func peerInfoScreenData(
|
|||
revenueContextAndState,
|
||||
premiumGiftOptions,
|
||||
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
|
||||
if isMyProfile {
|
||||
availablePanes?.insert(.stories, at: 0)
|
||||
|
|
@ -1616,7 +1656,8 @@ func peerInfoScreenData(
|
|||
webAppPermissions: webAppPermissions,
|
||||
savedMusicContext: savedMusicContext,
|
||||
savedMusicState: savedMusicState,
|
||||
managedByBot: managedByBot
|
||||
managedByBot: managedByBot,
|
||||
businessConnectedBot: businessConnectedBot
|
||||
)
|
||||
}
|
||||
case .channel:
|
||||
|
|
@ -1862,7 +1903,8 @@ func peerInfoScreenData(
|
|||
webAppPermissions: nil,
|
||||
savedMusicContext: nil,
|
||||
savedMusicState: nil,
|
||||
managedByBot: nil
|
||||
managedByBot: nil,
|
||||
businessConnectedBot: nil
|
||||
)
|
||||
}
|
||||
case let .group(groupId):
|
||||
|
|
@ -2199,7 +2241,8 @@ func peerInfoScreenData(
|
|||
webAppPermissions: nil,
|
||||
savedMusicContext: nil,
|
||||
savedMusicState: nil,
|
||||
managedByBot: nil
|
||||
managedByBot: nil,
|
||||
businessConnectedBot: nil
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ final class PeerInfoInteraction {
|
|||
let editingOpenVerifyAccounts: () -> Void
|
||||
let editingToggleAutoTranslate: (Bool) -> Void
|
||||
let displayAutoTranslateLocked: () -> Void
|
||||
let editingOpenBusinessChatBots: () -> Void
|
||||
let getController: () -> ViewController?
|
||||
|
||||
init(
|
||||
|
|
@ -160,6 +161,7 @@ final class PeerInfoInteraction {
|
|||
editingOpenVerifyAccounts: @escaping () -> Void,
|
||||
editingToggleAutoTranslate: @escaping (Bool) -> Void,
|
||||
displayAutoTranslateLocked: @escaping () -> Void,
|
||||
editingOpenBusinessChatBots: @escaping () -> Void,
|
||||
getController: @escaping () -> ViewController?
|
||||
) {
|
||||
self.openUsername = openUsername
|
||||
|
|
@ -236,6 +238,7 @@ final class PeerInfoInteraction {
|
|||
self.editingOpenVerifyAccounts = editingOpenVerifyAccounts
|
||||
self.editingToggleAutoTranslate = editingToggleAutoTranslate
|
||||
self.displayAutoTranslateLocked = displayAutoTranslateLocked
|
||||
self.editingOpenBusinessChatBots = editingOpenBusinessChatBots
|
||||
self.getController = getController
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -682,6 +682,11 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
return
|
||||
}
|
||||
self.displayAutoTranslateLocked()
|
||||
}, editingOpenBusinessChatBots: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.editingOpenBusinessChatBots()
|
||||
},
|
||||
getController: { [weak self] in
|
||||
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() {
|
||||
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
|
||||
|
||||
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)))
|
||||
|
||||
|
|
|
|||
|
|
@ -370,6 +370,8 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
|||
let ItemBirthdayRemove = 11
|
||||
let ItemBirthdayHelp = 12
|
||||
let ItemPeerPersonalChannel = 13
|
||||
let ItemPeerChatAutomation = 14
|
||||
let ItemPeerChatAutomationHelp = 15
|
||||
|
||||
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
|
||||
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)
|
||||
}))
|
||||
if isEditingBirthDate, let birthday {
|
||||
|
|
@ -423,7 +425,7 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
|||
}))
|
||||
|
||||
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)
|
||||
}))
|
||||
}
|
||||
|
|
@ -431,7 +433,7 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
|||
if let addressName = data.peer?.addressName, !addressName.isEmpty {
|
||||
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)
|
||||
}))
|
||||
|
||||
|
|
@ -452,7 +454,7 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
|||
}
|
||||
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()
|
||||
}))
|
||||
|
||||
|
|
@ -468,12 +470,26 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
|||
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()
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
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: {
|
||||
interaction.openSettings(.addAccount)
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -645,13 +645,13 @@ final class ChatbotSetupScreenComponent: Component {
|
|||
let navigationTitleSize = self.navigationTitle.update(
|
||||
transition: transition,
|
||||
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
|
||||
)),
|
||||
environment: {},
|
||||
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 navigationTitleView.superview == nil {
|
||||
if let controller = self.environment?.controller(), let navigationBar = controller.navigationBar {
|
||||
|
|
@ -681,7 +681,7 @@ final class ChatbotSetupScreenComponent: Component {
|
|||
environment: {},
|
||||
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 iconView.superview == nil {
|
||||
self.scrollView.addSubview(iconView)
|
||||
|
|
@ -691,11 +691,11 @@ final class ChatbotSetupScreenComponent: Component {
|
|||
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(
|
||||
body: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.freeTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(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.itemPrimaryTextColor),
|
||||
link: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemAccentColor),
|
||||
linkAttribute: { attributes in
|
||||
return ("URL", "")
|
||||
|
|
@ -732,7 +732,7 @@ final class ChatbotSetupScreenComponent: Component {
|
|||
}
|
||||
)),
|
||||
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)
|
||||
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 {
|
||||
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(
|
||||
context: self.context,
|
||||
peer: peer,
|
||||
|
|
@ -27,7 +29,24 @@ extension ChatControllerImpl {
|
|||
getCaptionPanelView: { [weak self] in
|
||||
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 {
|
||||
return
|
||||
}
|
||||
|
|
@ -39,8 +58,8 @@ extension ChatControllerImpl {
|
|||
fromGallery: false,
|
||||
signals: signals,
|
||||
originalMediaReference: file.abstract,
|
||||
silentPosting: false,
|
||||
scheduleTime: nil,
|
||||
silentPosting: silentPosting,
|
||||
scheduleTime: scheduleTime == 0 ? nil : scheduleTime,
|
||||
replyToSubject: nil,
|
||||
parameters: parameters,
|
||||
getAnimatedTransitionSource: nil,
|
||||
|
|
@ -48,7 +67,8 @@ extension ChatControllerImpl {
|
|||
)
|
||||
},
|
||||
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 {
|
||||
enableMultiselection = false
|
||||
}
|
||||
let inputText = strongSelf.presentationInterfaceState.interfaceState.effectiveInputState.inputText
|
||||
|
||||
strongSelf.chatDisplayNode.dismissInput()
|
||||
let controller = mediaPasteboardScreen(
|
||||
|
|
@ -32,7 +33,15 @@ extension ChatControllerImpl {
|
|||
subjects: subjects,
|
||||
presentMediaPicker: { [weak self] subject, saveEditedPhotos, bannedSendPhotos, bannedSendVideos, present in
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -602,7 +602,7 @@ extension ChatControllerImpl {
|
|||
notificationSettings: nil,
|
||||
peerPresences: [:],
|
||||
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 {
|
||||
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"
|
||||
}
|
||||
|
||||
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?
|
||||
if context.account.peerId == peer.id {
|
||||
|
|
@ -1519,7 +1519,7 @@ extension ChatControllerImpl {
|
|||
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
|
||||
|
||||
|
|
@ -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
|
||||
if chatLocation.threadId == 1 {
|
||||
|
|
|
|||
|
|
@ -1763,7 +1763,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
if inputTextPanelNode.isFocused {
|
||||
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) {
|
||||
inputPanelNodeHandlesTransition = true
|
||||
|
|
@ -1775,7 +1775,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
} else {
|
||||
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)
|
||||
self.inputPanelNode = inputPanelNode
|
||||
if inputPanelNode.supernode !== self {
|
||||
|
|
@ -1786,7 +1786,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
self.inputPanelOverlayNode.view.addSubview(viewForOverlayContent)
|
||||
}
|
||||
} 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)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1797,7 +1797,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
if let secondaryInputPanelNode = inputPanelNodes.secondary, !previewing {
|
||||
if secondaryInputPanelNode !== 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)
|
||||
self.secondaryInputPanelNode = secondaryInputPanelNode
|
||||
if secondaryInputPanelNode.supernode == nil {
|
||||
|
|
@ -1808,7 +1808,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
|||
self.inputPanelOverlayNode.view.addSubview(viewForOverlayContent)
|
||||
}
|
||||
} 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)
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -3362,6 +3362,11 @@ public final class ChatHistoryListNodeImpl: ListViewImpl, ChatHistoryNode, ChatH
|
|||
if self.chatHistoryLocationValue?.content != locationInput {
|
||||
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 {
|
||||
if self.chatHistoryLocationValue?.content != locationInput {
|
||||
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 {
|
||||
self.presentationInterfaceState = interfaceState
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,10 @@ final class ChatPremiumRequiredInputPanelNode: ChatInputPanelNode {
|
|||
var isSecondary: Bool
|
||||
var interfaceState: ChatPresentationInterfaceState
|
||||
var metrics: LayoutMetrics
|
||||
var deviceMetrics: DeviceMetrics
|
||||
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.leftInset = leftInset
|
||||
self.rightInset = rightInset
|
||||
|
|
@ -43,6 +44,7 @@ final class ChatPremiumRequiredInputPanelNode: ChatInputPanelNode {
|
|||
self.isSecondary = isSecondary
|
||||
self.interfaceState = interfaceState
|
||||
self.metrics = metrics
|
||||
self.deviceMetrics = deviceMetrics
|
||||
self.isMediaInputExpanded = isMediaInputExpanded
|
||||
}
|
||||
}
|
||||
|
|
@ -74,8 +76,8 @@ final class ChatPremiumRequiredInputPanelNode: ChatInputPanelNode {
|
|||
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 {
|
||||
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)
|
||||
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, deviceMetrics: deviceMetrics, isMediaInputExpanded: isMediaInputExpanded)
|
||||
if let currentLayout = self.currentLayout, currentLayout.params == params {
|
||||
return currentLayout.height
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
|
|||
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 {
|
||||
self.presentationInterfaceState = interfaceState
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,9 +32,10 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode {
|
|||
var isSecondary: Bool
|
||||
var interfaceState: ChatPresentationInterfaceState
|
||||
var metrics: LayoutMetrics
|
||||
var deviceMetrics: DeviceMetrics
|
||||
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.leftInset = leftInset
|
||||
self.rightInset = rightInset
|
||||
|
|
@ -45,6 +46,7 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode {
|
|||
self.isSecondary = isSecondary
|
||||
self.interfaceState = interfaceState
|
||||
self.metrics = metrics
|
||||
self.deviceMetrics = deviceMetrics
|
||||
self.isMediaInputExpanded = isMediaInputExpanded
|
||||
}
|
||||
}
|
||||
|
|
@ -110,16 +112,15 @@ final class ChatTagSearchInputPanelNode: ChatInputPanelNode {
|
|||
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 rightInset = rightInset + 8.0
|
||||
|
||||
if bottomInset <= 32.0 {
|
||||
leftInset += 18.0
|
||||
rightInset += 18.0
|
||||
}
|
||||
let compactBottomSideInset = self.compactBottomSideInset(bottomInset: bottomInset, deviceMetrics: deviceMetrics)
|
||||
leftInset += compactBottomSideInset
|
||||
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 {
|
||||
return currentLayout.height
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ final class ChatUnblockInputPanelNode: ChatInputPanelNode {
|
|||
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 {
|
||||
self.presentationInterfaceState = interfaceState
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ final class DeleteChatInputPanelNode: ChatInputPanelNode {
|
|||
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 {
|
||||
self.presentationInterfaceState = interfaceState
|
||||
|
||||
|
|
|
|||
|
|
@ -840,7 +840,9 @@ final class OverlayAudioPlayerControllerNode: ViewControllerTracingNode, ASGestu
|
|||
containerTransform = CATransform3DScale(containerTransform, scale, scale, scale)
|
||||
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ final class SecretChatHandshakeStatusInputPanelNode: ChatInputPanelNode {
|
|||
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
|
||||
|
||||
var text: String?
|
||||
|
|
|
|||
|
|
@ -18,12 +18,15 @@ import UndoUI
|
|||
import BrowserUI
|
||||
|
||||
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
|
||||
controller.present(controllerToPresent, in: .window(.root))
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
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 {
|
||||
switch result {
|
||||
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):
|
||||
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 browserController = context.sharedContext.makeInstantPageController(context: context, webPage: webPage, anchor: anchor, sourceLocation: sourceLocation)
|
||||
(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 {
|
||||
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)
|
||||
|
|
@ -128,7 +131,6 @@ func handleTextLinkActionImpl(context: AccountContext, peerId: EnginePeer.Id?, n
|
|||
}))
|
||||
}
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
switch action {
|
||||
case .tap:
|
||||
switch itemLink {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue