From 5038b2dcfa4c07e9e860834a304da4746c1e4a34 Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Sat, 27 Feb 2021 13:29:30 -0800 Subject: [PATCH] Handle emoji with non-ASCII URL paths --- .../NSMutableAttributedString+Extensions.swift | 4 ++-- Extensions/URL+Extensions.swift | 12 ++++++++++++ Metatext.xcodeproj/project.pbxproj | 2 ++ .../ViewModels/View Models/EmojiViewModel.swift | 12 +++++------- Views/UIKit/Content Configurations/EmojiView.swift | 11 ++++++++++- 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Extensions/NSMutableAttributedString+Extensions.swift b/Extensions/NSMutableAttributedString+Extensions.swift index 9e29972..0130bac 100644 --- a/Extensions/NSMutableAttributedString+Extensions.swift +++ b/Extensions/NSMutableAttributedString+Extensions.swift @@ -17,9 +17,9 @@ extension NSMutableAttributedString { if !identityContext.appPreferences.shouldReduceMotion, identityContext.appPreferences.animateCustomEmojis, let urlString = emoji.url { - imageURL = URL(string: urlString) + imageURL = URL(stringEscapingPath: urlString) } else if let staticURLString = emoji.staticUrl { - imageURL = URL(string: staticURLString) + imageURL = URL(stringEscapingPath: staticURLString) } else { imageURL = nil } diff --git a/Extensions/URL+Extensions.swift b/Extensions/URL+Extensions.swift index ac0bce2..ddc84c6 100644 --- a/Extensions/URL+Extensions.swift +++ b/Extensions/URL+Extensions.swift @@ -8,6 +8,18 @@ extension URL { return scheme == "http" || scheme == "https" } + + init?(stringEscapingPath: String) { + guard let pathEscaped = stringEscapingPath.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) + else { return nil } + + let httpsColonUnescaped = pathEscaped.replacingOccurrences( + of: "https%3A", + with: "https:", + range: pathEscaped.range(of: "https%3A")) + + self.init(string: httpsColonUnescaped) + } } extension URL: Identifiable { diff --git a/Metatext.xcodeproj/project.pbxproj b/Metatext.xcodeproj/project.pbxproj index b01902f..f3080af 100644 --- a/Metatext.xcodeproj/project.pbxproj +++ b/Metatext.xcodeproj/project.pbxproj @@ -65,6 +65,7 @@ D04F34BC25E42ADC00714251 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = D04F34BB25E42ADC00714251 /* SDWebImage */; }; D04F34C225E42AE500714251 /* SDWebImage in Frameworks */ = {isa = PBXBuildFile; productRef = D04F34C125E42AE500714251 /* SDWebImage */; }; D04F9E8E259E9C950081B0C9 /* ViewModels in Frameworks */ = {isa = PBXBuildFile; productRef = D04F9E8D259E9C950081B0C9 /* ViewModels */; }; + D052DBDD25EAF01800FFB628 /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0030981250C6C8500EACB32 /* URL+Extensions.swift */; }; D05936CF25A8D79800754FDF /* EditAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936CE25A8D79800754FDF /* EditAttachmentViewController.swift */; }; D05936D025A8D79800754FDF /* EditAttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936CE25A8D79800754FDF /* EditAttachmentViewController.swift */; }; D05936DE25A937EC00754FDF /* EditThumbnailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D05936DD25A937EC00754FDF /* EditThumbnailView.swift */; }; @@ -1193,6 +1194,7 @@ D0D93EC525D9C75E00C622ED /* AutocompleteItemContentConfiguration.swift in Sources */, D059373425AAEA7000754FDF /* CompositionPollView.swift in Sources */, D021A67B25C3E32A008A0C0D /* PlayerView.swift in Sources */, + D052DBDD25EAF01800FFB628 /* URL+Extensions.swift in Sources */, D021A69025C3E4B8008A0C0D /* EmojiContentConfiguration.swift in Sources */, D08E52D2257C811200FA2C5F /* ShareExtensionError+Extensions.swift in Sources */, D00CB23D25C9305D008EF267 /* NSMutableAttributedString+Extensions.swift in Sources */, diff --git a/ViewModels/Sources/ViewModels/View Models/EmojiViewModel.swift b/ViewModels/Sources/ViewModels/View Models/EmojiViewModel.swift index 60b48ee..d61e72e 100644 --- a/ViewModels/Sources/ViewModels/View Models/EmojiViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/EmojiViewModel.swift @@ -18,15 +18,13 @@ public extension EmojiViewModel { var system: Bool { emoji.system } - var url: URL? { + var url: String? { guard case let .custom(emoji, _) = emoji else { return nil } - if identityContext.appPreferences.animateCustomEmojis, let urlString = emoji.url { - return URL(string: urlString) - } else if let staticURLString = emoji.staticUrl { - return URL(string: staticURLString) + if identityContext.appPreferences.animateCustomEmojis { + return emoji.url + } else { + return emoji.staticUrl } - - return nil } } diff --git a/Views/UIKit/Content Configurations/EmojiView.swift b/Views/UIKit/Content Configurations/EmojiView.swift index 09d54c4..194294c 100644 --- a/Views/UIKit/Content Configurations/EmojiView.swift +++ b/Views/UIKit/Content Configurations/EmojiView.swift @@ -76,7 +76,16 @@ private extension EmojiView { emojiLabel.isHidden = true emojiLabel.text = nil imageView.isHidden = false - imageView.sd_setImage(with: emojiConfiguration.viewModel.url) + + let url: URL? + + if let urlString = emojiConfiguration.viewModel.url { + url = URL(stringEscapingPath: urlString) + } else { + url = nil + } + + imageView.sd_setImage(with: url) } accessibilityLabel = emojiConfiguration.viewModel.name