forked from zelo72/mastodon-ios
94 lines
3.3 KiB
Swift
94 lines
3.3 KiB
Swift
//
|
|
// StatusFilterService.swift
|
|
// Mastodon
|
|
//
|
|
// Created by Cirno MainasuK on 2021-7-14.
|
|
//
|
|
|
|
import os.log
|
|
import Foundation
|
|
import Combine
|
|
import CoreData
|
|
import CoreDataStack
|
|
import MastodonSDK
|
|
import MastodonMeta
|
|
|
|
final class StatusFilterService {
|
|
|
|
var disposeBag = Set<AnyCancellable>()
|
|
|
|
// input
|
|
weak var apiService: APIService?
|
|
weak var authenticationService: AuthenticationService?
|
|
let filterUpdatePublisher = PassthroughSubject<Void, Never>()
|
|
|
|
// output
|
|
@Published var activeFilters: [Mastodon.Entity.Filter] = []
|
|
|
|
init(
|
|
apiService: APIService,
|
|
authenticationService: AuthenticationService
|
|
) {
|
|
self.apiService = apiService
|
|
self.authenticationService = authenticationService
|
|
|
|
// fetch account filters every 300s
|
|
// also trigger fetch when app resume from background
|
|
let filterUpdateTimerPublisher = Timer.publish(every: 300.0, on: .main, in: .common)
|
|
.autoconnect()
|
|
.share()
|
|
.eraseToAnyPublisher()
|
|
|
|
filterUpdateTimerPublisher
|
|
.map { _ in }
|
|
.subscribe(filterUpdatePublisher)
|
|
.store(in: &disposeBag)
|
|
|
|
let activeMastodonAuthenticationBox = authenticationService.activeMastodonAuthenticationBox
|
|
Publishers.CombineLatest(
|
|
activeMastodonAuthenticationBox,
|
|
filterUpdatePublisher
|
|
)
|
|
.flatMap { box, _ -> AnyPublisher<Result<Mastodon.Response.Content<[Mastodon.Entity.Filter]>, Error>, Never> in
|
|
guard let box = box else {
|
|
return Just(Result { throw APIService.APIError.implicit(.authenticationMissing) }).eraseToAnyPublisher()
|
|
}
|
|
return apiService.filters(mastodonAuthenticationBox: box)
|
|
.map { response in
|
|
let now = Date()
|
|
let newResponse = response.map { filters in
|
|
return filters.filter { filter in
|
|
if let expiresAt = filter.expiresAt {
|
|
// filter out expired rules
|
|
return expiresAt > now
|
|
} else {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
return Result<Mastodon.Response.Content<[Mastodon.Entity.Filter]>, Error>.success(newResponse)
|
|
}
|
|
.catch { error in
|
|
Just(Result<Mastodon.Response.Content<[Mastodon.Entity.Filter]>, Error>.failure(error))
|
|
}
|
|
.eraseToAnyPublisher()
|
|
}
|
|
.sink { result in
|
|
switch result {
|
|
case .success(let response):
|
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: fetch account filters success. %ld items", ((#file as NSString).lastPathComponent), #line, #function, response.value.count)
|
|
self.activeFilters = response.value
|
|
case .failure(let error):
|
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: fetch account filters fail: %s", ((#file as NSString).lastPathComponent), #line, #function, error.localizedDescription)
|
|
|
|
break
|
|
}
|
|
}
|
|
.store(in: &disposeBag)
|
|
|
|
// make initial trigger once
|
|
filterUpdatePublisher.send()
|
|
}
|
|
|
|
}
|