mirror of
https://github.com/metabolist/metatext.git
synced 2024-06-13 02:49:21 +00:00
94 lines
3.2 KiB
Swift
94 lines
3.2 KiB
Swift
// Copyright © 2020 Metabolist. All rights reserved.
|
|
|
|
import Combine
|
|
import Foundation
|
|
import Mastodon
|
|
import ServiceLayer
|
|
|
|
public final class ExploreViewModel: ObservableObject {
|
|
public let searchViewModel: SearchViewModel
|
|
public let events: AnyPublisher<Event, Never>
|
|
@Published public var instanceViewModel: InstanceViewModel?
|
|
@Published public var trends = [Tag]()
|
|
@Published public private(set) var loading = false
|
|
@Published public var alertItem: AlertItem?
|
|
public let identityContext: IdentityContext
|
|
|
|
private let exploreService: ExploreService
|
|
private let eventsSubject = PassthroughSubject<Event, Never>()
|
|
private var cancellables = Set<AnyCancellable>()
|
|
|
|
init(service: ExploreService, identityContext: IdentityContext) {
|
|
exploreService = service
|
|
self.identityContext = identityContext
|
|
searchViewModel = SearchViewModel(
|
|
searchService: exploreService.searchService(),
|
|
identityContext: identityContext)
|
|
events = eventsSubject.eraseToAnyPublisher()
|
|
|
|
identityContext.$identity
|
|
.compactMap { $0.instance?.uri }
|
|
.removeDuplicates()
|
|
.flatMap { service.instanceServicePublisher(uri: $0) }
|
|
.map { InstanceViewModel(instanceService: $0) }
|
|
.receive(on: DispatchQueue.main)
|
|
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
|
.assign(to: &$instanceViewModel)
|
|
}
|
|
}
|
|
|
|
public extension ExploreViewModel {
|
|
enum Event {
|
|
case navigation(Navigation)
|
|
}
|
|
|
|
enum Section: Hashable {
|
|
case trending
|
|
case instance
|
|
}
|
|
|
|
enum Item: Hashable {
|
|
case tag(Tag)
|
|
case instance
|
|
case profileDirectory
|
|
}
|
|
|
|
func refresh() {
|
|
exploreService.fetchTrends()
|
|
.handleEvents(receiveOutput: { [weak self] trends in
|
|
DispatchQueue.main.async {
|
|
self?.trends = trends
|
|
}
|
|
})
|
|
.ignoreOutput()
|
|
.merge(with: identityContext.service.refreshInstance())
|
|
.receive(on: DispatchQueue.main)
|
|
.handleEvents(receiveSubscription: { [weak self] _ in self?.loading = true },
|
|
receiveCompletion: { [weak self] _ in self?.loading = false })
|
|
.sink { _ in } receiveValue: { _ in }
|
|
.store(in: &cancellables)
|
|
}
|
|
|
|
func viewModel(tag: Tag) -> TagViewModel {
|
|
.init(tag: tag, identityContext: identityContext)
|
|
}
|
|
|
|
func select(item: ExploreViewModel.Item) {
|
|
switch item {
|
|
case let .tag(tag):
|
|
eventsSubject.send(
|
|
.navigation(.collection(exploreService
|
|
.navigationService
|
|
.timelineService(timeline: .tag(tag.name)))))
|
|
case .instance:
|
|
break
|
|
case .profileDirectory:
|
|
eventsSubject.send(
|
|
.navigation(.collection(identityContext
|
|
.service
|
|
.service(accountList: .directory(local: true),
|
|
titleComponents: ["explore.profile-directory"]))))
|
|
}
|
|
}
|
|
}
|