Mention by display name rather than hex encoded public key

pull/59/head
Niels Andriesse 6 years ago
parent 966748ed1b
commit 2f39cd45f3

@ -567,6 +567,7 @@
B82584A02315024B001B41CB /* RSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* RSSFeedPoller.swift */; }; B82584A02315024B001B41CB /* RSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* RSSFeedPoller.swift */; };
B845B4D4230CD09100D759F0 /* GroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* GroupChatPoller.swift */; }; B845B4D4230CD09100D759F0 /* GroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* GroupChatPoller.swift */; };
B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; }; B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; };
B84664F3234FE4540083A1CD /* Mention.swift in Sources */ = {isa = PBXBuildFile; fileRef = B84664F2234FE4530083A1CD /* Mention.swift */; };
B86BD08123399883000F5AE3 /* QRCodeModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08023399883000F5AE3 /* QRCodeModal.swift */; }; B86BD08123399883000F5AE3 /* QRCodeModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08023399883000F5AE3 /* QRCodeModal.swift */; };
B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08323399ACF000F5AE3 /* Modal.swift */; }; B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08323399ACF000F5AE3 /* Modal.swift */; };
B86BD08623399CEF000F5AE3 /* SeedModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08523399CEF000F5AE3 /* SeedModal.swift */; }; B86BD08623399CEF000F5AE3 /* SeedModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08523399CEF000F5AE3 /* SeedModal.swift */; };
@ -1378,6 +1379,7 @@
B825849F2315024B001B41CB /* RSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RSSFeedPoller.swift; sourceTree = "<group>"; }; B825849F2315024B001B41CB /* RSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RSSFeedPoller.swift; sourceTree = "<group>"; };
B845B4D3230CD09000D759F0 /* GroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupChatPoller.swift; sourceTree = "<group>"; }; B845B4D3230CD09000D759F0 /* GroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupChatPoller.swift; sourceTree = "<group>"; };
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; }; B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; };
B84664F2234FE4530083A1CD /* Mention.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mention.swift; sourceTree = "<group>"; };
B86BD08023399883000F5AE3 /* QRCodeModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeModal.swift; sourceTree = "<group>"; }; B86BD08023399883000F5AE3 /* QRCodeModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeModal.swift; sourceTree = "<group>"; };
B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; }; B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; };
B86BD08523399CEF000F5AE3 /* SeedModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedModal.swift; sourceTree = "<group>"; }; B86BD08523399CEF000F5AE3 /* SeedModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedModal.swift; sourceTree = "<group>"; };
@ -2652,6 +2654,7 @@
B8162F0222891AD600D46544 /* FriendRequestView.swift */, B8162F0222891AD600D46544 /* FriendRequestView.swift */,
B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */, B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */,
24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */, 24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */,
B84664F2234FE4530083A1CD /* Mention.swift */,
B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */, B89841E222B7579F00B1BDC6 /* NewConversationVC.swift */,
B8258491230FA5DA001B41CB /* ScanQRCodeVC.h */, B8258491230FA5DA001B41CB /* ScanQRCodeVC.h */,
B8258492230FA5E9001B41CB /* ScanQRCodeVC.m */, B8258492230FA5E9001B41CB /* ScanQRCodeVC.m */,
@ -3879,6 +3882,7 @@
345BC30C2047030700257B7C /* OWS2FASettingsViewController.m in Sources */, 345BC30C2047030700257B7C /* OWS2FASettingsViewController.m in Sources */,
340FC8B7204DAC8D007AEB0F /* OWSConversationSettingsViewController.m in Sources */, 340FC8B7204DAC8D007AEB0F /* OWSConversationSettingsViewController.m in Sources */,
34BECE2E1F7ABCE000D7438D /* GifPickerViewController.swift in Sources */, 34BECE2E1F7ABCE000D7438D /* GifPickerViewController.swift in Sources */,
B84664F3234FE4540083A1CD /* Mention.swift in Sources */,
34D1F0C01F8EC1760066283D /* MessageRecipientStatusUtils.swift in Sources */, 34D1F0C01F8EC1760066283D /* MessageRecipientStatusUtils.swift in Sources */,
45F659731E1BD99C00444429 /* CallKitCallUIAdaptee.swift in Sources */, 45F659731E1BD99C00444429 /* CallKitCallUIAdaptee.swift in Sources */,
34277A5E20751BDC006049F2 /* OWSQuotedMessageView.m in Sources */, 34277A5E20751BDC006049F2 /* OWSQuotedMessageView.m in Sources */,

@ -0,0 +1,13 @@
@objc(LKMention)
public final class Mention : NSObject {
@objc public let locationInString: UInt
@objc public let hexEncodedPublicKey: String
@objc public let displayName: String
@objc public init(locationInString: UInt, hexEncodedPublicKey: String, displayName: String) {
self.locationInString = locationInString
self.hexEncodedPublicKey = hexEncodedPublicKey
self.displayName = displayName
}
}

@ -3,7 +3,7 @@
@objc(LKUserSelectionView) @objc(LKUserSelectionView)
final class UserSelectionView : UIView, UITableViewDataSource, UITableViewDelegate { final class UserSelectionView : UIView, UITableViewDataSource, UITableViewDelegate {
@objc var users: [String] = [] { didSet { tableView.reloadData(); tableView.contentOffset = CGPoint.zero } } @objc var users: [String] = [] { didSet { tableView.reloadData() } }
@objc var hasGroupContext = false @objc var hasGroupContext = false
@objc var delegate: UserSelectionViewDelegate? @objc var delegate: UserSelectionViewDelegate?

@ -213,7 +213,10 @@ typedef enum : NSUInteger {
@property (nonatomic) CGFloat extraContentInsetPadding; @property (nonatomic) CGFloat extraContentInsetPadding;
@property (nonatomic) CGFloat contentInsetBottom; @property (nonatomic) CGFloat contentInsetBottom;
@property (nonatomic) NSInteger mentionStartIndex; // Mentions
@property (nonatomic) NSInteger currentMentionStartIndex;
@property (nonatomic) NSMutableArray<LKMention *> *mentions;
@property (nonatomic) NSString *oldText;
@end @end
@ -259,7 +262,8 @@ typedef enum : NSUInteger {
self.scrollContinuity = kScrollContinuityBottom; self.scrollContinuity = kScrollContinuityBottom;
_mentionStartIndex = -1; _currentMentionStartIndex = -1;
_mentions = [NSMutableArray new];
} }
#pragma mark - Dependencies #pragma mark - Dependencies
@ -3018,6 +3022,9 @@ typedef enum : NSUInteger {
{ {
[self tryToSendAttachments:attachments messageText:messageText]; [self tryToSendAttachments:attachments messageText:messageText];
[self.inputToolbar clearTextMessageAnimated:NO]; [self.inputToolbar clearTextMessageAnimated:NO];
self.oldText = @"";
self.currentMentionStartIndex = -1;
self.mentions = @[].mutableCopy;
// we want to already be at the bottom when the user returns, rather than have to watch // we want to already be at the bottom when the user returns, rather than have to watch
// the new message scroll into view. // the new message scroll into view.
@ -3769,32 +3776,74 @@ typedef enum : NSUInteger {
- (void)textViewDidChange:(UITextView *)textView - (void)textViewDidChange:(UITextView *)textView
{ {
if (textView.text.length == 0) { return; } // Prepare
NSString *newText = textView.text;
// Typing indicators
if (newText.length > 0) {
[self.typingIndicators didStartTypingOutgoingInputInThread:self.thread]; [self.typingIndicators didStartTypingOutgoingInputInThread:self.thread];
NSUInteger currentEndIndex = textView.text.length - 1; }
unichar lastCharacter = [textView.text characterAtIndex:currentEndIndex]; // Mentions
BOOL isBackspace = newText.length < self.oldText.length;
if (isBackspace) {
self.currentMentionStartIndex = -1;
for (LKMention *mention in self.mentions) {
BOOL isValid;
if (mention.locationInString > (NSUInteger)MAX((NSInteger)newText.length - 1, 0)) {
isValid = NO;
} else {
isValid = [[newText substringFromIndex:mention.locationInString] hasPrefix:[NSString stringWithFormat:@"@%@", mention.displayName]];
}
if (!isValid) {
[self.mentions removeObject:mention];
}
}
} else if (newText.length > 0) {
NSUInteger currentEndIndex = newText.length - 1;
unichar lastCharacter = [newText characterAtIndex:currentEndIndex];
if (lastCharacter == '@') { if (lastCharacter == '@') {
NSArray<NSString *> *userIDs = [LKAPI getUserIDsFor:@"" in:self.thread.uniqueId]; NSArray<NSString *> *userIDs = [LKAPI getUserIDsFor:@"" in:self.thread.uniqueId];
self.mentionStartIndex = (NSInteger)currentEndIndex + 1; self.currentMentionStartIndex = (NSInteger)currentEndIndex;
[self.inputToolbar showUserSelectionViewFor:userIDs in:self.thread]; [self.inputToolbar showUserSelectionViewFor:userIDs in:self.thread];
} else if ([NSCharacterSet.whitespaceAndNewlineCharacterSet characterIsMember:lastCharacter]) { } else if ([NSCharacterSet.whitespaceAndNewlineCharacterSet characterIsMember:lastCharacter]) {
self.mentionStartIndex = -1; self.currentMentionStartIndex = -1;
[self.inputToolbar hideUserSelectionView]; [self.inputToolbar hideUserSelectionView];
} else { } else {
if (self.mentionStartIndex != -1) { if (self.currentMentionStartIndex != -1) {
NSString *query = [textView.text substringFromIndex:(NSUInteger)self.mentionStartIndex]; NSString *query = [newText substringFromIndex:(NSUInteger)self.currentMentionStartIndex + 1]; // + 1 to get rid of the @
NSArray<NSString *> *userIDs = [LKAPI getUserIDsFor:query in:self.thread.uniqueId]; NSArray<NSString *> *userIDs = [LKAPI getUserIDsFor:query in:self.thread.uniqueId];
[self.inputToolbar showUserSelectionViewFor:userIDs in:self.thread]; [self.inputToolbar showUserSelectionViewFor:userIDs in:self.thread];
} }
} }
}
self.oldText = newText;
} }
- (void)handleUserSelected:(NSString *)user from:(LKUserSelectionView *)userSelectionView - (void)handleUserSelected:(NSString *)hexEncodedPublicKey from:(LKUserSelectionView *)userSelectionView
{ {
NSUInteger mentionStartIndex = (NSUInteger)self.currentMentionStartIndex;
__block NSString *displayName;
[OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
NSString *collection = [NSString stringWithFormat:@"%@.%llu", LKGroupChatAPI.publicChatServer, LKGroupChatAPI.publicChatServerID];
displayName = [transaction objectForKey:hexEncodedPublicKey inCollection:collection];
}];
LKMention *mention = [[LKMention alloc] initWithLocationInString:mentionStartIndex hexEncodedPublicKey:hexEncodedPublicKey displayName:displayName];
[self.mentions addObject:mention];
NSString *oldText = self.inputToolbar.messageText; NSString *oldText = self.inputToolbar.messageText;
NSUInteger mentionStartIndex = (NSUInteger)self.mentionStartIndex; NSString *newText = [oldText stringByReplacingCharactersInRange:NSMakeRange(mentionStartIndex, oldText.length - mentionStartIndex) withString:[NSString stringWithFormat:@"@%@", displayName]];
NSString *newText = [oldText stringByReplacingCharactersInRange:NSMakeRange(mentionStartIndex, oldText.length - mentionStartIndex) withString:user];
[self.inputToolbar setMessageText:newText animated:NO]; [self.inputToolbar setMessageText:newText animated:NO];
[self.inputToolbar hideUserSelectionView];
}
- (NSString *)getMessageBody
{
NSString *result = self.inputToolbar.messageText;
NSUInteger shift = 0;
for (LKMention *mention in self.mentions) {
NSRange range = NSMakeRange(mention.locationInString + shift, mention.displayName.length + 1); // + 1 to include the @
shift = shift + mention.hexEncodedPublicKey.length - mention.displayName.length;
result = [result stringByReplacingCharactersInRange:range withString:[[NSString alloc] initWithFormat:@"@%@", mention.hexEncodedPublicKey]];
}
return result;
} }
- (void)inputTextViewSendMessagePressed - (void)inputTextViewSendMessagePressed
@ -4045,6 +4094,9 @@ typedef enum : NSUInteger {
{ {
[self tryToSendAttachments:attachments messageText:messageText]; [self tryToSendAttachments:attachments messageText:messageText];
[self.inputToolbar clearTextMessageAnimated:NO]; [self.inputToolbar clearTextMessageAnimated:NO];
self.oldText = @"";
self.currentMentionStartIndex = -1;
self.mentions = @[].mutableCopy;
[self dismissViewControllerAnimated:YES completion:nil]; [self dismissViewControllerAnimated:YES completion:nil];
// We always want to scroll to the bottom of the conversation after the local user // We always want to scroll to the bottom of the conversation after the local user
@ -4415,7 +4467,7 @@ typedef enum : NSUInteger {
[BenchManager startEventWithTitle:@"Send Message milestone: toggleDefaultKeyboard completed" [BenchManager startEventWithTitle:@"Send Message milestone: toggleDefaultKeyboard completed"
eventId:@"fromSendUntil_toggleDefaultKeyboard"]; eventId:@"fromSendUntil_toggleDefaultKeyboard"];
[self tryToSendTextMessage:self.inputToolbar.messageText updateKeyboardState:YES]; [self tryToSendTextMessage:[self getMessageBody] updateKeyboardState:YES];
} }
- (void)tryToSendTextMessage:(NSString *)text updateKeyboardState:(BOOL)updateKeyboardState - (void)tryToSendTextMessage:(NSString *)text updateKeyboardState:(BOOL)updateKeyboardState
@ -4473,6 +4525,9 @@ typedef enum : NSUInteger {
[BenchManager benchWithTitle:@"clearTextMessageAnimated" [BenchManager benchWithTitle:@"clearTextMessageAnimated"
block:^{ block:^{
[self.inputToolbar clearTextMessageAnimated:YES]; [self.inputToolbar clearTextMessageAnimated:YES];
self.oldText = @"";
self.currentMentionStartIndex = -1;
self.mentions = @[].mutableCopy;
}]; }];
[BenchManager completeEventWithEventId:@"fromSendUntil_clearTextMessageAnimated"]; [BenchManager completeEventWithEventId:@"fromSendUntil_clearTextMessageAnimated"];

Loading…
Cancel
Save