From f215298917d615aacb1e773cb3f3844096953b99 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Fri, 30 Dec 2022 16:55:13 +0100 Subject: [PATCH] Embed + tap on statuses link from any instances --- Packages/Env/Sources/Env/Routeur.swift | 19 +++++++++++++++++-- .../Sources/Models/Alias/HTMLString.swift | 13 ++++++------- .../Sources/Network/Endpoint/Search.swift | 1 + .../Sources/Status/Row/StatusRowView.swift | 2 +- .../Status/Row/StatusRowViewModel.swift | 16 ++++++++++++---- 5 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Packages/Env/Sources/Env/Routeur.swift b/Packages/Env/Sources/Env/Routeur.swift index 87a8ce38..f8077b91 100644 --- a/Packages/Env/Sources/Env/Routeur.swift +++ b/Packages/Env/Sources/Env/Routeur.swift @@ -28,6 +28,7 @@ public enum SheetDestinations: Identifiable { } } +@MainActor public class RouterPath: ObservableObject { public var client: Client? @@ -49,8 +50,22 @@ public class RouterPath: ObservableObject { navigate(to: .accountDetail(id: mention.id)) return .handled } else if let client = client, - let id = status.content.findStatusesIds(instance: client.server)?.first(where: { String($0) == url.lastPathComponent}) { - navigate(to: .statusDetail(id: String(id))) + let id = Int(url.lastPathComponent) { + if url.absoluteString.contains(client.server) { + navigate(to: .statusDetail(id: String(id))) + } else { + Task { + let results: SearchResults? = try? await client.get(endpoint: Search.search(query: url.absoluteString, + type: "statuses", + offset: nil), + forceVersion: .v2) + if let status = results?.statuses.first { + navigate(to: .statusDetail(id: status.id)) + } else { + await UIApplication.shared.open(url) + } + } + } return .handled } return .systemAction diff --git a/Packages/Models/Sources/Models/Alias/HTMLString.swift b/Packages/Models/Sources/Models/Alias/HTMLString.swift index 4401bd9d..6109688c 100644 --- a/Packages/Models/Sources/Models/Alias/HTMLString.swift +++ b/Packages/Models/Sources/Models/Alias/HTMLString.swift @@ -24,20 +24,19 @@ extension HTMLString { } } - public func findStatusesIds(instance: String) -> [Int]? { + public func findStatusesURLs() -> [URL]? { do { let document: Document = try SwiftSoup.parse(self) let links: Elements = try document.select("a") - var ids: [Int] = [] + var URLs: [URL] = [] for link in links { let href = try link.attr("href") - if href.contains(instance.lowercased()), - let url = URL(string: href), - let statusId = Int(url.lastPathComponent) { - ids.append(statusId) + if let url = URL(string: href), + let _ = Int(url.lastPathComponent) { + URLs.append(url) } } - return ids + return URLs } catch { return nil } diff --git a/Packages/Network/Sources/Network/Endpoint/Search.swift b/Packages/Network/Sources/Network/Endpoint/Search.swift index 491f767f..51f9a4f7 100644 --- a/Packages/Network/Sources/Network/Endpoint/Search.swift +++ b/Packages/Network/Sources/Network/Endpoint/Search.swift @@ -20,6 +20,7 @@ public enum Search: Endpoint { if let offset { params.append(.init(name: "offset", value: String(offset))) } + params.append(.init(name: "resolve", value: "true")) return params } } diff --git a/Packages/Status/Sources/Status/Row/StatusRowView.swift b/Packages/Status/Sources/Status/Row/StatusRowView.swift index 8a581117..ead80fb1 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowView.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowView.swift @@ -134,7 +134,7 @@ public struct StatusRowView: View { StatusMediaPreviewView(attachements: status.mediaAttachments, isCompact: viewModel.isCompact) .padding(.vertical, 4) } - if let card = status.card, !viewModel.isCompact { + if let card = status.card, !viewModel.isCompact, viewModel.embededStatus?.url != status.card?.url { StatusCardView(card: card) } } diff --git a/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift b/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift index 3e87f0ee..52f13054 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowViewModel.swift @@ -39,11 +39,19 @@ public class StatusRowViewModel: ObservableObject { func loadEmbededStatus() async { guard let client, - let ids = status.content.findStatusesIds(instance: client.server), - !ids.isEmpty, - let id = ids.first else { return } + let urls = status.content.findStatusesURLs(), + !urls.isEmpty, + let url = urls.first else { return } do { - self.embededStatus = try await client.get(endpoint: Statuses.status(id: String(id))) + if url.absoluteString.contains(client.server), let id = Int(url.lastPathComponent) { + self.embededStatus = try await client.get(endpoint: Statuses.status(id: String(id))) + } else { + let results: SearchResults = try await client.get(endpoint: Search.search(query: url.absoluteString, + type: "statuses", + offset: 0), + forceVersion: .v2) + self.embededStatus = results.statuses.first + } } catch { } }