mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-25 09:41:00 +00:00
Notifications marker
This commit is contained in:
parent
6294b1c52f
commit
9274cd2615
4 changed files with 48 additions and 15 deletions
|
@ -14,6 +14,8 @@ public protocol CollectionService {
|
|||
var navigationService: NavigationService { get }
|
||||
var positionTimeline: Timeline? { get }
|
||||
func request(maxId: String?, minId: String?, search: Search?) -> AnyPublisher<Never, Error>
|
||||
func requestMarkerLastReadId() -> AnyPublisher<CollectionItem.Id, Error>
|
||||
func setMarkerLastReadId(_ id: CollectionItem.Id) -> AnyPublisher<CollectionItem.Id, Error>
|
||||
}
|
||||
|
||||
extension CollectionService {
|
||||
|
@ -30,4 +32,10 @@ extension CollectionService {
|
|||
public var titleLocalizationComponents: AnyPublisher<[String], Never> { Empty().eraseToAnyPublisher() }
|
||||
|
||||
public var positionTimeline: Timeline? { nil }
|
||||
|
||||
public func requestMarkerLastReadId() -> AnyPublisher<CollectionItem.Id, Error> { Empty().eraseToAnyPublisher() }
|
||||
|
||||
public func setMarkerLastReadId(_ id: CollectionItem.Id) -> AnyPublisher<CollectionItem.Id, Error> {
|
||||
Empty().eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,12 +119,6 @@ public extension IdentityService {
|
|||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func getMarker(_ markerTimeline: Marker.Timeline) -> AnyPublisher<Marker, Error> {
|
||||
mastodonAPIClient.request(MarkersEndpoint.get([markerTimeline]))
|
||||
.compactMap { $0[markerTimeline.rawValue] }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func getLocalLastReadId(timeline: Timeline) -> String? {
|
||||
contentDatabase.lastReadId(timelineId: timeline.id)
|
||||
}
|
||||
|
|
|
@ -55,4 +55,16 @@ extension NotificationsService: CollectionService {
|
|||
.flatMap { contentDatabase.insert(notifications: $0.result) }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
public func requestMarkerLastReadId() -> AnyPublisher<CollectionItem.Id, Error> {
|
||||
mastodonAPIClient.request(MarkersEndpoint.get([.notifications]))
|
||||
.compactMap { $0.values.first?.lastReadId }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
public func setMarkerLastReadId(_ id: CollectionItem.Id) -> AnyPublisher<CollectionItem.Id, Error> {
|
||||
mastodonAPIClient.request(MarkersEndpoint.post([.notifications: id]))
|
||||
.compactMap { $0.values.first?.lastReadId }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,10 +21,11 @@ public class CollectionItemsViewModel: ObservableObject {
|
|||
private var topVisibleIndexPath = IndexPath(item: 0, section: 0)
|
||||
private let lastReadId = CurrentValueSubject<String?, Never>(nil)
|
||||
private var lastSelectedLoadMore: LoadMore?
|
||||
private var hasRequestedUsingMarker = false
|
||||
private var markerScrollPositionItemId: CollectionItem.Id?
|
||||
private var localLastReadId: CollectionItem.Id?
|
||||
private var markerLastReadId: CollectionItem.Id?
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
public init(collectionService: CollectionService, identityContext: IdentityContext) {
|
||||
self.collectionService = collectionService
|
||||
self.identityContext = identityContext
|
||||
|
@ -50,18 +51,32 @@ public class CollectionItemsViewModel: ObservableObject {
|
|||
.sink { _ in }
|
||||
.store(in: &cancellables)
|
||||
|
||||
if let timeline = collectionService.positionTimeline {
|
||||
if identityContext.appPreferences.positionBehavior(timeline: timeline) == .localRememberPosition {
|
||||
markerScrollPositionItemId = identityContext.service.getLocalLastReadId(timeline: timeline)
|
||||
}
|
||||
|
||||
lastReadId
|
||||
.filter { _ in
|
||||
identityContext.appPreferences.positionBehavior(timeline: timeline) == .localRememberPosition
|
||||
}
|
||||
let debouncedLastReadId = lastReadId
|
||||
.compactMap { $0 }
|
||||
.removeDuplicates()
|
||||
.debounce(for: .seconds(Self.lastReadIdDebounceInterval), scheduler: DispatchQueue.global())
|
||||
.share()
|
||||
|
||||
debouncedLastReadId
|
||||
.filter { [weak self] in
|
||||
guard let markerLastReadId = self?.markerLastReadId else { return false }
|
||||
|
||||
return $0 > markerLastReadId
|
||||
}
|
||||
.flatMap { collectionService.setMarkerLastReadId($0) }
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { _ in } receiveValue: { [weak self] in self?.markerLastReadId = $0 }
|
||||
.store(in: &cancellables)
|
||||
|
||||
if let timeline = collectionService.positionTimeline {
|
||||
if identityContext.appPreferences.positionBehavior(timeline: timeline) == .localRememberPosition {
|
||||
localLastReadId = identityContext.service.getLocalLastReadId(timeline: timeline)
|
||||
}
|
||||
|
||||
debouncedLastReadId
|
||||
.filter { _ in
|
||||
identityContext.appPreferences.positionBehavior(timeline: timeline) == .localRememberPosition
|
||||
}
|
||||
.flatMap { identityContext.service.setLocalLastReadId($0, timeline: timeline) }
|
||||
.sink { _ in } receiveValue: { _ in }
|
||||
.store(in: &cancellables)
|
||||
|
@ -119,6 +134,10 @@ extension CollectionItemsViewModel: CollectionViewModel {
|
|||
receiveCompletion: { [weak self] _ in self?.loadingSubject.send(false) })
|
||||
.sink { _ in }
|
||||
.store(in: &cancellables)
|
||||
collectionService.requestMarkerLastReadId()
|
||||
.sink { _ in } receiveValue: { [weak self] in self?.markerLastReadId = $0 }
|
||||
.store(in: &cancellables)
|
||||
|
||||
}
|
||||
|
||||
public func select(indexPath: IndexPath) {
|
||||
|
@ -375,9 +394,9 @@ private extension CollectionItemsViewModel {
|
|||
let items = lastUpdate.sections.map(\.items).reduce([], +)
|
||||
let newItems = newSections.map(\.items).reduce([], +)
|
||||
|
||||
if let itemId = markerScrollPositionItemId,
|
||||
if let itemId = localLastReadId,
|
||||
newItems.contains(where: { $0.itemId == itemId }) {
|
||||
markerScrollPositionItemId = nil
|
||||
localLastReadId = nil
|
||||
|
||||
return itemId
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue