Get rid of network request during share extension launch

Closes #438
This commit is contained in:
Shadowfacts 2023-12-02 15:33:15 -05:00
parent 99caaa0f28
commit 23f383a7f9
4 changed files with 56 additions and 27 deletions

View File

@ -16,6 +16,11 @@ public struct UserAccountInfo: Equatable, Hashable, Identifiable {
public private(set) var username: String! public private(set) var username: String!
public let accessToken: String public let accessToken: String
// Sort of hack to be able to access these from the share extension.
public internal(set) var serverDefaultLanguage: String?
public internal(set) var serverDefaultVisibility: String?
public internal(set) var serverDefaultFederation: Bool?
fileprivate static let tempAccountID = "temp" fileprivate static let tempAccountID = "temp"
static func id(instanceURL: URL, username: String?) -> String { static func id(instanceURL: URL, username: String?) -> String {
@ -47,21 +52,47 @@ public struct UserAccountInfo: Equatable, Hashable, Identifiable {
self.accessToken = accessToken self.accessToken = accessToken
} }
init?(userDefaultsDict dict: [String: String]) { init?(userDefaultsDict dict: [String: Any]) {
guard let id = dict["id"], guard let id = dict["id"] as? String,
let instanceURL = dict["instanceURL"], let instanceURL = dict["instanceURL"] as? String,
let url = URL(string: instanceURL), let url = URL(string: instanceURL),
let clientID = dict["clientID"], let clientID = dict["clientID"] as? String,
let secret = dict["clientSecret"], let secret = dict["clientSecret"] as? String,
let accessToken = dict["accessToken"] else { let accessToken = dict["accessToken"] as? String else {
return nil return nil
} }
self.id = id self.id = id
self.instanceURL = url self.instanceURL = url
self.clientID = clientID self.clientID = clientID
self.clientSecret = secret self.clientSecret = secret
self.username = dict["username"] self.username = dict["username"] as? String
self.accessToken = accessToken self.accessToken = accessToken
self.serverDefaultLanguage = dict["serverDefaultLanguage"] as? String
self.serverDefaultVisibility = dict["serverDefaultVisibility"] as? String
self.serverDefaultFederation = dict["serverDefaultFederation"] as? Bool
}
var userDefaultsDict: [String: Any] {
var dict: [String: Any] = [
"id": id,
"instanceURL": instanceURL.absoluteString,
"clientID": clientID,
"clientSecret": clientSecret,
"accessToken": accessToken,
]
if let username {
dict["username"] = username
}
if let serverDefaultLanguage {
dict["serverDefaultLanguage"] = serverDefaultLanguage
}
if let serverDefaultVisibility {
dict["serverDefaultVisibility"] = serverDefaultVisibility
}
if let serverDefaultFederation {
dict["serverDefaultFederation"] = serverDefaultFederation
}
return dict
} }
/// A filename-safe string for this account /// A filename-safe string for this account

View File

@ -46,19 +46,7 @@ public class UserAccountsManager: ObservableObject {
} }
set { set {
objectWillChange.send() objectWillChange.send()
let array = newValue.map { (info) -> [String: String] in let array = newValue.map(\.userDefaultsDict)
var res = [
"id": info.id,
"instanceURL": info.instanceURL.absoluteString,
"clientID": info.clientID,
"clientSecret": info.clientSecret,
"accessToken": info.accessToken
]
if let username = info.username {
res["username"] = username
}
return res
}
defaults.set(array, forKey: accountsKey) defaults.set(array, forKey: accountsKey)
} }
} }
@ -147,6 +135,17 @@ public class UserAccountsManager: ObservableObject {
mostRecentAccountID = account?.id mostRecentAccountID = account?.id
} }
public func updateServerPreferences(_ account: UserAccountInfo, defaultLanguage: String?, defaultVisibility: String?, defaultFederation: Bool?) {
guard let index = accounts.firstIndex(where: { $0.id == account.id }) else {
return
}
var account = account
account.serverDefaultLanguage = defaultLanguage
account.serverDefaultVisibility = defaultVisibility
account.serverDefaultFederation = defaultFederation
accounts[index] = account
}
} }
public extension Notification.Name { public extension Notification.Name {

View File

@ -53,18 +53,14 @@ class ShareViewController: UIViewController {
private func createDraft(account: UserAccountInfo) async -> Draft { private func createDraft(account: UserAccountInfo) async -> Draft {
async let (text, attachments) = getDraftConfigurationFromExtensionContext() async let (text, attachments) = getDraftConfigurationFromExtensionContext()
// TODO: I really don't like that there's a network request in the hot path here, but we don't have easy access to AccountPreferences :/
let serverPrefs = try? await Client(baseURL: account.instanceURL, accessToken: account.accessToken).run(Client.getPreferences()).0
let visibility = Preferences.shared.defaultPostVisibility.resolved(withServerDefault: serverPrefs?.postingDefaultVisibility)
let draft = DraftsPersistentContainer.shared.createDraft( let draft = DraftsPersistentContainer.shared.createDraft(
accountID: account.id, accountID: account.id,
text: await text, text: await text,
contentWarning: "", contentWarning: "",
inReplyToID: nil, inReplyToID: nil,
visibility: visibility, visibility: Preferences.shared.defaultPostVisibility.resolved(withServerDefault: account.serverDefaultVisibility.flatMap(Visibility.init(rawValue:))),
language: serverPrefs?.postingDefaultLanguage, language: account.serverDefaultLanguage,
localOnly: !(serverPrefs?.postingDefaultFederation ?? true) localOnly: !(account.serverDefaultFederation ?? true)
) )
for attachment in await attachments { for attachment in await attachments {

View File

@ -371,6 +371,9 @@ class MastodonController: ObservableObject {
accountPreferences!.serverDefaultLanguage = prefs.postingDefaultLanguage accountPreferences!.serverDefaultLanguage = prefs.postingDefaultLanguage
accountPreferences!.serverDefaultVisibility = prefs.postingDefaultVisibility accountPreferences!.serverDefaultVisibility = prefs.postingDefaultVisibility
accountPreferences!.serverDefaultFederation = prefs.postingDefaultFederation ?? true accountPreferences!.serverDefaultFederation = prefs.postingDefaultFederation ?? true
if let accountInfo {
UserAccountsManager.shared.updateServerPreferences(accountInfo, defaultLanguage: prefs.postingDefaultLanguage, defaultVisibility: prefs.postingDefaultVisibility.rawValue, defaultFederation: prefs.postingDefaultFederation)
}
} }
private func updateActiveInstance(from instance: Instance) { private func updateActiveInstance(from instance: Instance) {