Update WebURL to version with IDNA support

Closes #163
This commit is contained in:
Shadowfacts 2022-07-09 11:45:27 -04:00
parent 0c37b99a68
commit 9b3cc61dcb
10 changed files with 41 additions and 39 deletions

View File

@ -16,7 +16,7 @@ let package = Package(
],
dependencies: [
// Dependencies declare other packages that this package depends on.
.package(url: "https://github.com/karwa/swift-url.git", from: "0.3.1"),
.package(url: "https://github.com/karwa/swift-url.git", branch: "main"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.

View File

@ -12,13 +12,13 @@ import WebURLFoundationExtras
public class Hashtag: Codable {
public let name: String
public let url: URL
public let url: WebURL
/// Only present when returned from the trending hashtags endpoint
public let history: [History]?
public init(name: String, url: URL) {
self.name = name
self.url = url
self.url = WebURL(url)!
self.history = nil
}
@ -26,24 +26,14 @@ public class Hashtag: Codable {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
// pixelfed (possibly others) don't fully escape special characters in the hashtag url
do {
let webURL = try container.decode(WebURL.self, forKey: .url)
if let url = URL(webURL) {
self.url = url
} else {
let s = try? container.decode(String.self, forKey: .url)
throw DecodingError.dataCorruptedError(forKey: .url, in: container, debugDescription: "unable to convert WebURL \(s?.debugDescription ?? "nil") to URL")
}
} catch {
self.url = try container.decode(URL.self, forKey: .url)
}
self.url = try container.decode(WebURL.self, forKey: .url)
self.history = try container.decodeIfPresent([History].self, forKey: .history)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
try container.encode(url.absoluteString, forKey: .url)
try container.encode(url, forKey: .url)
try container.encodeIfPresent(history, forKey: .history)
}

View File

@ -8,10 +8,9 @@
import Foundation
import WebURL
import WebURLFoundationExtras
public class Mention: Codable {
public let url: URL
public let url: WebURL
public let username: String
public let acct: String
/// The instance-local ID of the user being mentioned.
@ -22,17 +21,7 @@ public class Mention: Codable {
self.username = try container.decode(String.self, forKey: .username)
self.acct = try container.decode(String.self, forKey: .acct)
self.id = try container.decode(String.self, forKey: .id)
do {
let webURL = try container.decode(WebURL.self, forKey: .url)
if let url = URL(webURL) {
self.url = url
} else {
let s = try? container.decode(String.self, forKey: .url)
throw DecodingError.dataCorruptedError(forKey: .url, in: container, debugDescription: "unable to convert WebURL \(s?.debugDescription ?? "nil") to URL")
}
} catch {
self.url = try container.decode(URL.self, forKey: .url)
}
self.url = try container.decode(WebURL.self, forKey: .url)
}
private enum CodingKeys: String, CodingKey {

View File

@ -12,9 +12,14 @@ import WebURLFoundationExtras
class URLTests: XCTestCase {
func testDecodeURL() {
print(WebURL(URL(string: "https://xn--baw-joa.social/@unituebingen")!))
let url = WebURL("https://xn--baw-joa.social/@unituebingen")
print(url)
XCTAssertNotNil(WebURL(URL(string: "https://xn--baw-joa.social/@unituebingen")!))
XCTAssertNotNil(WebURL("https://xn--baw-joa.social/@unituebingen"))
XCTAssertNotNil(URLComponents(string: "https://xn--baw-joa.social/test/é"))
XCTAssertNotNil(WebURL("https://xn--baw-joa.social/test/é"))
if #available(iOS 16.0, *) {
XCTAssertNotNil(try? URL.ParseStrategy().parse("https://xn--baw-joa.social/test/é"))
XCTAssertNotNil(try? URL.ParseStrategy().parse("http://見.香港/热狗/🌭"))
}
}
}

View File

@ -9,6 +9,7 @@
import Foundation
import CoreData
import Pachyderm
import WebURLFoundationExtras
@objc(SavedHashtag)
public final class SavedHashtag: NSManagedObject {
@ -32,6 +33,6 @@ extension SavedHashtag {
convenience init(hashtag: Hashtag, context: NSManagedObjectContext) {
self.init(context: context)
self.name = hashtag.name
self.url = hashtag.url
self.url = URL(hashtag.url)!
}
}

View File

@ -10,6 +10,7 @@ import UIKit
import Combine
import Pachyderm
import CoreData
import WebURLFoundationExtras
class ExploreViewController: UIViewController, UICollectionViewDelegate {
@ -582,7 +583,10 @@ extension ExploreViewController: UICollectionViewDragDelegate {
activity.displaysAuxiliaryScene = true
provider = NSItemProvider(object: activity)
case let .savedHashtag(hashtag):
provider = NSItemProvider(object: hashtag.url as NSURL)
guard let url = URL(hashtag.url) else {
return []
}
provider = NSItemProvider(object: url as NSURL)
if let activity = UserActivityManager.showTimelineActivity(timeline: .tag(hashtag: hashtag.name), accountID: accountID) {
activity.displaysAuxiliaryScene = true
provider.registerObject(activity, visibility: .all)

View File

@ -8,6 +8,7 @@
import UIKit
import Pachyderm
import WebURLFoundationExtras
class TrendingHashtagsViewController: UIViewController {
@ -105,10 +106,11 @@ extension TrendingHashtagsViewController: UICollectionViewDelegate {
extension TrendingHashtagsViewController: UICollectionViewDragDelegate {
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
guard let item = dataSource.itemIdentifier(for: indexPath),
case let .tag(hashtag) = item else {
case let .tag(hashtag) = item,
let url = URL(hashtag.url) else {
return []
}
let provider = NSItemProvider(object: hashtag.url as NSURL)
let provider = NSItemProvider(object: url as NSURL)
if let activity = UserActivityManager.showTimelineActivity(timeline: .tag(hashtag: hashtag.name), accountID: mastodonController.accountInfo!.id) {
activity.displaysAuxiliaryScene = true
provider.registerObject(activity, visibility: .all)

View File

@ -9,6 +9,7 @@
import UIKit
import Pachyderm
import SafariServices
import WebURLFoundationExtras
class SearchViewController: UIViewController {
@ -295,7 +296,10 @@ extension SearchViewController: UICollectionViewDragDelegate {
}
switch item {
case let .tag(hashtag):
let provider = NSItemProvider(object: hashtag.url as NSURL)
guard let url = URL(hashtag.url) else {
return []
}
let provider = NSItemProvider(object: url as NSURL)
if let activity = UserActivityManager.showTimelineActivity(timeline: .tag(hashtag: hashtag.name), accountID: mastodonController.accountInfo!.id) {
activity.displaysAuxiliaryScene = true
provider.registerObject(activity, visibility: .all)

View File

@ -9,6 +9,7 @@
import UIKit
import SafariServices
import Pachyderm
import WebURLFoundationExtras
protocol MenuActionProvider: AnyObject {
var navigationDelegate: TuskerNavigationDelegate? { get }
@ -116,7 +117,12 @@ extension MenuActionProvider {
actionsSection = []
}
let shareSection = actionsForURL(hashtag.url, sourceView: sourceView)
let shareSection: [UIMenuElement]
if let url = URL(hashtag.url) {
shareSection = actionsForURL(url, sourceView: sourceView)
} else {
shareSection = []
}
return [
UIMenu(title: "", image: nil, identifier: nil, options: [.displayInline], children: shareSection),

View File

@ -8,6 +8,7 @@
import UIKit
import Pachyderm
import WebURLFoundationExtras
class StatusContentTextView: ContentTextView {
@ -27,7 +28,7 @@ class StatusContentTextView: ContentTextView {
let status = mastodonController.persistentContainer.status(for: statusID) {
mention = status.mentions.first { (mention) in
// Mastodon and Pleroma include the @ in the <a> text, GNU Social does not
(text.dropFirst() == mention.username || text == mention.username) && url.host == mention.url.host!
(text.dropFirst() == mention.username || text == mention.username) && url.host == mention.url.host!.serialized
}
} else {
mention = nil
@ -41,7 +42,7 @@ class StatusContentTextView: ContentTextView {
let mastodonController = mastodonController,
let status = mastodonController.persistentContainer.status(for: statusID) {
hashtag = status.hashtags.first { (hashtag) in
hashtag.url == url
URL(hashtag.url) == url
}
} else {
hashtag = nil