From 07c46dfc7e0567b6dc2cb5e870e3d08bfe2cd369 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 1 Aug 2024 18:57:48 +0200 Subject: [PATCH] Various fixes --- .../Sources/BrowserAddressBarComponent.swift | 24 +------ .../BrowserAddressListItemComponent.swift | 18 +----- .../BrowserUI/Sources/BrowserWebContent.swift | 4 +- submodules/BrowserUI/Sources/Utils.swift | 42 +++++++++++++ .../Sources/CreateLinkScreen.swift | 2 +- .../Sources/MediaEditorScreen.swift | 5 +- .../Sources/ShareWithPeersScreen.swift | 63 +++++++++++-------- .../UrlEscaping/Sources/UrlEscaping.swift | 2 +- 8 files changed, 87 insertions(+), 73 deletions(-) diff --git a/submodules/BrowserUI/Sources/BrowserAddressBarComponent.swift b/submodules/BrowserUI/Sources/BrowserAddressBarComponent.swift index dcb1cd88c8..1c51f026da 100644 --- a/submodules/BrowserUI/Sources/BrowserAddressBarComponent.swift +++ b/submodules/BrowserUI/Sources/BrowserAddressBarComponent.swift @@ -281,15 +281,7 @@ final class AddressBarContentComponent: Component { } let isActive = self.textField?.isFirstResponder ?? false - var title: String = "" - if let parsedUrl = URL(string: component.url) { - title = parsedUrl.host ?? component.url - if title.hasPrefix("www.") { - title.removeSubrange(title.startIndex ..< title.index(title.startIndex, offsetBy: 4)) - } - title = title.idnaDecoded ?? title - } - + let title = getDisplayUrl(component.url, hostOnly: true) self.update(theme: component.theme, strings: component.strings, size: availableSize, isActive: isActive, title: title.lowercased(), isSecure: component.isSecure, collapseFraction: collapseFraction, isTablet: component.metrics.isTablet, transition: transition) return availableSize @@ -449,19 +441,7 @@ final class AddressBarContentComponent: Component { textField.addTarget(self, action: #selector(self.textFieldChanged(_:)), for: .editingChanged) } - var address = self.component?.url ?? "" - if let components = URLComponents(string: address) { - if #available(iOS 16.0, *), let encodedHost = components.encodedHost { - if let decodedHost = components.host, encodedHost != decodedHost { - address = address.replacingOccurrences(of: encodedHost, with: decodedHost) - } - } else if let encodedHost = components.host { - if let decodedHost = components.host?.idnaDecoded, encodedHost != decodedHost { - address = address.replacingOccurrences(of: encodedHost, with: decodedHost) - } - } - } - + let address = getDisplayUrl(self.component?.url ?? "") if textField.text != address { textField.text = address self.clearIconView.isHidden = address.isEmpty diff --git a/submodules/BrowserUI/Sources/BrowserAddressListItemComponent.swift b/submodules/BrowserUI/Sources/BrowserAddressListItemComponent.swift index aca503c26d..f41a5395ea 100644 --- a/submodules/BrowserUI/Sources/BrowserAddressListItemComponent.swift +++ b/submodules/BrowserUI/Sources/BrowserAddressListItemComponent.swift @@ -176,23 +176,7 @@ final class BrowserAddressListItemComponent: Component { if case let .Loaded(content) = component.webPage.content { title = content.title ?? content.url - var address = content.url - if let components = URLComponents(string: address) { - if #available(iOS 16.0, *), let encodedHost = components.encodedHost { - if let decodedHost = components.host, encodedHost != decodedHost { - address = address.replacingOccurrences(of: encodedHost, with: decodedHost) - } - } else if let encodedHost = components.host { - if let decodedHost = components.host?.idnaDecoded, encodedHost != decodedHost { - address = address.replacingOccurrences(of: encodedHost, with: decodedHost) - } - } - } - address = address.replacingOccurrences(of: "https://www.", with: "") - address = address.replacingOccurrences(of: "https://", with: "") - address = address.replacingOccurrences(of: "tonsite://", with: "") - address = address.trimmingCharacters(in: CharacterSet(charactersIn: "/")) - subtitle = address + subtitle = getDisplayUrl(content.url) parsedUrl = URL(string: content.url) diff --git a/submodules/BrowserUI/Sources/BrowserWebContent.swift b/submodules/BrowserUI/Sources/BrowserWebContent.swift index 284ff9f527..2611f92fb9 100644 --- a/submodules/BrowserUI/Sources/BrowserWebContent.swift +++ b/submodules/BrowserUI/Sources/BrowserWebContent.swift @@ -239,7 +239,7 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU let request = URLRequest(url: parsedUrl) self.webView.load(request) - title = parsedUrl.host ?? "" + title = getDisplayUrl(url, hostOnly: true) } self.errorView = ComponentHostView() @@ -744,7 +744,7 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU } func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { - if [-1003, -1100].contains((error as NSError).code) { + if [-1003, -1100, 102].contains((error as NSError).code) { self.currentError = error } else { self.currentError = nil diff --git a/submodules/BrowserUI/Sources/Utils.swift b/submodules/BrowserUI/Sources/Utils.swift index 7caff6dd87..49e3280e92 100644 --- a/submodules/BrowserUI/Sources/Utils.swift +++ b/submodules/BrowserUI/Sources/Utils.swift @@ -108,3 +108,45 @@ func getPrimaryUrl(message: Message) -> String? { } return primaryUrl } + +private let asciiChars = CharacterSet(charactersIn: "a".unicodeScalars.first! ... "z".unicodeScalars.first!) + +func getDisplayUrl(_ url: String, hostOnly: Bool = false) -> String { + if hostOnly { + var title = url + if let parsedUrl = URL(string: url) { + title = parsedUrl.host ?? url + if title.hasPrefix("www.") { + title.removeSubrange(title.startIndex ..< title.index(title.startIndex, offsetBy: 4)) + } + if let decoded = title.idnaDecoded, title != decoded { + if decoded.lowercased().rangeOfCharacter(from: asciiChars) == nil { + title = decoded + } + } + } + return title + } else { + var address = url + if let components = URLComponents(string: address) { + if #available(iOS 16.0, *), let encodedHost = components.encodedHost { + if let decodedHost = components.host, encodedHost != decodedHost { + if decodedHost.lowercased().rangeOfCharacter(from: asciiChars) == nil { + address = address.replacingOccurrences(of: encodedHost, with: decodedHost) + } + } + } else if let encodedHost = components.host { + if let decodedHost = components.host?.idnaDecoded, encodedHost != decodedHost { + if decodedHost.lowercased().rangeOfCharacter(from: asciiChars) == nil { + address = address.replacingOccurrences(of: encodedHost, with: decodedHost) + } + } + } + } + address = address.replacingOccurrences(of: "https://www.", with: "") + address = address.replacingOccurrences(of: "https://", with: "") + address = address.replacingOccurrences(of: "tonsite://", with: "") + address = address.trimmingCharacters(in: CharacterSet(charactersIn: "/")) + return address + } +} diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/CreateLinkScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/CreateLinkScreen.swift index ec63761850..8b64da17ae 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/CreateLinkScreen.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/CreateLinkScreen.swift @@ -120,7 +120,7 @@ private final class SheetContent: CombinedComponent { let explicitLink = explicitUrl(context.component.link) var isValidLink = false - if isValidUrl(explicitLink, validSchemes: ["http": true, "https": true, "tonsite": true]) { + if isValidUrl(explicitLink) { isValidLink = true } diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift index 49c5a40cff..ff60dcfd7d 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift @@ -5940,13 +5940,10 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate } self.push(controller) - editCoverImpl = { [weak self, weak controller] in + editCoverImpl = { [weak self] in if let self { self.node.openCoverSelection(exclusive: false) } - if let controller { - controller.dismiss() - } } }) } diff --git a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift index 42f157d5d9..e575681b3e 100644 --- a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift +++ b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift @@ -1690,8 +1690,12 @@ final class ShareWithPeersScreenComponent: Component { title: item.title, image: item.image, hasNext: false, - action: { + action: { [weak self] in + guard let self, let component = self.component else { + return + } component.editCover() + self.saveAndDismiss() } )), environment: {}, @@ -1993,6 +1997,36 @@ final class ShareWithPeersScreenComponent: Component { private var currentHasChannels: Bool? private var currentHasCover: Bool? + func saveAndDismiss() { + guard let component = self.component, let environment = self.environment, let controller = environment.controller() as? ShareWithPeersScreen else { + return + } + let base: EngineStoryPrivacy.Base + if self.selectedCategories.contains(.everyone) { + base = .everyone + } else if self.selectedCategories.contains(.closeFriends) { + base = .closeFriends + } else if self.selectedCategories.contains(.contacts) { + base = .contacts + } else if self.selectedCategories.contains(.selectedContacts) { + base = .nobody + } else { + base = .nobody + } + component.completion( + self.sendAsPeerId, + EngineStoryPrivacy( + base: base, + additionallyIncludePeers: self.selectedPeers + ), + self.selectedOptions.contains(.screenshot), + self.selectedOptions.contains(.pin), + self.component?.stateContext.stateValue?.peers.filter { self.selectedPeers.contains($0.id) } ?? [], + false + ) + controller.requestDismiss() + } + func update(component: ShareWithPeersScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize { guard !self.isDismissed else { return availableSize @@ -2475,33 +2509,10 @@ final class ShareWithPeersScreenComponent: Component { component: AnyComponent(Button( content: AnyComponent(Text(text: environment.strings.Common_Cancel, font: Font.regular(17.0), color: environment.theme.rootController.navigationBar.accentTextColor)), action: { [weak self] in - guard let self, let environment = self.environment, let controller = environment.controller() as? ShareWithPeersScreen else { + guard let self else { return } - let base: EngineStoryPrivacy.Base - if self.selectedCategories.contains(.everyone) { - base = .everyone - } else if self.selectedCategories.contains(.closeFriends) { - base = .closeFriends - } else if self.selectedCategories.contains(.contacts) { - base = .contacts - } else if self.selectedCategories.contains(.selectedContacts) { - base = .nobody - } else { - base = .nobody - } - component.completion( - self.sendAsPeerId, - EngineStoryPrivacy( - base: base, - additionallyIncludePeers: self.selectedPeers - ), - self.selectedOptions.contains(.screenshot), - self.selectedOptions.contains(.pin), - self.component?.stateContext.stateValue?.peers.filter { self.selectedPeers.contains($0.id) } ?? [], - false - ) - controller.requestDismiss() + self.saveAndDismiss() } ).minSize(CGSize(width: navigationHeight, height: navigationHeight))), environment: {}, diff --git a/submodules/UrlEscaping/Sources/UrlEscaping.swift b/submodules/UrlEscaping/Sources/UrlEscaping.swift index 83a6fed01c..3bc674f9e4 100644 --- a/submodules/UrlEscaping/Sources/UrlEscaping.swift +++ b/submodules/UrlEscaping/Sources/UrlEscaping.swift @@ -22,7 +22,7 @@ public extension CharacterSet { }() } -public func isValidUrl(_ url: String, validSchemes: [String: Bool] = ["http": true, "https": true]) -> Bool { +public func isValidUrl(_ url: String, validSchemes: [String: Bool] = ["http": true, "https": true, "tonsite": true]) -> Bool { if let escapedUrl = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let url = URL(string: escapedUrl), let scheme = url.scheme?.lowercased(), let requiresTopLevelDomain = validSchemes[scheme], let host = url.host, (!requiresTopLevelDomain || host.contains(".")) && url.user == nil { if requiresTopLevelDomain { let components = host.components(separatedBy: ".")