TM-SGNL-iOS/SignalServiceKit/Contacts/Threads/LastVisibleInteractionStore.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

112 lines
3.6 KiB
Swift

//
// 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 = 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 {
@objc
func hasLastVisibleInteraction(transaction: SDSAnyReadTransaction) -> Bool {
return DependenciesBridge.shared.lastVisibleInteractionStore.hasLastVisibleInteraction(
for: self,
tx: transaction.asV2Read
)
}
@objc
func clearLastVisibleInteraction(transaction: SDSAnyWriteTransaction) {
return DependenciesBridge.shared.lastVisibleInteractionStore.clearLastVisibleInteraction(
for: self,
tx: transaction.asV2Write
)
}
@objc
func lastVisibleSortId(transaction: SDSAnyReadTransaction) -> NSNumber? {
guard
let lastVisibleInteraction = DependenciesBridge.shared.lastVisibleInteractionStore
.lastVisibleInteraction(for: self, tx: transaction.asV2Read)
else {
return nil
}
return NSNumber(value: lastVisibleInteraction.sortId)
}
@objc
func setLastVisibleInteraction(
sortId: UInt64,
onScreenPercentage: CGFloat,
transaction: SDSAnyWriteTransaction
) {
let lastVisibleInteraction = LastVisibleInteraction(sortId: sortId, onScreenPercentage: onScreenPercentage)
DependenciesBridge.shared.lastVisibleInteractionStore.setLastVisibleInteraction(
lastVisibleInteraction,
for: self,
tx: transaction.asV2Write
)
}
}