Path: blob/main/SignalServiceKit/Threads/LastVisibleInteractionStore.swift
1 views
//
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
extension TSThread {
public struct LastVisibleInteraction: Codable, Equatable {
public let sortId: UInt64
public let onScreenPercentage: CGFloat
public init(sortId: UInt64, onScreenPercentage: CGFloat) {
self.sortId = sortId
self.onScreenPercentage = onScreenPercentage
}
}
}
/// Tracks the last visible interaction per thread (the interaction we last scrolled to).
public class LastVisibleInteractionStore {
public typealias LastVisibleInteraction = TSThread.LastVisibleInteraction
private let kvStore: KeyValueStore
public init() {
self.kvStore = KeyValueStore(collection: "lastVisibleInteractionStore")
}
public func hasLastVisibleInteraction(for thread: TSThread, tx: DBReadTransaction) -> Bool {
return lastVisibleInteraction(for: thread, tx: tx) != nil
}
public func lastVisibleInteraction(for thread: TSThread, tx: DBReadTransaction) -> LastVisibleInteraction? {
guard let data = kvStore.getData(thread.uniqueId, transaction: tx) else {
return nil
}
do {
return try JSONDecoder().decode(LastVisibleInteraction.self, from: data)
} catch {
owsFailDebug("Error: \(error)")
return nil
}
}
public func clearLastVisibleInteraction(for thread: TSThread, tx: DBWriteTransaction) {
setLastVisibleInteraction(nil, for: thread, tx: tx)
}
public func setLastVisibleInteraction(
_ lastVisibleInteraction: LastVisibleInteraction?,
for thread: TSThread,
tx: DBWriteTransaction,
) {
guard let lastVisibleInteraction else {
kvStore.removeValue(forKey: thread.uniqueId, transaction: tx)
return
}
let data: Data
do {
data = try JSONEncoder().encode(lastVisibleInteraction)
} catch {
owsFailDebug("Error: \(error)")
kvStore.removeValue(forKey: thread.uniqueId, transaction: tx)
return
}
kvStore.setData(data, key: thread.uniqueId, transaction: tx)
}
}
extension TSThread {
func hasLastVisibleInteraction(transaction: DBReadTransaction) -> Bool {
return DependenciesBridge.shared.lastVisibleInteractionStore.hasLastVisibleInteraction(
for: self,
tx: transaction,
)
}
func clearLastVisibleInteraction(transaction: DBWriteTransaction) {
return DependenciesBridge.shared.lastVisibleInteractionStore.clearLastVisibleInteraction(
for: self,
tx: transaction,
)
}
func lastVisibleSortId(transaction: DBReadTransaction) -> UInt64? {
guard
let lastVisibleInteraction = DependenciesBridge.shared.lastVisibleInteractionStore
.lastVisibleInteraction(for: self, tx: transaction)
else {
return nil
}
return lastVisibleInteraction.sortId
}
func setLastVisibleInteraction(
sortId: UInt64,
onScreenPercentage: CGFloat,
transaction: DBWriteTransaction,
) {
let lastVisibleInteraction = LastVisibleInteraction(sortId: sortId, onScreenPercentage: onScreenPercentage)
DependenciesBridge.shared.lastVisibleInteractionStore.setLastVisibleInteraction(
lastVisibleInteraction,
for: self,
tx: transaction,
)
}
}