diff --git a/.gitignore b/.gitignore
index 88dff742..f87813e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@
*.perspective
*.perspectivev3
*.mode1v3
+*.xcworkspace
+*xcuserdata
build
.DS_Store
Classes/ShareKit/SHKConfig.h
diff --git a/Classes/ShareKit/Core/SHKSharers.plist b/Classes/ShareKit/Core/SHKSharers.plist
index db686302..84e8201f 100644
--- a/Classes/ShareKit/Core/SHKSharers.plist
+++ b/Classes/ShareKit/Core/SHKSharers.plist
@@ -21,6 +21,7 @@
SHKReadItLater
SHKInstapaper
SHKTumblr
+ SHKTwitPic
diff --git a/Classes/ShareKit/Localization/de.lproj/Localizable.strings b/Classes/ShareKit/Localization/de.lproj/Localizable.strings
index bb36dab7..80e851a0 100644
--- a/Classes/ShareKit/Localization/de.lproj/Localizable.strings
+++ b/Classes/ShareKit/Localization/de.lproj/Localizable.strings
@@ -40,6 +40,7 @@
"Create an account at %@" = "Erstelle einen Account auf %@";
"Send to Twitter" = "An Twitter senden";
+"Send to TwitPic" = "An TwitPic senden";
"Message is too long" = "Nachricht zu lang";
"Twitter posts can only be 140 characters in length." = "Twitter Nachrichten können maximal 140 Zeichen lang sein.";
diff --git a/Classes/ShareKit/Localization/en.lproj/Localizable.strings b/Classes/ShareKit/Localization/en.lproj/Localizable.strings
index cf945769..89b1aabd 100644
--- a/Classes/ShareKit/Localization/en.lproj/Localizable.strings
+++ b/Classes/ShareKit/Localization/en.lproj/Localizable.strings
@@ -40,6 +40,7 @@
"Create an account at %@" = "Create an account at %@";
"Send to Twitter" = "Send to Twitter";
+"Send to TwitPic" = "Send to TwitPic";
"Message is too long" = "Message is too long";
"Twitter posts can only be 140 characters in length." = "Twitter posts can only be 140 characters in length.";
diff --git a/Classes/ShareKit/Localization/fr.lproj/Localizable.strings b/Classes/ShareKit/Localization/fr.lproj/Localizable.strings
index a64249b3..70613724 100644
--- a/Classes/ShareKit/Localization/fr.lproj/Localizable.strings
+++ b/Classes/ShareKit/Localization/fr.lproj/Localizable.strings
@@ -40,6 +40,7 @@
"Create an account at %@" = "Créer un compte sur %@";
"Send to Twitter" = "Envoyer sur Twitter";
+"Send to TwitPic" = "Envoyer sur TwitPic";
"Message is too long" = "Message trop long";
"Twitter posts can only be 140 characters in length." = "Les messages Twitter ne peuvent dépasser 140 caractères.";
diff --git a/Classes/ShareKit/Localization/ko.lproj/Localizable.strings b/Classes/ShareKit/Localization/ko.lproj/Localizable.strings
index c565c797..49af23d4 100644
--- a/Classes/ShareKit/Localization/ko.lproj/Localizable.strings
+++ b/Classes/ShareKit/Localization/ko.lproj/Localizable.strings
@@ -40,6 +40,7 @@
"Create an account at %@" = "%@ 계정 만들기";
"Send to Twitter" = "Twitter로 보내기";
+"Send to TwitPic" = "TwitPic로 보내기";
"Message is too long" = "메시지가 너무 깁니다";
"Twitter posts can only be 140 characters in length." = "Twitter 메시지는 140자를 넘을 수 없습니다.";
diff --git a/Classes/ShareKit/Localization/nl.lproj/Localizable.strings b/Classes/ShareKit/Localization/nl.lproj/Localizable.strings
index e93eb30b..aab582e5 100644
--- a/Classes/ShareKit/Localization/nl.lproj/Localizable.strings
+++ b/Classes/ShareKit/Localization/nl.lproj/Localizable.strings
@@ -40,6 +40,7 @@
"Create an account at %@" = "Maak een account op %@";
"Send to Twitter" = "Verzend naar Twitter";
+"Send to TwitPic" = "Verzend naar TwitPic";
"Message is too long" = "Bericht is te lang";
"Twitter posts can only be 140 characters in length." = "Twitter bericht mag maar 140 karakters bevatten.";
diff --git a/Classes/ShareKit/Localization/vi.lproj/Localizable.strings b/Classes/ShareKit/Localization/vi.lproj/Localizable.strings
index 0b9d66d6..17268e80 100644
Binary files a/Classes/ShareKit/Localization/vi.lproj/Localizable.strings and b/Classes/ShareKit/Localization/vi.lproj/Localizable.strings differ
diff --git a/Classes/ShareKit/Localization/zh_CN.lproj/Localizable.strings b/Classes/ShareKit/Localization/zh_CN.lproj/Localizable.strings
index b3b6eb56..03175b87 100644
--- a/Classes/ShareKit/Localization/zh_CN.lproj/Localizable.strings
+++ b/Classes/ShareKit/Localization/zh_CN.lproj/Localizable.strings
@@ -41,6 +41,7 @@
"Create an account at %@" = "在 %@ 上创建一个账户";
"Send to Twitter" = "发送到 Twitter";
+"Send to TwitPic" = "发送到 TwitPic";
"Message is too long" = "消息太长了";
"Twitter posts can only be 140 characters in length." = "Twitter 消息不能超过 140 个字符。";
diff --git a/Classes/ShareKit/SHKConfig.h b/Classes/ShareKit/SHKConfig.h
index c2aa3565..9bc66a23 100644
--- a/Classes/ShareKit/SHKConfig.h
+++ b/Classes/ShareKit/SHKConfig.h
@@ -79,13 +79,20 @@
#define SHKBitLyLogin @""
#define SHKBitLyKey @""
+// Evernote http://www.evernote.com/about/developer/api/
+#define SHKEvernoteConsumerKey @""
+#define SHKEvernoteSecretKey @""
+#define SHKEvernoteUserStoreURL @""
+#define SHKEvernoteNetStoreURLBase @""
+
// ShareMenu Ordering
#define SHKShareMenuAlphabeticalOrder 1 // Setting this to 1 will show list in Alphabetical Order, setting to 0 will follow the order in SHKShares.plist
// Append 'Shared With 'Signature to Email (and related forms)
#define SHKSharedWithSignature 0
-
+// TwitPic http://dev.twitpic.com/
+#define SHKTwitPicAPIKey @""
/*
UI Configuration : Basic
diff --git a/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPic.h b/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPic.h
new file mode 100644
index 00000000..90d4f6ba
--- /dev/null
+++ b/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPic.h
@@ -0,0 +1,44 @@
+//
+// SHKTwitPic.h
+// ShareKit
+//
+// Created by David Linsin on 2/5/11.
+// Copyright 2011 furryfishApps.com. All rights reserved.
+//
+
+#import
+#import "SHKOAuthSharer.h"
+#import "SHKTwitPicForm.h"
+
+@interface SHKTwitPic : SHKOAuthSharer {
+ NSString *twitPicAPIKey;
+}
+
+@property (nonatomic, retain) NSString *twitPicAPIKey;
+
+#pragma mark -
+#pragma mark UI Implementation
+
+- (void)showTwitterForm;
+
+#pragma mark -
+#pragma mark Share API Methods
+
+- (void)sendForm:(SHKTwitPicForm *)form;
+
+- (void)sendImage;
+- (void)sendImage:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data;
+- (void)sendImage:(OAServiceTicket *)ticket didFailWithError:(NSError*)error;
+
+- (void)sendStatus:(NSString*)status;
+- (void)sendStatusTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data;
+- (void)sendStatusTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error;
+
+#pragma mark -
+#pragma mark twitpic specific
+
+- (BOOL)shareOnTwitter;
+- (void)setShareOnTwitter:(BOOL)share;
+
+
+@end
diff --git a/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPic.m b/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPic.m
new file mode 100644
index 00000000..a6419a32
--- /dev/null
+++ b/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPic.m
@@ -0,0 +1,340 @@
+//
+// SHKTwitPic.m
+// ShareKit
+//
+// Created by David Linsin on 2/5/11.
+// Copyright 2011 furryfishApps.com. All rights reserved.
+//
+
+#import "SHKTwitPic.h"
+
+
+@implementation SHKTwitPic
+
+@synthesize twitPicAPIKey;
+
+- (id)init {
+ self = [super init];
+ if (self) {
+ // OAUTH
+ self.consumerKey = SHKTwitterConsumerKey;
+ self.secretKey = SHKTwitterSecret;
+ self.authorizeCallbackURL = [NSURL URLWithString:SHKTwitterCallbackUrl];// HOW-TO: In your Twitter application settings, use the "Callback URL" field. If you do not have this field in the settings, set your application type to 'Browser'.
+
+
+ // You do not need to edit these, they are the same for everyone
+ self.authorizeURL = [NSURL URLWithString:@"https://twitter.com/oauth/authorize"];
+ self.requestURL = [NSURL URLWithString:@"https://twitter.com/oauth/request_token"];
+ self.accessURL = [NSURL URLWithString:@"https://twitter.com/oauth/access_token"];
+
+ self.twitPicAPIKey = SHKTwitPicAPIKey;
+ }
+ return self;
+}
+
+
+#pragma mark -
+#pragma mark Configuration : Service Defination
+
++ (NSString *)sharerTitle {
+ return @"TwitPic";
+}
+
++ (BOOL)canShareImage {
+ return YES;
+}
+
+
+#pragma mark -
+#pragma mark Configuration : Dynamic Enable
+
+- (BOOL)shouldAutoShare {
+ return NO;
+}
+
+
+#pragma mark -
+#pragma mark Authorization
+
+- (BOOL)isAuthorized {
+ return [super restoreAccessToken];
+}
+
+- (void)promptAuthorization {
+ [super authorizationFormShow];
+}
+
+
+#pragma mark xAuth
+
++ (NSString *)authorizationFormCaption {
+ return SHKLocalizedString(@"Create a free account at %@", @"Twitter.com");
+}
+
++ (NSArray *)authorizationFormFields {
+ if ([SHKTwitterUsername isEqualToString:@""])
+ return [super authorizationFormFields];
+
+ return [NSArray arrayWithObjects:
+ [SHKFormFieldSettings label:SHKLocalizedString(@"Username") key:@"username" type:SHKFormFieldTypeText start:nil],
+ [SHKFormFieldSettings label:SHKLocalizedString(@"Password") key:@"password" type:SHKFormFieldTypePassword start:nil],
+ [SHKFormFieldSettings label:SHKLocalizedString(@"Send to Twitter") key:@"sendToTwitter" type:SHKFormFieldTypeSwitch start:SHKFormFieldSwitchOn],
+ nil];
+}
+
+- (void)authorizationFormValidate:(SHKFormController *)form {
+ self.pendingForm = form;
+ [self tokenAccess];
+}
+
+- (void)tokenAccessModifyRequest:(OAMutableURLRequest *)oRequest {
+ NSDictionary *formValues = [pendingForm formValues];
+ OARequestParameter *username = [[[OARequestParameter alloc] initWithName:@"x_auth_username"
+ value:[formValues objectForKey:@"username"]] autorelease];
+
+ OARequestParameter *password = [[[OARequestParameter alloc] initWithName:@"x_auth_password"
+ value:[formValues objectForKey:@"password"]] autorelease];
+
+ OARequestParameter *mode = [[[OARequestParameter alloc] initWithName:@"x_auth_mode"
+ value:@"client_auth"] autorelease];
+
+ [oRequest setParameters:[NSArray arrayWithObjects:username, password, mode, nil]];
+}
+
+- (void)tokenAccessTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data {
+ if (ticket.didSucceed) {
+ [self setShareOnTwitter:[[[super.pendingForm formValues] objectForKey:@"sendToTwitter"] isEqualToString:SHKFormFieldSwitchOn]];
+ [pendingForm close];
+ } else {
+ NSString *response = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
+
+ SHKLog(@"tokenAccessTicket Response Body: %@", response);
+
+ [self tokenAccessTicket:ticket didFailWithError:[SHK error:response]];
+ return;
+ }
+
+ [super tokenAccessTicket:ticket didFinishWithData:data];
+}
+
+#pragma mark -
+#pragma mark UI Implementation
+
+- (void)show {
+ [item setCustomValue:item.title forKey:@"status"];
+ [self showTwitterForm];
+}
+
+- (void)showTwitterForm {
+ SHKTwitPicForm *rootView = [[SHKTwitPicForm alloc] initWithNibName:nil bundle:nil];
+ rootView.delegate = self;
+
+ // force view to load so we can set textView text
+ [rootView view];
+
+ rootView.textView.text = [item customValueForKey:@"status"];
+ rootView.hasAttachment = YES;
+
+ [self pushViewController:rootView animated:NO];
+
+ [[SHK currentHelper] showViewController:self];
+}
+
+- (void)sendForm:(SHKTwitPicForm *)form {
+ [item setCustomValue:form.textView.text forKey:@"status"];
+ [self tryToSend];
+}
+
+#pragma mark -
+#pragma mark Share API Methods
+
+- (BOOL)validate {
+ NSString *status = [item customValueForKey:@"status"];
+ return status != nil && (int)status.length >= 0 && status.length <= 140;
+}
+
+- (BOOL)send {
+ if (![self validate]) {
+ [self show];
+ } else {
+ [self sendImage];
+ [self sendDidStart];
+ return YES;
+ }
+ return NO;
+}
+
+- (NSString*)oauthHeader {
+ NSURL *serviceURL = [NSURL URLWithString:@"https://api.twitter.com/1/account/verify_credentials.json"];
+
+ OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:serviceURL
+ consumer:consumer
+ token:accessToken
+ realm:@"http://api.twitter.com/"
+ signatureProvider:signatureProvider];
+ [oRequest prepare];
+
+ NSDictionary * headerDict = [oRequest allHTTPHeaderFields];
+ NSString * oauthHeader = [NSString stringWithString:[headerDict valueForKey:@"Authorization"]];
+
+ [oRequest release];
+ oRequest = nil;
+ return oauthHeader;
+}
+
+- (NSData*)imageData {
+ CGFloat compression = 0.9f;
+ NSData *imageData = UIImageJPEGRepresentation([item image], compression);
+
+ // TODO
+ // Note from Nate to creator of sendImage method - This seems like it could be a source of sluggishness.
+ // For example, if the image is large (say 3000px x 3000px for example), it would be better to resize the image
+ // to an appropriate size (max of img.ly) and then start trying to compress.
+
+ while ([imageData length] > 700000 && compression > 0.1) {
+ // NSLog(@"Image size too big, compression more: current data size: %d bytes",[imageData length]);
+ compression -= 0.1;
+ imageData = UIImageJPEGRepresentation([item image], compression);
+
+ }
+ return imageData;
+}
+
+- (void)sendImage {
+ NSString * oauthHeader = [self oauthHeader];
+
+ NSURL *serviceURL = [NSURL URLWithString:@"http://api.twitpic.com/2/upload.json"];
+ OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:serviceURL
+ consumer:consumer
+ token:accessToken
+ realm:@"http://api.twitter.com/"
+ signatureProvider:signatureProvider];
+
+ // NASTY workaround to prevent Authorization HTTP header field to be set later on, TwitPic doesn't like it
+ [oRequest prepare];
+ [oRequest setValue:nil forHTTPHeaderField:@"Authorization"];
+ // END NASTY workaround
+
+ [oRequest setHTTPMethod:@"POST"];
+ [oRequest setValue:@"https://api.twitter.com/1/account/verify_credentials.json" forHTTPHeaderField:@"X-Auth-Service-Provider"];
+ [oRequest setValue:oauthHeader forHTTPHeaderField:@"X-Verify-Credentials-Authorization"];
+
+
+ NSString *boundary = @"0xKhTmLbOuNdArY";
+ NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
+ [oRequest setValue:contentType forHTTPHeaderField:@"Content-Type"];
+
+ NSMutableData *body = [NSMutableData data];
+
+ [body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+ [body appendData:[@"Content-Disposition: form-data; name=\"key\"\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
+ [body appendData:[self.twitPicAPIKey dataUsingEncoding:NSUTF8StringEncoding]];
+ [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
+
+ [body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+ [body appendData:[@"Content-Disposition: form-data; name=\"media\"; filename=\"upload.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
+ [body appendData:[@"Content-Type: image/jpg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
+ [body appendData:[self imageData]];
+ [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
+
+ [body appendData:[[NSString stringWithFormat:@"--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+ [body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"message\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
+ [body appendData:[[item customValueForKey:@"status"] dataUsingEncoding:NSUTF8StringEncoding]];
+ [body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
+
+ [body appendData:[[NSString stringWithFormat:@"--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
+
+ [oRequest setHTTPBody:body];
+
+ [self sendDidStart];
+
+ // Start the request
+ OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest
+ delegate:self
+ didFinishSelector:@selector(sendImage:didFinishWithData:)
+ didFailSelector:@selector(sendImage:didFailWithError:)];
+
+ [fetcher start];
+
+
+ [oRequest release];
+}
+
+- (void)sendImage:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data {
+ if (ticket.didSucceed) {
+ if ([self shareOnTwitter]) {
+ NSString *url = @"";
+ NSScanner *scanner = [NSScanner scannerWithString:[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]];
+ [scanner scanUpToString:@"\"url\":\"" intoString:nil];
+
+ if ([scanner scanString:@"\"url\":\"" intoString:nil]) {
+ [scanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"\""] intoString:&url];
+ url = [url stringByReplacingOccurrencesOfString:@"\\" withString:@""];
+ NSString *twitPicStatus = [NSString stringWithFormat:@"%@ %@", [item customValueForKey:@"status"], url];
+ [self sendStatus: twitPicStatus];
+ } else {
+ [self sendDidFailWithError:nil];
+ }
+ } else {
+ [self sendDidFinish];
+ }
+ } else {
+ [self sendDidFailWithError:nil];
+ }
+}
+
+- (void)sendImage:(OAServiceTicket *)ticket didFailWithError:(NSError*)error {
+ [self sendDidFailWithError:error];
+}
+
+- (void)sendStatus:(NSString*)status {
+ OAMutableURLRequest *oRequest = [[OAMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://api.twitter.com/1/statuses/update.json"]
+ consumer:consumer
+ token:accessToken
+ realm:nil
+ signatureProvider:nil];
+
+ [oRequest setHTTPMethod:@"POST"];
+
+ OARequestParameter *statusParam = [[OARequestParameter alloc] initWithName:@"status" value:status];
+ NSArray *params = [NSArray arrayWithObjects:statusParam, nil];
+ [oRequest setParameters:params];
+ [statusParam release];
+
+ OAAsynchronousDataFetcher *fetcher = [OAAsynchronousDataFetcher asynchronousFetcherWithRequest:oRequest
+ delegate:self
+ didFinishSelector:@selector(sendStatusTicket:didFinishWithData:)
+ didFailSelector:@selector(sendStatusTicket:didFailWithError:)];
+
+ [fetcher start];
+ [oRequest release];
+}
+
+- (void)sendStatusTicket:(OAServiceTicket *)ticket didFinishWithData:(NSData *)data {
+
+ if (ticket.didSucceed) {
+ [self sendDidFinish];
+ } else {
+ NSString *string = @"Your picture is on TwitPic, but we couldn't share it on Twitter!";
+ NSError *error = [NSError errorWithDomain:@"Twitter" code:2 userInfo:[NSDictionary dictionaryWithObject:string forKey:NSLocalizedDescriptionKey]];
+ [self sendDidFailWithError:error];
+ }
+
+}
+
+- (void)sendStatusTicket:(OAServiceTicket *)ticket didFailWithError:(NSError*)error {
+ [self sendDidFailWithError:error];
+}
+
+#pragma mark -
+#pragma mark twitpic specific
+
+- (BOOL)shareOnTwitter {
+ return [[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithFormat:@"%@_shareOnTwitter", [self sharerId]]];
+}
+
+- (void)setShareOnTwitter:(BOOL)share {
+ [[NSUserDefaults standardUserDefaults] setBool:share forKey:[NSString stringWithFormat:@"%@_shareOnTwitter", [self sharerId]]];
+}
+
+@end
diff --git a/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPicForm.h b/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPicForm.h
new file mode 100644
index 00000000..302251c4
--- /dev/null
+++ b/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPicForm.h
@@ -0,0 +1,49 @@
+//
+// SHKTwitPicForm.h
+// ShareKit
+//
+// Created by Nathan Weiner on 6/22/10.
+// Adapted by David Linsin on 2/8/11 to support TwitPic.
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+
+#import
+
+
+@interface SHKTwitPicForm : UIViewController
+{
+ id delegate;
+ UITextView *textView;
+ UILabel *counter;
+ BOOL hasAttachment;
+}
+
+@property (nonatomic, retain) id delegate;
+@property (nonatomic, retain) UITextView *textView;
+@property (nonatomic, retain) UILabel *counter;
+@property BOOL hasAttachment;
+
+- (void)layoutCounter;
+- (void)save;
+- (void)keyboardWillShow:(NSNotification *)notification;
+
+@end
diff --git a/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPicForm.m b/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPicForm.m
new file mode 100644
index 00000000..6b3ac20d
--- /dev/null
+++ b/Classes/ShareKit/Sharers/Services/TwitPic/SHKTwitPicForm.m
@@ -0,0 +1,239 @@
+//
+// SHKTwitPicForm.m
+// ShareKit
+//
+// Created by Nathan Weiner on 6/22/10.
+// Adapted by David Linsin on 2/8/11 to support TwitPic.
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+
+#import "SHKTwitPicForm.h"
+#import "SHK.h"
+#import "SHKTwitPic.h"
+
+
+@implementation SHKTwitPicForm
+
+@synthesize delegate;
+@synthesize textView;
+@synthesize counter;
+@synthesize hasAttachment;
+
+- (void)dealloc
+{
+ [delegate release];
+ [textView release];
+ [counter release];
+ [super dealloc];
+}
+
+- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
+ {
+ self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
+ target:self
+ action:@selector(cancel)];
+
+ self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:SHKLocalizedString(@"Send to TwitPic")
+ style:UIBarButtonItemStyleDone
+ target:self
+ action:@selector(save)];
+ }
+ return self;
+}
+
+
+
+- (void)loadView
+{
+ [super loadView];
+
+ self.view.backgroundColor = [UIColor whiteColor];
+
+ self.textView = [[UITextView alloc] initWithFrame:self.view.bounds];
+ textView.delegate = self;
+ textView.font = [UIFont systemFontOfSize:15];
+ textView.contentInset = UIEdgeInsetsMake(5,5,0,0);
+ textView.backgroundColor = [UIColor whiteColor];
+ textView.autoresizesSubviews = YES;
+ textView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+
+ [self.view addSubview:textView];
+}
+
+- (void)viewDidAppear:(BOOL)animated
+{
+ [super viewDidAppear:animated];
+
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+ [nc addObserver:self selector:@selector(keyboardWillShow:) name: UIKeyboardWillShowNotification object:nil];
+
+ [self.textView becomeFirstResponder];
+}
+
+- (void)viewDidDisappear:(BOOL)animated
+{
+ [super viewDidDisappear:animated];
+
+ // Remove observers
+ NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
+ [nc removeObserver:self name: UIKeyboardWillShowNotification object:nil];
+
+ // Remove the SHK view wrapper from the window
+ [[SHK currentHelper] viewWasDismissed];
+}
+
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
+{
+ return YES;
+}
+
+//#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+- (void)keyboardWillShow:(NSNotification *)notification
+{
+ CGRect keyboardFrame;
+ CGFloat keyboardHeight;
+
+ // 3.2 and above
+ /*if (UIKeyboardFrameEndUserInfoKey)
+ {
+ [[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrame];
+ if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown)
+ keyboardHeight = keyboardFrame.size.height;
+ else
+ keyboardHeight = keyboardFrame.size.width;
+ }
+
+ // < 3.2
+ else
+ {*/
+
+ [[notification.userInfo valueForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame];
+ keyboardHeight = keyboardFrame.size.height;
+ //}
+
+ // Find the bottom of the screen (accounting for keyboard overlay)
+ // This is pretty much only for pagesheet's on the iPad
+ UIInterfaceOrientation orient = [[UIApplication sharedApplication] statusBarOrientation];
+ BOOL inLandscape = orient == UIInterfaceOrientationLandscapeLeft || orient == UIInterfaceOrientationLandscapeRight;
+ BOOL upsideDown = orient == UIInterfaceOrientationPortraitUpsideDown || orient == UIInterfaceOrientationLandscapeRight;
+
+ CGPoint topOfViewPoint = [self.view convertPoint:CGPointZero toView:nil];
+ CGFloat topOfView = inLandscape ? topOfViewPoint.x : topOfViewPoint.y;
+
+ CGFloat screenHeight = inLandscape ? [[UIScreen mainScreen] applicationFrame].size.width : [[UIScreen mainScreen] applicationFrame].size.height;
+
+ CGFloat distFromBottom = screenHeight - ((upsideDown ? screenHeight - topOfView : topOfView ) + self.view.bounds.size.height) + ([UIApplication sharedApplication].statusBarHidden || upsideDown ? 0 : 20);
+ CGFloat maxViewHeight = self.view.bounds.size.height - keyboardHeight + distFromBottom;
+
+ textView.frame = CGRectMake(0,0,self.view.bounds.size.width,maxViewHeight);
+ [self layoutCounter];
+}
+//#pragma GCC diagnostic pop
+
+#pragma mark -
+
+- (void)updateCounter
+{
+ if (counter == nil)
+ {
+ self.counter = [[UILabel alloc] initWithFrame:CGRectZero];
+ counter.backgroundColor = [UIColor clearColor];
+ counter.opaque = NO;
+ counter.font = [UIFont boldSystemFontOfSize:14];
+ counter.textAlignment = UITextAlignmentRight;
+
+ counter.autoresizesSubviews = YES;
+ counter.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
+
+ [self.view addSubview:counter];
+ [self layoutCounter];
+
+ [counter release];
+ }
+
+ int count = (hasAttachment?115:140) - textView.text.length;
+ counter.text = [NSString stringWithFormat:@"%@%i", hasAttachment ? @"Image + ":@"" , count];
+ counter.textColor = count >= 0 ? [UIColor blackColor] : [UIColor redColor];
+}
+
+- (void)layoutCounter
+{
+ counter.frame = CGRectMake(textView.bounds.size.width-150-15,
+ textView.bounds.size.height-15-9,
+ 150,
+ 15);
+}
+
+- (void)textViewDidBeginEditing:(UITextView *)textView
+{
+ [self updateCounter];
+}
+
+- (void)textViewDidChange:(UITextView *)textView
+{
+ [self updateCounter];
+}
+
+- (void)textViewDidEndEditing:(UITextView *)textView
+{
+ [self updateCounter];
+}
+
+#pragma mark -
+
+- (void)cancel
+{
+ [[SHK currentHelper] hideCurrentViewControllerAnimated:YES];
+ [(SHKTwitPic *)delegate sendDidCancel];
+}
+
+- (void)save
+{
+ if (textView.text.length > (hasAttachment?115:140))
+ {
+ [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Message is too long")
+ message:SHKLocalizedString(@"Twitter posts can only be 140 characters in length.")
+ delegate:nil
+ cancelButtonTitle:SHKLocalizedString(@"Close")
+ otherButtonTitles:nil] autorelease] show];
+ return;
+ }
+
+ else if (textView.text.length == 0)
+ {
+ [[[[UIAlertView alloc] initWithTitle:SHKLocalizedString(@"Message is empty")
+ message:SHKLocalizedString(@"You must enter a message in order to post.")
+ delegate:nil
+ cancelButtonTitle:SHKLocalizedString(@"Close")
+ otherButtonTitles:nil] autorelease] show];
+ return;
+ }
+
+ [(SHKTwitPic *)delegate sendForm:self];
+
+ [[SHK currentHelper] hideCurrentViewControllerAnimated:YES];
+}
+
+@end
diff --git a/Classes/ShareKit/UI/SHKShareMenu.m b/Classes/ShareKit/UI/SHKShareMenu.m
index a496a112..0475a320 100644
--- a/Classes/ShareKit/UI/SHKShareMenu.m
+++ b/Classes/ShareKit/UI/SHKShareMenu.m
@@ -250,9 +250,10 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UISwitch *toggle = (UISwitch *)[cell editingAccessoryView];
- [toggle setOn:!toggle.on animated:YES];
+ BOOL newOn = !toggle.on;
+ [toggle setOn:newOn animated:YES];
- if (toggle.on)
+ if (newOn)
[exclusions removeObjectForKey:[rowData objectForKey:@"className"]];
else
diff --git a/ShareKit.xcodeproj/project.pbxproj b/ShareKit.xcodeproj/project.pbxproj
index adcbf90e..2abfb2e2 100755
--- a/ShareKit.xcodeproj/project.pbxproj
+++ b/ShareKit.xcodeproj/project.pbxproj
@@ -106,6 +106,8 @@
43D1DEF011D5CDD200550D75 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43D1DEEF11D5CDD200550D75 /* SystemConfiguration.framework */; };
43EF406E11D3FFF800B1F700 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43EF406D11D3FFF800B1F700 /* Security.framework */; };
43FF9C7412270E9F00ADE53C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 43FF9C7212270E9F00ADE53C /* Localizable.strings */; };
+ B61E9AE112FED78600EB044B /* SHKTwitPicForm.m in Sources */ = {isa = PBXBuildFile; fileRef = B61E9AE012FED78600EB044B /* SHKTwitPicForm.m */; };
+ B69E7E0B12FDA9C400EE23DC /* SHKTwitPic.m in Sources */ = {isa = PBXBuildFile; fileRef = B69E7E0A12FDA9C400EE23DC /* SHKTwitPic.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -311,6 +313,10 @@
43FF9C7312270E9F00ADE53C /* en */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = en; path = Classes/ShareKit/Localization/en.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; };
43FF9C7512270EB900ADE53C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Classes/ShareKit/Localization/de.lproj/Localizable.strings; sourceTree = SOURCE_ROOT; };
8D1107310486CEB800E47090 /* ShareKit-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "ShareKit-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; };
+ B61E9ADF12FED78600EB044B /* SHKTwitPicForm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKTwitPicForm.h; sourceTree = ""; };
+ B61E9AE012FED78600EB044B /* SHKTwitPicForm.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKTwitPicForm.m; sourceTree = ""; };
+ B69E7E0912FDA9C400EE23DC /* SHKTwitPic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHKTwitPic.h; sourceTree = ""; };
+ B69E7E0A12FDA9C400EE23DC /* SHKTwitPic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SHKTwitPic.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -720,6 +726,7 @@
43A536C011DBE3B9004A1712 /* Services */ = {
isa = PBXGroup;
children = (
+ B69E7E0812FDA9A800EE23DC /* TwitPic */,
43A536C111DBE3B9004A1712 /* Delicious */,
4379F2891291AC9700D2A41E /* Evernote */,
43A536C411DBE3B9004A1712 /* Facebook */,
@@ -891,6 +898,17 @@
name = Localization;
sourceTree = "";
};
+ B69E7E0812FDA9A800EE23DC /* TwitPic */ = {
+ isa = PBXGroup;
+ children = (
+ B69E7E0912FDA9C400EE23DC /* SHKTwitPic.h */,
+ B69E7E0A12FDA9C400EE23DC /* SHKTwitPic.m */,
+ B61E9ADF12FED78600EB044B /* SHKTwitPicForm.h */,
+ B61E9AE012FED78600EB044B /* SHKTwitPicForm.m */,
+ );
+ path = TwitPic;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -1052,6 +1070,8 @@
4379F2C11291AC9700D2A41E /* SHKEvernote.m in Sources */,
4379F2EA1291AE5700D2A41E /* NSData+md5.m in Sources */,
4379F3B21291C45700D2A41E /* SHKTextMessage.m in Sources */,
+ B69E7E0B12FDA9C400EE23DC /* SHKTwitPic.m in Sources */,
+ B61E9AE112FED78600EB044B /* SHKTwitPicForm.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};