TM-SGNL-iOS/SignalServiceKit/Messages/Interactions/TSInteraction.m
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

256 lines
7.1 KiB
Objective-C

//
// Copyright 2017 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
#import "TSInteraction.h"
#import "TSThread.h"
#import <SignalServiceKit/NSDate+OWS.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
{
switch (value) {
case OWSInteractionType_Unknown:
return @"OWSInteractionType_Unknown";
case OWSInteractionType_IncomingMessage:
return @"OWSInteractionType_IncomingMessage";
case OWSInteractionType_OutgoingMessage:
return @"OWSInteractionType_OutgoingMessage";
case OWSInteractionType_Error:
return @"OWSInteractionType_Error";
case OWSInteractionType_Call:
return @"OWSInteractionType_Call";
case OWSInteractionType_Info:
return @"OWSInteractionType_Info";
case OWSInteractionType_ThreadDetails:
return @"OWSInteractionType_ThreadDetails";
case OWSInteractionType_TypingIndicator:
return @"OWSInteractionType_TypingIndicator";
case OWSInteractionType_UnreadIndicator:
return @"OWSInteractionType_UnreadIndicator";
case OWSInteractionType_DateHeader:
return @"OWSInteractionType_DateHeader";
case OWSInteractionType_UnknownThreadWarning:
return @"OWSInteractionType_UnknownThreadWarning";
case OWSInteractionType_DefaultDisappearingMessageTimer:
return @"OWSInteractionType_DefaultDisappearingMessageTimer";
}
}
// MARK: -
@interface TSInteraction ()
@property (nonatomic) uint64_t sortId;
@property (nonatomic) uint64_t receivedAtTimestamp;
@property (nonatomic) uint64_t timestamp;
@end
// MARK: -
@implementation TSInteraction
- (instancetype)initWithCustomUniqueId:(NSString *)uniqueId
timestamp:(uint64_t)timestamp
receivedAtTimestamp:(uint64_t)receivedAtTimestamp
thread:(TSThread *)thread
{
self = [super initWithUniqueId:uniqueId];
if (!self) {
return self;
}
_timestamp = timestamp;
_receivedAtTimestamp = receivedAtTimestamp;
_uniqueThreadId = thread.uniqueId;
return self;
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
receivedAtTimestamp:(uint64_t)receivedAtTimestamp
thread:(TSThread *)thread
{
NSString *uniqueId = [[self class] generateUniqueId];
self = [super initWithUniqueId:uniqueId];
if (!self) {
return self;
}
_timestamp = timestamp;
_receivedAtTimestamp = receivedAtTimestamp;
_uniqueThreadId = thread.uniqueId;
return self;
}
// --- CODE GENERATION MARKER
// This snippet is generated by /Scripts/sds_codegen/sds_generate.py. Do not manually edit it, instead run
// `sds_codegen.sh`.
// clang-format off
- (instancetype)initWithGrdbId:(int64_t)grdbId
uniqueId:(NSString *)uniqueId
receivedAtTimestamp:(uint64_t)receivedAtTimestamp
sortId:(uint64_t)sortId
timestamp:(uint64_t)timestamp
uniqueThreadId:(NSString *)uniqueThreadId
{
self = [super initWithGrdbId:grdbId
uniqueId:uniqueId];
if (!self) {
return self;
}
_receivedAtTimestamp = receivedAtTimestamp;
_sortId = sortId;
_timestamp = timestamp;
_uniqueThreadId = uniqueThreadId;
return self;
}
// clang-format on
// --- CODE GENERATION MARKER
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return nil;
}
// Previously the receivedAtTimestamp field lived on TSMessage, but we've moved it up
// to the TSInteraction superclass.
if (_receivedAtTimestamp == 0) {
// Upgrade from the older "TSMessage.receivedAtDate" and "TSMessage.receivedAt" properties if
// necessary.
NSDate *receivedAtDate = [coder decodeObjectForKey:@"receivedAtDate"];
if (!receivedAtDate) {
receivedAtDate = [coder decodeObjectForKey:@"receivedAt"];
}
if (receivedAtDate) {
_receivedAtTimestamp = [NSDate ows_millisecondsSince1970ForDate:receivedAtDate];
}
// For TSInteractions which are not TSMessage's, the timestamp *is* the receivedAtTimestamp
if (_receivedAtTimestamp == 0) {
_receivedAtTimestamp = _timestamp;
}
}
return self;
}
#pragma mark Thread
- (nullable TSThread *)threadWithTx:(SDSAnyReadTransaction *)tx
{
if (self.uniqueThreadId == nil) {
// This might be true for a few legacy interactions enqueued in the message
// sender. The message sender will handle this case.
return nil;
}
// However, it's also possible that the thread doesn't exist.
return [TSThread anyFetchWithUniqueId:self.uniqueThreadId transaction:tx];
}
#pragma mark Date operations
- (NSDate *)receivedAtDate
{
return [NSDate ows_dateWithMillisecondsSince1970:self.receivedAtTimestamp];
}
- (NSDate *)timestampDate
{
return [NSDate ows_dateWithMillisecondsSince1970:self.timestamp];
}
- (OWSInteractionType)interactionType
{
OWSFailDebug(@"unknown interaction type.");
return OWSInteractionType_Unknown;
}
- (NSString *)description
{
return [NSString
stringWithFormat:@"%@ in thread: %@ timestamp: %llu", [super description], self.uniqueThreadId, self.timestamp];
}
#pragma mark - Any Transaction Hooks
- (void)anyDidInsertWithTransaction:(SDSAnyWriteTransaction *)transaction
{
[super anyDidInsertWithTransaction:transaction];
TSThread *fetchedThread = [self threadWithTx:transaction];
[fetchedThread updateWithInsertedMessage:self transaction:transaction];
// Don't update interactionReadCache; this instance's sortId isn't
// populated yet.
}
- (void)anyDidUpdateWithTransaction:(SDSAnyWriteTransaction *)transaction
{
[super anyDidUpdateWithTransaction:transaction];
TSThread *fetchedThread = [self threadWithTx:transaction];
[fetchedThread updateWithUpdatedMessage:self transaction:transaction];
[SSKEnvironment.shared.modelReadCachesRef.interactionReadCache didUpdateInteraction:self transaction:transaction];
}
#pragma mark -
- (BOOL)isDynamicInteraction
{
return NO;
}
#pragma mark - sorting migration
- (void)replaceSortId:(uint64_t)sortId
{
_sortId = sortId;
}
#if TESTABLE_BUILD
- (void)replaceTimestamp:(uint64_t)timestamp transaction:(SDSAnyWriteTransaction *)transaction
{
[self anyUpdateWithTransaction:transaction
block:^(TSInteraction *interaction) { interaction.timestamp = timestamp; }];
}
- (void)replaceReceivedAtTimestamp:(uint64_t)receivedAtTimestamp
{
self.receivedAtTimestamp = receivedAtTimestamp;
}
- (void)replaceReceivedAtTimestamp:(uint64_t)receivedAtTimestamp transaction:(SDSAnyWriteTransaction *)transaction
{
[self anyUpdateWithTransaction:transaction
block:^(TSInteraction *interaction) {
interaction.receivedAtTimestamp = receivedAtTimestamp;
}];
}
#endif
@end
NS_ASSUME_NONNULL_END