mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-22 00:01:00 +00:00
Ordered timelines
This commit is contained in:
parent
35a90f866c
commit
2dae234849
8 changed files with 49 additions and 7 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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] {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue