mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Various fixes
This commit is contained in:
parent
afaba07b76
commit
9d703f5b60
14 changed files with 188 additions and 55 deletions
|
|
@ -1296,7 +1296,7 @@ public protocol SharedAccountContext: AnyObject {
|
|||
|
||||
func makeIncomingMessagePrivacyScreen(context: AccountContext, value: GlobalPrivacySettings.NonContactChatsPrivacy, exceptions: SelectivePrivacySettings, update: @escaping (GlobalPrivacySettings.NonContactChatsPrivacy) -> Void) -> ViewController
|
||||
|
||||
func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, botPeer: EnginePeer, chatPeer: EnginePeer?, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?)
|
||||
func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, botPeer: EnginePeer, chatPeer: EnginePeer?, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?, verifyAgeCompletion: ((Int) -> Void)?)
|
||||
|
||||
func makeAffiliateProgramSetupScreenInitialData(context: AccountContext, peerId: EnginePeer.Id, mode: AffiliateProgramSetupScreenMode) -> Signal<AffiliateProgramSetupScreenInitialData, NoError>
|
||||
func makeAffiliateProgramSetupScreen(context: AccountContext, initialData: AffiliateProgramSetupScreenInitialData) -> ViewController
|
||||
|
|
|
|||
|
|
@ -1250,7 +1250,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true,
|
||||
payload: nil
|
||||
payload: nil,
|
||||
verifyAgeCompletion: nil
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3282,7 +3282,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true,
|
||||
payload: nil
|
||||
payload: nil,
|
||||
verifyAgeCompletion: nil
|
||||
)
|
||||
interaction.dismissSearch()
|
||||
}
|
||||
|
|
@ -4268,7 +4269,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true,
|
||||
payload: nil
|
||||
payload: nil,
|
||||
verifyAgeCompletion: nil
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4287,7 +4289,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true,
|
||||
payload: nil
|
||||
payload: nil,
|
||||
verifyAgeCompletion: nil
|
||||
)
|
||||
interaction.dismissSearch()
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -405,6 +405,20 @@ public func presentAgeVerification(context: AccountContext, parentController: Vi
|
|||
if state.verificationPassed {
|
||||
completion()
|
||||
} else {
|
||||
let miniappPromise = Promise<EnginePeer?>(nil)
|
||||
var useVerifyAgeBot = false
|
||||
if let value = context.currentAppConfiguration.with({ $0 }).data?["force_verify_age_bot"] as? Bool, value {
|
||||
useVerifyAgeBot = value
|
||||
}
|
||||
if useVerifyAgeBot, let verifyAgeBotUsername = context.currentAppConfiguration.with({ $0 }).data?["verify_age_bot_username"] as? String {
|
||||
miniappPromise.set(context.engine.peers.resolvePeerByName(name: verifyAgeBotUsername, referrer: nil)
|
||||
|> mapToSignal { result in
|
||||
if case let .result(peer) = result {
|
||||
return .single(peer)
|
||||
}
|
||||
return .complete()
|
||||
})
|
||||
}
|
||||
let infoScreen = AgeVerificationScreen(context: context, completion: { [weak parentController] check, availability in
|
||||
if check {
|
||||
var requiredAge = 18
|
||||
|
|
@ -412,24 +426,60 @@ public func presentAgeVerification(context: AccountContext, parentController: Vi
|
|||
requiredAge = Int(value)
|
||||
}
|
||||
|
||||
let scanScreen = FaceScanScreen(context: context, availability: availability, requiredAge: requiredAge, completion: { [weak parentController] passed in
|
||||
if passed {
|
||||
let _ = updateAgeVerificationState(engine: context.engine, { _ in
|
||||
return AgeVerificationState(verificationPassed: passed)
|
||||
}).start()
|
||||
completion()
|
||||
|
||||
let navigationController = parentController?.navigationController
|
||||
Queue.mainQueue().after(2.0) {
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .actionSucceeded(title: presentationData.strings.AgeVerification_Success_Title, text: presentationData.strings.AgeVerification_Success_Text, cancel: nil, destructive: false), action: { _ in return true })
|
||||
(navigationController?.viewControllers.last as? ViewController)?.present(controller, in: .window(.root))
|
||||
}
|
||||
let success = { [weak parentController] in
|
||||
let _ = updateAgeVerificationState(engine: context.engine, { _ in
|
||||
return AgeVerificationState(verificationPassed: true)
|
||||
}).start()
|
||||
completion()
|
||||
|
||||
let navigationController = parentController?.navigationController
|
||||
Queue.mainQueue().after(2.0) {
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .actionSucceeded(title: presentationData.strings.AgeVerification_Success_Title, text: presentationData.strings.AgeVerification_Success_Text, cancel: nil, destructive: false), action: { _ in return true })
|
||||
(navigationController?.viewControllers.last as? ViewController)?.present(controller, in: .current)
|
||||
}
|
||||
}
|
||||
|
||||
let failure = { [weak parentController] in
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_banned", scale: 0.066, colors: [:], title: presentationData.strings.AgeVerification_Fail_Title, text: presentationData.strings.AgeVerification_Fail_Text, customUndoText: nil, timeout: nil), action: { _ in return true })
|
||||
parentController?.present(controller, in: .current)
|
||||
}
|
||||
|
||||
let _ = (miniappPromise.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
if let peer, let parentController {
|
||||
context.sharedContext.openWebApp(
|
||||
context: context,
|
||||
parentController: parentController,
|
||||
updatedPresentationData: nil,
|
||||
botPeer: peer,
|
||||
chatPeer: nil,
|
||||
threadId: nil,
|
||||
buttonText: "",
|
||||
url: "",
|
||||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true,
|
||||
payload: nil,
|
||||
verifyAgeCompletion: { age in
|
||||
if age >= requiredAge {
|
||||
success()
|
||||
} else {
|
||||
failure()
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
let controller = UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_banned", scale: 0.066, colors: [:], title: presentationData.strings.AgeVerification_Fail_Title, text: presentationData.strings.AgeVerification_Fail_Text, customUndoText: nil, timeout: nil), action: { _ in return true })
|
||||
parentController?.present(controller, in: .window(.root))
|
||||
let scanScreen = FaceScanScreen(context: context, availability: availability, completion: { age in
|
||||
if age >= requiredAge {
|
||||
success()
|
||||
} else {
|
||||
failure()
|
||||
}
|
||||
})
|
||||
parentController?.push(scanScreen)
|
||||
}
|
||||
})
|
||||
parentController?.push(scanScreen)
|
||||
}
|
||||
})
|
||||
parentController?.push(infoScreen)
|
||||
|
|
|
|||
|
|
@ -25,16 +25,13 @@ final class FaceScanScreenComponent: Component {
|
|||
|
||||
let context: AccountContext
|
||||
let availability: Signal<AgeVerificationAvailability, NoError>
|
||||
let requiredAge: Int
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
availability: Signal<AgeVerificationAvailability, NoError>,
|
||||
requiredAge: Int
|
||||
availability: Signal<AgeVerificationAvailability, NoError>
|
||||
) {
|
||||
self.context = context
|
||||
self.availability = availability
|
||||
self.requiredAge = requiredAge
|
||||
}
|
||||
|
||||
static func ==(lhs: FaceScanScreenComponent, rhs: FaceScanScreenComponent) -> Bool {
|
||||
|
|
@ -307,7 +304,7 @@ final class FaceScanScreenComponent: Component {
|
|||
}
|
||||
|
||||
private func fillSegment(_ segmentIndex: Int) {
|
||||
guard let component = self.component, !self.completedAngles.contains(segmentIndex) else {
|
||||
guard !self.completedAngles.contains(segmentIndex) else {
|
||||
return
|
||||
}
|
||||
self.completedAngles.insert(segmentIndex)
|
||||
|
|
@ -321,7 +318,7 @@ final class FaceScanScreenComponent: Component {
|
|||
if !self.ages.isEmpty {
|
||||
let averageAge = self.ages.reduce(0, +) / Double(self.ages.count)
|
||||
if let environment = self.environment, let controller = environment.controller() as? FaceScanScreen {
|
||||
controller.completion(averageAge >= Double(component.requiredAge))
|
||||
controller.completion(Int(averageAge))
|
||||
controller.dismiss(animated: true)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -437,7 +434,7 @@ final class FaceScanScreenComponent: Component {
|
|||
|
||||
let center = CGPoint(x: availableSize.width / 2, y: environment.statusBarHeight + 10.0 + widthRadius * 1.3)
|
||||
|
||||
var previewScale = 1.0
|
||||
var previewScale = 0.85
|
||||
if self.processState == .tracking || self.processState == .readyToStart || self.processState == .completed || self.transitioningToViewFinder {
|
||||
let circlePath = CGPath(roundedRect: CGRect(x: center.x - radius, y: center.y - radius, width: radius * 2, height: radius * 2), cornerWidth: radius, cornerHeight: radius, transform: nil)
|
||||
path.addPath(circlePath)
|
||||
|
|
@ -545,21 +542,19 @@ final class FaceScanScreenComponent: Component {
|
|||
|
||||
public final class FaceScanScreen: ViewControllerComponentContainer {
|
||||
private let context: AccountContext
|
||||
fileprivate let completion: (Bool) -> Void
|
||||
fileprivate let completion: (Int) -> Void
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
availability: Signal<AgeVerificationAvailability, NoError>,
|
||||
requiredAge: Int,
|
||||
completion: @escaping (Bool) -> Void
|
||||
completion: @escaping (Int) -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.completion = completion
|
||||
|
||||
super.init(context: context, component: FaceScanScreenComponent(
|
||||
context: context,
|
||||
availability: availability,
|
||||
requiredAge: requiredAge
|
||||
availability: availability
|
||||
), navigationBarAppearance: .none, theme: .default, updatedPresentationData: nil)
|
||||
|
||||
self.title = ""
|
||||
|
|
|
|||
|
|
@ -1257,7 +1257,8 @@ final class AffiliateProgramSetupScreenComponent: Component {
|
|||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true,
|
||||
payload: nil
|
||||
payload: nil,
|
||||
verifyAgeCompletion: nil
|
||||
)
|
||||
} else if let navigationController = controller.navigationController as? NavigationController {
|
||||
component.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: component.context, chatLocation: .peer(item.peer), subject: nil, keepStack: .always, animated: true, pushController: { [weak navigationController] chatController, animated, completion in
|
||||
|
|
|
|||
|
|
@ -1451,7 +1451,8 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
|||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true,
|
||||
payload: nil
|
||||
payload: nil,
|
||||
verifyAgeCompletion: nil
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||
return
|
||||
}
|
||||
|
||||
let promptController = promptController(sharedContext: self.context.sharedContext, updatedPresentationData: nil, text: params.presentationData.strings.PeerInfo_Gifts_CreateCollection_Title, titleFont: .bold, subtitle: params.presentationData.strings.PeerInfo_Gifts_CreateCollection_Text, value: "", placeholder: params.presentationData.strings.PeerInfo_Gifts_CreateCollection_Placeholder, characterLimit: 20, displayCharacterLimit: true, apply: { [weak self] value in
|
||||
let promptController = promptController(sharedContext: self.context.sharedContext, updatedPresentationData: nil, text: params.presentationData.strings.PeerInfo_Gifts_CreateCollection_Title, titleFont: .bold, subtitle: params.presentationData.strings.PeerInfo_Gifts_CreateCollection_Text, value: "", placeholder: params.presentationData.strings.PeerInfo_Gifts_CreateCollection_Placeholder, characterLimit: 12, displayCharacterLimit: true, apply: { [weak self] value in
|
||||
guard let self, let value else {
|
||||
return
|
||||
}
|
||||
|
|
@ -264,7 +264,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||
return
|
||||
}
|
||||
|
||||
let promptController = promptController(sharedContext: self.context.sharedContext, updatedPresentationData: nil, text: params.presentationData.strings.PeerInfo_Gifts_RenameCollection_Title, titleFont: .bold, value: collection.title, placeholder: params.presentationData.strings.PeerInfo_Gifts_CreateCollection_Placeholder, characterLimit: 20, displayCharacterLimit: true, apply: { [weak self] value in
|
||||
let promptController = promptController(sharedContext: self.context.sharedContext, updatedPresentationData: nil, text: params.presentationData.strings.PeerInfo_Gifts_RenameCollection_Title, titleFont: .bold, value: collection.title, placeholder: params.presentationData.strings.PeerInfo_Gifts_CreateCollection_Placeholder, characterLimit: 12, displayCharacterLimit: true, apply: { [weak self] value in
|
||||
guard let self, let value else {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -900,7 +900,21 @@ final class AuthorizedApplicationContext {
|
|||
}
|
||||
|
||||
if openAppIfAny, case let .user(user) = peer, let botInfo = user.botInfo, botInfo.flags.contains(.hasWebApp), let parentController = self.rootController.viewControllers.last as? ViewController {
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: parentController, updatedPresentationData: nil, botPeer: peer, chatPeer: nil, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: true, payload: nil)
|
||||
self.context.sharedContext.openWebApp(
|
||||
context: self.context,
|
||||
parentController: parentController,
|
||||
updatedPresentationData: nil,
|
||||
botPeer: peer,
|
||||
chatPeer: nil,
|
||||
threadId: nil,
|
||||
buttonText: "",
|
||||
url: "",
|
||||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true,
|
||||
payload: nil,
|
||||
verifyAgeCompletion: nil
|
||||
)
|
||||
} else {
|
||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: alwaysKeepMessageId || isOutgoingMessage ? messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false) } : nil, activateInput: activateInput ? .text : nil))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ func openWebAppImpl(
|
|||
simple: Bool,
|
||||
source: ChatOpenWebViewSource,
|
||||
skipTermsOfService: Bool,
|
||||
payload: String?
|
||||
payload: String?,
|
||||
verifyAgeCompletion: ((Int) -> Void)?
|
||||
) {
|
||||
if context.isFrozen {
|
||||
parentController.push(context.sharedContext.makeAccountFreezeInfoScreen(context: context))
|
||||
|
|
@ -246,7 +247,7 @@ func openWebAppImpl(
|
|||
navigationController = parentController.effectiveNavigationController
|
||||
}
|
||||
return navigationController ?? (context.sharedContext.mainWindow?.viewController as? NavigationController)
|
||||
})
|
||||
}, verifyAgeCompletion: verifyAgeCompletion)
|
||||
controller.navigationPresentation = .flatModal
|
||||
parentController.push(controller)
|
||||
|
||||
|
|
@ -351,7 +352,21 @@ public extension ChatControllerImpl {
|
|||
}
|
||||
self.chatDisplayNode.dismissInput()
|
||||
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, botPeer: EnginePeer(peer), chatPeer: EnginePeer(peer), threadId: self.chatLocation.threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: false, payload: nil)
|
||||
self.context.sharedContext.openWebApp(
|
||||
context: self.context,
|
||||
parentController: self,
|
||||
updatedPresentationData: self.updatedPresentationData,
|
||||
botPeer: EnginePeer(peer),
|
||||
chatPeer: EnginePeer(peer),
|
||||
threadId: self.chatLocation.threadId,
|
||||
buttonText: buttonText,
|
||||
url: url,
|
||||
simple: simple,
|
||||
source: source,
|
||||
skipTermsOfService: false,
|
||||
payload: nil,
|
||||
verifyAgeCompletion: nil
|
||||
)
|
||||
}
|
||||
|
||||
fileprivate static func botRequestSwitchInline(context: AccountContext, controller: ChatControllerImpl?, peerId: EnginePeer.Id, botAddress: String, query: String, chatTypes: [ReplyMarkupButtonRequestPeerType]?, completion: @escaping () -> Void) -> Void {
|
||||
|
|
@ -616,7 +631,21 @@ public extension ChatControllerImpl {
|
|||
}
|
||||
})
|
||||
} else {
|
||||
context.sharedContext.openWebApp(context: context, parentController: parentController, updatedPresentationData: updatedPresentationData, botPeer: botPeer, chatPeer: nil, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false, payload: payload)
|
||||
context.sharedContext.openWebApp(
|
||||
context: context,
|
||||
parentController: parentController,
|
||||
updatedPresentationData: updatedPresentationData,
|
||||
botPeer: botPeer,
|
||||
chatPeer: nil,
|
||||
threadId: nil,
|
||||
buttonText: "",
|
||||
url: "",
|
||||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: false,
|
||||
payload: payload,
|
||||
verifyAgeCompletion: nil
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8907,7 +8907,21 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
commit()
|
||||
})
|
||||
} else {
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, botPeer: peer, chatPeer: nil, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false, payload: botAppStart.payload)
|
||||
self.context.sharedContext.openWebApp(
|
||||
context: self.context,
|
||||
parentController: self,
|
||||
updatedPresentationData: self.updatedPresentationData,
|
||||
botPeer: peer,
|
||||
chatPeer: nil,
|
||||
threadId: nil,
|
||||
buttonText: "",
|
||||
url: "",
|
||||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: false,
|
||||
payload: botAppStart.payload,
|
||||
verifyAgeCompletion: nil
|
||||
)
|
||||
commit()
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3882,8 +3882,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||
return incomingMessagePrivacyScreen(context: context, value: value, exceptions: exceptions, update: update)
|
||||
}
|
||||
|
||||
public func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, botPeer: EnginePeer, chatPeer: EnginePeer?, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?) {
|
||||
openWebAppImpl(context: context, parentController: parentController, updatedPresentationData: updatedPresentationData, botPeer: botPeer, chatPeer: chatPeer, threadId: threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: skipTermsOfService, payload: payload)
|
||||
public func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, botPeer: EnginePeer, chatPeer: EnginePeer?, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?, verifyAgeCompletion: ((Int) -> Void)?) {
|
||||
openWebAppImpl(context: context, parentController: parentController, updatedPresentationData: updatedPresentationData, botPeer: botPeer, chatPeer: chatPeer, threadId: threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: skipTermsOfService, payload: payload, verifyAgeCompletion: verifyAgeCompletion)
|
||||
}
|
||||
|
||||
public func makeAffiliateProgramSetupScreenInitialData(context: AccountContext, peerId: EnginePeer.Id, mode: AffiliateProgramSetupScreenMode) -> Signal<AffiliateProgramSetupScreenInitialData, NoError> {
|
||||
|
|
|
|||
|
|
@ -653,10 +653,14 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||
self.animateTransitionIn()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@available(iOSApplicationExtension 15.0, iOS 15.0, *)
|
||||
func webView(_ webView: WKWebView, requestMediaCapturePermissionFor origin: WKSecurityOrigin, initiatedByFrame frame: WKFrameInfo, type: WKMediaCaptureType, decisionHandler: @escaping (WKPermissionDecision) -> Void) {
|
||||
decisionHandler(.prompt)
|
||||
if self.controller?.isVerifyAgeBot == true && type == .camera {
|
||||
decisionHandler(.grant)
|
||||
} else {
|
||||
decisionHandler(.prompt)
|
||||
}
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
|
||||
|
|
@ -1756,6 +1760,12 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||
}
|
||||
case "web_app_hide_keyboard":
|
||||
self.view.window?.endEditing(true)
|
||||
case "web_app_verify_age":
|
||||
if let json, self.controller?.isVerifyAgeBot == true {
|
||||
if let ageValue = json["age"] as? Double {
|
||||
self.controller?.verifyAgeCompletion?(Int(ageValue))
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
@ -3281,6 +3291,8 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||
public var completion: () -> Void = {}
|
||||
public var requestSwitchInline: (String, [ReplyMarkupButtonRequestPeerType]?, @escaping () -> Void) -> Void = { _, _, _ in }
|
||||
|
||||
public var verifyAgeCompletion: ((Int) -> Void)?
|
||||
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, params: WebAppParameters, replyToMessageId: MessageId?, threadId: Int64?) {
|
||||
self.context = context
|
||||
self.source = params.source
|
||||
|
|
@ -3323,16 +3335,20 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||
self.navigationItem.leftBarButtonItem?.action = #selector(self.cancelPressed)
|
||||
self.navigationItem.leftBarButtonItem?.target = self
|
||||
|
||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customDisplayNode: self.moreButtonNode)
|
||||
self.navigationItem.rightBarButtonItem?.action = #selector(self.moreButtonPressed)
|
||||
self.navigationItem.rightBarButtonItem?.target = self
|
||||
if !self.isVerifyAgeBot {
|
||||
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customDisplayNode: self.moreButtonNode)
|
||||
self.navigationItem.rightBarButtonItem?.action = #selector(self.moreButtonPressed)
|
||||
self.navigationItem.rightBarButtonItem?.target = self
|
||||
}
|
||||
|
||||
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Back, style: .plain, target: nil, action: nil)
|
||||
|
||||
let titleView = WebAppTitleView(context: self.context, theme: self.presentationData.theme)
|
||||
titleView.title = WebAppTitle(title: params.botName, counter: self.presentationData.strings.WebApp_Miniapp, isVerified: params.botVerified)
|
||||
self.navigationItem.titleView = titleView
|
||||
self.titleView = titleView
|
||||
if !self.isVerifyAgeBot {
|
||||
let titleView = WebAppTitleView(context: self.context, theme: self.presentationData.theme)
|
||||
titleView.title = WebAppTitle(title: params.botName, counter: self.presentationData.strings.WebApp_Miniapp, isVerified: params.botVerified)
|
||||
self.navigationItem.titleView = titleView
|
||||
self.titleView = titleView
|
||||
}
|
||||
|
||||
self.moreButtonNode.action = { [weak self] _, gesture in
|
||||
if let strongSelf = self {
|
||||
|
|
@ -3387,6 +3403,13 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||
self.presentationDataDisposable?.dispose()
|
||||
}
|
||||
|
||||
private var isVerifyAgeBot: Bool {
|
||||
if let ageBotUsername = self.context.currentAppConfiguration.with({ $0 }).data?["verify_age_bot_username"] as? String {
|
||||
return self.botAddress == ageBotUsername
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public func beforeMaximize(navigationController: NavigationController, completion: @escaping () -> Void) {
|
||||
switch self.source {
|
||||
case .generic, .settings:
|
||||
|
|
@ -3857,7 +3880,8 @@ public func standaloneWebAppController(
|
|||
willDismiss: @escaping () -> Void = {},
|
||||
didDismiss: @escaping () -> Void = {},
|
||||
getNavigationController: @escaping () -> NavigationController? = { return nil },
|
||||
getSourceRect: (() -> CGRect?)? = nil
|
||||
getSourceRect: (() -> CGRect?)? = nil,
|
||||
verifyAgeCompletion: ((Int) -> Void)? = nil
|
||||
) -> ViewController {
|
||||
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: .peer(id: params.peerId), buttons: [.standalone], initialButton: .standalone, fromMenu: params.source == .menu, hasTextInput: false, isFullSize: params.fullSize, makeEntityInputView: {
|
||||
return nil
|
||||
|
|
@ -3868,6 +3892,7 @@ public func standaloneWebAppController(
|
|||
webAppController.completion = completion
|
||||
webAppController.getNavigationController = getNavigationController
|
||||
webAppController.requestSwitchInline = requestSwitchInline
|
||||
webAppController.verifyAgeCompletion = verifyAgeCompletion
|
||||
present(webAppController, webAppController.mediaPickerContext)
|
||||
}
|
||||
controller.willDismiss = willDismiss
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"app": "11.14",
|
||||
"app": "11.13.3",
|
||||
"xcode": "16.2",
|
||||
"bazel": "8.2.1:22ff65b05869f6160e5157b1b425a14a62085d71d8baef571f462b8fe5a703a3",
|
||||
"macos": "15"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue