This commit is contained in:
Justin Mazzocchi 2020-08-30 16:59:49 -07:00
parent 9b59e2fbea
commit f86d8188b3
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
37 changed files with 67 additions and 67 deletions

View file

@ -243,11 +243,11 @@ private extension ContentDatabase {
extension Account: TableRecord, FetchableRecord, PersistableRecord { extension Account: TableRecord, FetchableRecord, PersistableRecord {
public static func databaseJSONDecoder(for column: String) -> JSONDecoder { public static func databaseJSONDecoder(for column: String) -> JSONDecoder {
MastodonDecoder() APIDecoder()
} }
public static func databaseJSONEncoder(for column: String) -> JSONEncoder { public static func databaseJSONEncoder(for column: String) -> JSONEncoder {
MastodonEncoder() APIEncoder()
} }
} }
@ -325,11 +325,11 @@ private extension Timeline {
extension Filter: TableRecord, FetchableRecord, PersistableRecord { extension Filter: TableRecord, FetchableRecord, PersistableRecord {
public static func databaseJSONDecoder(for column: String) -> JSONDecoder { public static func databaseJSONDecoder(for column: String) -> JSONDecoder {
MastodonDecoder() APIDecoder()
} }
public static func databaseJSONEncoder(for column: String) -> JSONEncoder { public static func databaseJSONEncoder(for column: String) -> JSONEncoder {
MastodonEncoder() APIEncoder()
} }
} }
@ -453,11 +453,11 @@ private extension StoredStatus {
extension StoredStatus: TableRecord, FetchableRecord, PersistableRecord { extension StoredStatus: TableRecord, FetchableRecord, PersistableRecord {
static func databaseJSONDecoder(for column: String) -> JSONDecoder { static func databaseJSONDecoder(for column: String) -> JSONDecoder {
MastodonDecoder() APIDecoder()
} }
static func databaseJSONEncoder(for column: String) -> JSONEncoder { static func databaseJSONEncoder(for column: String) -> JSONEncoder {
MastodonEncoder() APIEncoder()
} }
} }

View file

@ -5,7 +5,7 @@ import Combine
import Mastodon import Mastodon
// swiftlint:disable force_try // swiftlint:disable force_try
private let decoder = MastodonDecoder() private let decoder = APIDecoder()
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
private let devInstanceURL = URL(string: "https://mastodon.social")! private let devInstanceURL = URL(string: "https://mastodon.social")!
private let devIdentityID = UUID(uuidString: "E621E1F8-C36C-495A-93FC-0C247A3E6E5F")! private let devIdentityID = UUID(uuidString: "E621E1F8-C36C-495A-93FC-0C247A3E6E5F")!

View file

@ -3,7 +3,7 @@
import Foundation import Foundation
import Mastodon import Mastodon
extension MastodonTarget: Stubbing { extension Target: Stubbing {
func stub(url: URL) -> HTTPStub? { func stub(url: URL) -> HTTPStub? {
(endpoint as? Stubbing)?.stub(url: url) (endpoint as? Stubbing)?.stub(url: url)
} }

View file

@ -2,10 +2,10 @@
import Foundation import Foundation
public struct MastodonError: Error, Codable { public struct APIError: Error, Codable {
public let error: String public let error: String
} }
extension MastodonError: LocalizedError { extension APIError: LocalizedError {
public var errorDescription: String? { error } public var errorDescription: String? { error }
} }

View file

@ -2,7 +2,7 @@
import Foundation import Foundation
public struct MastodonContext: Codable, Hashable { public struct Context: Codable, Hashable {
public let ancestors: [Status] public let ancestors: [Status]
public let descendants: [Status] public let descendants: [Status]

View file

@ -2,7 +2,7 @@
import Foundation import Foundation
public struct MastodonPreferences: Codable { public struct Preferences: Codable {
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case postingDefaultVisibility = "posting:default:visibility" case postingDefaultVisibility = "posting:default:visibility"
case postingDefaultSensitive = "posting:default:sensitive" case postingDefaultSensitive = "posting:default:sensitive"
@ -18,7 +18,7 @@ public struct MastodonPreferences: Codable {
public let readingExpandSpoilers: Bool public let readingExpandSpoilers: Bool
} }
public extension MastodonPreferences { public extension Preferences {
enum ExpandMedia: String, Codable, Unknowable { enum ExpandMedia: String, Codable, Unknowable {
case `default` case `default`
case showAll case showAll

View file

@ -3,27 +3,27 @@
import Foundation import Foundation
import Combine import Combine
public class MastodonClient: HTTPClient { public class APIClient: HTTPClient {
public var instanceURL: URL? public var instanceURL: URL?
public var accessToken: String? public var accessToken: String?
public required init(session: Session) { public required init(session: Session) {
super.init(session: session, decoder: MastodonDecoder()) super.init(session: session, decoder: APIDecoder())
} }
public override func request<T: DecodableTarget>(_ target: T) -> AnyPublisher<T.ResultType, Error> { public override func request<T: DecodableTarget>(_ target: T) -> AnyPublisher<T.ResultType, Error> {
super.request(target, decodeErrorsAs: MastodonError.self) super.request(target, decodeErrorsAs: APIError.self)
} }
} }
extension MastodonClient { extension APIClient {
public func request<E: MastodonEndpoint>(_ endpoint: E) -> AnyPublisher<E.ResultType, Error> { public func request<E: Endpoint>(_ endpoint: E) -> AnyPublisher<E.ResultType, Error> {
guard let instanceURL = instanceURL else { guard let instanceURL = instanceURL else {
return Fail(error: URLError(.badURL)).eraseToAnyPublisher() return Fail(error: URLError(.badURL)).eraseToAnyPublisher()
} }
return super.request( return super.request(
MastodonTarget(baseURL: instanceURL, endpoint: endpoint, accessToken: accessToken), Target(baseURL: instanceURL, endpoint: endpoint, accessToken: accessToken),
decodeErrorsAs: MastodonError.self) decodeErrorsAs: APIError.self)
} }
} }

View file

@ -2,7 +2,7 @@
import Foundation import Foundation
public class MastodonDecoder: JSONDecoder { public class APIDecoder: JSONDecoder {
public override init() { public override init() {
super.init() super.init()

View file

@ -2,7 +2,7 @@
import Foundation import Foundation
public class MastodonEncoder: JSONEncoder { public class APIEncoder: JSONEncoder {
public override init() { public override init() {
super.init() super.init()

View file

@ -2,7 +2,7 @@
import Foundation import Foundation
public protocol MastodonEndpoint { public protocol Endpoint {
associatedtype ResultType: Decodable associatedtype ResultType: Decodable
var APIVersion: String { get } var APIVersion: String { get }
var context: [String] { get } var context: [String] { get }
@ -13,7 +13,7 @@ public protocol MastodonEndpoint {
var headers: HTTPHeaders? { get } var headers: HTTPHeaders? { get }
} }
public extension MastodonEndpoint { public extension Endpoint {
var defaultContext: [String] { var defaultContext: [String] {
["api", APIVersion] ["api", APIVersion]
} }

View file

@ -13,7 +13,7 @@ public enum AccessTokenEndpoint {
) )
} }
extension AccessTokenEndpoint: MastodonEndpoint { extension AccessTokenEndpoint: Endpoint {
public typealias ResultType = AccessToken public typealias ResultType = AccessToken
public var context: [String] { [] } public var context: [String] { [] }

View file

@ -6,7 +6,7 @@ public enum AccountEndpoint {
case verifyCredentials case verifyCredentials
} }
extension AccountEndpoint: MastodonEndpoint { extension AccountEndpoint: Endpoint {
public typealias ResultType = Account public typealias ResultType = Account
public var context: [String] { public var context: [String] {

View file

@ -6,7 +6,7 @@ public enum AppAuthorizationEndpoint {
case apps(clientName: String, redirectURI: String, scopes: String, website: URL?) case apps(clientName: String, redirectURI: String, scopes: String, website: URL?)
} }
extension AppAuthorizationEndpoint: MastodonEndpoint { extension AppAuthorizationEndpoint: Endpoint {
public typealias ResultType = AppAuthorization public typealias ResultType = AppAuthorization
public var pathComponentsInContext: [String] { public var pathComponentsInContext: [String] {

View file

@ -6,8 +6,8 @@ public enum ContextEndpoint {
case context(id: String) case context(id: String)
} }
extension ContextEndpoint: MastodonEndpoint { extension ContextEndpoint: Endpoint {
public typealias ResultType = MastodonContext public typealias ResultType = Context
public var context: [String] { public var context: [String] {
defaultContext + ["statuses"] defaultContext + ["statuses"]

View file

@ -8,7 +8,7 @@ public enum DeletionEndpoint {
case filter(id: String) case filter(id: String)
} }
extension DeletionEndpoint: MastodonEndpoint { extension DeletionEndpoint: Endpoint {
public typealias ResultType = [String: String] public typealias ResultType = [String: String]
public var context: [String] { public var context: [String] {

View file

@ -18,7 +18,7 @@ public enum FilterEndpoint {
expiresIn: Date?) expiresIn: Date?)
} }
extension FilterEndpoint: MastodonEndpoint { extension FilterEndpoint: Endpoint {
public typealias ResultType = Filter public typealias ResultType = Filter
public var context: [String] { public var context: [String] {

View file

@ -6,7 +6,7 @@ public enum FiltersEndpoint {
case filters case filters
} }
extension FiltersEndpoint: MastodonEndpoint { extension FiltersEndpoint: Endpoint {
public typealias ResultType = [Filter] public typealias ResultType = [Filter]
public var context: [String] { public var context: [String] {

View file

@ -6,7 +6,7 @@ public enum InstanceEndpoint {
case instance case instance
} }
extension InstanceEndpoint: MastodonEndpoint { extension InstanceEndpoint: Endpoint {
public typealias ResultType = Instance public typealias ResultType = Instance
public var pathComponentsInContext: [String] { public var pathComponentsInContext: [String] {

View file

@ -6,7 +6,7 @@ public enum ListEndpoint {
case create(title: String) case create(title: String)
} }
extension ListEndpoint: MastodonEndpoint { extension ListEndpoint: Endpoint {
public typealias ResultType = MastodonList public typealias ResultType = MastodonList
public var context: [String] { public var context: [String] {

View file

@ -6,7 +6,7 @@ public enum ListsEndpoint {
case lists case lists
} }
extension ListsEndpoint: MastodonEndpoint { extension ListsEndpoint: Endpoint {
public typealias ResultType = [MastodonList] public typealias ResultType = [MastodonList]
public var pathComponentsInContext: [String] { public var pathComponentsInContext: [String] {

View file

@ -2,7 +2,7 @@
import Foundation import Foundation
public struct Paged<T: MastodonEndpoint> { public struct Paged<T: Endpoint> {
public let endpoint: T public let endpoint: T
public let maxID: String? public let maxID: String?
public let minID: String? public let minID: String?
@ -18,7 +18,7 @@ public struct Paged<T: MastodonEndpoint> {
} }
} }
extension Paged: MastodonEndpoint { extension Paged: Endpoint {
public typealias ResultType = T.ResultType public typealias ResultType = T.ResultType
public var APIVersion: String { endpoint.APIVersion } public var APIVersion: String { endpoint.APIVersion }

View file

@ -6,8 +6,8 @@ public enum PreferencesEndpoint {
case preferences case preferences
} }
extension PreferencesEndpoint: MastodonEndpoint { extension PreferencesEndpoint: Endpoint {
public typealias ResultType = MastodonPreferences public typealias ResultType = Preferences
public var pathComponentsInContext: [String] { public var pathComponentsInContext: [String] {
switch self { switch self {

View file

@ -13,7 +13,7 @@ public enum PushSubscriptionEndpoint {
case delete case delete
} }
extension PushSubscriptionEndpoint: MastodonEndpoint { extension PushSubscriptionEndpoint: Endpoint {
public typealias ResultType = PushSubscription public typealias ResultType = PushSubscription
public var context: [String] { public var context: [String] {

View file

@ -8,7 +8,7 @@ public enum StatusEndpoint {
case unfavourite(id: String) case unfavourite(id: String)
} }
extension StatusEndpoint: MastodonEndpoint { extension StatusEndpoint: Endpoint {
public typealias ResultType = Status public typealias ResultType = Status
public var context: [String] { public var context: [String] {

View file

@ -9,7 +9,7 @@ public enum TimelinesEndpoint {
case list(id: String) case list(id: String)
} }
extension TimelinesEndpoint: MastodonEndpoint { extension TimelinesEndpoint: Endpoint {
public typealias ResultType = [Status] public typealias ResultType = [Status]
public var context: [String] { public var context: [String] {

View file

@ -2,7 +2,7 @@
import Foundation import Foundation
public struct MastodonTarget<E: MastodonEndpoint> { public struct Target<E: Endpoint> {
public let baseURL: URL public let baseURL: URL
public let endpoint: E public let endpoint: E
public let accessToken: String? public let accessToken: String?
@ -14,7 +14,7 @@ public struct MastodonTarget<E: MastodonEndpoint> {
} }
} }
extension MastodonTarget: DecodableTarget { extension Target: DecodableTarget {
public typealias ResultType = E.ResultType public typealias ResultType = E.ResultType
public var pathComponents: [String] { endpoint.pathComponents } public var pathComponents: [String] { endpoint.pathComponents }

View file

@ -57,7 +57,7 @@ public extension DecodableDefault {
} }
public enum ExpandMediaDefault: Source { public enum ExpandMediaDefault: Source {
public static var defaultValue: MastodonPreferences.ExpandMedia { .default } public static var defaultValue: Preferences.ExpandMedia { .default }
} }
} }
} }

View file

@ -289,13 +289,13 @@
D047FA7F24C3E21000AF17C5 = { D047FA7F24C3E21000AF17C5 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D0E0F1E424FC49FC002C04BF /* Mastodon */,
D0C7D45224F76169001EBDBB /* Assets.xcassets */, D0C7D45224F76169001EBDBB /* Assets.xcassets */,
D0C7D46424F76169001EBDBB /* Databases */, D0C7D46424F76169001EBDBB /* Databases */,
D0ED1BB224CE3A1600B4899C /* Development Assets */, D0ED1BB224CE3A1600B4899C /* Development Assets */,
D0C7D46824F76169001EBDBB /* Extensions */, D0C7D46824F76169001EBDBB /* Extensions */,
D0666A7924C7745A00F3F04B /* Frameworks */, D0666A7924C7745A00F3F04B /* Frameworks */,
D0C7D45624F76169001EBDBB /* Localizations */, D0C7D45624F76169001EBDBB /* Localizations */,
D0E0F1E424FC49FC002C04BF /* Mastodon */,
D0C7D43824F76169001EBDBB /* Model */, D0C7D43824F76169001EBDBB /* Model */,
D0C7D47324F76169001EBDBB /* Networking */, D0C7D47324F76169001EBDBB /* Networking */,
D0E5361A24E3EB4D00FB1CE1 /* Notification Service Extension */, D0E5361A24E3EB4D00FB1CE1 /* Notification Service Extension */,

View file

@ -40,7 +40,7 @@ extension Identity {
@DecodableDefault.StatusVisibilityPublic var postingDefaultVisibility: Status.Visibility @DecodableDefault.StatusVisibilityPublic var postingDefaultVisibility: Status.Visibility
@DecodableDefault.False var postingDefaultSensitive @DecodableDefault.False var postingDefaultSensitive
var postingDefaultLanguage: String? var postingDefaultLanguage: String?
@DecodableDefault.ExpandMediaDefault var readingExpandMedia: MastodonPreferences.ExpandMedia @DecodableDefault.ExpandMediaDefault var readingExpandMedia: Mastodon.Preferences.ExpandMedia
@DecodableDefault.False var readingExpandSpoilers @DecodableDefault.False var readingExpandSpoilers
} }
} }
@ -58,7 +58,7 @@ extension Identity {
} }
extension Identity.Preferences { extension Identity.Preferences {
func updated(from serverPreferences: MastodonPreferences) -> Self { func updated(from serverPreferences: Preferences) -> Self {
var mutable = self var mutable = self
if useServerPostingReadingPreferences { if useServerPostingReadingPreferences {

View file

@ -22,7 +22,7 @@ class NotificationService: UNNotificationServiceExtension {
do { do {
let decryptedJSON = try Self.extractAndDecrypt(userInfo: request.content.userInfo) let decryptedJSON = try Self.extractAndDecrypt(userInfo: request.content.userInfo)
pushNotification = try MastodonDecoder().decode(PushNotification.self, from: decryptedJSON) pushNotification = try APIDecoder().decode(PushNotification.self, from: decryptedJSON)
} catch { } catch {
contentHandler(bestAttemptContent) contentHandler(bestAttemptContent)

View file

@ -50,7 +50,7 @@ extension AllIdentitiesService {
func deleteIdentity(_ identity: Identity) -> AnyPublisher<Never, Error> { func deleteIdentity(_ identity: Identity) -> AnyPublisher<Never, Error> {
let secretsService = SecretsService(identityID: identity.id, keychainService: environment.keychainServiceType) let secretsService = SecretsService(identityID: identity.id, keychainService: environment.keychainServiceType)
let networkClient = MastodonClient(session: environment.session) let networkClient = APIClient(session: environment.session)
networkClient.instanceURL = identity.url networkClient.instanceURL = identity.url

View file

@ -5,12 +5,12 @@ import Combine
import Mastodon import Mastodon
struct AuthenticationService { struct AuthenticationService {
private let networkClient: MastodonClient private let networkClient: APIClient
private let webAuthSessionType: WebAuthSession.Type private let webAuthSessionType: WebAuthSession.Type
private let webAuthSessionContextProvider = WebAuthSessionContextProvider() private let webAuthSessionContextProvider = WebAuthSessionContextProvider()
init(environment: AppEnvironment) { init(environment: AppEnvironment) {
networkClient = MastodonClient(session: environment.session) networkClient = APIClient(session: environment.session)
webAuthSessionType = environment.webAuthSessionType webAuthSessionType = environment.webAuthSessionType
} }
} }
@ -22,7 +22,7 @@ extension AuthenticationService {
redirectURI: OAuth.callbackURL.absoluteString, redirectURI: OAuth.callbackURL.absoluteString,
scopes: OAuth.scopes, scopes: OAuth.scopes,
website: OAuth.website) website: OAuth.website)
let target = MastodonTarget(baseURL: instanceURL, endpoint: endpoint, accessToken: nil) let target = Target(baseURL: instanceURL, endpoint: endpoint, accessToken: nil)
return networkClient.request(target) return networkClient.request(target)
} }
@ -63,7 +63,7 @@ extension AuthenticationService {
grantType: OAuth.grantType, grantType: OAuth.grantType,
scopes: OAuth.scopes, scopes: OAuth.scopes,
redirectURI: OAuth.callbackURL.absoluteString) redirectURI: OAuth.callbackURL.absoluteString)
let target = MastodonTarget(baseURL: instanceURL, endpoint: endpoint, accessToken: nil) let target = Target(baseURL: instanceURL, endpoint: endpoint, accessToken: nil)
return networkClient.request(target) return networkClient.request(target)
} }

View file

@ -11,7 +11,7 @@ class IdentityService {
private let identityDatabase: IdentityDatabase private let identityDatabase: IdentityDatabase
private let contentDatabase: ContentDatabase private let contentDatabase: ContentDatabase
private let environment: AppEnvironment private let environment: AppEnvironment
private let networkClient: MastodonClient private let networkClient: APIClient
private let secretsService: SecretsService private let secretsService: SecretsService
private let observationErrorsInput = PassthroughSubject<Error, Never>() private let observationErrorsInput = PassthroughSubject<Error, Never>()
@ -35,7 +35,7 @@ class IdentityService {
secretsService = SecretsService( secretsService = SecretsService(
identityID: identityID, identityID: identityID,
keychainService: environment.keychainServiceType) keychainService: environment.keychainServiceType)
networkClient = MastodonClient(session: environment.session) networkClient = APIClient(session: environment.session)
networkClient.instanceURL = identity.url networkClient.instanceURL = identity.url
networkClient.accessToken = try? secretsService.item(.accessToken) networkClient.accessToken = try? secretsService.item(.accessToken)

View file

@ -9,12 +9,12 @@ struct ContextService {
let paginates = false let paginates = false
private let status: Status private let status: Status
private let context = CurrentValueSubject<MastodonContext, Never>(MastodonContext(ancestors: [], descendants: [])) private let context = CurrentValueSubject<Context, Never>(Context(ancestors: [], descendants: []))
private let networkClient: MastodonClient private let networkClient: APIClient
private let contentDatabase: ContentDatabase private let contentDatabase: ContentDatabase
private let collection: TransientStatusCollection private let collection: TransientStatusCollection
init(status: Status, networkClient: MastodonClient, contentDatabase: ContentDatabase) { init(status: Status, networkClient: APIClient, contentDatabase: ContentDatabase) {
self.status = status self.status = status
self.networkClient = networkClient self.networkClient = networkClient
self.contentDatabase = contentDatabase self.contentDatabase = contentDatabase

View file

@ -8,10 +8,10 @@ struct TimelineService {
let statusSections: AnyPublisher<[[Status]], Error> let statusSections: AnyPublisher<[[Status]], Error>
private let timeline: Timeline private let timeline: Timeline
private let networkClient: MastodonClient private let networkClient: APIClient
private let contentDatabase: ContentDatabase private let contentDatabase: ContentDatabase
init(timeline: Timeline, networkClient: MastodonClient, contentDatabase: ContentDatabase) { init(timeline: Timeline, networkClient: APIClient, contentDatabase: ContentDatabase) {
self.timeline = timeline self.timeline = timeline
self.networkClient = networkClient self.networkClient = networkClient
self.contentDatabase = contentDatabase self.contentDatabase = contentDatabase

View file

@ -6,10 +6,10 @@ import Mastodon
struct StatusService { struct StatusService {
let status: Status let status: Status
private let networkClient: MastodonClient private let networkClient: APIClient
private let contentDatabase: ContentDatabase private let contentDatabase: ContentDatabase
init(status: Status, networkClient: MastodonClient, contentDatabase: ContentDatabase) { init(status: Status, networkClient: APIClient, contentDatabase: ContentDatabase) {
self.status = status self.status = status
self.networkClient = networkClient self.networkClient = networkClient
self.contentDatabase = contentDatabase self.contentDatabase = contentDatabase

View file

@ -2,7 +2,7 @@
import SwiftUI import SwiftUI
import class Mastodon.Status import class Mastodon.Status
import struct Mastodon.MastodonPreferences import struct Mastodon.Preferences
struct PostingReadingPreferencesView: View { struct PostingReadingPreferencesView: View {
@StateObject var viewModel: PostingReadingPreferencesViewModel @StateObject var viewModel: PostingReadingPreferencesViewModel
@ -33,9 +33,9 @@ struct PostingReadingPreferencesView: View {
Text("preferences.reading-expand-media") Text("preferences.reading-expand-media")
Picker("", selection: $viewModel.preferences.readingExpandMedia, Picker("", selection: $viewModel.preferences.readingExpandMedia,
content: { content: {
Text("preferences.expand-media.default").tag(MastodonPreferences.ExpandMedia.default) Text("preferences.expand-media.default").tag(Preferences.ExpandMedia.default)
Text("preferences.expand-media.show-all").tag(MastodonPreferences.ExpandMedia.showAll) Text("preferences.expand-media.show-all").tag(Preferences.ExpandMedia.showAll)
Text("preferences.expand-media.hide-all").tag(MastodonPreferences.ExpandMedia.hideAll) Text("preferences.expand-media.hide-all").tag(Preferences.ExpandMedia.hideAll)
}) })
.pickerStyle(SegmentedPickerStyle()) .pickerStyle(SegmentedPickerStyle())
} }