From f6fed5b2374c7d847c68efccce363f9513aa2efb Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Sun, 8 Apr 2018 23:17:47 +0300 Subject: PM posts --- Juick.xcodeproj/project.pbxproj | 14 ++++++ Juick/APIClient.h | 1 + Juick/APIClient.m | 19 +++++++++ Juick/AppDelegate.m | 3 -- Juick/Supporting Files/Juick-Info.plist | 2 +- Juick/ViewControllers/ChatViewController.h | 4 +- Juick/ViewControllers/ChatViewController.m | 53 ++++++++++++++++++++--- Juick/ViewControllers/DialogsViewController.m | 1 - Juick/ViewControllers/DiscoverViewController.m | 2 + Juick/Views/MessageCell.xib | 4 +- Juick/Views/MessageInputView.h | 15 +++++++ Juick/Views/MessageInputView.m | 19 +++++++++ Juick/Views/MessageInputView.xib | 59 ++++++++++++++++++++++++++ Podfile | 1 + Podfile.lock | 10 ++++- 15 files changed, 193 insertions(+), 14 deletions(-) create mode 100644 Juick/Views/MessageInputView.h create mode 100644 Juick/Views/MessageInputView.m create mode 100644 Juick/Views/MessageInputView.xib diff --git a/Juick.xcodeproj/project.pbxproj b/Juick.xcodeproj/project.pbxproj index 736ec50..b49ed47 100644 --- a/Juick.xcodeproj/project.pbxproj +++ b/Juick.xcodeproj/project.pbxproj @@ -47,6 +47,8 @@ 77A0954A181F1F25002BDECD /* Message.m in Sources */ = {isa = PBXBuildFile; fileRef = 77A09549181F1F25002BDECD /* Message.m */; }; 77B09994189D0B9900A84F59 /* UIImage+Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = 77B09993189D0B9900A84F59 /* UIImage+Utils.m */; }; 77B099A6189D57F000A84F59 /* User.m in Sources */ = {isa = PBXBuildFile; fileRef = 77B099A5189D57F000A84F59 /* User.m */; }; + 77B8B399207A52BD005CB20C /* MessageInputView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 77B8B398207A52BD005CB20C /* MessageInputView.xib */; }; + 77B8B39C207A5629005CB20C /* MessageInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 77B8B39B207A5629005CB20C /* MessageInputView.m */; }; 77C67EE51828342000427098 /* NSURL+PathParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = 77C67EE41828342000427098 /* NSURL+PathParameters.m */; }; 77C67EE81828379700427098 /* ColorScheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 77C67EE71828379700427098 /* ColorScheme.m */; }; 77C67EEA18283C8D00427098 /* buttons.png in Resources */ = {isa = PBXBuildFile; fileRef = 77C67EE918283C8D00427098 /* buttons.png */; }; @@ -132,6 +134,9 @@ 77B09993189D0B9900A84F59 /* UIImage+Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Utils.m"; sourceTree = ""; }; 77B099A4189D57F000A84F59 /* User.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = User.h; sourceTree = ""; }; 77B099A5189D57F000A84F59 /* User.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = User.m; sourceTree = ""; }; + 77B8B398207A52BD005CB20C /* MessageInputView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MessageInputView.xib; sourceTree = ""; }; + 77B8B39A207A5629005CB20C /* MessageInputView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MessageInputView.h; sourceTree = ""; }; + 77B8B39B207A5629005CB20C /* MessageInputView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MessageInputView.m; sourceTree = ""; }; 77C67EE31828342000427098 /* NSURL+PathParameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+PathParameters.h"; sourceTree = ""; }; 77C67EE41828342000427098 /* NSURL+PathParameters.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+PathParameters.m"; sourceTree = ""; }; 77C67EE61828379700427098 /* ColorScheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorScheme.h; sourceTree = ""; }; @@ -347,6 +352,9 @@ 773E63A2204BE036008B8F8D /* BubbleMessageCell.m */, 773E63A4204BE11B008B8F8D /* FixedLabel.h */, 773E63A5204BE11B008B8F8D /* FixedLabel.m */, + 77B8B398207A52BD005CB20C /* MessageInputView.xib */, + 77B8B39A207A5629005CB20C /* MessageInputView.h */, + 77B8B39B207A5629005CB20C /* MessageInputView.m */, ); path = Views; sourceTree = ""; @@ -453,6 +461,7 @@ 77317BC7181BBE8500D60005 /* Images.xcassets in Resources */, 77C67EEA18283C8D00427098 /* buttons.png in Resources */, 773F23391F76ED5E00B5B0DF /* Splash@3x.png in Resources */, + 77B8B399207A52BD005CB20C /* MessageInputView.xib in Resources */, 77C6ADDE1F770EB2000AEA8C /* Main.storyboard in Resources */, 773F23381F76ED5E00B5B0DF /* Splash@2x.png in Resources */, 776C41BE1FD3EF180063B82E /* MessageCell.xib in Resources */, @@ -506,6 +515,8 @@ "${BUILT_PRODUCTS_DIR}/DateTools/DateTools.framework", "${BUILT_PRODUCTS_DIR}/MWFeedParser/MWFeedParser.framework", "${BUILT_PRODUCTS_DIR}/PDKeychainBindingsController/PDKeychainBindingsController.framework", + "${BUILT_PRODUCTS_DIR}/PHFComposeBarView/PHFComposeBarView.framework", + "${BUILT_PRODUCTS_DIR}/PHFDelegateChain/PHFDelegateChain.framework", "${BUILT_PRODUCTS_DIR}/TTTAttributedLabel/TTTAttributedLabel.framework", "${BUILT_PRODUCTS_DIR}/TagListView-ObjC/TagListView_ObjC.framework", "${BUILT_PRODUCTS_DIR}/YYCache/YYCache.framework", @@ -519,6 +530,8 @@ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DateTools.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MWFeedParser.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PDKeychainBindingsController.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PHFComposeBarView.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PHFDelegateChain.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TTTAttributedLabel.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TagListView_ObjC.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/YYCache.framework", @@ -559,6 +572,7 @@ 773E6397204BCB64008B8F8D /* ConversationCell.m in Sources */, 776C41BD1FD3EF180063B82E /* MessageCell.m in Sources */, 77317BB8181BBE8500D60005 /* main.m in Sources */, + 77B8B39C207A5629005CB20C /* MessageInputView.m in Sources */, 774528C21F930C06004D110B /* Attachment.m in Sources */, 773E63A6204BE11B008B8F8D /* FixedLabel.m in Sources */, ); diff --git a/Juick/APIClient.h b/Juick/APIClient.h index 46e86c7..dd7d13b 100644 --- a/Juick/APIClient.h +++ b/Juick/APIClient.h @@ -19,6 +19,7 @@ -(void) pullNextFromPath:(NSString *)path params:(NSDictionary *)params callback:(void(^)(NSArray *, NSError *))callback; -(void) postMessage:(NSString *)text result:(void(^)(Message *, NSError *))callback; -(void) postReplyToThread:(NSNumber *)mid inReplyTo:(NSNumber *)rid text:(NSString *)text result:(void(^)(Message *, NSError *))callback; +-(void) postPMToUser:(NSString *)uname text:(NSString *)text result:(void(^)(NSError *))callback; -(void) fetchChats:(void(^)(NSArray *, NSError *))callback; -(void) fetchChatWithUser:(NSString *)uname callback:(void(^)(NSArray *, NSError *))callback; diff --git a/Juick/APIClient.m b/Juick/APIClient.m index 079db5a..1b3fb6e 100644 --- a/Juick/APIClient.m +++ b/Juick/APIClient.m @@ -102,6 +102,25 @@ }]; }]; } +-(void) postPMToUser:(NSString *)uname text:(NSString *)text result:(void (^)(NSError *))callback { + AFHTTPSessionManager *manager = [APIClient sharedClient].manager; + [self.backgroundQueue addOperationWithBlock:^{ + [manager POST:@"/pm" parameters:nil constructingBodyWithBlock:^(id _Nonnull formData) { + [formData appendPartWithFormData:[text dataUsingEncoding:NSUTF8StringEncoding] name:@"body"]; + [formData appendPartWithFormData:[uname dataUsingEncoding:NSUTF8StringEncoding] name:@"uname"]; + } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + callback(nil); + }]; + } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { + NSLog(@"Error: %@", [error localizedDescription]); + [[NSOperationQueue mainQueue] addOperationWithBlock:^{ + callback(error); + }]; + }]; + }]; +} + -(void) fetchChats:(void (^)(NSArray *, NSError *))callback { AFHTTPSessionManager *manager = [APIClient sharedClient].manager; [self.backgroundQueue addOperationWithBlock:^{ diff --git a/Juick/AppDelegate.m b/Juick/AppDelegate.m index 3e92687..9bbf567 100644 --- a/Juick/AppDelegate.m +++ b/Juick/AppDelegate.m @@ -83,7 +83,6 @@ //Called to let your app know which action was selected by the user for a given notification. -(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler{ NSDictionary *userInfo = response.notification.request.content.userInfo; - NSLog(@"User Info : %@", userInfo); [self parseNotificationPayload:userInfo]; UITabBarController *main = (UITabBarController *)self.window.rootViewController; if ([self.pushedThread integerValue] > 0) { @@ -91,10 +90,8 @@ UINavigationController *discover = (UINavigationController *)[main.viewControllers objectAtIndex:0]; [[discover.viewControllers objectAtIndex:0] performSegueWithIdentifier:@"threadViewSegue" sender:discover]; } else { - NSLog(@"Pushing to PM"); [main setSelectedIndex:1]; UINavigationController *dialogs = (UINavigationController *)[main.viewControllers objectAtIndex:1]; - NSLog(@"perform PM segue"); [[dialogs.viewControllers objectAtIndex:0] performSegueWithIdentifier:@"chatSegue" sender:dialogs]; } completionHandler(); diff --git a/Juick/Supporting Files/Juick-Info.plist b/Juick/Supporting Files/Juick-Info.plist index cee6d40..796dab8 100644 --- a/Juick/Supporting Files/Juick-Info.plist +++ b/Juick/Supporting Files/Juick-Info.plist @@ -21,7 +21,7 @@ CFBundleSignature ???? CFBundleVersion - 64 + 65 ITSAppUsesNonExemptEncryption LSApplicationCategoryType diff --git a/Juick/ViewControllers/ChatViewController.h b/Juick/ViewControllers/ChatViewController.h index 7ea8030..3479942 100644 --- a/Juick/ViewControllers/ChatViewController.h +++ b/Juick/ViewControllers/ChatViewController.h @@ -9,7 +9,9 @@ #import #import "User.h" -@interface ChatViewController : UITableViewController +@import PHFComposeBarView; + +@interface ChatViewController : UITableViewController @property(nonatomic, strong) NSMutableArray *messages; @property(nonatomic, strong) NSString *uname; @end diff --git a/Juick/ViewControllers/ChatViewController.m b/Juick/ViewControllers/ChatViewController.m index e94bb40..489de66 100644 --- a/Juick/ViewControllers/ChatViewController.m +++ b/Juick/ViewControllers/ChatViewController.m @@ -12,6 +12,8 @@ @interface ChatViewController () +@property (nonatomic, readwrite, retain) UIView *inputAccessoryView; + @end @implementation ChatViewController @@ -23,7 +25,13 @@ self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive; self.tableView.allowsSelection = NO; + [self reloadChat]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil]; +} + +-(void) reloadChat { self.messages = [NSMutableArray array]; + [self.tableView reloadData]; [[APIClient sharedClient] fetchChatWithUser:self.uname callback:^(NSArray *messages, NSError *err) { if (err == nil) { [self.messages addObjectsFromArray:[[messages reverseObjectEnumerator] allObjects]]; @@ -39,11 +47,6 @@ }]; } -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { @@ -62,4 +65,44 @@ return cell; } +-(BOOL) canBecomeFirstResponder { + return YES; +} + +- (UIView *) inputAccessoryView { + if (!_inputAccessoryView) { + PHFComposeBarView *composeView = [[PHFComposeBarView alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height - PHFComposeBarViewInitialHeight, self.view.bounds.size.width, PHFComposeBarViewInitialHeight)]; + composeView.delegate = self; + [composeView.bottomAnchor constraintEqualToSystemSpacingBelowAnchor:self.view.safeAreaLayoutGuide.bottomAnchor multiplier:1.0f]; + composeView.maxLinesCount = 4; + _inputAccessoryView = composeView; + } + return _inputAccessoryView; +} + +-(void) keyboardWillChangeFrame:(NSNotification *)notification { + NSDictionary *userInfo = [notification userInfo]; + if (userInfo) { + CGRect beginFrame = [userInfo [UIKeyboardFrameBeginUserInfoKey] CGRectValue]; + CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGFloat delta = endFrame.origin.y - beginFrame.origin.y; + CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue]; + UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; + [UIView animateWithDuration:duration delay:0 options:(animationCurve << 16) animations:^{ + self.tableView.contentOffset = CGPointMake(0, self.tableView.contentOffset.y - delta); + } completion:nil]; + } +} + +-(void) composeBarViewDidPressButton:(PHFComposeBarView *)composeBarView { + [[APIClient sharedClient] postPMToUser:self.uname text:composeBarView.text result:^(NSError *err) { + if (!err) { + NSLog(@"Success!"); + [composeBarView becomeFirstResponder]; + [composeBarView setText:nil animated:NO]; + [self reloadChat]; + } + }]; +} + @end diff --git a/Juick/ViewControllers/DialogsViewController.m b/Juick/ViewControllers/DialogsViewController.m index a36acf3..d080176 100644 --- a/Juick/ViewControllers/DialogsViewController.m +++ b/Juick/ViewControllers/DialogsViewController.m @@ -59,7 +59,6 @@ if ([segue.identifier isEqualToString:@"chatSegue"]) { NSString *uname; AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; - NSLog(@"pushed name is %@", appDelegate.pushedUname); if ([appDelegate.pushedUname length] > 0) { uname = [appDelegate.pushedUname copy]; appDelegate.pushedThread = nil; diff --git a/Juick/ViewControllers/DiscoverViewController.m b/Juick/ViewControllers/DiscoverViewController.m index 110d8c7..d57947e 100644 --- a/Juick/ViewControllers/DiscoverViewController.m +++ b/Juick/ViewControllers/DiscoverViewController.m @@ -11,6 +11,7 @@ #import "MessageCell.h" #import "APIClient.h" #import "AppDelegate.h" +#import "ColorScheme.h" @interface DiscoverViewController () @@ -107,6 +108,7 @@ [self.tableView reloadData]; [self refreshData:NO]; }]]; + [filterAlert.view setTintColor:[ColorScheme linkColor]]; [self presentViewController:filterAlert animated:YES completion:nil]; } diff --git a/Juick/Views/MessageCell.xib b/Juick/Views/MessageCell.xib index bb7f9c5..7d410af 100644 --- a/Juick/Views/MessageCell.xib +++ b/Juick/Views/MessageCell.xib @@ -1,11 +1,11 @@ - + - + diff --git a/Juick/Views/MessageInputView.h b/Juick/Views/MessageInputView.h new file mode 100644 index 0000000..38ce721 --- /dev/null +++ b/Juick/Views/MessageInputView.h @@ -0,0 +1,15 @@ +// +// MessageInputView.h +// Juick +// +// Created by Vitaly Takmazov on 08/04/2018. +// Copyright © 2018 com.juick. All rights reserved. +// + +#import + +@interface MessageInputView : UIVisualEffectView +@property (strong, nonatomic) IBOutlet NSLayoutConstraint *bottomConstraint; +@property (strong, nonatomic) IBOutlet UITextField *textView; + +@end diff --git a/Juick/Views/MessageInputView.m b/Juick/Views/MessageInputView.m new file mode 100644 index 0000000..f16f490 --- /dev/null +++ b/Juick/Views/MessageInputView.m @@ -0,0 +1,19 @@ +// +// MessageInputView.m +// Juick +// +// Created by Vitaly Takmazov on 08/04/2018. +// Copyright © 2018 com.juick. All rights reserved. +// + +#import "MessageInputView.h" +#import "ColorScheme.h" + +@implementation MessageInputView + +-(void) awakeFromNib { + [super awakeFromNib]; + [self setTintColor:[ColorScheme linkColor]]; +} + +@end diff --git a/Juick/Views/MessageInputView.xib b/Juick/Views/MessageInputView.xib new file mode 100644 index 0000000..70fcdef --- /dev/null +++ b/Juick/Views/MessageInputView.xib @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Podfile b/Podfile index b3c1309..68fc736 100644 --- a/Podfile +++ b/Podfile @@ -11,5 +11,6 @@ target "Juick" do pod 'YYWebImage' pod 'DateTools' pod 'TagListView-ObjC' + pod 'PHFComposeBarView' end diff --git a/Podfile.lock b/Podfile.lock index 2b63ee0..44d82be 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -25,6 +25,9 @@ PODS: - "MWFeedParser/NSDate+InternetDateTime (1.0.1)" - "MWFeedParser/NSString+HTML (1.0.1)" - PDKeychainBindingsController (0.0.1) + - PHFComposeBarView (2.1.0): + - PHFDelegateChain (~> 1.0) + - PHFDelegateChain (1.0.1) - TagListView-ObjC (0.1.1) - TTTAttributedLabel (2.0.0) - YYCache (1.0.4) @@ -41,6 +44,7 @@ DEPENDENCIES: - DateTools - MWFeedParser - PDKeychainBindingsController + - PHFComposeBarView - TagListView-ObjC - TTTAttributedLabel - YYModel @@ -52,6 +56,8 @@ SPEC REPOS: - DateTools - MWFeedParser - PDKeychainBindingsController + - PHFComposeBarView + - PHFDelegateChain - TagListView-ObjC - TTTAttributedLabel - YYCache @@ -64,6 +70,8 @@ SPEC CHECKSUMS: DateTools: 933ac9c490f21f92127cf690ccd8c397e0126caf MWFeedParser: 2cf646014c1baf6ad1b08c480b40a08180079247 PDKeychainBindingsController: fa8cb3cf99f2ea9240d61066ed0549f34e2cec3c + PHFComposeBarView: 6382ab846e2f4d8634273c4a78d074bc5deed07f + PHFDelegateChain: 491f9cd8a3fb8761f390ff05f74a0e168d48d285 TagListView-ObjC: 432991e24c5177eb4fa7d721de7084f09f39a0b8 TTTAttributedLabel: 8cffe8e127e4e82ff3af1e5386d4cd0ad000b656 YYCache: 8105b6638f5e849296c71f331ff83891a4942952 @@ -71,6 +79,6 @@ SPEC CHECKSUMS: YYModel: 2a7fdd96aaa4b86a824e26d0c517de8928c04b30 YYWebImage: 5f7f36aee2ae293f016d418c7d6ba05c4863e928 -PODFILE CHECKSUM: b2b57aadac65d2dcd8ce5561ec85dab3d8479d0b +PODFILE CHECKSUM: 549f6e80e7e48860145b72aec2fc2fb77ee039ee COCOAPODS: 1.5.0 -- cgit v1.2.3