diff --git a/TelegramUI/AuthorizationSequenceCodeEntryController.swift b/TelegramUI/AuthorizationSequenceCodeEntryController.swift index eef0423adf..aa22851d01 100644 --- a/TelegramUI/AuthorizationSequenceCodeEntryController.swift +++ b/TelegramUI/AuthorizationSequenceCodeEntryController.swift @@ -17,7 +17,7 @@ final class AuthorizationSequenceCodeEntryController: ViewController { var requestNextOption: (() -> Void)? var data: (String, SentAuthorizationCodeType, AuthorizationCodeNextType?, Int32?)? - var termsOfService: UnauthorizedAccountTermsOfService? + var termsOfService: (UnauthorizedAccountTermsOfService, Bool)? private let hapticFeedback = HapticFeedback() @@ -80,7 +80,7 @@ final class AuthorizationSequenceCodeEntryController: ViewController { self.controllerNode.activateInput() } - func updateData(number: String, codeType: SentAuthorizationCodeType, nextType: AuthorizationCodeNextType?, timeout: Int32?, termsOfService: UnauthorizedAccountTermsOfService?) { + func updateData(number: String, codeType: SentAuthorizationCodeType, nextType: AuthorizationCodeNextType?, timeout: Int32?, termsOfService: (UnauthorizedAccountTermsOfService, Bool)?) { self.termsOfService = termsOfService if self.data?.0 != number || self.data?.1 != codeType || self.data?.2 != nextType || self.data?.3 != timeout { self.data = (number, codeType, nextType, timeout) @@ -124,7 +124,7 @@ final class AuthorizationSequenceCodeEntryController: ViewController { } private func continueWithCode(_ code: String) { - if let termsOfService = self.termsOfService { + if let (termsOfService, exclusuve) = self.termsOfService, exclusuve { var acceptImpl: (() -> Void)? var declineImpl: (() -> Void)? let controller = TermsOfServiceController(theme: TermsOfServiceControllerTheme(authTheme: self.theme), strings: self.strings, text: termsOfService.text, entities: termsOfService.entities, ageConfirmation: termsOfService.ageConfirmation, signingUp: true, accept: { _ in diff --git a/TelegramUI/AuthorizationSequenceController.swift b/TelegramUI/AuthorizationSequenceController.swift index 9c6c46e150..6e58f099c9 100644 --- a/TelegramUI/AuthorizationSequenceController.swift +++ b/TelegramUI/AuthorizationSequenceController.swift @@ -169,7 +169,7 @@ public final class AuthorizationSequenceController: NavigationController { return controller } - private func codeEntryController(number: String, type: SentAuthorizationCodeType, nextType: AuthorizationCodeNextType?, timeout: Int32?, termsOfService: UnauthorizedAccountTermsOfService?) -> AuthorizationSequenceCodeEntryController { + private func codeEntryController(number: String, type: SentAuthorizationCodeType, nextType: AuthorizationCodeNextType?, timeout: Int32?, termsOfService: (UnauthorizedAccountTermsOfService, Bool)?) -> AuthorizationSequenceCodeEntryController { var currentController: AuthorizationSequenceCodeEntryController? for c in self.viewControllers { if let c = c as? AuthorizationSequenceCodeEntryController { @@ -190,7 +190,7 @@ public final class AuthorizationSequenceController: NavigationController { if let strongSelf = self { controller?.inProgress = true - strongSelf.actionDisposable.set((authorizeWithCode(account: strongSelf.account, code: code) |> deliverOnMainQueue).start(error: { error in + strongSelf.actionDisposable.set((authorizeWithCode(account: strongSelf.account, code: code, termsOfService: termsOfService?.0) |> deliverOnMainQueue).start(error: { error in Queue.mainQueue().async { if let strongSelf = self, let controller = controller { controller.inProgress = false @@ -475,7 +475,7 @@ public final class AuthorizationSequenceController: NavigationController { return controller } - private func signUpController(firstName: String, lastName: String) -> AuthorizationSequenceSignUpController { + private func signUpController(firstName: String, lastName: String, termsOfService: UnauthorizedAccountTermsOfService?) -> AuthorizationSequenceSignUpController { var currentController: AuthorizationSequenceSignUpController? for c in self.viewControllers { if let c = c as? AuthorizationSequenceSignUpController { @@ -519,7 +519,7 @@ public final class AuthorizationSequenceController: NavigationController { } } } - controller.updateData(firstName: firstName, lastName: lastName) + controller.updateData(firstName: firstName, lastName: lastName, termsOfService: termsOfService) return controller } @@ -541,8 +541,8 @@ public final class AuthorizationSequenceController: NavigationController { self.setViewControllers([self.splashController(), self.passwordRecoveryController(emailPattern: emailPattern)], animated: !self.viewControllers.isEmpty) case let .awaitingAccountReset(protectedUntil, number): self.setViewControllers([self.splashController(), self.awaitingAccountResetController(protectedUntil: protectedUntil, number: number)], animated: !self.viewControllers.isEmpty) - case let .signUp(_, _, _, firstName, lastName): - self.setViewControllers([self.splashController(), self.signUpController(firstName: firstName, lastName: lastName)], animated: !self.viewControllers.isEmpty) + case let .signUp(_, _, _, firstName, lastName, termsOfService): + self.setViewControllers([self.splashController(), self.signUpController(firstName: firstName, lastName: lastName, termsOfService: termsOfService)], animated: !self.viewControllers.isEmpty) } } else if let _ = state as? AuthorizedAccountState { } diff --git a/TelegramUI/AuthorizationSequenceSignUpController.swift b/TelegramUI/AuthorizationSequenceSignUpController.swift index c92eee5567..6d10e8f615 100644 --- a/TelegramUI/AuthorizationSequenceSignUpController.swift +++ b/TelegramUI/AuthorizationSequenceSignUpController.swift @@ -2,6 +2,7 @@ import Foundation import Display import AsyncDisplayKit import SwiftSignalKit +import TelegramCore import LegacyComponents @@ -14,6 +15,8 @@ final class AuthorizationSequenceSignUpController: ViewController { private let theme: AuthorizationTheme var initialName: (String, String) = ("", "") + private var termsOfService: UnauthorizedAccountTermsOfService? + var signUpWithName: ((String, String, Data?) -> Void)? private let hapticFeedback = HapticFeedback() @@ -63,6 +66,15 @@ final class AuthorizationSequenceSignUpController: ViewController { self.controllerNode.signUpWithName = { [weak self] _, _ in self?.nextPressed() } + self.controllerNode.openTermsOfService = { [weak self] in + guard let strongSelf = self, let termsOfService = strongSelf.termsOfService else { + return + } + strongSelf.view.endEditing(true) + strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: defaultPresentationTheme), title: strongSelf.strings.Login_TermsOfServiceHeader, text: termsOfService.text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.strings.Common_OK, action: {})]), in: .window(.root)) + } + + self.controllerNode.updateData(firstName: self.initialName.0, lastName: self.initialName.1, hasTermsOfService: self.termsOfService != nil) } override func viewDidAppear(_ animated: Bool) { @@ -71,13 +83,15 @@ final class AuthorizationSequenceSignUpController: ViewController { self.controllerNode.activateInput() } - func updateData(firstName: String, lastName: String) { + func updateData(firstName: String, lastName: String, termsOfService: UnauthorizedAccountTermsOfService?) { if self.isNodeLoaded { - if (firstName, lastName) != self.controllerNode.currentName { - self.controllerNode.updateData(firstName: firstName, lastName: lastName) + if (firstName, lastName) != self.controllerNode.currentName || self.termsOfService != termsOfService { + self.termsOfService = termsOfService + self.controllerNode.updateData(firstName: firstName, lastName: lastName, hasTermsOfService: termsOfService != nil) } } else { self.initialName = (firstName, lastName) + self.termsOfService = termsOfService } } diff --git a/TelegramUI/AuthorizationSequenceSignUpControllerNode.swift b/TelegramUI/AuthorizationSequenceSignUpControllerNode.swift index f0b2e9669e..0d7959d3ed 100644 --- a/TelegramUI/AuthorizationSequenceSignUpControllerNode.swift +++ b/TelegramUI/AuthorizationSequenceSignUpControllerNode.swift @@ -22,6 +22,7 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel private let titleNode: ASTextNode private let currentOptionNode: ASTextNode + private let termsNode: ImmediateTextNode private let firstNameField: TextFieldNode private let lastNameField: TextFieldNode @@ -53,7 +54,7 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel } var signUpWithName: ((String, String) -> Void)? - var requestNextOption: (() -> Void)? + var openTermsOfService: (() -> Void)? var inProgress: Bool = false { didSet { @@ -77,6 +78,14 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel self.currentOptionNode.displaysAsynchronously = false self.currentOptionNode.attributedText = NSAttributedString(string: self.strings.Login_InfoHelp, font: Font.regular(16.0), textColor: theme.textPlaceholderColor, paragraphAlignment: .center) + self.termsNode = ImmediateTextNode() + self.termsNode.textAlignment = .center + self.termsNode.maximumNumberOfLines = 0 + self.termsNode.displaysAsynchronously = false + let body = MarkdownAttributeSet(font: Font.regular(16.0), textColor: theme.primaryColor) + let link = MarkdownAttributeSet(font: Font.regular(16.0), textColor: theme.accentColor, additionalAttributes: [TelegramTextAttributes.URL: ""]) + self.termsNode.attributedText = parseMarkdownIntoAttributedString(strings.Login_TermsOfServiceLabel.replacingOccurrences(of: "]", with: "]()"), attributes: MarkdownAttributes(body: body, bold: body, link: link, linkAttribute: { _ in nil }), textAlignment: .center) + self.firstSeparatorNode = ASDisplayNode() self.firstSeparatorNode.isLayerBacked = true self.firstSeparatorNode.backgroundColor = self.theme.separatorColor @@ -138,6 +147,8 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel self.addSubnode(self.lastNameField) self.addSubnode(self.titleNode) self.addSubnode(self.currentOptionNode) + self.addSubnode(self.termsNode) + self.termsNode.isHidden = true self.addSubnode(self.addPhotoButton) /*self.addPhotoButton.highligthedChanged = { [weak self] highlighted in @@ -157,11 +168,30 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel }*/ self.addPhotoButton.addTarget(self, action: #selector(self.addPhotoPressed), forControlEvents: .touchUpInside) + + self.termsNode.linkHighlightColor = self.theme.accentColor.withAlphaComponent(0.5) + self.termsNode.highlightAttributeAction = { attributes in + if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] { + return NSAttributedStringKey(rawValue: TelegramTextAttributes.URL) + } else { + return nil + } + } + self.termsNode.tapAttributeAction = { [weak self] attributes in + if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] { + self?.openTermsOfService?() + } + } } - func updateData(firstName: String, lastName: String) { + func updateData(firstName: String, lastName: String, hasTermsOfService: Bool) { + self.termsNode.isHidden = !hasTermsOfService self.firstNameField.textField.attributedPlaceholder = NSAttributedString(string: firstName, font: Font.regular(20.0), textColor: self.theme.textPlaceholderColor) self.lastNameField.textField.attributedPlaceholder = NSAttributedString(string: lastName, font: Font.regular(20.0), textColor: self.theme.textPlaceholderColor) + + if let (layout, navigationHeight) = self.layoutArguments { + self.containerLayoutUpdated(layout, navigationBarHeight: navigationHeight, transition: .immediate) + } } func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition) { @@ -193,12 +223,16 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel let minimalNoticeSpacing: CGFloat = 11.0 let maxNoticeSpacing: CGFloat = 35.0 let noticeSize = self.currentOptionNode.measure(CGSize(width: layout.size.width - 28.0, height: CGFloat.greatestFiniteMagnitude)) + let termsSize = self.termsNode.updateLayout(CGSize(width: layout.size.width - 28.0, height: CGFloat.greatestFiniteMagnitude)) + + let noticeHeight: CGFloat = noticeSize.height + (self.termsNode.isHidden ? 0.0 : (termsSize.height + 4.0)) + let minimalTermsOfServiceSpacing: CGFloat = 6.0 let maxTermsOfServiceSpacing: CGFloat = 20.0 let minTrailingSpacing: CGFloat = 10.0 let inputHeight = inputFieldsHeight - let essentialHeight = additionalTitleSpacing + titleSize.height + minimalTitleSpacing + inputHeight + minimalNoticeSpacing + noticeSize.height + let essentialHeight = additionalTitleSpacing + titleSize.height + minimalTitleSpacing + inputHeight + minimalNoticeSpacing + noticeHeight let additionalHeight = minimalTermsOfServiceSpacing + minTrailingSpacing let navigationHeight: CGFloat @@ -230,23 +264,24 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel transition.updateFrame(node: self.lastSeparatorNode, frame: CGRect(origin: CGPoint(x: leftInset, y: lastFieldFrame.maxY), size: CGSize(width: layout.size.width - leftInset, height: UIScreenPixel))) let additionalAvailableHeight = max(1.0, availableHeight - lastFieldFrame.maxY) - let additionalAvailableSpacing = max(1.0, additionalAvailableHeight - noticeSize.height) + let additionalAvailableSpacing = max(1.0, additionalAvailableHeight - noticeHeight) let noticeSpacingFactor = maxNoticeSpacing / (maxNoticeSpacing + maxTermsOfServiceSpacing + minTrailingSpacing) let termsOfServiceSpacingFactor = maxTermsOfServiceSpacing / (maxNoticeSpacing + maxTermsOfServiceSpacing + minTrailingSpacing) let noticeSpacing: CGFloat let termsOfServiceSpacing: CGFloat - if additionalAvailableHeight <= maxNoticeSpacing + noticeSize.height + maxTermsOfServiceSpacing + minTrailingSpacing { + if additionalAvailableHeight <= maxNoticeSpacing + noticeHeight + maxTermsOfServiceSpacing + minTrailingSpacing { termsOfServiceSpacing = min(floor(termsOfServiceSpacingFactor * additionalAvailableSpacing), maxTermsOfServiceSpacing) - noticeSpacing = floor((additionalAvailableHeight - termsOfServiceSpacing - noticeSize.height) / 2.0) + noticeSpacing = floor((additionalAvailableHeight - termsOfServiceSpacing - noticeHeight) / 2.0) } else { noticeSpacing = min(floor(noticeSpacingFactor * additionalAvailableSpacing), maxNoticeSpacing) termsOfServiceSpacing = min(floor(termsOfServiceSpacingFactor * additionalAvailableSpacing), maxTermsOfServiceSpacing) } let currentOptionFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - noticeSize.width) / 2.0), y: lastFieldFrame.maxY + noticeSpacing), size: noticeSize) - transition.updateFrame(node: self.currentOptionNode, frame: currentOptionFrame) + let termsFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - termsSize.width) / 2.0), y: layout.size.height - insets.bottom - termsSize.height - 1.0), size: termsSize) + transition.updateFrame(node: self.termsNode, frame: termsFrame) } func activateInput() { diff --git a/TelegramUI/PresentationCallManager.swift b/TelegramUI/PresentationCallManager.swift index e4624ff277..caa42797c2 100644 --- a/TelegramUI/PresentationCallManager.swift +++ b/TelegramUI/PresentationCallManager.swift @@ -226,6 +226,12 @@ public final class PresentationCallManager { } } })) + } else { + for (_, state, _) in ringingStates { + if state.id != self.currentCall?.internalId { + self.callSessionManager.drop(internalId: state.id, reason: .missed) + } + } } } }