fix: acct lookup support

This commit is contained in:
sunxiaojian 2021-03-02 13:27:53 +08:00
parent 2e8183adc6
commit a9fdd2efa3
5 changed files with 101 additions and 1 deletions

View File

@ -336,6 +336,7 @@ extension MastodonPickServerViewController {
} else { } else {
let mastodonRegisterViewModel = MastodonRegisterViewModel( let mastodonRegisterViewModel = MastodonRegisterViewModel(
domain: server.domain, domain: server.domain,
context: self.context,
authenticateInfo: response.authenticateInfo, authenticateInfo: response.authenticateInfo,
instance: response.instance.value, instance: response.instance.value,
applicationToken: response.applicationToken.value applicationToken: response.applicationToken.value

View File

@ -18,6 +18,7 @@ final class MastodonRegisterViewModel {
let authenticateInfo: AuthenticationViewModel.AuthenticateInfo let authenticateInfo: AuthenticationViewModel.AuthenticateInfo
let instance: Mastodon.Entity.Instance let instance: Mastodon.Entity.Instance
let applicationToken: Mastodon.Entity.Token let applicationToken: Mastodon.Entity.Token
let context: AppContext
let username = CurrentValueSubject<String, Never>("") let username = CurrentValueSubject<String, Never>("")
let displayName = CurrentValueSubject<String, Never>("") let displayName = CurrentValueSubject<String, Never>("")
@ -46,11 +47,13 @@ final class MastodonRegisterViewModel {
init( init(
domain: String, domain: String,
context: AppContext,
authenticateInfo: AuthenticationViewModel.AuthenticateInfo, authenticateInfo: AuthenticationViewModel.AuthenticateInfo,
instance: Mastodon.Entity.Instance, instance: Mastodon.Entity.Instance,
applicationToken: Mastodon.Entity.Token applicationToken: Mastodon.Entity.Token
) { ) {
self.domain = domain self.domain = domain
self.context = context
self.authenticateInfo = authenticateInfo self.authenticateInfo = authenticateInfo
self.instance = instance self.instance = instance
self.applicationToken = applicationToken self.applicationToken = applicationToken
@ -78,6 +81,21 @@ final class MastodonRegisterViewModel {
} }
.assign(to: \.value, on: usernameValidateState) .assign(to: \.value, on: usernameValidateState)
.store(in: &disposeBag) .store(in: &disposeBag)
username.debounce(for: .milliseconds(300), scheduler: DispatchQueue.main).removeDuplicates()
.sink { [weak self] text in
self?.lookupAccount(by: text)
}
.store(in: &disposeBag)
usernameValidateState
.sink { [weak self] validateState in
if validateState == .valid {
self?.usernameErrorPrompt.value = nil
}
}
.store(in: &disposeBag)
displayName displayName
.map { displayname in .map { displayname in
guard !displayname.isEmpty else { return .empty } guard !displayname.isEmpty else { return .empty }
@ -145,6 +163,23 @@ final class MastodonRegisterViewModel {
.assign(to: \.value, on: isAllValid) .assign(to: \.value, on: isAllValid)
.store(in: &disposeBag) .store(in: &disposeBag)
} }
func lookupAccount(by acct: String) {
if acct.isEmpty {
return
}
let query = Mastodon.API.Account.AccountLookupQuery(acct: acct)
context.apiService.accountLookup(domain: domain, query: query, authorization: applicationAuthorization)
.sink { _ in
} receiveValue: { [weak self] account in
guard let self = self else { return }
let text = L10n.Scene.Register.Error.Reason.taken(L10n.Scene.Register.Error.Item.username)
self.usernameErrorPrompt.value = MastodonRegisterViewModel.errorPromptAttributedString(for: text)
}
.store(in: &disposeBag)
}
} }
extension MastodonRegisterViewModel { extension MastodonRegisterViewModel {

View File

@ -204,7 +204,7 @@ extension MastodonServerRulesViewController {
@objc private func confirmButtonPressed(_ sender: UIButton) { @objc private func confirmButtonPressed(_ sender: UIButton) {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
let viewModel = MastodonRegisterViewModel(domain: self.viewModel.domain, authenticateInfo: self.viewModel.authenticateInfo, instance: self.viewModel.instance, applicationToken: self.viewModel.applicationToken) let viewModel = MastodonRegisterViewModel(domain: self.viewModel.domain,context: self.context, authenticateInfo: self.viewModel.authenticateInfo, instance: self.viewModel.instance, applicationToken: self.viewModel.applicationToken)
self.coordinator.present(scene: .mastodonRegister(viewModel: viewModel), from: self, transition: .show) self.coordinator.present(scene: .mastodonRegister(viewModel: viewModel), from: self, transition: .show)
} }
} }

View File

@ -152,4 +152,17 @@ extension APIService {
) )
} }
func accountLookup(
domain: String,
query: Mastodon.API.Account.AccountLookupQuery,
authorization: Mastodon.API.OAuth.Authorization
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Account>, Error> {
return Mastodon.API.Account.lookupAccount(
session: session,
domain: domain,
query: query,
authorization: authorization
)
}
} }

View File

@ -132,3 +132,54 @@ extension Mastodon.API.Account {
} }
} }
extension Mastodon.API.Account {
static func accountsLookupEndpointURL(domain: String) -> URL {
return Mastodon.API.endpointURL(domain: domain).appendingPathComponent("accounts/lookup")
}
public struct AccountLookupQuery: GetQuery {
public var acct: String
public init(acct: String) {
self.acct = acct
}
var queryItems: [URLQueryItem]? {
var items: [URLQueryItem] = []
items.append(URLQueryItem(name: "acct", value: acct))
return items
}
}
/// lookup account by acct.
///
/// - Version: 3.3.1
/// - Parameters:
/// - session: `URLSession`
/// - domain: Mastodon instance domain. e.g. "example.com"
/// - query: `AccountInfoQuery` with account query information,
/// - authorization: user token
/// - Returns: `AnyPublisher` contains `Account` nested in the response
public static func lookupAccount(
session: URLSession,
domain: String,
query: AccountLookupQuery,
authorization: Mastodon.API.OAuth.Authorization?
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Account>, Error> {
let request = Mastodon.API.get(
url: accountsLookupEndpointURL(domain: domain),
query: query,
authorization: authorization
)
return session.dataTaskPublisher(for: request)
.tryMap { data, response in
let value = try Mastodon.API.decode(type: Mastodon.Entity.Account.self, from: data, response: response)
return Mastodon.Response.Content(value: value, response: response)
}
.eraseToAnyPublisher()
}
}