From 0d39948c7e036829091e670b61b9a9f34417af16 Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Wed, 31 Oct 2012 01:59:34 +0100 Subject: [PATCH] fixed mentions --- Controller.h | 2 +- Controller.m | 9 +- Core.js | 72 ++++++++-- English.lproj/MainMenu.xib | 271 ++++++++++++++++++++++++++++++++++++- NewMessageWindow.h | 3 +- NewMessageWindow.m | 15 +- TweetModel.h | 2 + TweetModel.m | 3 +- hmac-helper.js | 3 + 9 files changed, 357 insertions(+), 23 deletions(-) diff --git a/Controller.h b/Controller.h index ff54f10..c2fd489 100644 --- a/Controller.h +++ b/Controller.h @@ -40,7 +40,7 @@ - (void)authentificationSucceded:(id)sender; - (void)initWebViews; - (void)initHotKeys; -- (void)openNewMessageWindowInReplyTo:(NSString *)userName statusId:(NSString *)statusId; +- (void)openNewMessageWindowInReplyTo:(NSString *)userName statusId:(NSString *)statusId withString:(NSString *)string; - (NSString *)pluginURL; - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent; - (void)unreadMentions:(NSInteger)count; diff --git a/Controller.m b/Controller.m index cd81d96..2030378 100644 --- a/Controller.m +++ b/Controller.m @@ -175,10 +175,10 @@ [[NSDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:nil]; } -- (void)openNewMessageWindowInReplyTo:(NSString *)userName statusId:(NSString *)statusId { +- (void)openNewMessageWindowInReplyTo:(NSString *)userName statusId:(NSString *)statusId withString:(NSString *)string { [NSApp activateIgnoringOtherApps:YES]; NewMessageWindow *newTweet = (NewMessageWindow *)[[NSDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:nil]; - [newTweet inReplyTo:userName statusId:statusId]; + [newTweet inReplyTo:userName statusId:statusId withString:string]; } - (void)openNewMessageWindowWithString:(NSString *)aString { @@ -202,7 +202,10 @@ - (IBAction)sendTweet:(id)sender { TweetModel *tweet = (TweetModel *)[sender object]; - NSString *func = [NSString stringWithFormat:@"tentia_instance.sendNewMessage(\"%@\", \"%@\")", [tweet.text stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""], tweet.inReplyTostatusId]; + NSString *func = [NSString stringWithFormat:@"tentia_instance.sendNewMessage(\"%@\", \"%@\", \"%@\")", + [tweet.text stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""], + tweet.inReplyTostatusId, + tweet.inReplyToEntity]; [timelineView stringByEvaluatingJavaScriptFromString:func]; } diff --git a/Core.js b/Core.js index f886ded..2e87bc7 100644 --- a/Core.js +++ b/Core.js @@ -73,7 +73,16 @@ Core.prototype.getItem = function(status) { var template = this.getTemplate(); - template.reply_to.onclick = function() { replyTo(status.entity, status.id); return false; } + template.reply_to.onclick = function() { + var mentions = []; + for (var i = 0; i < status.mentions.length; i++) { + var mention = status.mentions[i]; + if(mention.entity != controller.stringForKey_("entity")) + mentions.push(mention); + }; + replyTo(status.entity, status.id, mentions); + return false; + } //template.retweet.onclick = function() { template.retweet.className = "hidden"; _this.retweet(status.id_str, template.item); return false; } //template.image.src = status.user.profile_image_url; @@ -87,7 +96,10 @@ Core.prototype.getItem = function(status) { var basic = profile["https://tent.io/types/info/basic/v0.1.0"]; if (profile && basic) { - if(basic.name) template.username.innerText = basic.name; + if(basic.name) { + template.username.title = template.username.innerText; + template.username.innerText = basic.name; + } if(basic.avatar_url) template.image.src = basic.avatar_url; } }); @@ -113,7 +125,7 @@ Core.prototype.getItem = function(status) { else */template.in_reply.parentNode.className = "hidden"; //template.in_reply.href = WEBSITE_PATH + status.in_reply_to_screen_name + "/status/" + status.in_reply_to_status_id_str; - template.message.innerHTML = replaceTwitterLinks(replaceURLWithHTMLLinks(status.content.text, status.entities, template.message)); + template.message.innerHTML = replaceUsernamesWithLinks(replaceURLWithHTMLLinks(status.content.text, status.entities, template.message)); var time = document.createElement("abbr"); time.innerText = ISODateString(new Date(status.published_at * 1000)); @@ -346,7 +358,7 @@ Core.prototype.getNewData = function(supress_new_with_timeout) { } -Core.prototype.sendNewMessage = function(content, in_reply_to_status_id) { +Core.prototype.sendNewMessage = function(content, in_reply_to_status_id, in_reply_to_entity) { var _this = this; @@ -355,7 +367,7 @@ Core.prototype.sendNewMessage = function(content, in_reply_to_status_id) { var http_method = "POST"; var callback = function(data) { _this.getNewData(true); } - var data = JSON.stringify({ + var data = { "type": "https://tent.io/types/post/status/v0.1.0", "published_at": (new Date().getTime() / 1000), "permissions": { @@ -363,14 +375,19 @@ Core.prototype.sendNewMessage = function(content, in_reply_to_status_id) { }, "content": { "text": content, - } - }); + }, + }; + + var mentions = parseMentions(content, in_reply_to_status_id, in_reply_to_entity); + if (mentions.length > 0) { + data["mentions"] = mentions; + } getURL( url.toString(), http_method, callback, - data, + JSON.stringify(data), makeAuthHeader( url.toString(), http_method, @@ -415,6 +432,7 @@ Core.prototype.sendNewMessage = function(content, in_reply_to_status_id) { } });*/ } + /* Core.prototype.retweet = function(status_id, item) { @@ -531,7 +549,9 @@ Core.prototype.findUsernamesFor = function(query) { /* Helper functions */ function replaceURLWithHTMLLinks(text, entities, message_node) { - if(!entities) return text; + var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_()|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; + return text.replace(exp, "$1"); + /* var urls = entities.urls; @@ -594,7 +614,7 @@ function replaceURLWithHTMLLinks(text, entities, message_node) { return text;*/ } -function replaceTwitterLinks(text) { +function replaceUsernamesWithLinks(text, mentions) { return text; // FIXME! var username = /(^|\s)(\^)(\w+)/ig; var hash = /(^|\s)(#)(\w+)/ig; @@ -602,8 +622,12 @@ function replaceTwitterLinks(text) { return text.replace(hash, "$1$2$3"); } -function replyTo(username, status_id) { - controller.openNewMessageWindowInReplyTo_statusId_(username, status_id); +function replyTo(entity, status_id, mentions) { + var string = "^" + entity + " "; + for (var i = 0; i < mentions.length; i++) { + string += "^" + mentions[i].entity + " "; + } + controller.openNewMessageWindowInReplyTo_statusId_withString_(entity, status_id, string); } function loadPlugin(url) { @@ -659,6 +683,30 @@ function replaceShortened(url, message_node) { }); } +function parseMentions(text, post_id, entity) { + var mentions = []; + + if (post_id && entity) { + mentions.push({ + post: post_id, + entity: entity + }) + } + + var res = text.match(/((\^https?):\/\/\S+)/ig); + + if (res) { + for (var i = 0; i < res.length; i++) { + var e = res[i].substring(1); + if (e != entity) { + mentions.push({entity:e}); + } + } + } + + return mentions; +} + function ISODateString(d){ function pad(n){return n<10 ? '0'+n : n} return d.getUTCFullYear()+'-' diff --git a/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib index 1afcfcc..757db1d 100644 --- a/English.lproj/MainMenu.xib +++ b/English.lproj/MainMenu.xib @@ -21,9 +21,15 @@ YES + NSButton + NSButtonCell NSCustomObject + NSImageCell + NSImageView NSMenu NSMenuItem + NSTextField + NSTextFieldCell NSView NSWindowTemplate WebView @@ -903,6 +909,168 @@ mentions YES + + 15 + 2 + {{641, 502}, {480, 186}} + 611845120 + Login + NSWindow + + + + + 256 + + YES + + + 268 + + YES + + YES + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple PNG pasteboard type + NSFilenamesPboardType + NeXT Encapsulated PostScript v1.2 pasteboard type + NeXT TIFF v4.0 pasteboard type + + + {{20, 20}, {146, 146}} + + + + YES + + 0 + 33554432 + + NSImage + Icon + + 0 + 0 + 0 + YES + + NO + YES + + + + 268 + {{194, 82}, {266, 22}} + + + + _NS:9 + YES + + -1804599231 + 272630784 + + + LucidaGrande + 13 + 1044 + + https://someone.tent.is + _NS:9 + + YES + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 6 + System + textColor + + 3 + MAA + + + + NO + + + + 268 + {{191, 112}, {163, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + Add your entity to log in: + + _NS:1535 + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2NjY3AA + + + + 6 + System + controlTextColor + + + + NO + + + + 268 + {{391, 46}, {75, 32}} + + + + _NS:9 + YES + + 67108864 + 134217728 + Login + + _NS:9 + + -2038284288 + 129 + + + 200 + 25 + + NO + + + {480, 186} + + + + _NS:20 + + {{0, 0}, {2560, 1418}} + {10000000000000, 10000000000000} + YES + @@ -1974,6 +2142,83 @@ + + 592 + + + YES + + + + + + 593 + + + YES + + + + + + + + + 594 + + + YES + + + + + + 595 + + + + + 596 + + + YES + + + + + + 597 + + + + + 598 + + + YES + + + + + + 599 + + + + + 600 + + + YES + + + + + + 601 + + + @@ -2069,6 +2314,17 @@ 561.IBPluginDependency 57.IBPluginDependency 58.IBPluginDependency + 592.IBPluginDependency + 592.NSWindowTemplate.visibleAtLaunch + 593.IBPluginDependency + 594.IBPluginDependency + 595.IBPluginDependency + 596.IBPluginDependency + 597.IBPluginDependency + 598.IBPluginDependency + 599.IBPluginDependency + 600.IBPluginDependency + 601.IBPluginDependency 72.IBPluginDependency 73.IBPluginDependency 79.IBPluginDependency @@ -2169,6 +2425,17 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -2189,7 +2456,7 @@ - 591 + 601 @@ -2321,11 +2588,13 @@ YES YES + Icon NSMenuCheckmark NSMenuMixedState YES + {512, 512} {11, 11} {10, 3} diff --git a/NewMessageWindow.h b/NewMessageWindow.h index 2ed4270..2513461 100644 --- a/NewMessageWindow.h +++ b/NewMessageWindow.h @@ -15,13 +15,14 @@ IBOutlet NSTextField *textField; IBOutlet NSTextField *counter; NSString *inReplyTostatusId; + NSString *inReplyToEntity; } @property (nonatomic, retain) IBOutlet NSTextField *textField; @property (nonatomic, retain) IBOutlet NSTextField *counter; - (IBAction)sendTweet:(NSControl *)control; -- (void)inReplyTo:(NSString *)userName statusId:(NSString *)statusId; +- (void)inReplyTo:(NSString *)userName statusId:(NSString *)statusId withString:(NSString *)string; - (void)withString:(NSString *)aString; @end diff --git a/NewMessageWindow.m b/NewMessageWindow.m index 86ea2d0..5ae0150 100644 --- a/NewMessageWindow.m +++ b/NewMessageWindow.m @@ -23,6 +23,7 @@ // Add your subclass-specific initialization here. // If an error occurs here, send a [self release] message and return nil. inReplyTostatusId = @""; + inReplyToEntity = @""; } return self; } @@ -33,11 +34,11 @@ // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead. return @"NewMessageWindow"; } - +/* - (NSString *)displayName { return @"New Tweet"; } - +*/ - (void)windowControllerDidLoadNib:(NSWindowController *) aController { [super windowControllerDidLoadNib:aController]; @@ -72,13 +73,18 @@ return YES; } -- (void)inReplyTo:(NSString *)userName statusId:(NSString *)statusId { - [textField setStringValue:[NSString stringWithFormat:@"^%@ ", userName]]; +- (void)inReplyTo:(NSString *)entity statusId:(NSString *)statusId withString:(NSString *)string { + [textField setStringValue:string]; NSRange range = {[[textField stringValue] length] , 0}; [[textField currentEditor] setSelectedRange:range]; + [inReplyTostatusId release]; inReplyTostatusId = statusId; [inReplyTostatusId retain]; + + [inReplyToEntity release]; + inReplyToEntity = entity; + [inReplyToEntity retain]; } - (void)withString:(NSString *)aString { @@ -105,6 +111,7 @@ TweetModel *tweet = [[[TweetModel alloc] init] autorelease]; tweet.text = [control stringValue]; tweet.inReplyTostatusId = inReplyTostatusId; + tweet.inReplyToEntity = inReplyToEntity; [[NSNotificationCenter defaultCenter] postNotificationName:@"sendTweet" object:tweet]; [self close]; } else { diff --git a/TweetModel.h b/TweetModel.h index c891b69..51f08b9 100644 --- a/TweetModel.h +++ b/TweetModel.h @@ -12,9 +12,11 @@ @interface TweetModel : NSObject { NSString *text; NSString *inReplyTostatusId; + NSString *inReplyToEntity; } @property (nonatomic, retain) NSString *text; @property (nonatomic, retain) NSString *inReplyTostatusId; +@property (nonatomic, retain) NSString *inReplyToEntity; @end diff --git a/TweetModel.m b/TweetModel.m index 51aa5c0..dc917ea 100644 --- a/TweetModel.m +++ b/TweetModel.m @@ -11,11 +11,12 @@ @implementation TweetModel -@synthesize text, inReplyTostatusId; +@synthesize text, inReplyTostatusId, inReplyToEntity; - (void)dealloc { [text release]; [inReplyTostatusId release]; + [inReplyToEntity release]; [super dealloc]; } diff --git a/hmac-helper.js b/hmac-helper.js index a900fa0..84eb9a0 100644 --- a/hmac-helper.js +++ b/hmac-helper.js @@ -89,5 +89,8 @@ function findProfileURL(entity, callback) { } function debug(string) { + if (typeof string == "Object") { + string = JSON.stirngify(string); + } alert("DEBUG: " + string); } \ No newline at end of file