Ordered timelines

This commit is contained in:
Justin Mazzocchi 2021-01-31 07:42:44 -08:00
parent 35a90f866c
commit 2dae234849
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
8 changed files with 49 additions and 7 deletions

View file

@ -128,6 +128,7 @@ extension ContentDatabase {
.references("timelineRecord", onDelete: .cascade)
t.column("statusId", .text).indexed().notNull()
.references("statusRecord", onDelete: .cascade)
t.column("order", .integer)
t.primaryKey(["timelineId", "statusId"], onConflict: .replace)
}

View file

@ -58,6 +58,7 @@ public extension ContentDatabase {
.eraseToAnyPublisher()
}
// swiftlint:disable:next function_body_length
func insert(
statuses: [Status],
timeline: Timeline,
@ -69,10 +70,24 @@ public extension ContentDatabase {
let maxIdPresent = try String.fetchOne($0, timelineRecord.statuses.select(max(StatusRecord.Columns.id)))
var order = timeline.ordered
? try Int.fetchOne(
$0,
TimelineStatusJoin.filter(TimelineStatusJoin.Columns.timelineId == timeline.id)
.select(max(TimelineStatusJoin.Columns.order)))
: nil
for status in statuses {
try status.save($0)
try TimelineStatusJoin(timelineId: timeline.id, statusId: status.id).save($0)
if let order = order {
print("saving with order: \(order)")
}
try TimelineStatusJoin(timelineId: timeline.id, statusId: status.id, order: order).save($0)
if let presentOrder = order {
order = presentOrder + 1
}
}
if let maxIdPresent = maxIdPresent,
@ -447,7 +462,8 @@ public extension ContentDatabase {
func timelinePublisher(_ timeline: Timeline) -> AnyPublisher<[CollectionSection], Error> {
ValueObservation.tracking(
TimelineItemsInfo.request(TimelineRecord.filter(TimelineRecord.Columns.id == timeline.id)).fetchOne)
TimelineItemsInfo.request(TimelineRecord.filter(TimelineRecord.Columns.id == timeline.id),
ordered: timeline.ordered).fetchOne)
.removeDuplicates()
.publisher(in: databaseWriter)
.handleEvents(

View file

@ -17,15 +17,17 @@ extension TimelineItemsInfo {
let pinnedStatusInfos: [StatusInfo]
}
static func addingIncludes<T: DerivableRequest>( _ request: T) -> T where T.RowDecoder == TimelineRecord {
request.including(all: StatusInfo.addingIncludes(TimelineRecord.statuses).forKey(CodingKeys.statusInfos))
static func addingIncludes<T: DerivableRequest>( _ request: T, ordered: Bool) -> T where T.RowDecoder == TimelineRecord {
let statusesAssociation = ordered ? TimelineRecord.orderedStatuses : TimelineRecord.statuses
return request.including(all: StatusInfo.addingIncludes(statusesAssociation).forKey(CodingKeys.statusInfos))
.including(all: TimelineRecord.loadMores.forKey(CodingKeys.loadMoreRecords))
.including(optional: PinnedStatusesInfo.addingIncludes(TimelineRecord.account)
.forKey(CodingKeys.pinnedStatusesInfo))
}
static func request(_ request: QueryInterfaceRequest<TimelineRecord>) -> QueryInterfaceRequest<Self> {
addingIncludes(request).asRequest(of: self)
static func request(_ request: QueryInterfaceRequest<TimelineRecord>, ordered: Bool) -> QueryInterfaceRequest<Self> {
addingIncludes(request, ordered: ordered).asRequest(of: self)
}
func items(filters: [Filter]) -> [CollectionSection] {

View file

@ -29,6 +29,10 @@ extension TimelineRecord {
through: statusJoins,
using: TimelineStatusJoin.status)
.order(StatusRecord.Columns.id.desc)
static let orderedStatuses = hasMany(
StatusRecord.self,
through: statusJoins.order(TimelineStatusJoin.Columns.order),
using: TimelineStatusJoin.status)
static let account = belongsTo(AccountRecord.self, using: ForeignKey([Columns.accountId]))
static let loadMores = hasMany(LoadMoreRecord.self)
@ -36,6 +40,10 @@ extension TimelineRecord {
StatusInfo.request(request(for: Self.statuses))
}
var orderedStatuses: QueryInterfaceRequest<StatusInfo> {
StatusInfo.request(request(for: Self.orderedStatuses))
}
var loadMores: QueryInterfaceRequest<LoadMoreRecord> {
request(for: Self.loadMores)
}

View file

@ -7,6 +7,7 @@ import Mastodon
struct TimelineStatusJoin: ContentDatabaseRecord {
let timelineId: Timeline.Id
let statusId: Status.Id
let order: Int?
static let status = belongsTo(StatusRecord.self)
}
@ -15,5 +16,6 @@ extension TimelineStatusJoin {
enum Columns {
static let timelineId = Column(CodingKeys.timelineId)
static let statusId = Column(CodingKeys.statusId)
static let order = Column(CodingKeys.order)
}
}

View file

@ -32,6 +32,15 @@ public extension Timeline {
return nil
}
}
var ordered: Bool {
switch self {
case .favorites, .bookmarks:
return true
default:
return false
}
}
}
extension Timeline: Identifiable {

View file

@ -10,7 +10,6 @@ public struct TimelineService {
public let sections: AnyPublisher<[CollectionSection], Error>
public let navigationService: NavigationService
public let nextPageMaxId: AnyPublisher<String, Never>
public let preferLastPresentIdOverNextPageMaxId = true
public let title: AnyPublisher<String, Never>
public let titleLocalizationComponents: AnyPublisher<[String], Never>
@ -48,6 +47,10 @@ public struct TimelineService {
}
extension TimelineService: CollectionService {
public var preferLastPresentIdOverNextPageMaxId: Bool {
!timeline.ordered
}
public var markerTimeline: Marker.Timeline? {
switch timeline {
case .home:

View file

@ -33,6 +33,7 @@ final class AttachmentsView: UIView {
let attachmentView = AttachmentView(viewModel: attachmentViewModel, parentViewModel: viewModel)
attachmentView.playing = viewModel.shouldShowAttachments && attachmentViewModel.shouldAutoplay
attachmentView.removeButton.isHidden = !viewModel.canRemoveAttachments
attachmentView.editIcon.isHidden = !viewModel.canRemoveAttachments
if viewModel.attachmentViewModels.count == 2 && index == 1
|| viewModel.attachmentViewModels.count == 3 && index != 0