mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Implement sending quotes in group chats
This commit is contained in:
parent
5569e87485
commit
f205767b98
14 changed files with 43 additions and 11 deletions
|
@ -91,8 +91,14 @@ public final class LokiGroupChatPoller : NSObject {
|
|||
guard !isDuplicate else { return }
|
||||
guard let groupID = group.id.data(using: .utf8) else { return }
|
||||
let thread = TSGroupThread.getOrCreateThread(withGroupId: groupID)
|
||||
let signalQuote: TSQuotedMessage?
|
||||
if let quote = message.quote {
|
||||
signalQuote = TSQuotedMessage(timestamp: quote.quotedMessageTimestamp, authorId: quote.quoteeHexEncodedPublicKey, body: quote.quotedMessageBody, quotedAttachmentsForSending: [])
|
||||
} else {
|
||||
signalQuote = nil
|
||||
}
|
||||
let message = TSOutgoingMessage(outgoingMessageWithTimestamp: message.timestamp, in: thread, messageBody: message.body, attachmentIds: [], expiresInSeconds: 0,
|
||||
expireStartedAt: 0, isVoiceMessage: false, groupMetaMessage: .deliver, quotedMessage: nil, contactShare: nil, linkPreview: nil)
|
||||
expireStartedAt: 0, isVoiceMessage: false, groupMetaMessage: .deliver, quotedMessage: signalQuote, contactShare: nil, linkPreview: nil)
|
||||
storage.dbReadWriteConnection.readWrite { transaction in
|
||||
message.update(withSentRecipient: group.server, wasSentByUD: false, transaction: transaction)
|
||||
message.saveGroupChatMessageID(messageServerID, in: transaction)
|
||||
|
|
|
@ -74,9 +74,10 @@ class ConversationViewItemActions: NSObject {
|
|||
class func textActions(conversationViewItem: ConversationViewItem, shouldAllowReply: Bool, delegate: MessageActionsDelegate) -> [MenuAction] {
|
||||
var actions: [MenuAction] = []
|
||||
|
||||
let isGroup = conversationViewItem.isGroupThread
|
||||
let isGroup = conversationViewItem.isGroupThread;
|
||||
let isRSSFeed = conversationViewItem.isRSSFeed;
|
||||
|
||||
if shouldAllowReply && !isGroup {
|
||||
if shouldAllowReply && !isRSSFeed {
|
||||
let replyAction = MessageActionBuilder.reply(conversationViewItem: conversationViewItem, delegate: delegate)
|
||||
actions.append(replyAction)
|
||||
}
|
||||
|
|
|
@ -306,6 +306,7 @@ class ColorPickerView: UIView, ColorViewDelegate {
|
|||
@objc
|
||||
private class MockConversationViewItem: NSObject, ConversationViewItem {
|
||||
var userCanDeleteGroupMessage: Bool = false
|
||||
var isRSSFeed: Bool = false
|
||||
var interaction: TSInteraction = TSMessage()
|
||||
var interactionType: OWSInteractionType = OWSInteractionType.unknown
|
||||
var quotedReply: OWSQuotedReplyModel?
|
||||
|
|
|
@ -361,7 +361,7 @@ const CGFloat kRemotelySourcedContentRowSpacing = 3;
|
|||
OWSAssertDebug(CGSizeEqualToSize(
|
||||
CGSizeMake(kRemotelySourcedContentGlyphLength, kRemotelySourcedContentGlyphLength), glyphImage.size));
|
||||
UIImageView *glyphView = [[UIImageView alloc] initWithImage:glyphImage];
|
||||
glyphView.tintColor = Theme.secondaryColor;
|
||||
glyphView.tintColor = UIColor.whiteColor;
|
||||
[glyphView
|
||||
autoSetDimensionsToSize:CGSizeMake(kRemotelySourcedContentGlyphLength, kRemotelySourcedContentGlyphLength)];
|
||||
|
||||
|
|
|
@ -513,7 +513,7 @@ typedef enum : NSUInteger {
|
|||
_conversationStyle = [[ConversationStyle alloc] initWithThread:thread];
|
||||
|
||||
_conversationViewModel =
|
||||
[[ConversationViewModel alloc] initWithThread:thread focusMessageIdOnOpen:focusMessageId delegate:self];
|
||||
[[ConversationViewModel alloc] initWithThread:thread focusMessageIdOnOpen:focusMessageId isRSSFeed:self.isRSSFeed delegate:self];
|
||||
|
||||
_searchController = [[ConversationSearchController alloc] initWithThread:thread];
|
||||
_searchController.delegate = self;
|
||||
|
|
|
@ -67,6 +67,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType);
|
|||
@property (nonatomic, readonly, nullable) OWSQuotedReplyModel *quotedReply;
|
||||
|
||||
@property (nonatomic, readonly) BOOL isGroupThread;
|
||||
@property (nonatomic, readonly) BOOL isRSSFeed;
|
||||
@property (nonatomic, readonly) BOOL userCanDeleteGroupMessage;
|
||||
|
||||
@property (nonatomic, readonly) BOOL hasBodyText;
|
||||
|
@ -162,6 +163,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType);
|
|||
- (instancetype)init NS_UNAVAILABLE;
|
||||
- (instancetype)initWithInteraction:(TSInteraction *)interaction
|
||||
isGroupThread:(BOOL)isGroupThread
|
||||
isRSSFeed:(BOOL)isRSSFeed
|
||||
transaction:(YapDatabaseReadTransaction *)transaction
|
||||
conversationStyle:(ConversationStyle *)conversationStyle;
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
|
|||
@synthesize interaction = _interaction;
|
||||
@synthesize isFirstInCluster = _isFirstInCluster;
|
||||
@synthesize isGroupThread = _isGroupThread;
|
||||
@synthesize isRSSFeed = _isRSSFeed;
|
||||
@synthesize isLastInCluster = _isLastInCluster;
|
||||
@synthesize lastAudioMessageView = _lastAudioMessageView;
|
||||
@synthesize senderName = _senderName;
|
||||
|
@ -126,6 +127,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
|
|||
|
||||
- (instancetype)initWithInteraction:(TSInteraction *)interaction
|
||||
isGroupThread:(BOOL)isGroupThread
|
||||
isRSSFeed:(BOOL)isRSSFeed
|
||||
transaction:(YapDatabaseReadTransaction *)transaction
|
||||
conversationStyle:(ConversationStyle *)conversationStyle
|
||||
{
|
||||
|
@ -141,6 +143,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
|
|||
|
||||
_interaction = interaction;
|
||||
_isGroupThread = isGroupThread;
|
||||
_isRSSFeed = isRSSFeed;
|
||||
_conversationStyle = conversationStyle;
|
||||
|
||||
[self updateAuthorConversationColorNameWithTransaction:transaction];
|
||||
|
|
|
@ -98,10 +98,12 @@ typedef NS_ENUM(NSUInteger, ConversationUpdateItemType) {
|
|||
@property (nonatomic, readonly) ConversationViewState *viewState;
|
||||
@property (nonatomic, nullable) NSString *focusMessageIdOnOpen;
|
||||
@property (nonatomic, readonly, nullable) ThreadDynamicInteractions *dynamicInteractions;
|
||||
@property (nonatomic, readonly) BOOL isRSSFeed;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
- (instancetype)initWithThread:(TSThread *)thread
|
||||
focusMessageIdOnOpen:(nullable NSString *)focusMessageIdOnOpen
|
||||
isRSSFeed:(BOOL)isRSSFeed
|
||||
delegate:(id<ConversationViewModelDelegate>)delegate NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (void)ensureDynamicInteractionsAndUpdateIfNecessary:(BOOL)updateIfNecessary;
|
||||
|
|
|
@ -218,6 +218,7 @@ static const int kYapDatabaseRangeMaxLength = 25000;
|
|||
|
||||
- (instancetype)initWithThread:(TSThread *)thread
|
||||
focusMessageIdOnOpen:(nullable NSString *)focusMessageIdOnOpen
|
||||
isRSSFeed:(BOOL)isRSSFeed
|
||||
delegate:(id<ConversationViewModelDelegate>)delegate
|
||||
{
|
||||
self = [super init];
|
||||
|
@ -233,6 +234,7 @@ static const int kYapDatabaseRangeMaxLength = 25000;
|
|||
_persistedViewItems = @[];
|
||||
_unsavedOutgoingMessages = @[];
|
||||
self.focusMessageIdOnOpen = focusMessageIdOnOpen;
|
||||
_isRSSFeed = isRSSFeed;
|
||||
_viewState = [[ConversationViewState alloc] initWithViewItems:@[]];
|
||||
|
||||
[self configure];
|
||||
|
@ -1205,6 +1207,7 @@ static const int kYapDatabaseRangeMaxLength = 25000;
|
|||
|
||||
NSArray<NSString *> *loadedUniqueIds = [self.messageMapping loadedUniqueIds];
|
||||
BOOL isGroupThread = self.thread.isGroupThread;
|
||||
BOOL isRSSFeed = self.isRSSFeed;
|
||||
ConversationStyle *conversationStyle = self.delegate.conversationStyle;
|
||||
|
||||
[self ensureConversationProfileState];
|
||||
|
@ -1218,6 +1221,7 @@ static const int kYapDatabaseRangeMaxLength = 25000;
|
|||
if (!viewItem) {
|
||||
viewItem = [[ConversationInteractionViewItem alloc] initWithInteraction:interaction
|
||||
isGroupThread:isGroupThread
|
||||
isRSSFeed:isRSSFeed
|
||||
transaction:transaction
|
||||
conversationStyle:conversationStyle];
|
||||
}
|
||||
|
|
|
@ -2012,6 +2012,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
id<ConversationViewItem> viewItem =
|
||||
[[ConversationInteractionViewItem alloc] initWithInteraction:messageToQuote
|
||||
isGroupThread:thread.isGroupThread
|
||||
isRSSFeed:NO
|
||||
transaction:transaction
|
||||
conversationStyle:conversationStyle];
|
||||
quotedMessage = [
|
||||
|
@ -2033,6 +2034,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
id<ConversationViewItem> viewItem =
|
||||
[[ConversationInteractionViewItem alloc] initWithInteraction:messageToQuote
|
||||
isGroupThread:thread.isGroupThread
|
||||
isRSSFeed:NO
|
||||
transaction:transaction
|
||||
conversationStyle:conversationStyle];
|
||||
quotedMessage = [
|
||||
|
|
|
@ -579,6 +579,7 @@ class MediaPageViewController: UIPageViewController, UIPageViewControllerDataSou
|
|||
let conversationStyle = ConversationStyle(thread: thread)
|
||||
fetchedItem = ConversationInteractionViewItem(interaction: message,
|
||||
isGroupThread: thread.isGroupThread(),
|
||||
isRSSFeed: false,
|
||||
transaction: transaction,
|
||||
conversationStyle: conversationStyle)
|
||||
}
|
||||
|
|
|
@ -178,8 +178,7 @@ public final class LokiGroupChatAPI : NSObject {
|
|||
throw Error.parsingFailed
|
||||
}
|
||||
let timestamp = UInt64(date.timeIntervalSince1970) * 1000
|
||||
let quote: LokiGroupMessage.Quote?
|
||||
return LokiGroupMessage(serverID: serverID, hexEncodedPublicKey: userHexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp, quote: nil)
|
||||
return LokiGroupMessage(serverID: serverID, hexEncodedPublicKey: userHexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp, quote: message.quote)
|
||||
}
|
||||
}.recover { error -> Promise<LokiGroupMessage> in
|
||||
if let error = error as? NetworkManagerError, error.statusCode == 401 {
|
||||
|
|
|
@ -31,12 +31,21 @@ public final class LokiGroupMessage : NSObject {
|
|||
super.init()
|
||||
}
|
||||
|
||||
@objc public convenience init(hexEncodedPublicKey: String, displayName: String, body: String, type: String, timestamp: UInt64) {
|
||||
self.init(serverID: nil, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: type, timestamp: timestamp, quote: nil)
|
||||
@objc public convenience init(hexEncodedPublicKey: String, displayName: String, body: String, type: String, timestamp: UInt64, quotedMessageTimestamp: UInt64, quoteeHexEncodedPublicKey: String?, quotedMessageBody: String?) {
|
||||
let quote: Quote?
|
||||
if quotedMessageTimestamp != 0, let quoteeHexEncodedPublicKey = quoteeHexEncodedPublicKey, let quotedMessageBody = quotedMessageBody {
|
||||
quote = Quote(quotedMessageTimestamp: quotedMessageTimestamp, quoteeHexEncodedPublicKey: quoteeHexEncodedPublicKey, quotedMessageBody: quotedMessageBody)
|
||||
} else {
|
||||
quote = nil
|
||||
}
|
||||
self.init(serverID: nil, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: type, timestamp: timestamp, quote: quote)
|
||||
}
|
||||
|
||||
internal func toJSON() -> JSON {
|
||||
let value: JSON = [ "timestamp" : timestamp, "from" : displayName, "source" : hexEncodedPublicKey ]
|
||||
var value: JSON = [ "timestamp" : timestamp, "from" : displayName, "source" : hexEncodedPublicKey ]
|
||||
if let quote = quote {
|
||||
value["quote"] = [ "id" : quote.quotedMessageTimestamp, "author" : quote.quoteeHexEncodedPublicKey, "text" : quote.quotedMessageBody ]
|
||||
}
|
||||
return [ "text" : body, "annotations": [ [ "type" : type, "value" : value ] ] ]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1113,7 +1113,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
|
||||
NSString *displayName = SSKEnvironment.shared.profileManager.localProfileName;
|
||||
if (displayName == nil) { displayName = @"Anonymous"; }
|
||||
LKGroupMessage *groupMessage = [[LKGroupMessage alloc] initWithHexEncodedPublicKey:userHexEncodedPublicKey displayName:displayName body:message.body type:LKGroupChatAPI.publicChatMessageType timestamp:message.timestamp];
|
||||
TSQuotedMessage *quote = message.quotedMessage;
|
||||
LKGroupMessage *groupMessage = [[LKGroupMessage alloc] initWithHexEncodedPublicKey:userHexEncodedPublicKey displayName:displayName body:message.body type:LKGroupChatAPI.publicChatMessageType
|
||||
timestamp:message.timestamp quotedMessageTimestamp:quote.timestamp quoteeHexEncodedPublicKey:quote.authorId quotedMessageBody:quote.body];
|
||||
[[LKGroupChatAPI sendMessage:groupMessage toGroup:LKGroupChatAPI.publicChatServerID onServer:LKGroupChatAPI.publicChatServer]
|
||||
.thenOn(OWSDispatch.sendingQueue, ^(LKGroupMessage *groupMessage) {
|
||||
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
|
|
Loading…
Reference in a new issue