From 03c87105d3e4e69cb421fdd48d546ffd0663d5f0 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Mon, 27 Aug 2018 12:40:22 -0400 Subject: [PATCH] Add StatusContentLabel entity detection --- MastodonKit | 2 +- Tusker/Views/StatusContentLabel.swift | 60 +++++++++++++++++++++++++- Tusker/Views/StatusTableViewCell.swift | 19 +++++++- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/MastodonKit b/MastodonKit index 30aa01aa..b3653523 160000 --- a/MastodonKit +++ b/MastodonKit @@ -1 +1 @@ -Subproject commit 30aa01aa0ffb7cdd27030869d816cc0bc718ab3d +Subproject commit b3653523af6b15fae5e3f8d425304c93d9bef9c7 diff --git a/Tusker/Views/StatusContentLabel.swift b/Tusker/Views/StatusContentLabel.swift index bd016d72..90042a4c 100644 --- a/Tusker/Views/StatusContentLabel.swift +++ b/Tusker/Views/StatusContentLabel.swift @@ -7,10 +7,23 @@ // import UIKit +import MastodonKit import SwiftSoup +protocol StatusContentLabelDelegate { + + func selected(mention: Mention) + + func selected(tag: MastodonKit.Tag) + + func selected(url: URL) + +} + class StatusContentLabel: UILabel { + var delegate: StatusContentLabelDelegate? + override var text: String? { didSet { parseHTML() @@ -35,6 +48,12 @@ class StatusContentLabel: UILabel { } } + var status: Status! { + didSet { + text = status.content + } + } + private var _customizing = true private lazy var textStorage = NSTextStorage() @@ -165,6 +184,35 @@ class StatusContentLabel: UILabel { // MARK: - Interaction + private func getMention(for url: URL, text: String) -> Mention? { + return status.mentions.first(where: { mention -> Bool in + (text.dropFirst() == mention.username || text == mention.username) && url.host == URL(string: mention.url)!.host + }) + } + + private func getTag(for url: URL, text: String) -> MastodonKit.Tag? { + if let tag = status.tags.first(where: { tag -> Bool in + tag.url == url.absoluteString + }) { + return tag + } else if text.starts(with: "#") { + let tag = String(text.dropFirst()) + return MastodonKit.Tag(name: tag, url: url.absoluteString) + } else { + return nil + } + } + + private func getEntity(for url: URL, text: String) -> Any { + if let mention = getMention(for: url, text: text) { + return mention + } else if let tag = getTag(for: url, text: text) { + return tag + } else { + return url + } + } + private func onTouch(_ touch: UITouch) -> Bool { let location = touch.location(in: self) var avoidSuperCall = false @@ -185,7 +233,17 @@ class StatusContentLabel: UILabel { case .ended: guard let selectedLink = selectedLink else { return avoidSuperCall } - print("tapped \(selectedLink)") + let text = String(self.text![Range(selectedLink.range, in: self.text!)!]) +// print(getEntity(for: selectedLink.url, text: text)) + if let delegate = delegate { + if let mention = getMention(for: selectedLink.url, text: text) { + delegate.selected(mention: mention) + } else if let tag = getTag(for: selectedLink.url, text: text) { + delegate.selected(tag: tag) + } else { + delegate.selected(url: selectedLink.url) + } + } let when = DispatchTime.now() + Double(Int64(0.25 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) DispatchQueue.main.asyncAfter(deadline: when) { diff --git a/Tusker/Views/StatusTableViewCell.swift b/Tusker/Views/StatusTableViewCell.swift index 4d991c4f..16cedae9 100644 --- a/Tusker/Views/StatusTableViewCell.swift +++ b/Tusker/Views/StatusTableViewCell.swift @@ -49,7 +49,8 @@ class StatusTableViewCell: UITableViewCell { } } - contentLabel.text = status.content + contentLabel.status = status + contentLabel.delegate = self } override func prepareForReuse() { @@ -59,3 +60,19 @@ class StatusTableViewCell: UITableViewCell { } } + +extension StatusTableViewCell: StatusContentLabelDelegate { + + func selected(mention: Mention) { + print("selected mention: \(mention.acct)") + } + + func selected(tag: MastodonKit.Tag) { + print("selected tag: \(tag.name)") + } + + func selected(url: URL) { + print("selected url: \(url)") + } + +}