Embed + tap on statuses link from any instances

This commit is contained in:
Thomas Ricouard 2022-12-30 16:55:13 +01:00
parent 9cf7066663
commit f215298917
5 changed files with 37 additions and 14 deletions

View File

@ -28,6 +28,7 @@ public enum SheetDestinations: Identifiable {
} }
} }
@MainActor
public class RouterPath: ObservableObject { public class RouterPath: ObservableObject {
public var client: Client? public var client: Client?
@ -49,8 +50,22 @@ public class RouterPath: ObservableObject {
navigate(to: .accountDetail(id: mention.id)) navigate(to: .accountDetail(id: mention.id))
return .handled return .handled
} else if let client = client, } else if let client = client,
let id = status.content.findStatusesIds(instance: client.server)?.first(where: { String($0) == url.lastPathComponent}) { let id = Int(url.lastPathComponent) {
navigate(to: .statusDetail(id: String(id))) 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 .handled
} }
return .systemAction return .systemAction

View File

@ -24,20 +24,19 @@ extension HTMLString {
} }
} }
public func findStatusesIds(instance: String) -> [Int]? { public func findStatusesURLs() -> [URL]? {
do { do {
let document: Document = try SwiftSoup.parse(self) let document: Document = try SwiftSoup.parse(self)
let links: Elements = try document.select("a") let links: Elements = try document.select("a")
var ids: [Int] = [] var URLs: [URL] = []
for link in links { for link in links {
let href = try link.attr("href") let href = try link.attr("href")
if href.contains(instance.lowercased()), if let url = URL(string: href),
let url = URL(string: href), let _ = Int(url.lastPathComponent) {
let statusId = Int(url.lastPathComponent) { URLs.append(url)
ids.append(statusId)
} }
} }
return ids return URLs
} catch { } catch {
return nil return nil
} }

View File

@ -20,6 +20,7 @@ public enum Search: Endpoint {
if let offset { if let offset {
params.append(.init(name: "offset", value: String(offset))) params.append(.init(name: "offset", value: String(offset)))
} }
params.append(.init(name: "resolve", value: "true"))
return params return params
} }
} }

View File

@ -134,7 +134,7 @@ public struct StatusRowView: View {
StatusMediaPreviewView(attachements: status.mediaAttachments, isCompact: viewModel.isCompact) StatusMediaPreviewView(attachements: status.mediaAttachments, isCompact: viewModel.isCompact)
.padding(.vertical, 4) .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) StatusCardView(card: card)
} }
} }

View File

@ -39,11 +39,19 @@ public class StatusRowViewModel: ObservableObject {
func loadEmbededStatus() async { func loadEmbededStatus() async {
guard let client, guard let client,
let ids = status.content.findStatusesIds(instance: client.server), let urls = status.content.findStatusesURLs(),
!ids.isEmpty, !urls.isEmpty,
let id = ids.first else { return } let url = urls.first else { return }
do { 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 { } } catch { }
} }