Compare commits
2 Commits
6e964ff601
...
6ba5f70615
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 6ba5f70615 | |
Shadowfacts | 54c01be7ff |
|
@ -14,7 +14,6 @@ public class Attachment: Codable {
|
|||
public let url: URL
|
||||
public let remoteURL: URL?
|
||||
public let previewURL: URL?
|
||||
public let textURL: URL?
|
||||
public let meta: Metadata?
|
||||
public let description: String?
|
||||
public let blurHash: String?
|
||||
|
@ -33,7 +32,6 @@ public class Attachment: Codable {
|
|||
self.url = try container.decode(URL.self, forKey: .url)
|
||||
self.previewURL = try? container.decode(URL?.self, forKey: .previewURL)
|
||||
self.remoteURL = try? container.decode(URL?.self, forKey: .remoteURL)
|
||||
self.textURL = try? container.decode(URL?.self, forKey: .textURL)
|
||||
self.meta = try? container.decode(Metadata?.self, forKey: .meta)
|
||||
self.description = try? container.decode(String?.self, forKey: .description)
|
||||
self.blurHash = try? container.decode(String?.self, forKey: .blurHash)
|
||||
|
@ -45,7 +43,6 @@ public class Attachment: Codable {
|
|||
case url
|
||||
case remoteURL = "remote_url"
|
||||
case previewURL = "preview_url"
|
||||
case textURL = "text_url"
|
||||
case meta
|
||||
case description
|
||||
case blurHash = "blurhash"
|
||||
|
|
|
@ -7,17 +7,18 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import WebURL
|
||||
|
||||
public class Card: Codable {
|
||||
public let url: URL
|
||||
public let url: WebURL
|
||||
public let title: String
|
||||
public let description: String
|
||||
public let image: URL?
|
||||
public let image: WebURL?
|
||||
public let kind: Kind
|
||||
public let authorName: String?
|
||||
public let authorURL: URL?
|
||||
public let authorURL: WebURL?
|
||||
public let providerName: String?
|
||||
public let providerURL: URL?
|
||||
public let providerURL: WebURL?
|
||||
public let html: String?
|
||||
public let width: Int?
|
||||
public let height: Int?
|
||||
|
@ -26,15 +27,15 @@ public class Card: Codable {
|
|||
public required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.url = try container.decode(URL.self, forKey: .url)
|
||||
self.url = try container.decode(WebURL.self, forKey: .url)
|
||||
self.title = try container.decode(String.self, forKey: .title)
|
||||
self.description = try container.decode(String.self, forKey: .description)
|
||||
self.kind = try container.decode(Kind.self, forKey: .kind)
|
||||
self.image = try? container.decodeIfPresent(URL.self, forKey: .image)
|
||||
self.image = try? container.decodeIfPresent(WebURL.self, forKey: .image)
|
||||
self.authorName = try? container.decodeIfPresent(String.self, forKey: .authorName)
|
||||
self.authorURL = try? container.decodeIfPresent(URL.self, forKey: .authorURL)
|
||||
self.authorURL = try? container.decodeIfPresent(WebURL.self, forKey: .authorURL)
|
||||
self.providerName = try? container.decodeIfPresent(String.self, forKey: .providerName)
|
||||
self.providerURL = try? container.decodeIfPresent(URL.self, forKey: .providerURL)
|
||||
self.providerURL = try? container.decodeIfPresent(WebURL.self, forKey: .providerURL)
|
||||
self.html = try? container.decodeIfPresent(String.self, forKey: .html)
|
||||
self.width = try? container.decodeIfPresent(Int.self, forKey: .width)
|
||||
self.height = try? container.decodeIfPresent(Int.self, forKey: .height)
|
||||
|
|
|
@ -7,29 +7,22 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import WebURL
|
||||
|
||||
public class Emoji: Codable {
|
||||
public let shortcode: String
|
||||
public let url: URL
|
||||
public let staticURL: URL
|
||||
// these shouldn't need to be WebURLs as they're not external resources,
|
||||
// but some instances (pleroma?) has emoji urls that Foundation considers malformed so we use WebURL to be more lenient
|
||||
public let url: WebURL
|
||||
public let staticURL: WebURL
|
||||
public let visibleInPicker: Bool
|
||||
|
||||
public required init(from decoder: Decoder) throws {
|
||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
self.shortcode = try container.decode(String.self, forKey: .shortcode)
|
||||
if let url = try? container.decode(URL.self, forKey: .url) {
|
||||
self.url = url
|
||||
} else {
|
||||
let str = try container.decode(String.self, forKey: .url)
|
||||
self.url = URL(string: str.replacingOccurrences(of: " ", with: "%20"))!
|
||||
}
|
||||
if let url = try? container.decode(URL.self, forKey: .staticURL) {
|
||||
self.staticURL = url
|
||||
} else {
|
||||
let staticStr = try container.decode(String.self, forKey: .staticURL)
|
||||
self.staticURL = URL(string: staticStr.replacingOccurrences(of: " ", with: "%20"))!
|
||||
}
|
||||
self.url = try container.decode(WebURL.self, forKey: .url)
|
||||
self.staticURL = try container.decode(WebURL.self, forKey: .staticURL)
|
||||
self.visibleInPicker = try container.decode(Bool.self, forKey: .visibleInPicker)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,10 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import WebURL
|
||||
|
||||
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.
|
||||
|
|
|
@ -38,8 +38,7 @@ public final class Status: /*StatusProtocol,*/ Decodable {
|
|||
public let bookmarked: Bool?
|
||||
public let card: Card?
|
||||
public let poll: Poll?
|
||||
// Hometown only
|
||||
// TODO: glitch too?
|
||||
// Hometown, Glitch only
|
||||
public let localOnly: Bool?
|
||||
|
||||
public var applicationName: String? { application?.name }
|
||||
|
|
|
@ -126,6 +126,7 @@
|
|||
D6333B372137838300CE884A /* AttributedString+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B362137838300CE884A /* AttributedString+Helpers.swift */; };
|
||||
D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */; };
|
||||
D63569E023908A8D003DD353 /* StatusState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60A4FFB238B726A008AC647 /* StatusState.swift */; };
|
||||
D635ED5027ACD9260003635B /* WebURL in Frameworks */ = {isa = PBXBuildFile; productRef = D635ED4F27ACD9260003635B /* WebURL */; };
|
||||
D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63661BF2381C144004B9E16 /* PreferencesNavigationController.swift */; };
|
||||
D6370B9C24421FF30092A7FF /* Tusker.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = D6370B9A24421FF30092A7FF /* Tusker.xcdatamodeld */; };
|
||||
D63A8D0B2561C27F00D9DFFF /* ProfileStatusesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63A8D0A2561C27F00D9DFFF /* ProfileStatusesViewController.swift */; };
|
||||
|
@ -177,6 +178,8 @@
|
|||
D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626B21361C6700C9CBA2 /* Account+Preferences.swift */; };
|
||||
D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */; };
|
||||
D6674AEA23341F7600E8DF94 /* AppShortcutItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6674AE923341F7600E8DF94 /* AppShortcutItems.swift */; };
|
||||
D6676CA327A8D0020052936B /* WebURL in Frameworks */ = {isa = PBXBuildFile; productRef = D6676CA227A8D0020052936B /* WebURL */; };
|
||||
D6676CA527A8D0020052936B /* WebURLFoundationExtras in Frameworks */ = {isa = PBXBuildFile; productRef = D6676CA427A8D0020052936B /* WebURLFoundationExtras */; };
|
||||
D667E5E12134937B0057A976 /* TimelineStatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E02134937B0057A976 /* TimelineStatusTableViewCell.xib */; };
|
||||
D667E5F12134D5050057A976 /* UIViewController+Delegates.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5F02134D5050057A976 /* UIViewController+Delegates.swift */; };
|
||||
D667E5F52135BCD50057A976 /* ConversationTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D667E5F42135BCD50057A976 /* ConversationTableViewController.swift */; };
|
||||
|
@ -766,6 +769,7 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D635ED5027ACD9260003635B /* WebURL in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -781,10 +785,12 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D6676CA327A8D0020052936B /* WebURL in Frameworks */,
|
||||
D61099C02144B0CC00432DC2 /* Pachyderm.framework in Frameworks */,
|
||||
D6B0539F23BD2BA300A066FA /* SheetController in Frameworks */,
|
||||
D69CCBBF249E6EFD000AF167 /* CrashReporter in Frameworks */,
|
||||
D60CFFDB24A290BA00D00083 /* SwiftSoup in Frameworks */,
|
||||
D6676CA527A8D0020052936B /* WebURLFoundationExtras in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1720,6 +1726,9 @@
|
|||
dependencies = (
|
||||
);
|
||||
name = Pachyderm;
|
||||
packageProductDependencies = (
|
||||
D635ED4F27ACD9260003635B /* WebURL */,
|
||||
);
|
||||
productName = Pachyderm;
|
||||
productReference = D61099AB2144B0CC00432DC2 /* Pachyderm.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
|
@ -1765,6 +1774,8 @@
|
|||
D6B0539E23BD2BA300A066FA /* SheetController */,
|
||||
D69CCBBE249E6EFD000AF167 /* CrashReporter */,
|
||||
D60CFFDA24A290BA00D00083 /* SwiftSoup */,
|
||||
D6676CA227A8D0020052936B /* WebURL */,
|
||||
D6676CA427A8D0020052936B /* WebURLFoundationExtras */,
|
||||
);
|
||||
productName = Tusker;
|
||||
productReference = D6D4DDCC212518A000E1C4BB /* Tusker.app */;
|
||||
|
@ -1882,6 +1893,7 @@
|
|||
D6B0539D23BD2BA300A066FA /* XCRemoteSwiftPackageReference "SheetController" */,
|
||||
D69CCBBD249E6EFD000AF167 /* XCRemoteSwiftPackageReference "plcrashreporter" */,
|
||||
D60CFFD924A290BA00D00083 /* XCRemoteSwiftPackageReference "SwiftSoup" */,
|
||||
D6676CA127A8D0020052936B /* XCRemoteSwiftPackageReference "swift-url" */,
|
||||
);
|
||||
productRefGroup = D6D4DDCD212518A000E1C4BB /* Products */;
|
||||
projectDirPath = "";
|
||||
|
@ -2892,6 +2904,14 @@
|
|||
minimumVersion = 2.3.2;
|
||||
};
|
||||
};
|
||||
D6676CA127A8D0020052936B /* XCRemoteSwiftPackageReference "swift-url" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/karwa/swift-url";
|
||||
requirement = {
|
||||
branch = main;
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
D69CCBBD249E6EFD000AF167 /* XCRemoteSwiftPackageReference "plcrashreporter" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/microsoft/plcrashreporter";
|
||||
|
@ -2916,6 +2936,21 @@
|
|||
package = D60CFFD924A290BA00D00083 /* XCRemoteSwiftPackageReference "SwiftSoup" */;
|
||||
productName = SwiftSoup;
|
||||
};
|
||||
D635ED4F27ACD9260003635B /* WebURL */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D6676CA127A8D0020052936B /* XCRemoteSwiftPackageReference "swift-url" */;
|
||||
productName = WebURL;
|
||||
};
|
||||
D6676CA227A8D0020052936B /* WebURL */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D6676CA127A8D0020052936B /* XCRemoteSwiftPackageReference "swift-url" */;
|
||||
productName = WebURL;
|
||||
};
|
||||
D6676CA427A8D0020052936B /* WebURLFoundationExtras */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D6676CA127A8D0020052936B /* XCRemoteSwiftPackageReference "swift-url" */;
|
||||
productName = WebURLFoundationExtras;
|
||||
};
|
||||
D69CCBBE249E6EFD000AF167 /* CrashReporter */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = D69CCBBD249E6EFD000AF167 /* XCRemoteSwiftPackageReference "plcrashreporter" */;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"object": {
|
||||
"pins": [
|
||||
{
|
||||
"package": "plcrashreporter",
|
||||
"package": "PLCrashReporter",
|
||||
"repositoryURL": "https://github.com/microsoft/plcrashreporter",
|
||||
"state": {
|
||||
"branch": null,
|
||||
|
@ -19,6 +19,24 @@
|
|||
"version": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "swift-system",
|
||||
"repositoryURL": "https://github.com/apple/swift-system.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "836bc4557b74fe6d2660218d56e3ce96aff76574",
|
||||
"version": "1.1.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "swift-url",
|
||||
"repositoryURL": "https://github.com/karwa/swift-url",
|
||||
"state": {
|
||||
"branch": "main",
|
||||
"revision": "1519936d9813af86e57c06dc7f727cb281de9f16",
|
||||
"version": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"package": "SwiftSoup",
|
||||
"repositoryURL": "https://github.com/scinfu/SwiftSoup.git",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
import WebURLFoundationExtras
|
||||
|
||||
class EmojiCollectionViewCell: UICollectionViewCell {
|
||||
|
||||
|
@ -45,7 +46,7 @@ class EmojiCollectionViewCell: UICollectionViewCell {
|
|||
func updateUI(emoji: Emoji) {
|
||||
currentEmojiShortcode = emoji.shortcode
|
||||
|
||||
imageRequest = ImageCache.emojis.get(emoji.url) { [weak self] (_, image) in
|
||||
imageRequest = ImageCache.emojis.get(URL(emoji.url)!) { [weak self] (_, image) in
|
||||
guard let image = image else { return }
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self, self.currentEmojiShortcode == emoji.shortcode else { return }
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import SwiftUI
|
||||
import Pachyderm
|
||||
import WebURLFoundationExtras
|
||||
|
||||
private let emojiRegex = try! NSRegularExpression(pattern: ":(\\w+):", options: [])
|
||||
|
||||
|
@ -48,7 +49,7 @@ struct AccountDisplayNameLabel<Account: AccountProtocol>: View {
|
|||
}
|
||||
|
||||
group.enter()
|
||||
let request = ImageCache.emojis.get(emoji.url) { (_, image) in
|
||||
let request = ImageCache.emojis.get(URL(emoji.url)!) { (_, image) in
|
||||
defer { group.leave() }
|
||||
guard let image = image else { return }
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
import WebURLFoundationExtras
|
||||
|
||||
private let emojiRegex = try! NSRegularExpression(pattern: ":(\\w+):", options: [])
|
||||
|
||||
|
@ -56,7 +57,7 @@ extension BaseEmojiLabel {
|
|||
|
||||
foundEmojis = true
|
||||
|
||||
if let image = ImageCache.emojis.get(emoji.url)?.image {
|
||||
if let image = ImageCache.emojis.get(URL(emoji.url)!)?.image {
|
||||
// if the image is cached, add it immediately
|
||||
emojiImages[emoji.shortcode] = image
|
||||
} else {
|
||||
|
@ -64,9 +65,9 @@ extension BaseEmojiLabel {
|
|||
|
||||
group.enter()
|
||||
// todo: ImageCache.emojis.get here will re-check the memory and disk caches, there should be another method to force-refetch
|
||||
let request = ImageCache.emojis.get(emoji.url) { (_, image) in
|
||||
let request = ImageCache.emojis.get(URL(emoji.url)!) { (_, image) in
|
||||
guard let image = image,
|
||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: emoji.url, image: image) else {
|
||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: URL(emoji.url)!, image: image) else {
|
||||
group.leave()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import SwiftUI
|
||||
import Pachyderm
|
||||
import WebURLFoundationExtras
|
||||
|
||||
struct CustomEmojiImageView: View {
|
||||
let emoji: Emoji
|
||||
|
@ -33,7 +34,7 @@ struct CustomEmojiImageView: View {
|
|||
}
|
||||
|
||||
private func loadImage() {
|
||||
request = ImageCache.emojis.get(emoji.url) { (_, image) in
|
||||
request = ImageCache.emojis.get(URL(emoji.url)!) { (_, image) in
|
||||
DispatchQueue.main.async {
|
||||
self.request = nil
|
||||
if let image = image {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import UIKit
|
||||
import Pachyderm
|
||||
import SafariServices
|
||||
import WebURLFoundationExtras
|
||||
|
||||
class StatusCardView: UIView {
|
||||
|
||||
|
@ -141,9 +142,9 @@ class StatusCardView: UIView {
|
|||
if let imageURL = card.image {
|
||||
placeholderImageView.isHidden = true
|
||||
|
||||
imageRequest = ImageCache.attachments.get(imageURL, completion: { (_, image) in
|
||||
imageRequest = ImageCache.attachments.get(URL(imageURL)!, completion: { (_, image) in
|
||||
guard let image = image,
|
||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: imageURL, image: image) else {
|
||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: URL(imageURL)!, image: image) else {
|
||||
return
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
|
@ -200,7 +201,7 @@ class StatusCardView: UIView {
|
|||
setNeedsDisplay()
|
||||
|
||||
if let card = card, let delegate = navigationDelegate {
|
||||
delegate.selected(url: card.url)
|
||||
delegate.selected(url: URL(card.url)!)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,9 +220,9 @@ extension StatusCardView: UIContextMenuInteractionDelegate {
|
|||
guard let card = card else { return nil }
|
||||
|
||||
return UIContextMenuConfiguration(identifier: nil) {
|
||||
return SFSafariViewController(url: card.url)
|
||||
return SFSafariViewController(url: URL(card.url)!)
|
||||
} actionProvider: { (_) in
|
||||
let actions = self.actionsForURL(card.url, sourceView: self)
|
||||
let actions = self.actionsForURL(URL(card.url)!, sourceView: self)
|
||||
return UIMenu(title: "", image: nil, identifier: nil, options: [], children: actions)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,9 +91,8 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
|
|||
|
||||
doUpdateTimestamp(status: status)
|
||||
|
||||
let pinned = showPinned && (status.pinned ?? false)
|
||||
timestampLabel.isHidden = pinned
|
||||
pinImageView.isHidden = !pinned
|
||||
timestampLabel.isHidden = showPinned
|
||||
pinImageView.isHidden = !showPinned
|
||||
}
|
||||
|
||||
override func updateGrayscaleableUI(account: AccountMO, status: StatusMO) {
|
||||
|
|
|
@ -27,7 +27,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
|
||||
|
|
Loading…
Reference in New Issue