diff --git a/Controller.h b/Controller.h index 9217a6d..577505c 100644 --- a/Controller.h +++ b/Controller.h @@ -20,6 +20,7 @@ IBOutlet WebView *mentionsView; IBOutlet NSWindow *mentionsViewWindow; IBOutlet NSMenuItem *globalHotkeyMenuItem; + IBOutlet NSImageView *logoLayer; ViewDelegate *viewDelegate; OAuth *oauth; } @@ -29,6 +30,7 @@ @property (retain, nonatomic) IBOutlet WebView *mentionsView; @property (retain, nonatomic) IBOutlet NSWindow *mentionsViewWindow; @property (retain, nonatomic) IBOutlet NSMenuItem *globalHotkeyMenuItem; +@property (retain, nonatomic) IBOutlet NSImageView *logoLayer; @property (retain, nonatomic) IBOutlet ViewDelegate *viewDelegate; @property (retain, nonatomic) IBOutlet OAuth *oauth; diff --git a/Controller.m b/Controller.m index 5beca1b..46a0df7 100644 --- a/Controller.m +++ b/Controller.m @@ -31,6 +31,10 @@ selector:@selector(authentificationSucceded:) name:@"authentificationSucceded" object:nil]; + [nc addObserver:self + selector:@selector(getTweetUpdates:) + name:@"getTweetUpdates" + object:nil]; NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; [appleEventManager setEventHandler:self @@ -50,19 +54,22 @@ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSInteger defaultsNewTweetKey = (NSInteger)[defaults integerForKey:@"newTweetKey"]; - if ([NSNumber numberWithInt:defaultsNewTweetKey] != nil) { + + if ([defaults objectForKey:@"newTweetKey"] != nil) { newTweetKey = defaultsNewTweetKey; } else { [defaults setInteger:newTweetKey forKey:@"newTweetKey"]; } NSInteger defaultsNewTweetModifierKey = (NSInteger)[defaults integerForKey:@"newTweetModifierKey"]; - if ([NSNumber numberWithInt:defaultsNewTweetModifierKey] != nil) { + if ([defaults objectForKey:@"newTweetModifierKey"] != nil) { newTweetModifierKey = defaultsNewTweetModifierKey; } else { [defaults setInteger:newTweetModifierKey forKey:@"newTweetModifierKey"]; } + [defaults synchronize]; + NSUInteger cocoaModifiers = 0; if (newTweetModifierKey & shiftKey) cocoaModifiers = cocoaModifiers | NSShiftKeyMask; if (newTweetModifierKey & optionKey) cocoaModifiers = cocoaModifiers | NSAlternateKeyMask; @@ -115,6 +122,8 @@ [mentionsView setPolicyDelegate:viewDelegate]; [mentionsView setUIDelegate:viewDelegate]; [[mentionsView windowScriptObject] setValue:self forKey:@"controller"]; + + [logoLayer removeFromSuperview]; } + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector { @@ -157,11 +166,16 @@ } - (IBAction)sendTweet:(id)sender { + + [oauth updateTweet:[[sender object] objectAtIndex:0] + inReplaToStatus:[[sender object] objectAtIndex:1]]; + /* NSString *encodedString = [[[sender object] objectAtIndex:0] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; [timelineView stringByEvaluatingJavaScriptFromString: [NSString stringWithFormat:@"twittia_instance.sendNewTweet(\"%@\", \"%@\")", [encodedString stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""], [[sender object] objectAtIndex:1]]]; + */ } - (NSString *)pluginURL { @@ -189,6 +203,11 @@ } } +- (void)getTweetUpdates:(id)sender { + [timelineView stringByEvaluatingJavaScriptFromString:@"twittia_instance.getNewData(true)"]; + [mentionsView stringByEvaluatingJavaScriptFromString:@"twittia_instance.getNewData(true)"]; +} + /* CARBON */ diff --git a/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib index fcf78f2..ab7eeaa 100644 --- a/English.lproj/MainMenu.xib +++ b/English.lproj/MainMenu.xib @@ -21,10 +21,10 @@ YES - + - + YES @@ -829,6 +829,43 @@ NO YES + + + 274 + + 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 + + + {{17, 17}, {363, 547}} + + YES + + 67239424 + 33554432 + + NSImage + Icon + + + LucidaGrande + 13 + 1044 + + 0 + 3 + 0 + NO + + YES + {397, 581} @@ -969,11 +1006,7 @@ 67239424 134217728 Ok - - LucidaGrande - 13 - 1044 - + -2038284033 129 @@ -1463,6 +1496,14 @@ 584 + + + logoLayer + + + + 589 + @@ -2052,6 +2093,7 @@ YES + @@ -2157,6 +2199,20 @@ + + 587 + + + YES + + + + + + 588 + + + @@ -2331,6 +2387,9 @@ 576.IBPluginDependency 58.IBPluginDependency 58.ImportedFromIB2 + 587.IBEditorWindowLastContentRect + 587.IBPluginDependency + 588.IBPluginDependency 72.IBPluginDependency 72.ImportedFromIB2 73.IBPluginDependency @@ -2486,18 +2545,18 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{152, 238}, {397, 581}} + {{202, 267}, {397, 581}} com.apple.InterfaceBuilder.CocoaPlugin - {{152, 238}, {397, 581}} + {{202, 267}, {397, 581}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.WebKitIBPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{226, 247}, {376, 581}} + {{602, 245}, {376, 581}} com.apple.InterfaceBuilder.CocoaPlugin - {{226, 247}, {376, 581}} + {{602, 245}, {376, 581}} com.apple.InterfaceBuilder.CocoaPlugin @@ -2518,6 +2577,9 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin + {{21, 1074}, {48, 48}} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -2552,7 +2614,7 @@ - 584 + 589 @@ -2569,6 +2631,7 @@ YES globalHotkeyMenuItem + logoLayer mentionsView mentionsViewWindow oauth @@ -2579,6 +2642,7 @@ YES NSMenuItem + NSImageView WebView NSWindow OAuth @@ -2790,6 +2854,22 @@ Foundation.framework/Headers/NSFormatter.h + + NSImageCell + NSCell + + IBFrameworkSource + AppKit.framework/Headers/NSImageCell.h + + + + NSImageView + NSControl + + IBFrameworkSource + AppKit.framework/Headers/NSImageView.h + + NSMatrix NSControl diff --git a/Icon.icns b/Icon.icns new file mode 100644 index 0000000..c365038 Binary files /dev/null and b/Icon.icns differ diff --git a/OAuth.h b/OAuth.h index 52f11a2..bde3d69 100644 --- a/OAuth.h +++ b/OAuth.h @@ -29,5 +29,7 @@ - (id)init; - (void)requestAToken; - (IBAction)requestAccessTokenWithPIN:(id)sender; +- (void)updateTweet:(NSString *)tweet inReplaToStatus:(NSString *)statusId; + @end diff --git a/OAuth.m b/OAuth.m index df2700e..b8c0f6c 100644 --- a/OAuth.m +++ b/OAuth.m @@ -30,6 +30,7 @@ if (self = [super init]) { self.consumerToken = [[OAToken alloc] initWithKey:OAUTH_CONSUMER_KEY secret:OAUTH_CONSUMER_SECRET]; self.accessToken = [[OAToken alloc] initWithUserDefaultsUsingServiceProviderName:OAUTH_SERVICE_NAME prefix:APP_NAME]; + consumer = [[OAConsumer alloc] initWithKey:OAUTH_CONSUMER_KEY secret:OAUTH_CONSUMER_SECRET]; } return self; @@ -49,7 +50,6 @@ } -(void)requestAToken { - consumer = [[OAConsumer alloc] initWithKey:OAUTH_CONSUMER_KEY secret:OAUTH_CONSUMER_SECRET]; NSURL *url = [NSURL URLWithString:OAUTH_REQUEST_TOKEN_URL]; @@ -102,39 +102,26 @@ [request setHTTPMethod:@"POST"]; - OADataFetcher *fetcher = [[OADataFetcher alloc] init]; [fetcher fetchDataWithRequest:request delegate:self didFinishSelector:@selector(accessTokenTicket:didFinishWithData:) - didFailSelector:@selector(requestTokenTicket:didFailWithError:)]; + didFailSelector:@selector(accessTokenTicket:didFailWithError:)]; } - (void)accessTokenTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data { + NSLog(@"%@", ticket); if (ticket.didSucceed) { NSString *responseBody = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - accessToken = [[OAToken alloc] initWithHTTPResponseBody:responseBody]; + + self.accessToken = [[OAToken alloc] initWithHTTPResponseBody:responseBody]; [accessToken storeInUserDefaultsWithServiceProviderName:OAUTH_SERVICE_NAME prefix:APP_NAME]; + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc postNotificationName:@"authentificationSucceded" object:self]; - - /* - NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/home_timeline.json"]; - OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url - consumer:consumer - token:accessToken - realm:nil - signatureProvider:nil]; - - OADataFetcher *fetcher = [[OADataFetcher alloc] init]; - [fetcher fetchDataWithRequest:request - delegate:self - didFinishSelector:@selector(apiTicket:didFinishWithData:) - didFailSelector:@selector(requestTokenTicket:didFailWithError:)]; - */ + [nc postNotificationName:@"authentificationSucceded" object:self]; } } @@ -146,6 +133,54 @@ } } +- (void)accessTokenTicket:(OAServiceTicket *)ticket didFailWithError:(NSError *)error { + NSLog(@"ERROR a: %@", error); + //[self requestAccessTokenWithPIN:self]; + //[twitterPINPanel makeKeyAndOrderFront:self]; + + //NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@?oauth_token=%@", OAUTH_USER_AUTHORIZATION_URL, requestToken.key]]; + //s[[NSWorkspace sharedWorkspace] openURL:url]; +} +- (void)updateTweet:(NSString *)tweet inReplaToStatus:(NSString *)statusId { + + NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/update.json"]; + OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:url + consumer:consumer + token:accessToken + realm:nil + signatureProvider:nil]; + + OARequestParameter *source = [[OARequestParameter alloc] initWithName:@"source" value:@"twittia"]; + OARequestParameter *status = [[OARequestParameter alloc] initWithName:@"status" value:tweet]; + + NSMutableArray *params = [NSMutableArray arrayWithObjects:source, status, nil]; + + if (statusId) { + OARequestParameter *reply = [[OARequestParameter alloc] initWithName:@"in_reply_to_status_id" value:statusId]; + [params addObject:reply]; + } + + [request setHTTPMethod:@"POST"]; + [request setParameters:params]; + + OADataFetcher *fetcher = [[OADataFetcher alloc] init]; + [fetcher fetchDataWithRequest:request + delegate:self + didFinishSelector:@selector(updateTweetTicket:didFinishWithData:) + didFailSelector:@selector(updateTweetTokenTicket:didFailWithError:)]; +} + +- (void)updateTweetTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data { + if (ticket.didSucceed) { + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc postNotificationName:@"getTweetUpdates" object:self]; + + } +} + +- (void)updateTweetTokenTicket:(OAServiceTicket *)ticket didFailWithError:(NSError *)error { + NSLog(@"ERROR update tweet: %@", error); +} @end diff --git a/Twittia 2.xcodeproj/project.pbxproj b/Twittia 2.xcodeproj/project.pbxproj index d042456..736e97e 100644 --- a/Twittia 2.xcodeproj/project.pbxproj +++ b/Twittia 2.xcodeproj/project.pbxproj @@ -9,11 +9,12 @@ /* Begin PBXBuildFile section */ 1DDD582C0DA1D0D100B32029 /* MyDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58280DA1D0D100B32029 /* MyDocument.xib */; }; 1DDD582D0DA1D0D100B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD582A0DA1D0D100B32029 /* MainMenu.xib */; }; + 1F122D49118E1DE100E83B77 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1F122D48118E1DE100E83B77 /* Icon.icns */; }; 1F1990C6117BCA960049BEA7 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F1990C5117BCA960049BEA7 /* ApplicationServices.framework */; }; 1F3642EF118C8C35008198EF /* oauth.js in Resources */ = {isa = PBXBuildFile; fileRef = 1F3642ED118C8C35008198EF /* oauth.js */; }; 1F3642F0118C8C35008198EF /* sha1.js in Resources */ = {isa = PBXBuildFile; fileRef = 1F3642EE118C8C35008198EF /* sha1.js */; }; 1F364398118CBC77008198EF /* OAuth.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F364397118CBC77008198EF /* OAuth.m */; }; - 1F36440F118CC173008198EF /* OAuthConsumer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F36440E118CC173008198EF /* OAuthConsumer.framework */; }; + 1F36440F118CC173008198EF /* OAuthConsumer.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1F36440E118CC173008198EF /* OAuthConsumer.framework */; }; 1F36465E118DA5A7008198EF /* OAToken+WebView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F36465D118DA5A7008198EF /* OAToken+WebView.m */; }; 1F4673FE1180F7EA006CC37C /* TwittiaCore.js in Resources */ = {isa = PBXBuildFile; fileRef = 1F4673E61180F654006CC37C /* TwittiaCore.js */; }; 1F4674081180F7EE006CC37C /* jQuery.js in Resources */ = {isa = PBXBuildFile; fileRef = 1F4673E21180F519006CC37C /* jQuery.js */; }; @@ -21,6 +22,7 @@ 1F705EA6117889FA00C85707 /* sprite-icons.png in Resources */ = {isa = PBXBuildFile; fileRef = 1F705EA5117889FA00C85707 /* sprite-icons.png */; }; 1F70619F1178FBB300C85707 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F70619E1178FBB300C85707 /* Carbon.framework */; }; 1F77DB47118C5F1C007C7F1E /* Constants.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F77DB46118C5F1C007C7F1E /* Constants.m */; }; + 1FB074DD118DDAB60013A93C /* OAuthConsumer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F36440E118CC173008198EF /* OAuthConsumer.framework */; }; 1FE2FC93117A818D000504B0 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1FE2FC92117A818D000504B0 /* Sparkle.framework */; }; 1FE2FCA4117A83B1000504B0 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1FE2FC92117A818D000504B0 /* Sparkle.framework */; }; 1FFA36CD1177D861006C8562 /* even-bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 1FFA36C81177D861006C8562 /* even-bg.png */; }; @@ -44,6 +46,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + 1F36440F118CC173008198EF /* OAuthConsumer.framework in CopyFiles */, 1FE2FCA4117A83B1000504B0 /* Sparkle.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; @@ -56,6 +59,7 @@ 13E42FBA07B3F13500E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; 1DDD58290DA1D0D100B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MyDocument.xib; sourceTree = ""; }; 1DDD582B0DA1D0D100B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; }; + 1F122D48118E1DE100E83B77 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = ""; }; 1F198FC7117BC4AB0049BEA7 /* README.markdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.markdown; sourceTree = ""; }; 1F1990C5117BCA960049BEA7 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; }; 1F1990DF117BD2250049BEA7 /* Appcast.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Appcast.xml; sourceTree = ""; }; @@ -101,7 +105,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 1F36440F118CC173008198EF /* OAuthConsumer.framework in Frameworks */, + 1FB074DD118DDAB60013A93C /* OAuthConsumer.framework in Frameworks */, 8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */, 1FFA37071177DAF4006C8562 /* WebKit.framework in Frameworks */, 1F70619F1178FBB300C85707 /* Carbon.framework in Frameworks */, @@ -204,6 +208,7 @@ 2A37F4B8FDCFA73011CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 1F122D48118E1DE100E83B77 /* Icon.icns */, 1F1990DF117BD2250049BEA7 /* Appcast.xml */, 1F198FC7117BC4AB0049BEA7 /* README.markdown */, 1FE2FCA6117A8952000504B0 /* dsa_pub.pem */, @@ -285,6 +290,7 @@ 1F4674081180F7EE006CC37C /* jQuery.js in Resources */, 1FFA36D01177D861006C8562 /* default.css in Resources */, 1F705EA6117889FA00C85707 /* sprite-icons.png in Resources */, + 1F122D49118E1DE100E83B77 /* Icon.icns in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/TwittiaCore.js b/TwittiaCore.js index b6be94f..d873db3 100644 --- a/TwittiaCore.js +++ b/TwittiaCore.js @@ -212,18 +212,19 @@ Twittia.prototype.getNewData = function(supress_new_with_timeout) { }); } +/* Twittia.prototype.sendNewTweet = function(tweet, in_reply_to_status_id) { var url = "http://api.twitter.com/1/statuses/update.json"; - var data = "source=twittia&status=" + tweet; + var data = "source=twittia&status=" + OAuth.percentEncode(tweet); if(in_reply_to_status_id != '') data += "&in_reply_to_status_id=" + in_reply_to_status_id var parameters = { source: "twittia", status: tweet }; - if(in_reply_to_status_id != '') parameters.in_reply_to_status_id = in_reply_to_status_id + if(in_reply_to_status_id != '') parameters.in_reply_to_status_id = in_reply_to_status_id; var _this = this; - var message = { method:"POST" , action:url, parameters: parameters }; + var message = { method:"POST" , action:url, parameters:parameters }; OAuth.completeRequest(message, { consumerKey : controller.oauth.consumerToken.key @@ -249,12 +250,25 @@ Twittia.prototype.sendNewTweet = function(tweet, in_reply_to_status_id) { } }); } +*/ Twittia.prototype.retweet = function(status_id, item) { var url = "http://api.twitter.com/1/statuses/retweet/" + status_id + ".json"; var _this = this; + + var message = { method:"POST" , action:url }; + + OAuth.completeRequest(message, + { consumerKey : controller.oauth.consumerToken.key + , consumerSecret: controller.oauth.consumerToken.secret + , token : controller.oauth.accessToken.key + , tokenSecret : controller.oauth.accessToken.secret + }); $.ajax({ + beforeSend: function(xhr) { + xhr.setRequestHeader("Authorization", OAuth.getAuthorizationHeader("", message.parameters)); + }, url: url, type: 'POST', dataType: 'json', diff --git a/Twittia_2-Info.plist b/Twittia_2-Info.plist index a212f6e..ba1ed85 100644 --- a/Twittia_2-Info.plist +++ b/Twittia_2-Info.plist @@ -28,7 +28,7 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIconFile - + Icon.icns CFBundleIdentifier net.jeena.apps.twittia CFBundleInfoDictionaryVersion