mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-28 19:11:30 +00:00
Tags / DB refactor
This commit is contained in:
parent
510a6db11e
commit
2ca92ed098
4 changed files with 48 additions and 46 deletions
|
@ -93,34 +93,8 @@ extension ContentDatabase {
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
func statusesObservation(timeline: Timeline) -> AnyPublisher<[Status], Error> {
|
func statusesObservation(collection: StatusCollection) -> AnyPublisher<[Status], Error> {
|
||||||
ValueObservation
|
ValueObservation.tracking(collection.fetch)
|
||||||
.tracking(timeline.statuses
|
|
||||||
.including(required: StoredStatus.account)
|
|
||||||
.including(optional: StoredStatus.reblogAccount)
|
|
||||||
.including(optional: StoredStatus.reblog)
|
|
||||||
.asRequest(of: StatusResult.self)
|
|
||||||
.fetchAll)
|
|
||||||
.removeDuplicates()
|
|
||||||
.publisher(in: databaseQueue)
|
|
||||||
.map { $0.map(Status.init(statusResult:)) }
|
|
||||||
.eraseToAnyPublisher()
|
|
||||||
}
|
|
||||||
|
|
||||||
func statusesObservation(collection: TransientStatusCollection) -> AnyPublisher<[Status], Error> {
|
|
||||||
ValueObservation.tracking {
|
|
||||||
try StatusResult.fetchAll(
|
|
||||||
$0,
|
|
||||||
StoredStatus.filter(
|
|
||||||
try collection
|
|
||||||
.elements
|
|
||||||
.fetchAll($0)
|
|
||||||
.map(\.statusId)
|
|
||||||
.contains(Column("id")))
|
|
||||||
.including(required: StoredStatus.account)
|
|
||||||
.including(optional: StoredStatus.reblogAccount)
|
|
||||||
.including(optional: StoredStatus.reblog))
|
|
||||||
}
|
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
.publisher(in: databaseQueue)
|
.publisher(in: databaseQueue)
|
||||||
.map { $0.map(Status.init(statusResult:)) }
|
.map { $0.map(Status.init(statusResult:)) }
|
||||||
|
@ -136,13 +110,6 @@ extension ContentDatabase {
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
|
||||||
func filtersObservation() -> AnyPublisher<[Filter], Error> {
|
|
||||||
ValueObservation.tracking(Filter.fetchAll)
|
|
||||||
.removeDuplicates()
|
|
||||||
.publisher(in: databaseQueue)
|
|
||||||
.eraseToAnyPublisher()
|
|
||||||
}
|
|
||||||
|
|
||||||
func activeFiltersObservation(date: Date, context: Filter.Context? = nil) -> AnyPublisher<[Filter], Error> {
|
func activeFiltersObservation(date: Date, context: Filter.Context? = nil) -> AnyPublisher<[Filter], Error> {
|
||||||
ValueObservation.tracking(Filter.filter(Column("expiresAt") == nil || Column("expiresAt") > date).fetchAll)
|
ValueObservation.tracking(Filter.filter(Column("expiresAt") == nil || Column("expiresAt") > date).fetchAll)
|
||||||
.removeDuplicates()
|
.removeDuplicates()
|
||||||
|
@ -298,6 +265,7 @@ extension Account: TableRecord, FetchableRecord, PersistableRecord {
|
||||||
|
|
||||||
protocol StatusCollection: FetchableRecord, PersistableRecord {
|
protocol StatusCollection: FetchableRecord, PersistableRecord {
|
||||||
var id: String { get }
|
var id: String { get }
|
||||||
|
var fetch: (Database) throws -> [StatusResult] { get }
|
||||||
|
|
||||||
func joinRecord(status: Status) -> PersistableRecord
|
func joinRecord(status: Status) -> PersistableRecord
|
||||||
}
|
}
|
||||||
|
@ -315,15 +283,17 @@ extension Timeline: StatusCollection {
|
||||||
}
|
}
|
||||||
|
|
||||||
init(row: Row) {
|
init(row: Row) {
|
||||||
switch row[Columns.id] as String {
|
switch (row[Columns.id] as String, row[Columns.listTitle] as String?) {
|
||||||
case Timeline.home.id:
|
case (Timeline.home.id, _):
|
||||||
self = .home
|
self = .home
|
||||||
case Timeline.local.id:
|
case (Timeline.local.id, _):
|
||||||
self = .local
|
self = .local
|
||||||
case Timeline.federated.id:
|
case (Timeline.federated.id, _):
|
||||||
self = .federated
|
self = .federated
|
||||||
|
case (let id, .some(let title)):
|
||||||
|
self = .list(MastodonList(id: id, title: title))
|
||||||
default:
|
default:
|
||||||
self = .list(MastodonList(id: row[Columns.id], title: row[Columns.listTitle]))
|
self = .tag(row[Columns.id])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,6 +305,15 @@ extension Timeline: StatusCollection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fetch: (Database) throws -> [StatusResult] {
|
||||||
|
statuses
|
||||||
|
.including(required: StoredStatus.account)
|
||||||
|
.including(optional: StoredStatus.reblogAccount)
|
||||||
|
.including(optional: StoredStatus.reblog)
|
||||||
|
.asRequest(of: StatusResult.self)
|
||||||
|
.fetchAll
|
||||||
|
}
|
||||||
|
|
||||||
func joinRecord(status: Status) -> PersistableRecord {
|
func joinRecord(status: Status) -> PersistableRecord {
|
||||||
TimelineStatusJoin(timelineId: id, statusId: status.id)
|
TimelineStatusJoin(timelineId: id, statusId: status.id)
|
||||||
}
|
}
|
||||||
|
@ -374,6 +353,21 @@ private struct TransientStatusCollectionElement: Codable, TableRecord, Fetchable
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TransientStatusCollection: StatusCollection {
|
extension TransientStatusCollection: StatusCollection {
|
||||||
|
var fetch: (Database) throws -> [StatusResult] {
|
||||||
|
{
|
||||||
|
try StatusResult.fetchAll(
|
||||||
|
$0,
|
||||||
|
StoredStatus.filter(
|
||||||
|
try elements
|
||||||
|
.fetchAll($0)
|
||||||
|
.map(\.statusId)
|
||||||
|
.contains(Column("id")))
|
||||||
|
.including(required: StoredStatus.account)
|
||||||
|
.including(optional: StoredStatus.reblogAccount)
|
||||||
|
.including(optional: StoredStatus.reblog))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func joinRecord(status: Status) -> PersistableRecord {
|
func joinRecord(status: Status) -> PersistableRecord {
|
||||||
TransientStatusCollectionElement(transientStatusCollectionId: id, statusId: status.id)
|
TransientStatusCollectionElement(transientStatusCollectionId: id, statusId: status.id)
|
||||||
}
|
}
|
||||||
|
@ -489,11 +483,11 @@ extension StoredStatus: TableRecord, FetchableRecord, PersistableRecord {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct StatusResult: Codable, Hashable, FetchableRecord {
|
struct StatusResult: Codable, Hashable, FetchableRecord {
|
||||||
let account: Account
|
let account: Account
|
||||||
let status: StoredStatus
|
fileprivate let status: StoredStatus
|
||||||
let reblogAccount: Account?
|
let reblogAccount: Account?
|
||||||
let reblog: StoredStatus?
|
fileprivate let reblog: StoredStatus?
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension Status {
|
private extension Status {
|
||||||
|
|
|
@ -7,6 +7,7 @@ enum Timeline: Hashable {
|
||||||
case local
|
case local
|
||||||
case federated
|
case federated
|
||||||
case list(MastodonList)
|
case list(MastodonList)
|
||||||
|
case tag(String)
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Timeline {
|
extension Timeline {
|
||||||
|
@ -22,6 +23,8 @@ extension Timeline {
|
||||||
return .public(local: false)
|
return .public(local: false)
|
||||||
case let .list(list):
|
case let .list(list):
|
||||||
return .list(id: list.id)
|
return .list(id: list.id)
|
||||||
|
case let .tag(tag):
|
||||||
|
return .tag(tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +40,8 @@ extension Timeline: Identifiable {
|
||||||
return "federated"
|
return "federated"
|
||||||
case let .list(list):
|
case let .list(list):
|
||||||
return list.id
|
return list.id
|
||||||
|
case let .tag(tag):
|
||||||
|
return "#" + tag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ struct TimelineService {
|
||||||
self.timeline = timeline
|
self.timeline = timeline
|
||||||
self.networkClient = networkClient
|
self.networkClient = networkClient
|
||||||
self.contentDatabase = contentDatabase
|
self.contentDatabase = contentDatabase
|
||||||
statusSections = contentDatabase.statusesObservation(timeline: timeline)
|
statusSections = contentDatabase.statusesObservation(collection: timeline)
|
||||||
.map { [$0] }
|
.map { [$0] }
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ private extension TimelineService {
|
||||||
switch timeline {
|
switch timeline {
|
||||||
case .home, .list:
|
case .home, .list:
|
||||||
return .home
|
return .home
|
||||||
case .local, .federated:
|
case .local, .federated, .tag:
|
||||||
return .public
|
return .public
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ extension TabNavigationViewModel {
|
||||||
switch timeline {
|
switch timeline {
|
||||||
case .home, .list:
|
case .home, .list:
|
||||||
return identity.handle
|
return identity.handle
|
||||||
case .local, .federated:
|
case .local, .federated, .tag:
|
||||||
return identity.instance?.uri ?? ""
|
return identity.instance?.uri ?? ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,8 @@ extension TabNavigationViewModel {
|
||||||
return NSLocalizedString("timelines.federated", comment: "")
|
return NSLocalizedString("timelines.federated", comment: "")
|
||||||
case let .list(list):
|
case let .list(list):
|
||||||
return list.title
|
return list.title
|
||||||
|
case let .tag(tag):
|
||||||
|
return "#" + tag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +62,7 @@ extension TabNavigationViewModel {
|
||||||
case .local: return "person.3"
|
case .local: return "person.3"
|
||||||
case .federated: return "globe"
|
case .federated: return "globe"
|
||||||
case .list: return "scroll"
|
case .list: return "scroll"
|
||||||
|
case .tag: return "number"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue