Skip to content

Commit

Permalink
Highlight messages that mention the user's nickname.
Browse files Browse the repository at this point in the history
git-svn-id: http://source.colloquy.info/svn/trunk@3890 cc480944-b4dd-0310-b5e3-89908df9b951
  • Loading branch information
kijiro committed Dec 14, 2008
1 parent f37b65f commit fea8cc0
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 22 deletions.
3 changes: 3 additions & 0 deletions Additions/NSScannerAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@
- (BOOL) scanCharacterInto:(unichar *) unicharValue;
- (BOOL) scanStringLength:(unsigned) length intoString:(NSString **) stringValue;
- (BOOL) scanCharactersFromSet:(NSCharacterSet *) scanSet maxLength:(unsigned) length intoString:(NSString **) stringValue;

- (BOOL) scanXMLTagIntoString:(NSString **) stringValue;
- (BOOL) scanUpToXMLTagIntoString:(NSString **) stringValue;
@end
18 changes: 18 additions & 0 deletions Additions/NSScannerAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,22 @@ - (BOOL) scanCharactersFromSet:(NSCharacterSet *) scanSet maxLength:(unsigned) m

return NO;
}

- (BOOL) scanXMLTagIntoString:(NSString **) stringValue {
if( ![self scanString:@"<" intoString:NULL] )
return NO;

NSString *tag = nil;
BOOL result = [self scanUpToString:@">" intoString:&tag];
if( result ) [self scanString:@">" intoString:NULL];

if( result && stringValue )
*stringValue = [NSString stringWithFormat:@"<%@>", tag];

return result;
}

- (BOOL) scanUpToXMLTagIntoString:(NSString **) stringValue {
return [self scanUpToString:@"<" intoString:stringValue];
}
@end
1 change: 1 addition & 0 deletions Additions/NSStringAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ BOOL isValidUTF8( const char *s, unsigned len );

- (NSString *) stringWithDomainNameSegmentOfAddress;

- (NSArray *) componentsSeparatedByXMLTags;
- (NSArray *) componentsSeparatedByCharactersInSet:(NSCharacterSet *) separator limit:(unsigned long) limit remainingString:(NSString **) remainder;

- (BOOL) containsEmojiCharacters;
Expand Down
25 changes: 22 additions & 3 deletions Additions/NSStringAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -871,9 +871,7 @@ - (NSString *) stringByStrippingIllegalXMLCharacters {
}

- (NSString *) stringByStrippingXMLTags {
NSCharacterSet *tagCharacters = [NSCharacterSet characterSetWithCharactersInString:@"<>"];
NSRange range = [self rangeOfCharacterFromSet:tagCharacters options:NSLiteralSearch];
if( range.location == NSNotFound )
if( [self rangeOfString:@"<"].location == NSNotFound )
return self;

NSMutableString *result = [self mutableCopyWithZone:nil];
Expand All @@ -900,6 +898,27 @@ - (NSString *) stringWithDomainNameSegmentOfAddress {

#pragma mark -

- (NSArray *) componentsSeparatedByXMLTags {
if( [self rangeOfString:@"<"].location == NSNotFound )
return [NSArray arrayWithObject:self];

NSScanner *scanner = [[NSScanner allocWithZone:nil] initWithString:self];
[scanner setCharactersToBeSkipped:nil];

NSMutableArray *result = [[NSMutableArray allocWithZone:nil] init];

NSString *component = @"";
while( ! [scanner isAtEnd] ) {
if( [scanner scanUpToXMLTagIntoString:&component] )
[result addObject:component];
[scanner scanXMLTagIntoString:NULL];
}

[scanner release];

return [result autorelease];
}

- (NSArray *) componentsSeparatedByCharactersInSet:(NSCharacterSet *) separator limit:(unsigned long) limit remainingString:(NSString **) remainder {
if( [self rangeOfCharacterFromSet:separator].location == NSNotFound )
return [NSArray arrayWithObject:self];
Expand Down
3 changes: 3 additions & 0 deletions Mobile/Controllers/CQChatListViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ - (void) addMessagePreview:(NSDictionary *) info forChatController:(id <CQChatVi
if ([controller respondsToSelector:@selector(importantUnreadCount)])
cell.importantUnreadCount = controller.importantUnreadCount;

if (cell.importantUnreadCount == cell.unreadCount)
cell.unreadCount = 0;

[self _addMessagePreview:info toChatTableCell:cell animated:YES];
}

Expand Down
1 change: 0 additions & 1 deletion Mobile/Controllers/CQDirectChatController.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
IBOutlet CQChatInputBar *chatInputBar;
IBOutlet CQChatTranscriptView *transcriptView;

NSMutableArray *_pendingMessages;
NSMutableArray *_recentMessages;

id _target;
Expand Down
29 changes: 12 additions & 17 deletions Mobile/Controllers/CQDirectChatController.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ - (id) initWithTarget:(id) target {
[self.connection addChatUserWatchRule:_watchRule];
}

// Load the view now so it is ready to add messages.
self.view;

return self;
}

Expand All @@ -44,7 +47,6 @@ - (void) dealloc {

[_watchRule release];
[_recentMessages release];
[_pendingMessages release];
[_target release];

[super dealloc];
Expand Down Expand Up @@ -95,15 +97,6 @@ - (NSUInteger) importantUnreadCount {

#pragma mark -

- (void) viewDidLoad {
[super viewDidLoad];

[transcriptView addMessages:_pendingMessages];

[_pendingMessages release];
_pendingMessages = nil;
}

- (void) viewWillAppear:(BOOL) animated {
[super viewWillAppear:animated];

Expand Down Expand Up @@ -215,6 +208,15 @@ - (BOOL) transcriptView:(CQChatTranscriptView *) transcriptView handleOpenURL:(N
return YES;
}

- (NSArray *) highlightWordsForTranscriptView:(CQChatTranscriptView *) transcriptView {
return [NSArray arrayWithObject:self.connection.nickname];
}

- (void) transcriptView:(CQChatTranscriptView *) transcriptView highlightedMessageWithWord:(NSString *) highlightWord {
if (!_active)
++_unreadHighlightedMessages;
}

#pragma mark -

- (void) resetDidSendRecently {
Expand Down Expand Up @@ -332,13 +334,6 @@ - (void) addMessage:(NSDictionary *) info {
[_recentMessages removeObjectAtIndex:0];
}

if (!transcriptView) {
if (!_pendingMessages)
_pendingMessages = [[NSMutableArray alloc] init];
[_pendingMessages addObject:info];
return;
}

[transcriptView addMessage:info];
}

Expand Down
3 changes: 3 additions & 0 deletions Mobile/Views/CQChatTableCell.m
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ - (void) takeValuesFromChatViewController:(id <CQChatViewController>) controller
if ([controller respondsToSelector:@selector(importantUnreadCount)])
self.importantUnreadCount = controller.importantUnreadCount;
else self.importantUnreadCount = 0;

if (self.importantUnreadCount == self.unreadCount)
self.unreadCount = 0;
}

@synthesize maximumMessagePreviews = _maximumMessagePreviews;
Expand Down
2 changes: 2 additions & 0 deletions Mobile/Views/CQChatTranscriptView.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ typedef enum {
@protocol CQChatTranscriptViewDelegate <NSObject>
@optional
- (BOOL) transcriptView:(CQChatTranscriptView *) transcriptView handleOpenURL:(NSURL *) url;
- (NSArray *) highlightWordsForTranscriptView:(CQChatTranscriptView *) transcriptView;
- (void) transcriptView:(CQChatTranscriptView *) transcriptView highlightedMessageWithWord:(NSString *) highlightWord;
@end
40 changes: 39 additions & 1 deletion Mobile/Views/CQChatTranscriptView.m
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,50 @@ - (void) addMessage:(NSDictionary *) info {
NSString *messageString = [[NSString alloc] initWithChatData:message encoding:NSUTF8StringEncoding];
NSString *transformedMessageString = applyFunctionToTextInHTMLString(messageString, commonChatReplacment);

BOOL highlighted = NO;
if ([self.delegate respondsToSelector:@selector(highlightWordsForTranscriptView:)]) {
NSArray *highlightWords = [self.delegate highlightWordsForTranscriptView:self];
if (highlightWords.count) {
NSCharacterSet *escapedCharacters = [NSCharacterSet characterSetWithCharactersInString:@"^[]{}()\\.$*+?|"];
NSCharacterSet *trimCharacters = [NSCharacterSet characterSetWithCharactersInString:@"\"'"];
NSArray *messageStrings = [transformedMessageString componentsSeparatedByXMLTags];
NSString *singleMessageString = [messageStrings componentsJoinedByString:@""];

for (NSString *highlightWord in highlightWords) {
if (!highlightWord.length)
continue;

NSString *originalHighlightWord = highlightWord;
AGRegex *regex = nil;
if( [highlightWord hasPrefix:@"/"] && [highlightWord hasSuffix:@"/"] && highlightWord.length > 1 ) {
regex = [[AGRegex alloc] initWithPattern:[highlightWord substringWithRange:NSMakeRange( 1, highlightWord.length - 2 )] options:AGRegexCaseInsensitive];
} else {
highlightWord = [highlightWord stringByTrimmingCharactersInSet:trimCharacters];
highlightWord = [highlightWord stringByEscapingCharactersInSet:escapedCharacters];
regex = [[AGRegex alloc] initWithPattern:[NSString stringWithFormat:@"(?<=^|\\s|[^\\w])%@(?=$|\\s|[^\\w])", highlightWord] options:AGRegexCaseInsensitive];
}

if ([regex findInString:singleMessageString]) {
highlighted = YES;

if ([self.delegate respondsToSelector:@selector(transcriptView:highlightedMessageWithWord:)])
[self.delegate transcriptView:self highlightedMessageWithWord:originalHighlightWord];
}

[regex release];

if (highlighted)
break;
}
}
}

BOOL action = [[info objectForKey:@"action"] boolValue];

NSCharacterSet *escapedCharacters = [NSCharacterSet characterSetWithCharactersInString:@"\\'\""];
NSString *escapedMessage = [transformedMessageString stringByEscapingCharactersInSet:escapedCharacters];
NSString *escapedNickname = [user.nickname stringByEscapingCharactersInSet:escapedCharacters];
NSString *command = [NSString stringWithFormat:@"appendMessage('%@', '%@', %@, %@, %@)", escapedNickname, escapedMessage, @"false", (action ? @"true" : @"false"), (user.localUser ? @"true" : @"false")];
NSString *command = [NSString stringWithFormat:@"appendMessage('%@', '%@', %@, %@, %@)", escapedNickname, escapedMessage, (highlighted ? @"true" : @"false"), (action ? @"true" : @"false"), (user.localUser ? @"true" : @"false")];

[messageString release];

Expand Down

0 comments on commit fea8cc0

Please sign in to comment.