Implement TranslationLanguages fetching (IOS-271)
This commit is contained in:
parent
d4132640c5
commit
7f8587913f
|
@ -23,11 +23,40 @@ public class AuthenticationServiceProvider: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
func update(instance: Instance, where domain: String) {
|
||||
@discardableResult
|
||||
func updating(instance: Instance, where domain: String) -> Self {
|
||||
authentications = authentications.map { authentication in
|
||||
guard authentication.domain == domain else { return authentication }
|
||||
return authentication.updating(instance: instance)
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func updating(instanceV1 instance: Mastodon.Entity.Instance, for domain: String) -> Self {
|
||||
authentications = authentications.map { authentication in
|
||||
guard authentication.domain == domain else { return authentication }
|
||||
return authentication.updating(instanceV1: instance)
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func updating(instanceV2 instance: Mastodon.Entity.V2.Instance, for domain: String) -> Self {
|
||||
authentications = authentications.map { authentication in
|
||||
guard authentication.domain == domain else { return authentication }
|
||||
return authentication.updating(instanceV2: instance)
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func updating(translationLanguages: TranslationLanguages, for domain: String) -> Self {
|
||||
authentications = authentications.map { authentication in
|
||||
guard authentication.domain == domain else { return authentication }
|
||||
return authentication.updating(translationLanguages: translationLanguages)
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
func delete(authentication: MastodonAuthentication) throws {
|
||||
|
|
|
@ -5,6 +5,11 @@ import CoreDataStack
|
|||
import MastodonSDK
|
||||
|
||||
public struct MastodonAuthentication: Codable, Hashable, UserIdentifier {
|
||||
public enum InstanceConfiguration: Codable, Hashable {
|
||||
case v1(Mastodon.Entity.Instance, TranslationLanguages)
|
||||
case v2(Mastodon.Entity.V2.Instance, TranslationLanguages)
|
||||
}
|
||||
|
||||
public typealias ID = UUID
|
||||
|
||||
public private(set) var identifier: ID
|
||||
|
@ -22,6 +27,7 @@ public struct MastodonAuthentication: Codable, Hashable, UserIdentifier {
|
|||
|
||||
public private(set) var userID: String
|
||||
public private(set) var instanceObjectIdURI: URL?
|
||||
public private(set) var instanceConfiguration: InstanceConfiguration?
|
||||
|
||||
public var persistenceIdentifier: String {
|
||||
"\(username)@\(domain)"
|
||||
|
@ -49,7 +55,8 @@ public struct MastodonAuthentication: Codable, Hashable, UserIdentifier {
|
|||
updatedAt: now,
|
||||
activedAt: now,
|
||||
userID: userID,
|
||||
instanceObjectIdURI: nil
|
||||
instanceObjectIdURI: nil,
|
||||
instanceConfiguration: nil
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -65,7 +72,8 @@ public struct MastodonAuthentication: Codable, Hashable, UserIdentifier {
|
|||
updatedAt: Date? = nil,
|
||||
activedAt: Date? = nil,
|
||||
userID: String? = nil,
|
||||
instanceObjectIdURI: URL? = nil
|
||||
instanceObjectIdURI: URL? = nil,
|
||||
instanceConfiguration: InstanceConfiguration? = nil
|
||||
) -> Self {
|
||||
MastodonAuthentication(
|
||||
identifier: identifier ?? self.identifier,
|
||||
|
@ -79,7 +87,8 @@ public struct MastodonAuthentication: Codable, Hashable, UserIdentifier {
|
|||
updatedAt: updatedAt ?? self.updatedAt,
|
||||
activedAt: activedAt ?? self.activedAt,
|
||||
userID: userID ?? self.userID,
|
||||
instanceObjectIdURI: instanceObjectIdURI ?? self.instanceObjectIdURI
|
||||
instanceObjectIdURI: instanceObjectIdURI ?? self.instanceObjectIdURI,
|
||||
instanceConfiguration: instanceConfiguration ?? self.instanceConfiguration
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -117,6 +126,37 @@ public struct MastodonAuthentication: Codable, Hashable, UserIdentifier {
|
|||
copy(instanceObjectIdURI: instance.objectID.uriRepresentation())
|
||||
}
|
||||
|
||||
func updating(instanceV1 instance: Mastodon.Entity.Instance) -> Self {
|
||||
guard
|
||||
let instanceConfiguration = self.instanceConfiguration,
|
||||
case let InstanceConfiguration.v1(_, translationLanguages) = instanceConfiguration
|
||||
else {
|
||||
return copy(instanceConfiguration: .v1(instance, [:]))
|
||||
}
|
||||
return copy(instanceConfiguration: .v1(instance, translationLanguages))
|
||||
}
|
||||
|
||||
func updating(instanceV2 instance: Mastodon.Entity.V2.Instance) -> Self {
|
||||
guard
|
||||
let instanceConfiguration = self.instanceConfiguration,
|
||||
case let InstanceConfiguration.v2(_, translationLanguages) = instanceConfiguration
|
||||
else {
|
||||
return copy(instanceConfiguration: .v2(instance, [:]))
|
||||
}
|
||||
return copy(instanceConfiguration: .v2(instance, translationLanguages))
|
||||
}
|
||||
|
||||
func updating(translationLanguages: TranslationLanguages) -> Self {
|
||||
switch self.instanceConfiguration {
|
||||
case .v1(let instance, _):
|
||||
return copy(instanceConfiguration: .v1(instance, translationLanguages))
|
||||
case .v2(let instance, _):
|
||||
return copy(instanceConfiguration: .v2(instance, translationLanguages))
|
||||
case .none:
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
func updating(activatedAt: Date) -> Self {
|
||||
copy(activedAt: activatedAt)
|
||||
}
|
||||
|
|
|
@ -33,4 +33,11 @@ extension APIService {
|
|||
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.ExtendedDescription>, Error> {
|
||||
return Mastodon.API.Instance.extendedDescription(session: session, authorization: authenticationBox?.userAuthorization, domain: domain)
|
||||
}
|
||||
|
||||
public func translationLanguages(
|
||||
domain: String,
|
||||
authenticationBox: MastodonAuthenticationBox?
|
||||
) -> AnyPublisher<Mastodon.Response.Content<TranslationLanguages>, Error> {
|
||||
return Mastodon.API.Instance.translationLanguages(session: session, authorization: authenticationBox?.userAuthorization, domain: domain)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,10 +56,13 @@ extension InstanceService {
|
|||
return self.updateInstance(domain: domain, response: response)
|
||||
}
|
||||
}
|
||||
// .flatMap { [unowned self] response -> AnyPublisher<Void, Error> in
|
||||
// return
|
||||
// }
|
||||
.sink { _ in
|
||||
.sink { [weak self] completion in
|
||||
switch completion {
|
||||
case .finished:
|
||||
self?.updateTranslationLanguages(domain: domain)
|
||||
case .failure:
|
||||
break
|
||||
}
|
||||
} receiveValue: { [weak self] response in
|
||||
guard let _ = self else { return }
|
||||
// do nothing
|
||||
|
@ -67,19 +70,37 @@ extension InstanceService {
|
|||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
func updateTranslationLanguages(domain: String) {
|
||||
apiService?.translationLanguages(domain: domain, authenticationBox: authenticationService?.mastodonAuthenticationBoxes.first)
|
||||
.sink(receiveCompletion: { completion in
|
||||
// no-op
|
||||
}, receiveValue: { [weak self] response in
|
||||
self?.updateTranslationLanguages(domain: domain, response: response)
|
||||
})
|
||||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
private func updateTranslationLanguages(domain: String, response: Mastodon.Response.Content<TranslationLanguages>) {
|
||||
AuthenticationServiceProvider.shared
|
||||
.updating(translationLanguages: response.value, for: domain)
|
||||
}
|
||||
|
||||
private func updateInstance(domain: String, response: Mastodon.Response.Content<Mastodon.Entity.Instance>) -> AnyPublisher<Void, Error> {
|
||||
let managedObjectContext = self.backgroundManagedObjectContext
|
||||
let instanceEntity = response.value
|
||||
return managedObjectContext.performChanges {
|
||||
// get instance
|
||||
let (instance, _) = APIService.CoreData.createOrMergeInstance(
|
||||
into: managedObjectContext,
|
||||
domain: domain,
|
||||
entity: response.value,
|
||||
entity: instanceEntity,
|
||||
networkDate: response.networkDate
|
||||
)
|
||||
|
||||
// update instance
|
||||
AuthenticationServiceProvider.shared.update(instance: instance, where: domain)
|
||||
AuthenticationServiceProvider.shared
|
||||
.updating(instance: instance, where: domain)
|
||||
.updating(instanceV1: instanceEntity, for: domain)
|
||||
}
|
||||
.setFailureType(to: Error.self)
|
||||
.tryMap { result in
|
||||
|
@ -95,19 +116,22 @@ extension InstanceService {
|
|||
|
||||
private func updateInstanceV2(domain: String, response: Mastodon.Response.Content<Mastodon.Entity.V2.Instance>) -> AnyPublisher<Void, Error> {
|
||||
let managedObjectContext = self.backgroundManagedObjectContext
|
||||
let instanceEntity = response.value
|
||||
return managedObjectContext.performChanges {
|
||||
// get instance
|
||||
let (instance, _) = APIService.CoreData.createOrMergeInstance(
|
||||
in: managedObjectContext,
|
||||
context: .init(
|
||||
domain: domain,
|
||||
entity: response.value,
|
||||
entity: instanceEntity,
|
||||
networkDate: response.networkDate
|
||||
)
|
||||
)
|
||||
|
||||
// update instance
|
||||
AuthenticationServiceProvider.shared.update(instance: instance, where: domain)
|
||||
AuthenticationServiceProvider.shared
|
||||
.updating(instance: instance, where: domain)
|
||||
.updating(instanceV2: instanceEntity, for: domain)
|
||||
}
|
||||
.setFailureType(to: Error.self)
|
||||
.tryMap { result in
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// File.swift
|
||||
//
|
||||
//
|
||||
// Created by Marcus Kida on 20.06.24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
extension Mastodon.API.Instance {
|
||||
|
||||
static func translationLanguagesEndpointURL(domain: String) -> URL {
|
||||
return Mastodon.API.endpointURL(domain: domain).appendingPathComponent("instance/translation_languages")
|
||||
}
|
||||
|
||||
public static func translationLanguages(
|
||||
session: URLSession,
|
||||
authorization: Mastodon.API.OAuth.Authorization?,
|
||||
domain: String
|
||||
) -> AnyPublisher<Mastodon.Response.Content<TranslationLanguages>, Error> {
|
||||
let request = Mastodon.API.get(url: translationLanguagesEndpointURL(domain: domain), authorization: authorization)
|
||||
return session.dataTaskPublisher(for: request)
|
||||
.tryMap { data, response in
|
||||
let value = try Mastodon.API.decode(type: TranslationLanguages.self, from: data, response: response)
|
||||
return Mastodon.Response.Content(value: value, response: response)
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
}
|
|
@ -8,6 +8,8 @@
|
|||
import Foundation
|
||||
import Combine
|
||||
|
||||
public typealias TranslationLanguages = [String: [String]]
|
||||
|
||||
extension Mastodon.API.Instance {
|
||||
|
||||
static func instanceEndpointURL(domain: String) -> URL {
|
||||
|
|
|
@ -172,3 +172,13 @@ extension Mastodon.Entity.Instance.Configuration {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Mastodon.Entity.Instance: Hashable {
|
||||
public static func == (lhs: Mastodon.Entity.Instance, rhs: Mastodon.Entity.Instance) -> Bool {
|
||||
lhs.uri == rhs.uri
|
||||
}
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(uri)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,3 +110,13 @@ extension Mastodon.Entity.V2.Instance {
|
|||
public let account: Mastodon.Entity.Account?
|
||||
}
|
||||
}
|
||||
|
||||
extension Mastodon.Entity.V2.Instance: Hashable {
|
||||
public static func == (lhs: Mastodon.Entity.V2.Instance, rhs: Mastodon.Entity.V2.Instance) -> Bool {
|
||||
lhs.domain == rhs.domain
|
||||
}
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(domain)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue