159 lines
4.2 KiB
Swift
159 lines
4.2 KiB
Swift
//
|
|
// Copyright 2019 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public enum LinkPreviewError: Int, Error {
|
|
/// A preview could not be generated from available input
|
|
case noPreview
|
|
/// A preview should have been generated, but something unexpected caused it to fail
|
|
case invalidPreview
|
|
/// A preview could not be generated due to an issue fetching a network resource
|
|
case fetchFailure
|
|
/// A preview could not be generated because the feature is disabled
|
|
case featureDisabled
|
|
}
|
|
|
|
// MARK: - OWSLinkPreviewDraft
|
|
|
|
// This contains the info for a link preview "draft".
|
|
public class OWSLinkPreviewDraft: NSObject {
|
|
|
|
public let url: URL
|
|
public var urlString: String {
|
|
return url.absoluteString
|
|
}
|
|
public let title: String?
|
|
public let imageData: Data?
|
|
public let imageMimeType: String?
|
|
public let previewDescription: String?
|
|
public let date: Date?
|
|
|
|
public init(
|
|
url: URL,
|
|
title: String?,
|
|
imageData: Data? = nil,
|
|
imageMimeType: String? = nil,
|
|
previewDescription: String? = nil,
|
|
date: Date? = nil
|
|
) {
|
|
self.url = url
|
|
self.title = title
|
|
self.imageData = imageData
|
|
self.imageMimeType = imageMimeType
|
|
self.previewDescription = previewDescription
|
|
self.date = date
|
|
}
|
|
|
|
public var displayDomain: String? {
|
|
return URL(string: urlString).flatMap(LinkPreviewHelper.displayDomain(forUrl:))
|
|
}
|
|
}
|
|
|
|
// MARK: - OWSLinkPreview
|
|
|
|
@objc
|
|
public class OWSLinkPreview: MTLModel, Codable {
|
|
|
|
public struct Metadata {
|
|
public let urlString: String
|
|
public let title: String?
|
|
public let previewDescription: String?
|
|
public let date: Date?
|
|
}
|
|
|
|
@objc
|
|
public var urlString: String?
|
|
|
|
@objc
|
|
public var title: String?
|
|
|
|
@objc
|
|
public var previewDescription: String?
|
|
|
|
@objc
|
|
public var date: Date?
|
|
|
|
public init(
|
|
urlString: String,
|
|
title: String? = nil
|
|
) {
|
|
self.urlString = urlString
|
|
self.title = title
|
|
|
|
super.init()
|
|
}
|
|
|
|
public convenience init(
|
|
metadata: Metadata
|
|
) {
|
|
self.init(
|
|
urlString: metadata.urlString,
|
|
title: metadata.title
|
|
)
|
|
self.previewDescription = metadata.previewDescription
|
|
self.date = metadata.date
|
|
}
|
|
|
|
public override init() {
|
|
super.init()
|
|
}
|
|
|
|
public required init!(coder: NSCoder) {
|
|
super.init(coder: coder)
|
|
}
|
|
|
|
public required init(dictionary dictionaryValue: [String: Any]!) throws {
|
|
try super.init(dictionary: dictionaryValue)
|
|
}
|
|
|
|
@objc
|
|
public class func isNoPreviewError(_ error: Error) -> Bool {
|
|
guard let error = error as? LinkPreviewError else {
|
|
return false
|
|
}
|
|
return error == .noPreview
|
|
}
|
|
|
|
public var displayDomain: String? {
|
|
urlString.flatMap(URL.init(string: )).flatMap(LinkPreviewHelper.displayDomain(forUrl:))
|
|
}
|
|
|
|
// MARK: - Codable
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case urlString
|
|
case title
|
|
case usesV2AttachmentReferenceValue
|
|
case imageAttachmentId
|
|
case previewDescription
|
|
case date
|
|
}
|
|
|
|
public required init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
urlString = try container.decodeIfPresent(String.self, forKey: .urlString)
|
|
title = try container.decodeIfPresent(String.self, forKey: .title)
|
|
previewDescription = try container.decodeIfPresent(String.self, forKey: .previewDescription)
|
|
date = try container.decodeIfPresent(Date.self, forKey: .date)
|
|
super.init()
|
|
}
|
|
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
if let urlString = urlString {
|
|
try container.encode(urlString, forKey: .urlString)
|
|
}
|
|
if let title = title {
|
|
try container.encode(title, forKey: .title)
|
|
}
|
|
if let previewDescription = previewDescription {
|
|
try container.encode(previewDescription, forKey: .previewDescription)
|
|
}
|
|
if let date = date {
|
|
try container.encode(date, forKey: .date)
|
|
}
|
|
}
|
|
}
|