Refactoring

This commit is contained in:
Justin Mazzocchi 2020-10-05 00:04:15 -07:00
parent f3e1baecaa
commit a07d25c80b
No known key found for this signature in database
GPG Key ID: E223E6937AAFB01C
8 changed files with 96 additions and 101 deletions

View File

@ -0,0 +1,38 @@
// Copyright © 2020 Metabolist. All rights reserved.
import Combine
import DB
import Foundation
import Mastodon
import MastodonAPI
public struct ContextService: CollectionService {
public let sections: AnyPublisher<[[CollectionItem]], Error>
public let navigationService: NavigationService
public let nextPageMaxIDs: AnyPublisher<String?, Never> = Empty().eraseToAnyPublisher()
public let title: String? = nil
public var contextParentID: String? { statusID }
private let statusID: String
private let mastodonAPIClient: MastodonAPIClient
private let contentDatabase: ContentDatabase
init(statusID: String, mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) {
self.statusID = statusID
self.mastodonAPIClient = mastodonAPIClient
self.contentDatabase = contentDatabase
sections = contentDatabase.contextObservation(parentID: statusID)
navigationService = NavigationService(
status: nil,
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase)
}
public func request(maxID: String?, minID: String?) -> AnyPublisher<Never, Error> {
mastodonAPIClient.request(StatusEndpoint.status(id: statusID))
.flatMap(contentDatabase.insert(status:))
.merge(with: mastodonAPIClient.request(ContextEndpoint.context(id: statusID))
.flatMap { contentDatabase.insert(context: $0, parentID: statusID) })
.eraseToAnyPublisher()
}
}

View File

@ -177,8 +177,8 @@ public extension IdentityService {
.eraseToAnyPublisher()
}
func service(timeline: Timeline) -> StatusListService {
StatusListService(timeline: timeline, mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
func service(timeline: Timeline) -> TimelineService {
TimelineService(timeline: timeline, mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
}
}

View File

@ -31,7 +31,7 @@ public extension NavigationService {
if let tag = tag(url: url) {
return Just(
.collection(
StatusListService(
TimelineService(
timeline: .tag(tag),
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase)))
@ -39,13 +39,7 @@ public extension NavigationService {
} else if let accountID = accountID(url: url) {
return Just(.profile(profileService(id: accountID))).eraseToAnyPublisher()
} else if mastodonAPIClient.instanceURL.host == url.host, let statusID = url.statusID {
return Just(
.collection(
StatusListService(
statusID: statusID,
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase)))
.eraseToAnyPublisher()
return Just(.collection(contextService(id: statusID))).eraseToAnyPublisher()
}
if url.shouldWebfinger {
@ -55,8 +49,8 @@ public extension NavigationService {
}
}
func contextStatusListService(id: String) -> StatusListService {
StatusListService(statusID: id, mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
func contextService(id: String) -> ContextService {
ContextService(statusID: id, mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
}
func profileService(id: String) -> ProfileService {
@ -113,18 +107,14 @@ private extension NavigationService {
.map { results -> Navigation in
if let tag = results.hashtags.first {
return .collection(
StatusListService(
TimelineService(
timeline: .tag(tag.name),
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase))
} else if let account = results.accounts.first {
return .profile(profileService(account: account))
} else if let status = results.statuses.first {
return .collection(
StatusListService(
statusID: status.id,
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase))
return .collection(contextService(id: status.id))
} else {
return .url(url)
}

View File

@ -50,8 +50,8 @@ public struct ProfileService {
}
public extension ProfileService {
func statusListService(profileCollection: ProfileCollection) -> StatusListService {
StatusListService(
func timelineService(profileCollection: ProfileCollection) -> TimelineService {
TimelineService(
timeline: .profile(accountId: accountID, profileCollection: profileCollection),
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase)

View File

@ -1,78 +0,0 @@
// Copyright © 2020 Metabolist. All rights reserved.
import Combine
import DB
import Foundation
import Mastodon
import MastodonAPI
public struct StatusListService: CollectionService {
public let sections: AnyPublisher<[[CollectionItem]], Error>
public let nextPageMaxIDs: AnyPublisher<String?, Never>
public let contextParentID: String?
public let title: String?
public let navigationService: NavigationService
private let filterContext: Filter.Context
private let mastodonAPIClient: MastodonAPIClient
private let contentDatabase: ContentDatabase
private let requestClosure: (_ maxID: String?, _ minID: String?) -> AnyPublisher<Never, Error>
}
extension StatusListService {
init(timeline: Timeline, mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) {
var title: String?
if case let .tag(tag) = timeline {
title = "#".appending(tag)
}
let nextPageMaxIDsSubject = PassthroughSubject<String?, Never>()
self.init(sections: contentDatabase.observation(timeline: timeline),
nextPageMaxIDs: nextPageMaxIDsSubject.eraseToAnyPublisher(),
contextParentID: nil,
title: title,
navigationService: NavigationService(
status: nil,
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase),
filterContext: timeline.filterContext,
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase) { maxID, minID in
mastodonAPIClient.pagedRequest(timeline.endpoint, maxID: maxID, minID: minID)
.handleEvents(receiveOutput: { nextPageMaxIDsSubject.send($0.info.maxID) })
.flatMap { contentDatabase.insert(statuses: $0.result, timeline: timeline) }
.eraseToAnyPublisher()
}
}
init(statusID: String, mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) {
self.init(sections: contentDatabase.contextObservation(parentID: statusID),
nextPageMaxIDs: Empty().eraseToAnyPublisher(),
contextParentID: statusID,
title: nil,
navigationService: NavigationService(
status: nil,
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase),
filterContext: .thread,
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase) { _, _ in
Publishers.Merge(
mastodonAPIClient.request(StatusEndpoint.status(id: statusID))
.flatMap(contentDatabase.insert(status:))
.eraseToAnyPublisher(),
mastodonAPIClient.request(ContextEndpoint.context(id: statusID))
.flatMap { contentDatabase.insert(context: $0, parentID: statusID) }
.eraseToAnyPublisher())
.eraseToAnyPublisher()
}
}
}
public extension StatusListService {
func request(maxID: String?, minID: String?) -> AnyPublisher<Never, Error> {
requestClosure(maxID, minID)
}
}

View File

@ -0,0 +1,45 @@
// Copyright © 2020 Metabolist. All rights reserved.
import Combine
import DB
import Foundation
import Mastodon
import MastodonAPI
public struct TimelineService: CollectionService {
public let sections: AnyPublisher<[[CollectionItem]], Error>
public let navigationService: NavigationService
public let nextPageMaxIDs: AnyPublisher<String?, Never>
public let title: String?
public let contextParentID: String? = nil
private let timeline: Timeline
private let mastodonAPIClient: MastodonAPIClient
private let contentDatabase: ContentDatabase
private let nextPageMaxIDsSubject = PassthroughSubject<String?, Never>()
init(timeline: Timeline, mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) {
self.timeline = timeline
self.mastodonAPIClient = mastodonAPIClient
self.contentDatabase = contentDatabase
sections = contentDatabase.observation(timeline: timeline)
navigationService = NavigationService(
status: nil,
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase)
nextPageMaxIDs = nextPageMaxIDsSubject.eraseToAnyPublisher()
if case let .tag(tag) = timeline {
title = "#".appending(tag)
} else {
title = nil
}
}
public func request(maxID: String?, minID: String?) -> AnyPublisher<Never, Error> {
mastodonAPIClient.pagedRequest(timeline.endpoint, maxID: maxID, minID: minID)
.handleEvents(receiveOutput: { nextPageMaxIDsSubject.send($0.info.maxID) })
.flatMap { contentDatabase.insert(statuses: $0.result, timeline: timeline) }
.eraseToAnyPublisher()
}
}

View File

@ -66,7 +66,7 @@ extension ListViewModel: CollectionViewModel {
ListViewModel(
collectionService: collectionService
.navigationService
.contextStatusListService(id: configuration.status.displayStatus.id))))
.contextService(id: configuration.status.displayStatus.id))))
case .loadMore:
loadMoreViewModel(item: identifier)?.loadMore()
case let .account(account):

View File

@ -18,7 +18,7 @@ final public class ProfileViewModel {
self.profileService = profileService
collectionViewModel = CurrentValueSubject(
ListViewModel(collectionService: profileService.statusListService(profileCollection: .statuses)))
ListViewModel(collectionService: profileService.timelineService(profileCollection: .statuses)))
profileService.accountServicePublisher
.map(AccountViewModel.init(accountService:))
@ -26,7 +26,7 @@ final public class ProfileViewModel {
.assign(to: &$accountViewModel)
$collection.dropFirst()
.map(profileService.statusListService(profileCollection:))
.map(profileService.timelineService(profileCollection:))
.map(ListViewModel.init(collectionService:))
.sink { [weak self] in
guard let self = self else { return }