Go to link (IOS-141)

It's either a profile (then show the profile) or a status (than show the status) or a link (then open the link in safari)
This commit is contained in:
Nathan Mattes 2023-09-17 16:57:15 +02:00
parent cde28f576c
commit 4378c1e971
2 changed files with 60 additions and 5 deletions

View File

@ -118,7 +118,6 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc
}
func showStandardSearch(for searchText: String) {
guard let dataSource else { return }
var snapshot = dataSource.snapshot()
@ -127,8 +126,7 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc
.default(.people(searchText)),
.default(.profile(searchText, authContext.mastodonAuthenticationBox.domain))], toSection: .default)
if URL(string: searchText) != nil {
//TODO: Check if Mastodon-URL
if URL(string: searchText)?.isValidURL() ?? false {
snapshot.appendItems([.default(.openLink(searchText))], toSection: .default)
}
@ -188,6 +186,8 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc
activeTask = searchTask
}
//MARK: - Actions
func showPosts(tag: Mastodon.Entity.Tag) {
Task {
await DataSourceFacade.coordinateToHashtagScene(
@ -268,6 +268,50 @@ class SearchResultsOverviewTableViewController: UIViewController, NeedsDependenc
}
}
}
func goTo(link: String) {
let query = Mastodon.API.V2.Search.Query(
q: link,
type: .default,
resolve: true
)
let authContext = self.authContext
let managedObjectContext = context.managedObjectContext
Task {
let searchResult = try await context.apiService.search(
query: query,
authenticationBox: authContext.mastodonAuthenticationBox
).value
if let account = searchResult.accounts.first {
showProfile(for: account)
} else if let status = searchResult.statuses.first {
let status = try await managedObjectContext.perform {
return Persistence.Status.fetch(in: managedObjectContext, context: Persistence.Status.PersistContext(
domain: authContext.mastodonAuthenticationBox.domain,
entity: status,
me: authContext.mastodonAuthenticationBox.authenticationRecord.object(in: managedObjectContext)?.user,
statusCache: nil,
userCache: nil,
networkDate: Date()))
}
guard let status else { return }
await DataSourceFacade.coordinateToStatusThreadScene(
provider: self,
target: .status, // remove reblog wrapper
status: status.asRecord
)
} else if let url = URL(string: link) {
coordinator.present(scene: .safari(url: url), transition: .safariPresent(animated: true))
}
}
}
}
//MARK: UITableViewDelegate
@ -288,8 +332,8 @@ extension SearchResultsOverviewTableViewController: UITableViewDelegate {
searchForPeople(withName: searchText)
case .profile(let username, let domain):
searchForPerson(username: username, domain: domain)
case .openLink(let string):
delegate?.openLink(self)
case .openLink(let urlString):
goTo(link: urlString)
}
case .suggestion(let suggestionSectionEntry):
switch suggestionSectionEntry {

View File

@ -11,4 +11,15 @@ extension URL {
public static func httpScheme(domain: String) -> String {
return domain.hasSuffix(".onion") ? "http" : "https"
}
// inspired by https://stackoverflow.com/a/49072718
public func isValidURL() -> Bool {
if let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue),
let match = detector.firstMatch(in: absoluteString, options: [], range: NSRange(location: 0, length: absoluteString.utf16.count)) {
// it is a link, if the match covers the whole string
return match.range.length == absoluteString.utf16.count
} else {
return false
}
}
}