parent
0c37b99a68
commit
9b3cc61dcb
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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://見.香港/热狗/🌭"))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)!
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue