mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 06:35:51 +00:00
Web app improvements
This commit is contained in:
@@ -12,24 +12,25 @@ import AppBundle
|
||||
import AvatarNode
|
||||
import CheckNode
|
||||
import Markdown
|
||||
import TextFormat
|
||||
|
||||
private let textFont = Font.regular(13.0)
|
||||
private let boldTextFont = Font.semibold(13.0)
|
||||
|
||||
private func formattedText(_ text: String, color: UIColor, linkColor: UIColor, textAlignment: NSTextAlignment = .natural) -> NSAttributedString {
|
||||
return parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: color), bold: MarkdownAttributeSet(font: boldTextFont, textColor: color), link: MarkdownAttributeSet(font: textFont, textColor: linkColor), linkAttribute: { _ in return nil}), textAlignment: textAlignment)
|
||||
return parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: MarkdownAttributeSet(font: textFont, textColor: color), bold: MarkdownAttributeSet(font: boldTextFont, textColor: color), link: MarkdownAttributeSet(font: textFont, textColor: linkColor), linkAttribute: { _ in return (TelegramTextAttributes.URL, "") }), textAlignment: textAlignment)
|
||||
}
|
||||
|
||||
private final class WebAppTermsAlertContentNode: AlertContentNode {
|
||||
private final class WebAppTermsAlertContentNode: AlertContentNode, UIGestureRecognizerDelegate {
|
||||
private let strings: PresentationStrings
|
||||
private let title: String
|
||||
private let text: String
|
||||
|
||||
private let titleNode: ImmediateTextNode
|
||||
private let textNode: ASTextNode
|
||||
private let textNode: ImmediateTextNode
|
||||
|
||||
private let acceptTermsCheckNode: InteractiveCheckNode
|
||||
private let acceptTermsLabelNode: ASTextNode
|
||||
private let acceptTermsLabelNode: ImmediateTextNode
|
||||
|
||||
private let actionNodesSeparator: ASDisplayNode
|
||||
private let actionNodes: [TextAlertContentActionNode]
|
||||
@@ -50,6 +51,8 @@ private final class WebAppTermsAlertContentNode: AlertContentNode {
|
||||
}
|
||||
}
|
||||
|
||||
var openTerms: () -> Void = {}
|
||||
|
||||
init(context: AccountContext, theme: AlertControllerTheme, ptheme: PresentationTheme, strings: PresentationStrings, title: String, text: String, actions: [TextAlertAction]) {
|
||||
self.strings = strings
|
||||
self.title = title
|
||||
@@ -60,14 +63,14 @@ private final class WebAppTermsAlertContentNode: AlertContentNode {
|
||||
self.titleNode.maximumNumberOfLines = 1
|
||||
self.titleNode.textAlignment = .center
|
||||
|
||||
self.textNode = ASTextNode()
|
||||
self.textNode.displaysAsynchronously = false
|
||||
self.textNode = ImmediateTextNode()
|
||||
self.textNode.maximumNumberOfLines = 0
|
||||
self.textNode.displaysAsynchronously = false
|
||||
self.textNode.lineSpacing = 0.1
|
||||
|
||||
self.acceptTermsCheckNode = InteractiveCheckNode(theme: CheckNodeTheme(backgroundColor: theme.accentColor, strokeColor: theme.contrastColor, borderColor: theme.controlBorderColor, overlayBorder: false, hasInset: false, hasShadow: false))
|
||||
self.acceptTermsLabelNode = ASTextNode()
|
||||
self.acceptTermsLabelNode = ImmediateTextNode()
|
||||
self.acceptTermsLabelNode.maximumNumberOfLines = 4
|
||||
self.acceptTermsLabelNode.isUserInteractionEnabled = true
|
||||
|
||||
self.actionNodesSeparator = ASDisplayNode()
|
||||
self.actionNodesSeparator.isLayerBacked = true
|
||||
@@ -114,17 +117,60 @@ private final class WebAppTermsAlertContentNode: AlertContentNode {
|
||||
}
|
||||
}
|
||||
|
||||
self.acceptTermsLabelNode.highlightAttributeAction = { attributes in
|
||||
if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] {
|
||||
return NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
self.acceptTermsLabelNode.tapAttributeAction = { [weak self] attributes, _ in
|
||||
if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] {
|
||||
self?.openTerms()
|
||||
}
|
||||
}
|
||||
|
||||
self.updateTheme(theme)
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
self.acceptTermsLabelNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.acceptTap(_:))))
|
||||
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.acceptTap(_:)))
|
||||
tapGesture.delegate = self
|
||||
self.view.addGestureRecognizer(tapGesture)
|
||||
}
|
||||
|
||||
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
let location = gestureRecognizer.location(in: self.acceptTermsLabelNode.view)
|
||||
if self.acceptTermsLabelNode.bounds.contains(location) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
if !self.bounds.contains(point) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let (_, attributes) = self.acceptTermsLabelNode.attributesAtPoint(self.view.convert(point, to: self.acceptTermsLabelNode.view)) {
|
||||
if attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] == nil {
|
||||
return self.view
|
||||
}
|
||||
}
|
||||
|
||||
return super.hitTest(point, with: event)
|
||||
}
|
||||
|
||||
@objc private func acceptTap(_ gestureRecognizer: UITapGestureRecognizer) {
|
||||
let location = gestureRecognizer.location(in: self.acceptTermsLabelNode.view)
|
||||
if self.acceptTermsCheckNode.isUserInteractionEnabled {
|
||||
if let attributes = self.acceptTermsLabelNode.attributesAtPoint(location)?.1 {
|
||||
if attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
self.acceptedTerms = !self.acceptedTerms
|
||||
}
|
||||
}
|
||||
@@ -133,8 +179,20 @@ private final class WebAppTermsAlertContentNode: AlertContentNode {
|
||||
self.titleNode.attributedText = NSAttributedString(string: self.title, font: Font.semibold(17.0), textColor: theme.primaryColor, paragraphAlignment: .center)
|
||||
self.textNode.attributedText = NSAttributedString(string: self.text, font: Font.regular(13.0), textColor: theme.primaryColor, paragraphAlignment: .center)
|
||||
|
||||
let text = "I agree to the [Terms of Use]()"
|
||||
self.acceptTermsLabelNode.attributedText = formattedText(text, color: theme.primaryColor, linkColor: theme.accentColor)
|
||||
let attributedAgreeText = parseMarkdownIntoAttributedString(
|
||||
self.strings.WebApp_DisclaimerAgree,
|
||||
attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: textFont, textColor: theme.primaryColor),
|
||||
bold: MarkdownAttributeSet(font: boldTextFont, textColor: theme.primaryColor),
|
||||
link: MarkdownAttributeSet(font: textFont, textColor: theme.accentColor),
|
||||
linkAttribute: { contents in
|
||||
return (TelegramTextAttributes.URL, contents)
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
self.acceptTermsLabelNode.attributedText = attributedAgreeText
|
||||
self.acceptTermsLabelNode.linkHighlightColor = theme.accentColor.withAlphaComponent(0.2)
|
||||
|
||||
self.actionNodesSeparator.backgroundColor = theme.separatorColor
|
||||
for actionNode in self.actionNodes {
|
||||
@@ -163,7 +221,7 @@ private final class WebAppTermsAlertContentNode: AlertContentNode {
|
||||
|
||||
var entriesHeight: CGFloat = 0.0
|
||||
|
||||
let textSize = self.textNode.measure(CGSize(width: size.width - 48.0, height: size.height))
|
||||
let textSize = self.textNode.updateLayout(CGSize(width: size.width - 48.0, height: size.height))
|
||||
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - textSize.width) / 2.0), y: origin.y), size: textSize))
|
||||
origin.y += textSize.height
|
||||
|
||||
@@ -175,7 +233,7 @@ private final class WebAppTermsAlertContentNode: AlertContentNode {
|
||||
let condensedSize = CGSize(width: size.width - 76.0, height: size.height)
|
||||
|
||||
let spacing: CGFloat = 12.0
|
||||
let acceptTermsSize = self.acceptTermsLabelNode.measure(condensedSize)
|
||||
let acceptTermsSize = self.acceptTermsLabelNode.updateLayout(condensedSize)
|
||||
let acceptTermsTotalWidth = checkSize.width + spacing + acceptTermsSize.width
|
||||
let acceptTermsOriginX = floorToScreenPixels((size.width - acceptTermsTotalWidth) / 2.0)
|
||||
|
||||
@@ -267,7 +325,13 @@ private final class WebAppTermsAlertContentNode: AlertContentNode {
|
||||
}
|
||||
}
|
||||
|
||||
public func webAppTermsAlertController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: EnginePeer, completion: @escaping () -> Void) -> AlertController {
|
||||
public func webAppTermsAlertController(
|
||||
context: AccountContext,
|
||||
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?,
|
||||
peer: EnginePeer,
|
||||
requestWriteAccess: Bool,
|
||||
completion: @escaping (Bool) -> Void
|
||||
) -> AlertController {
|
||||
let theme = defaultDarkColorPresentationTheme
|
||||
let presentationData: PresentationData
|
||||
if let updatedPresentationData {
|
||||
@@ -278,18 +342,21 @@ public func webAppTermsAlertController(context: AccountContext, updatedPresentat
|
||||
let strings = presentationData.strings
|
||||
|
||||
var dismissImpl: ((Bool) -> Void)?
|
||||
let actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: "Continue", action: {
|
||||
completion()
|
||||
let actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: presentationData.strings.WebApp_DisclaimerContinue, action: {
|
||||
completion(false)
|
||||
dismissImpl?(true)
|
||||
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||
dismissImpl?(true)
|
||||
})]
|
||||
|
||||
let title = "Warning"
|
||||
let text = "You are about to use a mini app operated by an independent party not affiliated with Telegram. You must agree to the Terms of Use of mini apps to continue."
|
||||
let title = presentationData.strings.WebApp_DisclaimerTitle
|
||||
let text = presentationData.strings.WebApp_DisclaimerText
|
||||
|
||||
let contentNode = WebAppTermsAlertContentNode(context: context, theme: AlertControllerTheme(presentationData: presentationData), ptheme: theme, strings: strings, title: title, text: text, actions: actions)
|
||||
|
||||
contentNode.openTerms = {
|
||||
context.sharedContext.openExternalUrl(context: context, urlContext: .generic, url: presentationData.strings.WebApp_Disclaimer_URL, forceExternal: true, presentationData: context.sharedContext.currentPresentationData.with { $0 }, navigationController: nil, dismissInput: {
|
||||
})
|
||||
}
|
||||
let controller = AlertController(theme: AlertControllerTheme(presentationData: presentationData), contentNode: contentNode)
|
||||
dismissImpl = { [weak controller] animated in
|
||||
if animated {
|
||||
|
||||
Reference in New Issue
Block a user