Implement twitter entities as html links
This commit is contained in:
parent
45f56f01e3
commit
f305cc50e2
|
@ -18,14 +18,11 @@ struct TwitterHashtag: Codable, TwitterEntity {
|
||||||
case indices = "indices"
|
case indices = "indices"
|
||||||
}
|
}
|
||||||
|
|
||||||
var startIndex: Int {
|
|
||||||
if let indices = indices, indices.count > 0 {
|
|
||||||
return indices[0] - 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func renderAsHTML() -> String {
|
func renderAsHTML() -> String {
|
||||||
return ""
|
var html = String()
|
||||||
|
if let text = text {
|
||||||
|
html += "<a href=\"https://twitter.com/search?q=%23\(text)\">#\(text)</a>"
|
||||||
|
}
|
||||||
|
return html
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,19 +13,21 @@ struct TwitterMention: Codable, TwitterEntity {
|
||||||
let name: String?
|
let name: String?
|
||||||
let indices: [Int]?
|
let indices: [Int]?
|
||||||
let screenName: String?
|
let screenName: String?
|
||||||
let expandedURL: String?
|
|
||||||
let idStr: String?
|
let idStr: String?
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case name = "url"
|
case name = "url"
|
||||||
case indices = "indices"
|
case indices = "indices"
|
||||||
case screenName = "screen_name"
|
case screenName = "screen_name"
|
||||||
case expandedURL = "expandedURL"
|
|
||||||
case idStr = "idStr"
|
case idStr = "idStr"
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderAsHTML() -> String {
|
func renderAsHTML() -> String {
|
||||||
return ""
|
var html = String()
|
||||||
|
if let screenName = screenName {
|
||||||
|
html += "<a href=\"https://twitter.com/\(screenName)\">@\(screenName)</a>"
|
||||||
|
}
|
||||||
|
return html
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,16 +41,6 @@ final class TwitterStatus: Codable {
|
||||||
return "\(userURL)/status/\(idStr)"
|
return "\(userURL)/status/\(idStr)"
|
||||||
}
|
}
|
||||||
|
|
||||||
var displayText: String? {
|
|
||||||
if let text = fullText, let displayRange = displayTextRange, displayRange.count > 1,
|
|
||||||
let startIndex = text.index(text.startIndex, offsetBy: displayRange[0], limitedBy: text.endIndex),
|
|
||||||
let endIndex = text.index(text.startIndex, offsetBy: displayRange[1], limitedBy: text.endIndex) {
|
|
||||||
return String(text[startIndex..<endIndex])
|
|
||||||
} else {
|
|
||||||
return fullText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func renderAsText() -> String? {
|
func renderAsText() -> String? {
|
||||||
let statusToRender = retweetedStatus != nil ? retweetedStatus! : self
|
let statusToRender = retweetedStatus != nil ? retweetedStatus! : self
|
||||||
return statusToRender.displayText
|
return statusToRender.displayText
|
||||||
|
@ -66,8 +56,54 @@ final class TwitterStatus: Codable {
|
||||||
return renderAsOriginalHTML(topLevel: topLevel)
|
return renderAsOriginalHTML(topLevel: topLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension TwitterStatus {
|
||||||
|
|
||||||
|
var displayText: String? {
|
||||||
|
if let text = fullText, let displayRange = displayTextRange, displayRange.count > 1,
|
||||||
|
let startIndex = text.index(text.startIndex, offsetBy: displayRange[0], limitedBy: text.endIndex),
|
||||||
|
let endIndex = text.index(text.startIndex, offsetBy: displayRange[1], limitedBy: text.endIndex) {
|
||||||
|
return String(text[startIndex..<endIndex])
|
||||||
|
} else {
|
||||||
|
return fullText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var displayHTML: String? {
|
||||||
|
if let text = fullText, let displayRange = displayTextRange, displayRange.count > 1,
|
||||||
|
let displayStartIndex = text.index(text.startIndex, offsetBy: displayRange[0], limitedBy: text.endIndex),
|
||||||
|
let displayEndIndex = text.index(text.startIndex, offsetBy: displayRange[1], limitedBy: text.endIndex),
|
||||||
|
let entities = entities?.combineAndSort() {
|
||||||
|
|
||||||
|
var html = String()
|
||||||
|
var prevIndex = displayStartIndex
|
||||||
|
|
||||||
|
for entity in entities {
|
||||||
|
if let entityStartIndex = text.index(text.startIndex, offsetBy: entity.startIndex, limitedBy: text.endIndex),
|
||||||
|
let entityEndIndex = text.index(text.startIndex, offsetBy: entity.endIndex, limitedBy: text.endIndex) {
|
||||||
|
|
||||||
|
if prevIndex < entityStartIndex {
|
||||||
|
html += String(text[prevIndex..<entityStartIndex])
|
||||||
|
}
|
||||||
|
html += entity.renderAsHTML()
|
||||||
|
prevIndex = entityEndIndex
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if prevIndex < displayEndIndex {
|
||||||
|
html += String(text[prevIndex..<displayEndIndex])
|
||||||
|
}
|
||||||
|
|
||||||
|
return html
|
||||||
|
} else {
|
||||||
|
return displayText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func renderAsTweetHTML(_ status: TwitterStatus, topLevel: Bool) -> String {
|
func renderAsTweetHTML(_ status: TwitterStatus, topLevel: Bool) -> String {
|
||||||
var html = "<div>\(status.displayText ?? "")</div>"
|
var html = "<div>\(status.displayHTML ?? "")</div>"
|
||||||
|
|
||||||
if !topLevel, let createdAt = status.createdAt {
|
if !topLevel, let createdAt = status.createdAt {
|
||||||
let dateFormatter = DateFormatter()
|
let dateFormatter = DateFormatter()
|
||||||
|
|
|
@ -18,15 +18,12 @@ struct TwitterSymbol: Codable, TwitterEntity {
|
||||||
case indices = "indices"
|
case indices = "indices"
|
||||||
}
|
}
|
||||||
|
|
||||||
var startIndex: Int {
|
|
||||||
if let indices = indices, indices.count > 0 {
|
|
||||||
return indices[0] - 1
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func renderAsHTML() -> String {
|
func renderAsHTML() -> String {
|
||||||
return ""
|
var html = String()
|
||||||
|
if let name = name {
|
||||||
|
html += "<a href=\"https://twitter.com/search?q=%24\(name)\">$\(name)</a>"
|
||||||
|
}
|
||||||
|
return html
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,16 @@ struct TwitterURL: Codable, TwitterEntity {
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case url = "url"
|
case url = "url"
|
||||||
case indices = "indices"
|
case indices = "indices"
|
||||||
case displayURL = "displayURL"
|
case displayURL = "display_url"
|
||||||
case expandedURL = "expandedURL"
|
case expandedURL = "expanded_url"
|
||||||
}
|
}
|
||||||
|
|
||||||
func renderAsHTML() -> String {
|
func renderAsHTML() -> String {
|
||||||
return ""
|
var html = String()
|
||||||
|
if let expandedURL = expandedURL, let displayURL = displayURL {
|
||||||
|
html += "<a href=\"\(expandedURL)\">\(displayURL)</a>"
|
||||||
|
}
|
||||||
|
return html
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue