metatext/ServiceLayer/Sources/ServiceLayer/Services/SearchService.swift

50 lines
2.1 KiB
Swift
Raw Normal View History

2021-01-23 03:48:33 +00:00
// Copyright © 2020 Metabolist. All rights reserved.
import Combine
import DB
import Foundation
import Mastodon
import MastodonAPI
public struct SearchService {
2021-01-23 06:15:52 +00:00
public let sections: AnyPublisher<[CollectionSection], Error>
2021-01-23 03:48:33 +00:00
public let navigationService: NavigationService
public let nextPageMaxId: AnyPublisher<String, Never>
private let mastodonAPIClient: MastodonAPIClient
private let contentDatabase: ContentDatabase
private let nextPageMaxIdSubject = PassthroughSubject<String, Never>()
2021-01-25 02:10:41 +00:00
private let resultsSubject = PassthroughSubject<(Results, Search), Error>()
2021-01-23 03:48:33 +00:00
init(environment: AppEnvironment, mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) {
2021-01-23 03:48:33 +00:00
self.mastodonAPIClient = mastodonAPIClient
self.contentDatabase = contentDatabase
nextPageMaxId = nextPageMaxIdSubject.eraseToAnyPublisher()
navigationService = NavigationService(environment: environment,
mastodonAPIClient: mastodonAPIClient,
contentDatabase: contentDatabase)
2021-01-25 07:42:39 +00:00
sections = resultsSubject.scan((.empty, nil)) {
2021-01-25 02:10:41 +00:00
let (results, search) = $1
2021-01-25 07:42:39 +00:00
return (search.offset == nil ? results : $0.0.appending(results), search.limit)
2021-01-25 02:10:41 +00:00
}
2021-02-09 01:19:25 +00:00
.map(contentDatabase.publisher(results:limit:)).switchToLatest().eraseToAnyPublisher()
2021-01-23 03:48:33 +00:00
}
}
extension SearchService: CollectionService {
public func request(maxId: String?, minId: String?, search: Search?) -> AnyPublisher<Never, Error> {
guard let search = search else { return Empty().eraseToAnyPublisher() }
if (search.query.trimmingCharacters(in: .whitespaces).isEmpty){
return Empty().eraseToAnyPublisher()
}
2021-01-23 03:48:33 +00:00
return mastodonAPIClient.request(ResultsEndpoint.search(search))
2021-02-07 01:20:15 +00:00
.flatMap { results in contentDatabase.insert(results: results).collect().map { _ in results } }
2021-01-25 02:10:41 +00:00
.handleEvents(receiveOutput: { resultsSubject.send(($0, search)) })
2021-02-07 01:20:15 +00:00
.ignoreOutput()
2021-01-23 03:48:33 +00:00
.eraseToAnyPublisher()
}
}