mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-25 01:31:02 +00:00
Fix interacgtion with statuses in search results
This commit is contained in:
parent
6b27cd1579
commit
a3491cec85
3 changed files with 59 additions and 32 deletions
|
@ -425,37 +425,17 @@ public extension ContentDatabase {
|
|||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func process(results: Results) -> AnyPublisher<[CollectionSection], Error> {
|
||||
databaseWriter.writePublisher { db -> ([StatusInfo], [Status.Id]) in
|
||||
func insert(results: Results) -> AnyPublisher<Never, Error> {
|
||||
databaseWriter.writePublisher {
|
||||
for account in results.accounts {
|
||||
try account.save(db)
|
||||
try account.save($0)
|
||||
}
|
||||
|
||||
for status in results.statuses {
|
||||
try status.save(db)
|
||||
try status.save($0)
|
||||
}
|
||||
|
||||
let ids = results.statuses.map(\.id)
|
||||
let statusInfos = try StatusInfo.request(
|
||||
StatusRecord.filter(ids.contains(StatusRecord.Columns.id)))
|
||||
.fetchAll(db)
|
||||
|
||||
return (statusInfos, ids)
|
||||
}
|
||||
.map { statusInfos, ids -> [CollectionSection] in
|
||||
[
|
||||
.init(items: results.accounts.map(CollectionItem.account), titleLocalizedStringKey: "search.accounts"),
|
||||
.init(items: statusInfos
|
||||
.sorted { ids.firstIndex(of: $0.record.id) ?? 0 < ids.firstIndex(of: $1.record.id) ?? 0 }
|
||||
.map {
|
||||
.status(.init(info: $0),
|
||||
.init(showContentToggled: $0.showContentToggled,
|
||||
showAttachmentsToggled: $0.showAttachmentsToggled))
|
||||
},
|
||||
titleLocalizedStringKey: "search.statuses"),
|
||||
.init(items: results.hashtags.map(CollectionItem.tag), titleLocalizedStringKey: "search.tags")
|
||||
]
|
||||
}
|
||||
.ignoreOutput()
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
|
@ -528,6 +508,52 @@ public extension ContentDatabase {
|
|||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func publisher(results: Results) -> AnyPublisher<[CollectionSection], Error> {
|
||||
let accountIds = results.accounts.map(\.id)
|
||||
let statusIds = results.statuses.map(\.id)
|
||||
|
||||
let accountsPublisher = ValueObservation.tracking(
|
||||
AccountInfo.request(
|
||||
AccountRecord.filter(accountIds.contains(AccountRecord.Columns.id)))
|
||||
.fetchAll)
|
||||
.removeDuplicates()
|
||||
.publisher(in: databaseWriter)
|
||||
.map {
|
||||
$0.sorted {
|
||||
accountIds.firstIndex(of: $0.record.id) ?? 0
|
||||
< accountIds.firstIndex(of: $1.record.id) ?? 0
|
||||
}
|
||||
.map { CollectionItem.account(.init(info: $0)) }
|
||||
}
|
||||
|
||||
let statusesPublisher = ValueObservation.tracking(
|
||||
StatusInfo.request(
|
||||
StatusRecord.filter(statusIds.contains(StatusRecord.Columns.id)))
|
||||
.fetchAll)
|
||||
.removeDuplicates()
|
||||
.publisher(in: databaseWriter)
|
||||
.map {
|
||||
$0.sorted {
|
||||
statusIds.firstIndex(of: $0.record.id) ?? 0
|
||||
< statusIds.firstIndex(of: $1.record.id) ?? 0
|
||||
}
|
||||
.map {
|
||||
CollectionItem.status(
|
||||
.init(info: $0),
|
||||
.init(showContentToggled: $0.showContentToggled,
|
||||
showAttachmentsToggled: $0.showAttachmentsToggled))
|
||||
}
|
||||
}
|
||||
|
||||
return accountsPublisher.combineLatest(statusesPublisher)
|
||||
.map { accounts, statuses in
|
||||
[.init(items: accounts, titleLocalizedStringKey: "search.accounts"),
|
||||
.init(items: statuses, titleLocalizedStringKey: "search.statuses"),
|
||||
.init(items: results.hashtags.map(CollectionItem.tag), titleLocalizedStringKey: "search.tags")]
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func notificationsPublisher() -> AnyPublisher<[CollectionSection], Error> {
|
||||
ValueObservation.tracking(
|
||||
NotificationInfo.request(
|
||||
|
|
|
@ -14,14 +14,14 @@ public struct SearchService {
|
|||
private let mastodonAPIClient: MastodonAPIClient
|
||||
private let contentDatabase: ContentDatabase
|
||||
private let nextPageMaxIdSubject = PassthroughSubject<String, Never>()
|
||||
private let sectionsSubject = PassthroughSubject<[CollectionSection], Error>()
|
||||
private let resultsSubject = PassthroughSubject<Results, Error>()
|
||||
|
||||
init(mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) {
|
||||
self.mastodonAPIClient = mastodonAPIClient
|
||||
self.contentDatabase = contentDatabase
|
||||
nextPageMaxId = nextPageMaxIdSubject.eraseToAnyPublisher()
|
||||
navigationService = NavigationService(mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase)
|
||||
sections = sectionsSubject.eraseToAnyPublisher()
|
||||
sections = resultsSubject.flatMap(contentDatabase.publisher(results:)).eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,9 +30,8 @@ extension SearchService: CollectionService {
|
|||
guard let search = search else { return Empty().eraseToAnyPublisher() }
|
||||
|
||||
return mastodonAPIClient.request(ResultsEndpoint.search(search))
|
||||
.flatMap(contentDatabase.process(results:))
|
||||
.handleEvents(receiveOutput: sectionsSubject.send)
|
||||
.ignoreOutput()
|
||||
.handleEvents(receiveOutput: resultsSubject.send)
|
||||
.flatMap(contentDatabase.insert(results:))
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,12 +31,14 @@ final class LineChartView: UIView {
|
|||
|
||||
guard valueCount > 0, let maxValue = values.max() else { return }
|
||||
|
||||
let inset = Self.lineWidth / 2
|
||||
|
||||
for (index, value) in values.enumerated() {
|
||||
let x = CGFloat(index) / CGFloat(valueCount) * rect.width
|
||||
let y = rect.height - CGFloat(value) / max(CGFloat(maxValue), CGFloat(0).nextUp) * rect.height
|
||||
let point = CGPoint(
|
||||
x: min(max(x, Self.lineWidth / 2), rect.width - Self.lineWidth / 2),
|
||||
y: min(max(y, Self.lineWidth / 2), rect.height - Self.lineWidth / 2))
|
||||
x: min(max(x, inset), rect.width - inset),
|
||||
y: min(max(y, inset), rect.height - inset))
|
||||
|
||||
if index > 0 {
|
||||
path.addLine(to: point)
|
||||
|
|
Loading…
Reference in a new issue