Merge commit '7621e2f8dec938cf48181c8b10afc9b01f444e68' into beta

This commit is contained in:
Ilya Laktyushin
2025-12-06 02:17:48 +04:00
commit 8344b97e03
28070 changed files with 7995182 additions and 0 deletions
@@ -0,0 +1,24 @@
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
swift_library(
name = "ChatInputTextNode",
module_name = "ChatInputTextNode",
srcs = glob([
"Sources/**/*.swift",
]),
copts = [
"-warnings-as-errors",
],
deps = [
"//submodules/AsyncDisplayKit",
"//submodules/Display",
"//submodules/AppBundle",
"//submodules/TelegramUI/Components/Chat/ChatInputTextNode/ChatInputTextViewImpl",
"//submodules/TelegramUI/Components/Chat/MessageInlineBlockBackgroundView",
"//submodules/AccountContext",
"//submodules/TelegramUI/Components/TextNodeWithEntities",
],
visibility = [
"//visibility:public",
],
)
@@ -0,0 +1,23 @@
objc_library(
name = "ChatInputTextViewImpl",
enable_modules = True,
module_name = "ChatInputTextViewImpl",
srcs = glob([
"Sources/**/*.m",
"Sources/**/*.c",
"Sources/**/*.h",
], allow_empty=True),
hdrs = glob([
"PublicHeaders/**/*.h",
]),
includes = [
"PublicHeaders",
],
sdk_frameworks = [
"Foundation",
],
visibility = [
"//visibility:public",
],
)
@@ -0,0 +1,29 @@
#ifndef ChatInputTextViewImpl_h
#define ChatInputTextViewImpl_h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface ChatInputTextViewImplTargetForAction: NSObject
@property (nonatomic, strong, readonly) id _Nullable target;
- (instancetype _Nonnull)initWithTarget:(id _Nullable)target;
@end
@interface ChatInputTextViewImpl : UITextView
@property (nonatomic, copy) bool (^ _Nullable shouldCopy)();
@property (nonatomic, copy) bool (^ _Nullable shouldPaste)();
@property (nonatomic, copy) bool (^ _Nullable shouldRespondToAction)(SEL _Nullable);
@property (nonatomic, copy) ChatInputTextViewImplTargetForAction * _Nullable (^ _Nullable targetForAction)(SEL _Nullable);
@property (nonatomic, copy) bool (^ _Nullable shouldReturn)();
@property (nonatomic, copy) void (^ _Nullable backspaceWhileEmpty)();
@property (nonatomic, copy) void (^ _Nullable dropAutocorrectioniOS16)();
- (instancetype _Nonnull)initWithFrame:(CGRect)frame textContainer:(NSTextContainer * _Nullable)textContainer disableTiling:(bool)disableTiling;
@end
#endif /* Lottie_h */
@@ -0,0 +1,161 @@
#import <ChatInputTextViewImpl/ChatInputTextViewImpl.h>
@implementation ChatInputTextViewImplTargetForAction
- (instancetype)initWithTarget:(id _Nullable)target {
self = [super init];
if (self != nil) {
_target = target;
}
return self;
}
@end
@interface ChatInputTextViewImpl () <UIGestureRecognizerDelegate> {
UIGestureRecognizer *_tapRecognizer;
}
@end
@implementation ChatInputTextViewImpl
- (instancetype _Nonnull)initWithFrame:(CGRect)frame textContainer:(NSTextContainer * _Nullable)textContainer disableTiling:(bool)disableTiling {
self = [super initWithFrame:frame textContainer:textContainer];
if (self != nil) {
if (disableTiling) {
SEL selector = NSSelectorFromString(@"_disableTiledViews");
if (selector && [self respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[self performSelector:selector];
#pragma clang diagnostic pop
}
}
if (@available(iOS 17.0, *)) {
} else {
_tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(workaroundTapGesture:)];
_tapRecognizer.cancelsTouchesInView = false;
_tapRecognizer.delaysTouchesBegan = false;
_tapRecognizer.delaysTouchesEnded = false;
_tapRecognizer.delegate = self;
[self addGestureRecognizer:_tapRecognizer];
}
}
return self;
}
- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
return false;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return true;
}
- (void)workaroundTapGesture:(UITapGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateEnded) {
static Class promptClass = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
promptClass = NSClassFromString([[NSString alloc] initWithFormat:@"%@AutocorrectInlinePrompt", @"UI"]);
});
UIView *result = [self hitTest:[recognizer locationInView:self] withEvent:nil];
if (result != nil && [result class] == promptClass) {
if (_dropAutocorrectioniOS16) {
_dropAutocorrectioniOS16();
}
}
}
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (_targetForAction) {
ChatInputTextViewImplTargetForAction *result = _targetForAction(action);
if (result) {
return result.target != nil;
}
}
if (_shouldRespondToAction) {
if (!_shouldRespondToAction(action)) {
return false;
}
}
if (action == @selector(paste:)) {
NSArray *items = [UIMenuController sharedMenuController].menuItems;
if (((UIMenuItem *)items.firstObject).action == @selector(toggleBoldface:)) {
return false;
}
return true;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
static SEL promptForReplaceSelector;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
promptForReplaceSelector = NSSelectorFromString(@"_promptForReplace:");
});
if (action == promptForReplaceSelector) {
return false;
}
#pragma clang diagnostic pop
if (action == @selector(toggleUnderline:)) {
return false;
}
return [super canPerformAction:action withSender:sender];
}
- (id)targetForAction:(SEL)action withSender:(id)__unused sender {
if (_targetForAction) {
ChatInputTextViewImplTargetForAction *result = _targetForAction(action);
if (result) {
return result.target;
}
}
return [super targetForAction:action withSender:sender];
}
- (void)copy:(id)sender {
if (_shouldCopy == nil || _shouldCopy()) {
[super copy:sender];
}
}
- (void)paste:(id)sender {
if (_shouldPaste == nil || _shouldPaste()) {
[super paste:sender];
}
}
- (NSArray *)keyCommands {
UIKeyCommand *plainReturn = [UIKeyCommand keyCommandWithInput:@"\r" modifierFlags:kNilOptions action:@selector(handlePlainReturn:)];
return @[
plainReturn
];
}
- (void)handlePlainReturn:(id)__unused sender {
if (_shouldReturn) {
_shouldReturn();
}
}
- (void)deleteBackward {
bool notify = self.text.length == 0;
[super deleteBackward];
if (notify) {
if (_backspaceWhileEmpty) {
_backspaceWhileEmpty();
}
}
}
@end