Tags / DB refactor
This commit is contained in:
parent
510a6db11e
commit
2ca92ed098
|
@ -93,34 +93,8 @@ extension ContentDatabase {
|
|||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func statusesObservation(timeline: Timeline) -> AnyPublisher<[Status], Error> {
|
||||
ValueObservation
|
||||
.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))
|
||||
}
|
||||
func statusesObservation(collection: StatusCollection) -> AnyPublisher<[Status], Error> {
|
||||
ValueObservation.tracking(collection.fetch)
|
||||
.removeDuplicates()
|
||||
.publisher(in: databaseQueue)
|
||||
.map { $0.map(Status.init(statusResult:)) }
|
||||
|
@ -136,13 +110,6 @@ extension ContentDatabase {
|
|||
.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> {
|
||||
ValueObservation.tracking(Filter.filter(Column("expiresAt") == nil || Column("expiresAt") > date).fetchAll)
|
||||
.removeDuplicates()
|
||||
|
@ -298,6 +265,7 @@ extension Account: TableRecord, FetchableRecord, PersistableRecord {
|
|||
|
||||
protocol StatusCollection: FetchableRecord, PersistableRecord {
|
||||
var id: String { get }
|
||||
var fetch: (Database) throws -> [StatusResult] { get }
|
||||
|
||||
func joinRecord(status: Status) -> PersistableRecord
|
||||
}
|
||||
|
@ -315,15 +283,17 @@ extension Timeline: StatusCollection {
|
|||
}
|
||||
|
||||
init(row: Row) {
|
||||
switch row[Columns.id] as String {
|
||||
case Timeline.home.id:
|
||||
switch (row[Columns.id] as String, row[Columns.listTitle] as String?) {
|
||||
case (Timeline.home.id, _):
|
||||
self = .home
|
||||
case Timeline.local.id:
|
||||
case (Timeline.local.id, _):
|
||||
self = .local
|
||||
case Timeline.federated.id:
|
||||
case (Timeline.federated.id, _):
|
||||
self = .federated
|
||||
case (let id, .some(let title)):
|
||||
self = .list(MastodonList(id: id, title: title))
|
||||
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 {
|
||||
TimelineStatusJoin(timelineId: id, statusId: status.id)
|
||||
}
|
||||
|
@ -374,6 +353,21 @@ private struct TransientStatusCollectionElement: Codable, TableRecord, Fetchable
|
|||
}
|
||||
|
||||
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 {
|
||||
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 status: StoredStatus
|
||||
fileprivate let status: StoredStatus
|
||||
let reblogAccount: Account?
|
||||
let reblog: StoredStatus?
|
||||
fileprivate let reblog: StoredStatus?
|
||||
}
|
||||
|
||||
private extension Status {
|
||||
|
|
|
@ -7,6 +7,7 @@ enum Timeline: Hashable {
|
|||
case local
|
||||
case federated
|
||||
case list(MastodonList)
|
||||
case tag(String)
|
||||
}
|
||||
|
||||
extension Timeline {
|
||||
|
@ -22,6 +23,8 @@ extension Timeline {
|
|||
return .public(local: false)
|
||||
case let .list(list):
|
||||
return .list(id: list.id)
|
||||
case let .tag(tag):
|
||||
return .tag(tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +40,8 @@ extension Timeline: Identifiable {
|
|||
return "federated"
|
||||
case let .list(list):
|
||||
return list.id
|
||||
case let .tag(tag):
|
||||
return "#" + tag
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ struct TimelineService {
|
|||
self.timeline = timeline
|
||||
self.networkClient = networkClient
|
||||
self.contentDatabase = contentDatabase
|
||||
statusSections = contentDatabase.statusesObservation(timeline: timeline)
|
||||
statusSections = contentDatabase.statusesObservation(collection: timeline)
|
||||
.map { [$0] }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ private extension TimelineService {
|
|||
switch timeline {
|
||||
case .home, .list:
|
||||
return .home
|
||||
case .local, .federated:
|
||||
case .local, .federated, .tag:
|
||||
return .public
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ extension TabNavigationViewModel {
|
|||
switch timeline {
|
||||
case .home, .list:
|
||||
return identity.handle
|
||||
case .local, .federated:
|
||||
case .local, .federated, .tag:
|
||||
return identity.instance?.uri ?? ""
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ extension TabNavigationViewModel {
|
|||
return NSLocalizedString("timelines.federated", comment: "")
|
||||
case let .list(list):
|
||||
return list.title
|
||||
case let .tag(tag):
|
||||
return "#" + tag
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,6 +62,7 @@ extension TabNavigationViewModel {
|
|||
case .local: return "person.3"
|
||||
case .federated: return "globe"
|
||||
case .list: return "scroll"
|
||||
case .tag: return "number"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue