Refactoring
This commit is contained in:
parent
f3e1baecaa
commit
a07d25c80b
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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):
|
||||
|
|
|
@ -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 }
|
||||
|
|
Loading…
Reference in New Issue