mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-04 21:41:45 +00:00
Improve intro input
This commit is contained in:
parent
7e1ebdbc8c
commit
567375e55e
@ -11599,7 +11599,7 @@ Sorry for the inconvenience.";
|
||||
"ChatbotSetup.Recipients.IncludedSectionFooter" = "Select chats or entire chat categories which the bot **WILL** have access to.";
|
||||
|
||||
"ChatbotSetup.PermissionsSectionHeader" = "BOT PERMISSIONS";
|
||||
"ChatbotSetup.PermissionsSectionFooter" = "The bot will be able to view all new incoming messages, but not the messages that had been sent before you added the bot.";
|
||||
"ChatbotSetup.PermissionsSectionFooter" = "The bot can only reply on your behalf in chats that were active during the last 24h.";
|
||||
"ChatbotSetup.Permission.ReplyToMessages" = "Reply to Messages";
|
||||
|
||||
"ChatbotSetup.BotAddAction" = "ADD";
|
||||
|
||||
@ -376,6 +376,11 @@ final class ChatHistoryPreloadManager {
|
||||
}
|
||||
|
||||
private func update(indices: [(ChatHistoryPreloadIndex, Bool, Bool)], additionalPeerIds: Set<PeerId>) {
|
||||
#if DEBUG
|
||||
var indices = indices
|
||||
indices.removeAll()
|
||||
#endif
|
||||
|
||||
self.queue.async {
|
||||
var validEntityIds = Set(indices.map { $0.0.entity })
|
||||
for peerId in additionalPeerIds {
|
||||
@ -431,7 +436,7 @@ final class ChatHistoryPreloadManager {
|
||||
let key: PostboxViewKey
|
||||
switch index.entity {
|
||||
case let .peer(peerId, threadId):
|
||||
key = .messageOfInterestHole(location: .peer(peerId: peerId, threadId: threadId), namespace: Namespaces.Message.Cloud, count: 70)
|
||||
key = .messageOfInterestHole(location: .peer(peerId: peerId, threadId: threadId), namespace: Namespaces.Message.Cloud, count: 50)
|
||||
}
|
||||
view.disposable.set((self.postbox.combinedView(keys: [key])
|
||||
|> deliverOn(self.queue)).start(next: { [weak self] next in
|
||||
|
||||
@ -45,10 +45,12 @@ public final class ListMultilineTextFieldItemComponent: Component {
|
||||
public let placeholder: String
|
||||
public let autocapitalizationType: UITextAutocapitalizationType
|
||||
public let autocorrectionType: UITextAutocorrectionType
|
||||
public let returnKeyType: UIReturnKeyType
|
||||
public let characterLimit: Int?
|
||||
public let displayCharacterLimit: Bool
|
||||
public let emptyLineHandling: EmptyLineHandling
|
||||
public let updated: ((String) -> Void)?
|
||||
public let returnKeyAction: (() -> Void)?
|
||||
public let textUpdateTransition: Transition
|
||||
public let tag: AnyObject?
|
||||
|
||||
@ -62,10 +64,12 @@ public final class ListMultilineTextFieldItemComponent: Component {
|
||||
placeholder: String,
|
||||
autocapitalizationType: UITextAutocapitalizationType = .sentences,
|
||||
autocorrectionType: UITextAutocorrectionType = .default,
|
||||
returnKeyType: UIReturnKeyType = .default,
|
||||
characterLimit: Int? = nil,
|
||||
displayCharacterLimit: Bool = false,
|
||||
emptyLineHandling: EmptyLineHandling = .allowed,
|
||||
updated: ((String) -> Void)?,
|
||||
returnKeyAction: (() -> Void)? = nil,
|
||||
textUpdateTransition: Transition = .immediate,
|
||||
tag: AnyObject? = nil
|
||||
) {
|
||||
@ -78,10 +82,12 @@ public final class ListMultilineTextFieldItemComponent: Component {
|
||||
self.placeholder = placeholder
|
||||
self.autocapitalizationType = autocapitalizationType
|
||||
self.autocorrectionType = autocorrectionType
|
||||
self.returnKeyType = returnKeyType
|
||||
self.characterLimit = characterLimit
|
||||
self.displayCharacterLimit = displayCharacterLimit
|
||||
self.emptyLineHandling = emptyLineHandling
|
||||
self.updated = updated
|
||||
self.returnKeyAction = returnKeyAction
|
||||
self.textUpdateTransition = textUpdateTransition
|
||||
self.tag = tag
|
||||
}
|
||||
@ -114,6 +120,9 @@ public final class ListMultilineTextFieldItemComponent: Component {
|
||||
if lhs.autocorrectionType != rhs.autocorrectionType {
|
||||
return false
|
||||
}
|
||||
if lhs.returnKeyType != rhs.returnKeyType {
|
||||
return false
|
||||
}
|
||||
if lhs.characterLimit != rhs.characterLimit {
|
||||
return false
|
||||
}
|
||||
@ -196,6 +205,12 @@ public final class ListMultilineTextFieldItemComponent: Component {
|
||||
return false
|
||||
}
|
||||
|
||||
public func activateInput() {
|
||||
if let textFieldView = self.textField.view as? TextFieldComponent.View {
|
||||
textFieldView.activateInput()
|
||||
}
|
||||
}
|
||||
|
||||
func update(component: ListMultilineTextFieldItemComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: Transition) -> CGSize {
|
||||
self.isUpdating = true
|
||||
defer {
|
||||
@ -260,11 +275,18 @@ public final class ListMultilineTextFieldItemComponent: Component {
|
||||
characterLimit: component.characterLimit,
|
||||
emptyLineHandling: mappedEmptyLineHandling,
|
||||
formatMenuAvailability: .none,
|
||||
returnKeyType: component.returnKeyType,
|
||||
lockedFormatAction: {
|
||||
},
|
||||
present: { _ in
|
||||
},
|
||||
paste: { _ in
|
||||
},
|
||||
returnKeyAction: { [weak self] in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
component.returnKeyAction?()
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
|
||||
@ -77,6 +77,7 @@ final class BusinessIntroSetupScreenComponent: Component {
|
||||
private let introSection = ComponentView<Empty>()
|
||||
private let deleteSection = ComponentView<Empty>()
|
||||
|
||||
private var ignoreScrolling: Bool = false
|
||||
private var isUpdating: Bool = false
|
||||
|
||||
private var component: BusinessIntroSetupScreenComponent?
|
||||
@ -161,7 +162,9 @@ final class BusinessIntroSetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
self.updateScrolling(transition: .immediate)
|
||||
if !self.ignoreScrolling {
|
||||
self.updateScrolling(transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
private var scrolledUp = true
|
||||
@ -765,11 +768,21 @@ final class BusinessIntroSetupScreenComponent: Component {
|
||||
placeholder: "Enter Title",
|
||||
autocapitalizationType: .none,
|
||||
autocorrectionType: .no,
|
||||
returnKeyType: .next,
|
||||
characterLimit: 32,
|
||||
displayCharacterLimit: true,
|
||||
emptyLineHandling: .notAllowed,
|
||||
updated: { _ in
|
||||
},
|
||||
returnKeyAction: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
if let titleView = self.introSection.findTaggedView(tag: self.textInputTag) as? ListMultilineTextFieldItemComponent.View {
|
||||
titleView.activateInput()
|
||||
}
|
||||
},
|
||||
textUpdateTransition: .spring(duration: 0.4),
|
||||
tag: self.titleInputTag
|
||||
))))
|
||||
@ -786,11 +799,20 @@ final class BusinessIntroSetupScreenComponent: Component {
|
||||
placeholder: "Enter Message",
|
||||
autocapitalizationType: .none,
|
||||
autocorrectionType: .no,
|
||||
returnKeyType: .done,
|
||||
characterLimit: 70,
|
||||
displayCharacterLimit: true,
|
||||
emptyLineHandling: .notAllowed,
|
||||
updated: { _ in
|
||||
},
|
||||
returnKeyAction: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if let titleView = self.introSection.findTaggedView(tag: self.textInputTag) as? ListMultilineTextFieldItemComponent.View {
|
||||
titleView.endEditing(true)
|
||||
}
|
||||
},
|
||||
textUpdateTransition: .spring(duration: 0.4),
|
||||
tag: self.textInputTag
|
||||
))))
|
||||
@ -1083,6 +1105,7 @@ final class BusinessIntroSetupScreenComponent: Component {
|
||||
|
||||
let previousBounds = self.scrollView.bounds
|
||||
|
||||
self.ignoreScrolling = true
|
||||
let contentSize = CGSize(width: availableSize.width, height: contentHeight)
|
||||
if self.scrollView.frame != CGRect(origin: CGPoint(), size: availableSize) {
|
||||
self.scrollView.frame = CGRect(origin: CGPoint(), size: availableSize)
|
||||
@ -1123,6 +1146,7 @@ final class BusinessIntroSetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
self.topOverscrollLayer.frame = CGRect(origin: CGPoint(x: 0.0, y: -3000.0), size: CGSize(width: availableSize.width, height: 3000.0))
|
||||
self.ignoreScrolling = false
|
||||
|
||||
self.updateScrolling(transition: transition)
|
||||
|
||||
|
||||
@ -109,9 +109,11 @@ public final class TextFieldComponent: Component {
|
||||
public let characterLimit: Int?
|
||||
public let emptyLineHandling: EmptyLineHandling
|
||||
public let formatMenuAvailability: FormatMenuAvailability
|
||||
public let returnKeyType: UIReturnKeyType
|
||||
public let lockedFormatAction: () -> Void
|
||||
public let present: (ViewController) -> Void
|
||||
public let paste: (PasteData) -> Void
|
||||
public let returnKeyAction: (() -> Void)?
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
@ -128,9 +130,11 @@ public final class TextFieldComponent: Component {
|
||||
characterLimit: Int? = nil,
|
||||
emptyLineHandling: EmptyLineHandling = .allowed,
|
||||
formatMenuAvailability: FormatMenuAvailability,
|
||||
returnKeyType: UIReturnKeyType = .default,
|
||||
lockedFormatAction: @escaping () -> Void,
|
||||
present: @escaping (ViewController) -> Void,
|
||||
paste: @escaping (PasteData) -> Void
|
||||
paste: @escaping (PasteData) -> Void,
|
||||
returnKeyAction: (() -> Void)? = nil
|
||||
) {
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
@ -146,9 +150,11 @@ public final class TextFieldComponent: Component {
|
||||
self.characterLimit = characterLimit
|
||||
self.emptyLineHandling = emptyLineHandling
|
||||
self.formatMenuAvailability = formatMenuAvailability
|
||||
self.returnKeyType = returnKeyType
|
||||
self.lockedFormatAction = lockedFormatAction
|
||||
self.present = present
|
||||
self.paste = paste
|
||||
self.returnKeyAction = returnKeyAction
|
||||
}
|
||||
|
||||
public static func ==(lhs: TextFieldComponent, rhs: TextFieldComponent) -> Bool {
|
||||
@ -194,6 +200,9 @@ public final class TextFieldComponent: Component {
|
||||
if lhs.formatMenuAvailability != rhs.formatMenuAvailability {
|
||||
return false
|
||||
}
|
||||
if lhs.returnKeyType != rhs.returnKeyType {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -408,6 +417,13 @@ public final class TextFieldComponent: Component {
|
||||
}
|
||||
|
||||
public func chatInputTextNodeShouldReturn() -> Bool {
|
||||
guard let component = self.component else {
|
||||
return true
|
||||
}
|
||||
if let returnKeyAction = component.returnKeyAction {
|
||||
returnKeyAction()
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -565,6 +581,7 @@ public final class TextFieldComponent: Component {
|
||||
guard let component = self.component else {
|
||||
return true
|
||||
}
|
||||
|
||||
if let characterLimit = component.characterLimit {
|
||||
let string = self.inputState.inputText.string as NSString
|
||||
let updatedString = string.replacingCharacters(in: range, with: text)
|
||||
@ -582,6 +599,11 @@ public final class TextFieldComponent: Component {
|
||||
return false
|
||||
}
|
||||
case .notAllowed:
|
||||
if (range.length == 0 && text == "\n"), let returnKeyAction = component.returnKeyAction {
|
||||
returnKeyAction()
|
||||
return false
|
||||
}
|
||||
|
||||
let string = self.inputState.inputText.string as NSString
|
||||
let updatedString = string.replacingCharacters(in: range, with: text)
|
||||
if updatedString.range(of: "\n") != nil {
|
||||
@ -1081,6 +1103,10 @@ public final class TextFieldComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
if self.textView.returnKeyType != component.returnKeyType {
|
||||
self.textView.returnKeyType = component.returnKeyType
|
||||
}
|
||||
|
||||
if let initialText = component.externalState.initialText {
|
||||
component.externalState.initialText = nil
|
||||
self.updateInputState { _ in
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user