Ephemeral timelines

This commit is contained in:
Justin Mazzocchi 2020-12-02 11:39:42 -08:00
parent a62c6d9781
commit 03a4d1299d
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
3 changed files with 60 additions and 35 deletions

View file

@ -11,6 +11,7 @@ import Secrets
public struct ContentDatabase {
public let activeFiltersPublisher: AnyPublisher<[Filter], Error>
private let id: Identity.Id
private let databaseWriter: DatabaseWriter
public init(id: Identity.Id,
@ -19,6 +20,8 @@ public struct ContentDatabase {
inMemory: Bool,
appGroup: String,
keychain: Keychain.Type) throws {
self.id = id
if inMemory {
databaseWriter = DatabaseQueue()
try Self.migrator.migrate(databaseWriter)
@ -378,6 +381,21 @@ public extension ContentDatabase {
TimelineItemsInfo.request(TimelineRecord.filter(TimelineRecord.Columns.id == timeline.id)).fetchOne)
.removeDuplicates()
.publisher(in: databaseWriter)
.handleEvents(
receiveSubscription: { _ in
if let ephemeralityId = timeline.ephemeralityId(id: id) {
Self.ephemeralTimelines.add(ephemeralityId)
}
},
receiveCancel: {
guard let ephemeralityId = timeline.ephemeralityId(id: id) else { return }
Self.ephemeralTimelines.remove(ephemeralityId)
if Self.ephemeralTimelines.count(for: ephemeralityId) == 0 {
databaseWriter.asyncWrite(TimelineRecord(timeline: timeline).delete) { _, _ in }
}
})
.combineLatest(activeFiltersPublisher)
.compactMap { $0?.items(filters: $1) }
.eraseToAnyPublisher()
@ -480,6 +498,9 @@ public extension ContentDatabase {
private extension ContentDatabase {
static let cleanAfterLastReadIdCount = 40
static let ephemeralTimelines = NSCountedSet()
static func fileURL(id: Identity.Id, appGroup: String) throws -> URL {
try FileManager.default.databaseDirectoryURL(name: id.uuidString, appGroup: appGroup)
}

View file

@ -56,3 +56,42 @@ extension Timeline: Identifiable {
}
}
}
extension Timeline {
init?(record: TimelineRecord) {
switch (record.id,
record.listId,
record.listTitle,
record.tag,
record.accountId,
record.profileCollection) {
case (Timeline.home.id, _, _, _, _, _):
self = .home
case (Timeline.local.id, _, _, _, _, _):
self = .local
case (Timeline.federated.id, _, _, _, _, _):
self = .federated
case (_, .some(let listId), .some(let listTitle), _, _, _):
self = .list(List(id: listId, title: listTitle))
case (_, _, _, .some(let tag), _, _):
self = .tag(tag)
case (_, _, _, _, .some(let accountId), .some(let profileCollection)):
self = .profile(accountId: accountId, profileCollection: profileCollection)
case (Timeline.favorites.id, _, _, _, _, _):
self = .favorites
case (Timeline.bookmarks.id, _, _, _, _, _):
self = .bookmarks
default:
return nil
}
}
func ephemeralityId(id: Identity.Id) -> String? {
switch self {
case .tag, .favorites, .bookmarks:
return "\(id)-\(self.id)"
default:
return nil
}
}
}

View file

@ -1,35 +0,0 @@
// Copyright © 2020 Metabolist. All rights reserved.
import Foundation
import GRDB
import Mastodon
extension Timeline {
init?(record: TimelineRecord) {
switch (record.id,
record.listId,
record.listTitle,
record.tag,
record.accountId,
record.profileCollection) {
case (Timeline.home.id, _, _, _, _, _):
self = .home
case (Timeline.local.id, _, _, _, _, _):
self = .local
case (Timeline.federated.id, _, _, _, _, _):
self = .federated
case (_, .some(let listId), .some(let listTitle), _, _, _):
self = .list(List(id: listId, title: listTitle))
case (_, _, _, .some(let tag), _, _):
self = .tag(tag)
case (_, _, _, _, .some(let accountId), .some(let profileCollection)):
self = .profile(accountId: accountId, profileCollection: profileCollection)
case (Timeline.favorites.id, _, _, _, _, _):
self = .favorites
case (Timeline.bookmarks.id, _, _, _, _, _):
self = .bookmarks
default:
return nil
}
}
}