NetNewsWire/Frameworks/Account/FeedProvider/Reddit/RedditLink.swift

155 lines
3.9 KiB
Swift
Raw Normal View History

2020-05-04 21:42:34 +02:00
//
// RedditLink.swift
// Account
//
// Created by Maurice Parker on 5/4/20.
// Copyright © 2020 Ranchero Software, LLC. All rights reserved.
//
import Foundation
2020-05-07 05:19:06 +02:00
final class RedditLink: Codable {
2020-05-04 21:42:34 +02:00
let kind: String?
let data: RedditLinkData?
enum CodingKeys: String, CodingKey {
case kind = "kind"
case data = "data"
}
}
2020-05-07 05:19:06 +02:00
final class RedditLinkData: Codable {
2020-05-04 21:42:34 +02:00
let title: String?
let permalink: String?
let url: String?
let id: String?
2020-05-07 05:19:06 +02:00
let subredditNamePrefixed: String?
2020-05-04 21:42:34 +02:00
let selfHTML: String?
let selfText: String?
let postHint: String?
2020-05-04 21:42:34 +02:00
let author: String?
let created: Double?
2020-05-05 02:42:10 +02:00
let isVideo: Bool?
let media: RedditMedia?
2020-05-05 02:57:35 +02:00
let mediaEmbed: RedditMediaEmbed?
2020-05-06 03:17:46 +02:00
let preview: RedditPreview?
2020-05-07 05:19:06 +02:00
let crossPostParents: [RedditLinkData]?
2020-05-04 21:42:34 +02:00
enum CodingKeys: String, CodingKey {
case title = "title"
case permalink = "permalink"
case url = "url"
case id = "id"
2020-05-07 05:19:06 +02:00
case subredditNamePrefixed = "subreddit_name_prefixed"
2020-05-04 21:42:34 +02:00
case selfHTML = "selftext_html"
case selfText = "selftext"
case postHint = "post_hint"
2020-05-04 21:42:34 +02:00
case author = "author"
case created = "created_utc"
2020-05-05 02:42:10 +02:00
case isVideo = "is_video"
case media = "media"
2020-05-05 02:57:35 +02:00
case mediaEmbed = "media_embed"
2020-05-06 03:17:46 +02:00
case preview = "preview"
2020-05-07 05:19:06 +02:00
case crossPostParents = "crosspost_parent_list"
2020-05-04 21:42:34 +02:00
}
var createdDate: Date? {
guard let created = created else { return nil }
return Date(timeIntervalSince1970: created)
}
func renderAsHTML() -> String {
2020-05-07 05:19:06 +02:00
if let parent = crossPostParents?.first {
var html = "<blockquote>"
if let subreddit = parent.subredditNamePrefixed {
html += "<p><a href=\"https://www.reddit.com/\(subreddit)\">\(subreddit)</a></p>"
}
let parentHTML = parent.renderAsHTML()
if parentHTML.isEmpty {
html += renderURLAsHTML()
} else {
html += parentHTML
}
2020-05-07 05:19:06 +02:00
html += "</blockquote>"
return html
}
var html = String()
if let selfHTML = selfHTML {
html += selfHTML
}
html += renderURLAsHTML()
return html
}
func renderURLAsHTML() -> String {
guard let url = url else { return "" }
2020-05-06 04:08:51 +02:00
if url.hasSuffix(".gif") {
return "<img src=\"\(url)\">"
2020-05-06 04:08:51 +02:00
}
if isVideo ?? false, let videoURL = media?.video?.hlsURL {
2020-05-06 03:17:46 +02:00
var html = "<video "
if let previewImageURL = preview?.images?.first?.source?.url {
html += "poster=\"\(previewImageURL)\" "
}
if let width = media?.video?.width, let height = media?.video?.height {
html += "width=\"\(width)\" height=\"\(height)\" "
}
2020-05-06 04:08:51 +02:00
html += "src=\"\(videoURL)\"></video>"
return html
}
if let videoPreviewURL = preview?.videoPreview?.url {
var html = "<video "
if let previewImageURL = preview?.images?.first?.source?.url {
html += "poster=\"\(previewImageURL)\" "
}
if let width = preview?.videoPreview?.width, let height = preview?.videoPreview?.height {
html += "width=\"\(width)\" height=\"\(height)\" "
}
html += "src=\"\(videoPreviewURL)\"></video>"
html += linkOutURL(url)
2020-05-06 03:17:46 +02:00
return html
2020-05-05 02:42:10 +02:00
}
if !url.hasPrefix("https://imgur.com"), let mediaEmbedContent = mediaEmbed?.content {
return mediaEmbedContent
}
if let imageSource = preview?.images?.first?.source, let imageURL = imageSource.url {
var html = "<a href=\"\(url)\"><img src=\"\(imageURL)\" "
if postHint == "link" {
html += "class=\"nnw-nozoom\" "
}
if let width = imageSource.width, let height = imageSource.height {
html += "width=\"\(width)\" height=\"\(height)\" "
}
html += "></a>"
html += linkOutURL(url)
return html
}
return linkOutURL(url)
}
func linkOutURL(_ url: String) -> String {
2020-05-06 04:42:20 +02:00
guard let urlComponents = URLComponents(string: url), let host = urlComponents.host else {
return ""
}
guard !host.hasSuffix("reddit.com") && !host.hasSuffix("redd.it") else {
return ""
}
2020-05-06 19:39:58 +02:00
var displayURL = "\(urlComponents.host ?? "")\(urlComponents.path)"
if displayURL.count > 30 {
displayURL = "\(displayURL.prefix(30))..."
}
return "<div><a href=\"\(url)\">\(displayURL)</a></div>"
2020-05-04 21:42:34 +02:00
}
}