From 90537f9d120dde173c956a8cbca2e886c42f7365 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Mon, 22 Jul 2024 21:40:19 -0700 Subject: [PATCH] Fix not being able to resolve remote Mastodon posts Closes #515 --- .../ConversationViewController.swift | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Tusker/Screens/Conversation/ConversationViewController.swift b/Tusker/Screens/Conversation/ConversationViewController.swift index dde6534d..5b00a9d5 100644 --- a/Tusker/Screens/Conversation/ConversationViewController.swift +++ b/Tusker/Screens/Conversation/ConversationViewController.swift @@ -221,10 +221,16 @@ class ConversationViewController: UIViewController { completionHandler(nil) } } - if isLikelyMastodonRemoteStatus(url: url), - let (_, response) = try? await URLSession.appDefault.data(from: url, delegate: RedirectBlocker()), - let location = (response as? HTTPURLResponse)?.value(forHTTPHeaderField: "location") { - effectiveURL = location + if isLikelyMastodonRemoteStatus(url: url) { + var request = URLRequest(url: url) + // Mastodon uses an intermediate redirect page for browsers which requires user input that we don't want. + request.addValue("application/activity+json", forHTTPHeaderField: "accept") + if let (_, response) = try? await URLSession.appDefault.data(for: request, delegate: RedirectBlocker()), + let location = (response as? HTTPURLResponse)?.value(forHTTPHeaderField: "location") { + effectiveURL = location + } else { + effectiveURL = WebURL(url)!.serialized(excludingFragment: true) + } } else { effectiveURL = WebURL(url)!.serialized(excludingFragment: true) } @@ -232,9 +238,14 @@ class ConversationViewController: UIViewController { let request = Client.search(query: effectiveURL, types: [.statuses], resolve: true) do { let (results, _) = try await mastodonController.run(request) - guard let status = results.statuses.compactMap(\.value).first(where: { $0.url?.serialized() == effectiveURL }) else { + let statuses = results.statuses.compactMap(\.value) + // Don't try to exactly match effective URL because the URL form Mastodon + // uses for the ActivityPub redirect doesn't match what's returned by the API. + // Instead we just assume that, if only one status was returned, it worked. + guard statuses.count == 1 else { throw UnableToResolveError() } + let status = statuses[0] _ = mastodonController.persistentContainer.addOrUpdateOnViewContext(status: status) mode = .localID(status.id) return status.id