import Foundation import UIKit import SwiftSignalKit import AsyncDisplayKit import Display import TelegramCore import TelegramPresentationData import AccountContext import ComponentFlow import AlertComponent import AlertInputFieldComponent public func quickReplyNameAlertController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal)? = nil, text: String, subtext: String, value: String?, characterLimit: Int, apply: @escaping (String?) -> Void) -> (controller: AlertScreen, displayError: (String) -> Void) { let presentationData = context.sharedContext.currentPresentationData.with { $0 } let strings = presentationData.strings let inputState = AlertInputFieldComponent.ExternalState() var applyImpl: (() -> Void)? let errorPromise = ValuePromise(nil) let contentSignal = errorPromise.get() |> map { error in var content: [AnyComponentWithIdentity] = [] content.append(AnyComponentWithIdentity( id: "title", component: AnyComponent( AlertTitleComponent(title: text) ) )) if let error { content.append(AnyComponentWithIdentity( id: "text", component: AnyComponent( AlertTextComponent(content: .plain(error), color: .destructive) ) )) } else { content.append(AnyComponentWithIdentity( id: "text", component: AnyComponent( AlertTextComponent(content: .plain(subtext)) ) )) } content.append(AnyComponentWithIdentity( id: "input", component: AnyComponent( AlertInputFieldComponent( context: context, initialValue: value, placeholder: strings.QuickReply_ShortcutPlaceholder, characterLimit: characterLimit, hasClearButton: false, keyboardType: .URL, autocapitalizationType: .none, autocorrectionType: .no, isInitiallyFocused: true, externalState: inputState, shouldChangeText: { updatedText in if updatedText.isEmpty { return true } for scalar in updatedText.unicodeScalars { if scalar.value == 0x5f || scalar.value == 0x200c || scalar.value == 0xb7 || (scalar.value >= 0xd80 && scalar.value <= 0xdff) { continue } if CharacterSet.letters.contains(scalar) || CharacterSet.decimalDigits.contains(scalar) { continue } return false } return true }, returnKeyAction: { applyImpl?() } ) ) )) return content } var effectiveUpdatedPresentationData: (PresentationData, Signal) if let updatedPresentationData { effectiveUpdatedPresentationData = updatedPresentationData } else { effectiveUpdatedPresentationData = (presentationData, context.sharedContext.presentationData) } let alertController = AlertScreen( configuration: AlertScreen.Configuration(allowInputInset: true), contentSignal: contentSignal, actionsSignal: .single([ .init(title: strings.Common_Cancel, action: { apply(nil) }), .init(title: strings.Common_Done, type: .default, action: { applyImpl?() }, autoDismiss: false) ]), updatedPresentationData: effectiveUpdatedPresentationData ) applyImpl = { apply(inputState.value) } let displayError = { [weak inputState] error in errorPromise.set(error) inputState?.animateError() HapticFeedback().error() } return (alertController, displayError) }