From 03a8708ee32eced7335c64cd8be7fbcae9946f3d Mon Sep 17 00:00:00 2001 From: nvtu Date: Sat, 19 Aug 2017 23:12:31 +0700 Subject: [PATCH] Finish create group screen, add API create group, optimize UX when search group --- LifeLog/LifeLog.xcodeproj/project.pbxproj | 18 + LifeLog/LifeLog/BaseTableViewController.m | 3 + LifeLog/LifeLog/CreateGroupViewController.h | 36 ++ LifeLog/LifeLog/CreateGroupViewController.m | 116 +++++ LifeLog/LifeLog/CreateGroupViewController.xib | 601 ++++++++++++++++++++++++++ LifeLog/LifeLog/GroupObject.m | 2 +- LifeLog/LifeLog/Localizable.strings | Bin 5005 -> 5617 bytes LifeLog/LifeLog/SearchGroupViewController.h | 4 +- LifeLog/LifeLog/SearchGroupViewController.m | 20 +- LifeLog/LifeLog/SearchGroupViewController.xib | 2 +- LifeLog/LifeLog/ServerAPI.h | 1 + LifeLog/LifeLog/ServerAPI.m | 61 +++ 12 files changed, 859 insertions(+), 5 deletions(-) create mode 100644 LifeLog/LifeLog/CreateGroupViewController.h create mode 100644 LifeLog/LifeLog/CreateGroupViewController.m create mode 100644 LifeLog/LifeLog/CreateGroupViewController.xib diff --git a/LifeLog/LifeLog.xcodeproj/project.pbxproj b/LifeLog/LifeLog.xcodeproj/project.pbxproj index 821407a..cf94803 100644 --- a/LifeLog/LifeLog.xcodeproj/project.pbxproj +++ b/LifeLog/LifeLog.xcodeproj/project.pbxproj @@ -58,6 +58,8 @@ E9373E4A1F35AA180059355A /* HistoryObject.m in Sources */ = {isa = PBXBuildFile; fileRef = E9373E491F35AA180059355A /* HistoryObject.m */; }; E9373E4D1F361A230059355A /* HistoryGraphObject.m in Sources */ = {isa = PBXBuildFile; fileRef = E9373E4C1F361A230059355A /* HistoryGraphObject.m */; }; E9497FD51F46EC1100E6AF8D /* MemberObject.m in Sources */ = {isa = PBXBuildFile; fileRef = E9497FD41F46EC1100E6AF8D /* MemberObject.m */; }; + E95F4CED1F475C6A00D27E80 /* CreateGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E95F4CEB1F475C6A00D27E80 /* CreateGroupViewController.m */; }; + E95F4CEE1F475C6A00D27E80 /* CreateGroupViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E95F4CEC1F475C6A00D27E80 /* CreateGroupViewController.xib */; }; E9682E2E1F39675A00FE05A2 /* RankingTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = E9682E2C1F39675A00FE05A2 /* RankingTableViewCell.m */; }; E9682E2F1F39675A00FE05A2 /* RankingTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = E9682E2D1F39675A00FE05A2 /* RankingTableViewCell.xib */; }; E968550A1F3C444900317CEF /* AutoTransButton.m in Sources */ = {isa = PBXBuildFile; fileRef = E96855091F3C444900317CEF /* AutoTransButton.m */; }; @@ -184,6 +186,9 @@ E9373E4C1F361A230059355A /* HistoryGraphObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HistoryGraphObject.m; sourceTree = ""; }; E9497FD31F46EC1100E6AF8D /* MemberObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemberObject.h; sourceTree = ""; }; E9497FD41F46EC1100E6AF8D /* MemberObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MemberObject.m; sourceTree = ""; }; + E95F4CEA1F475C6A00D27E80 /* CreateGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CreateGroupViewController.h; sourceTree = ""; }; + E95F4CEB1F475C6A00D27E80 /* CreateGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CreateGroupViewController.m; sourceTree = ""; }; + E95F4CEC1F475C6A00D27E80 /* CreateGroupViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CreateGroupViewController.xib; sourceTree = ""; }; E9682E2B1F39675A00FE05A2 /* RankingTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RankingTableViewCell.h; sourceTree = ""; }; E9682E2C1F39675A00FE05A2 /* RankingTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RankingTableViewCell.m; sourceTree = ""; }; E9682E2D1F39675A00FE05A2 /* RankingTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RankingTableViewCell.xib; sourceTree = ""; }; @@ -436,6 +441,7 @@ 6E84E3AC1F27A954001EB88E /* SNS */ = { isa = PBXGroup; children = ( + E95F4CE91F475C4B00D27E80 /* CreateGroup */, E933E6751F4050E6002926F5 /* GroupDetail */, E933E6671F3E0479002926F5 /* SeachGroup */, 6E84E3BC1F27A9B1001EB88E /* SNSViewController.h */, @@ -581,6 +587,16 @@ name = AutoTranslateView; sourceTree = ""; }; + E95F4CE91F475C4B00D27E80 /* CreateGroup */ = { + isa = PBXGroup; + children = ( + E95F4CEA1F475C6A00D27E80 /* CreateGroupViewController.h */, + E95F4CEB1F475C6A00D27E80 /* CreateGroupViewController.m */, + E95F4CEC1F475C6A00D27E80 /* CreateGroupViewController.xib */, + ); + name = CreateGroup; + sourceTree = ""; + }; E99E13A71F336F0C00C78787 /* CustomView */ = { isa = PBXGroup; children = ( @@ -714,6 +730,7 @@ buildActionMask = 2147483647; files = ( 9CBDA1001F2F03810055DED1 /* RegisterViewController.xib in Resources */, + E95F4CEE1F475C6A00D27E80 /* CreateGroupViewController.xib in Resources */, 6E18CED41F2E39DB0029891F /* LoginViewController.xib in Resources */, E99E13AD1F336F4500C78787 /* CollectionView.xib in Resources */, 6E84E3BB1F27A9A0001EB88E /* RankingViewController.xib in Resources */, @@ -827,6 +844,7 @@ 6EDC8BF41F2C68D700765ACC /* CMMotionActivityExtra.m in Sources */, E933E6791F40513C002926F5 /* GroupDetailViewController.m in Sources */, 6EA4AF311F40BB7A00F52CFE /* StepObject.m in Sources */, + E95F4CED1F475C6A00D27E80 /* CreateGroupViewController.m in Sources */, 9CBDA0FF1F2F03810055DED1 /* RegisterViewController.m in Sources */, E9373E4A1F35AA180059355A /* HistoryObject.m in Sources */, 9CA8AEEA1F31BB4600C5FC74 /* ConfirmForgetPassViewController.m in Sources */, diff --git a/LifeLog/LifeLog/BaseTableViewController.m b/LifeLog/LifeLog/BaseTableViewController.m index 08ae3ab..8d63a91 100644 --- a/LifeLog/LifeLog/BaseTableViewController.m +++ b/LifeLog/LifeLog/BaseTableViewController.m @@ -61,6 +61,9 @@ } if(error == nil) { if(array.count != 0) { + if(_curPage == 1) { + [_curDataList removeAllObjects]; + } [_curDataList addObjectsFromArray:array]; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf.tableBase reloadData]; diff --git a/LifeLog/LifeLog/CreateGroupViewController.h b/LifeLog/LifeLog/CreateGroupViewController.h new file mode 100644 index 0000000..b78467a --- /dev/null +++ b/LifeLog/LifeLog/CreateGroupViewController.h @@ -0,0 +1,36 @@ +// +// CreateGroupViewController.h +// LifeLog +// +// Created by nvtu on 8/19/17. +// Copyright © 2017 PhongNV. All rights reserved. +// + +#import +#import "BaseViewController.h" +#import "AutoTransButton.h" +#import "Utilities.h" +#import "Entities.h" + +@interface CreateGroupViewController : BaseViewController + +@property (weak, nonatomic) IBOutlet UITextField *textName; +@property (weak, nonatomic) IBOutlet UITextField *textGoalWalk; +@property (weak, nonatomic) IBOutlet UITextField *textGoalRun; +@property (weak, nonatomic) IBOutlet UITextField *textGoalBike; + +@property (weak, nonatomic) IBOutlet UITextView *textGoal; + +@property (weak, nonatomic) IBOutlet UISwitch *switchWalk; +@property (weak, nonatomic) IBOutlet UISwitch *switchBike; +@property (weak, nonatomic) IBOutlet UISwitch *switchRun; +@property (weak, nonatomic) IBOutlet UISwitch *switchStep; +@property (weak, nonatomic) IBOutlet UISwitch *switchGym; +@property (weak, nonatomic) IBOutlet UISwitch *switchBegin; + +@property (copy) void (^createGroupSuccess)(GroupObject * group); + +- (IBAction)clickBack:(UIButton *)sender; +- (IBAction)clickCreateGroup:(AutoTransButton *)sender; + +@end diff --git a/LifeLog/LifeLog/CreateGroupViewController.m b/LifeLog/LifeLog/CreateGroupViewController.m new file mode 100644 index 0000000..7714cd0 --- /dev/null +++ b/LifeLog/LifeLog/CreateGroupViewController.m @@ -0,0 +1,116 @@ +// +// CreateGroupViewController.m +// LifeLog +// +// Created by nvtu on 8/19/17. +// Copyright © 2017 PhongNV. All rights reserved. +// + +#import "CreateGroupViewController.h" +#import "ServerAPI.h" + +@interface CreateGroupViewController () + +@end + +@implementation CreateGroupViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view from its nib. +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +#pragma mark IBAction + +- (IBAction)clickBack:(UIButton *)sender { + [self.navigationController popViewControllerAnimated:true]; +} + +- (IBAction)clickCreateGroup:(AutoTransButton *)sender { + NSString *name = self.textName.text; + NSString *goal = self.textGoal.text; + if(name.length == 0) { + [Utilities showErrorMessage:@"Fill name of group!" withViewController:self]; + return; + } + else if(name.length >= 255) { + [Utilities showErrorMessage:@"Name of group is too long!" withViewController:self]; + return; + } + else if(goal.length == 0) { + [Utilities showErrorMessage:@"Fill information for goal of group" withViewController:self]; + return; + } + if(self.switchWalk.on && [self.textGoalWalk.text intValue] == 0) { + [Utilities showErrorMessage:@"Add goal for walk mode" withViewController:self]; + return; + } + if(self.switchBike.on && [self.textGoalBike.text intValue] == 0) { + [Utilities showErrorMessage:@"Add goal for bike mode" withViewController:self]; + return; + } + if(self.switchRun.on && [self.textGoalRun.text intValue] == 0) { + [Utilities showErrorMessage:@"Add goal for run mode" withViewController:self]; + return; + } + GroupObject *object = [[GroupObject alloc] init]; + object.name = name; + object.goal = goal; + object.walkMode = self.switchWalk.on; + object.runMode = self.switchRun.on; + object.bikeMode = self.switchBike.on; + object.stepMode = self.switchStep.on; + object.gymMode = self.switchGym.on; + object.beginMode = self.switchBegin.on; + object.walkGoal = [self.textGoalWalk.text intValue]; + object.bikeGoal = [self.textGoalBike.text intValue]; + object.runGoal = [self.textGoalRun.text intValue]; + + NSLog(@"%@", object.name); + NSLog(@"%@", object.goal); + NSLog(@"%d", object.walkGoal); + NSLog(@"%d", object.bikeGoal); + NSLog(@"%d", object.runGoal); + NSLog(@"%d", object.walkMode); + NSLog(@"%d", object.runMode); + NSLog(@"%d", object.bikeMode); + NSLog(@"%d", object.stepMode); + NSLog(@"%d", object.gymMode); + NSLog(@"%d", object.beginMode); + + NSString * token = [[NSUserDefaults standardUserDefaults] stringForKey:kToken]; + MBProgressHUD *hudView = [MBProgressHUD showHUDAddedTo:self.view animated:true]; + [[ServerAPI server] requestCreateGroup:token withGroup:object CompletionHandler:^(GroupObject * group, NSError * error) { + CreateGroupViewController __weak *weakSelf = self; + if(error == nil) { + dispatch_async(dispatch_get_main_queue(), ^{ + if(weakSelf.createGroupSuccess != nil) { + [hudView hideAnimated:true]; + [weakSelf clickBack:nil]; + weakSelf.createGroupSuccess(object); + } + }); + } + else { + dispatch_async(dispatch_get_main_queue(), ^{ + [hudView hideAnimated:true]; + NSString *message = [error.userInfo objectForKey:@"message"]; + [Utilities showErrorMessage:message withViewController:weakSelf]; + }); + } + }]; +} + +#pragma mark UITextView Delegate + +-(BOOL) textFieldShouldReturn:(UITextField *)textField { + [self.view endEditing:true]; + return true; +} + +@end diff --git a/LifeLog/LifeLog/CreateGroupViewController.xib b/LifeLog/LifeLog/CreateGroupViewController.xib new file mode 100644 index 0000000..7179222 --- /dev/null +++ b/LifeLog/LifeLog/CreateGroupViewController.xib @@ -0,0 +1,601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LifeLog/LifeLog/GroupObject.m b/LifeLog/LifeLog/GroupObject.m index 598c81a..0f7b19a 100644 --- a/LifeLog/LifeLog/GroupObject.m +++ b/LifeLog/LifeLog/GroupObject.m @@ -17,7 +17,7 @@ if([dict objectForKey:@"group_avatar"] != nil) { self.avatar = dict[@"group_avatar"]; } - if([dict objectForKey:@"created_at"] != nil) { + if([dict objectForKey:@"created_at"] != nil && ![[dict objectForKey:@"created_at"] isKindOfClass:[NSNull class]]) { NSString *dateString = dict[@"created_at"]; self.createDate = [Utilities dateFromString:dateString withFormat:@"yyyy-MM-dd hh:mm:ss"]; } diff --git a/LifeLog/LifeLog/Localizable.strings b/LifeLog/LifeLog/Localizable.strings index 177caed1a834b88fd14c005039ee392d3a0fb082..c51b8b5eb4e921b3a855a511541be5bb5f99f0b8 100644 GIT binary patch delta 550 zcmeBG|ERs8S6EG7Um-ZTC^a=t!MP|ku_RT&y(qu5fJ-SSGc7eIKV1(f2Na#WT0kk{ zaYMu7rVWpqS3hpv^SF8Xlf84EbxcsQMpx@zq?ePFqnDSMo2sN>tDy9BLhtkC8*r*i z&!4QzEm;q-2dXzWu>h>~ar3;#&CNi&@aRs=F-%FU1S@~PXX3NzOP|kP_iV*XoI1)A zbF#sz!ySFR;i~H4UWGa#DKi`5d?!zDSGY2CRYj$FV6%ck{cx%&E=h&>COE`30GFzI zz4Xdlh@YEwJZ@fqOPyX)YI-Kb&Zix7pYCsd(a?%jZBmIIMkwNmvB{o-GD44=CP9=u MZk+kJsT*i60FQ;ziU0rr delta 7 OcmeyU-K)N#R~P^eIs+j9 diff --git a/LifeLog/LifeLog/SearchGroupViewController.h b/LifeLog/LifeLog/SearchGroupViewController.h index 0e93dfe..f8e1eb0 100644 --- a/LifeLog/LifeLog/SearchGroupViewController.h +++ b/LifeLog/LifeLog/SearchGroupViewController.h @@ -9,7 +9,9 @@ #import #import "BaseTableViewController.h" -@interface SearchGroupViewController : BaseTableViewController +@interface SearchGroupViewController : BaseTableViewController { + NSTimer *timerSearch; +} @property (weak, nonatomic) IBOutlet UITextField *textFieldSearch; diff --git a/LifeLog/LifeLog/SearchGroupViewController.m b/LifeLog/LifeLog/SearchGroupViewController.m index 9c7944a..52067b8 100644 --- a/LifeLog/LifeLog/SearchGroupViewController.m +++ b/LifeLog/LifeLog/SearchGroupViewController.m @@ -14,6 +14,7 @@ #import "Utilities.h" #import "SearchGroupTableViewCell.h" +#import "CreateGroupViewController.h" #import "GroupDetailViewController.h" @interface SearchGroupViewController () @@ -42,11 +43,18 @@ } - (IBAction)clickSearch:(id)sender { + [self.view endEditing:true]; [self resetData]; } - (IBAction)clickCreateGroup:(id)sender { - + CreateGroupViewController * create = [[CreateGroupViewController alloc] init]; + create.createGroupSuccess = ^(GroupObject *object){ + GroupDetailViewController * detail = [[GroupDetailViewController alloc] init]; + [detail setGroup:object]; + [self.navigationController pushViewController:detail animated:true]; + }; + [self.navigationController pushViewController:create animated:true]; } #pragma mark UITableView Delegate @@ -74,8 +82,16 @@ } #pragma mark UITextField Delegate +-(BOOL) textFieldShouldReturn:(UITextField *)textField { + [self.view endEditing:true]; + return true; +} + -(BOOL) textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { - [self resetData]; + if(timerSearch != nil) { + [timerSearch invalidate]; + } + timerSearch = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(resetData) userInfo:nil repeats:false]; return true; } diff --git a/LifeLog/LifeLog/SearchGroupViewController.xib b/LifeLog/LifeLog/SearchGroupViewController.xib index 7362232..aa0085c 100644 --- a/LifeLog/LifeLog/SearchGroupViewController.xib +++ b/LifeLog/LifeLog/SearchGroupViewController.xib @@ -112,7 +112,7 @@ - + diff --git a/LifeLog/LifeLog/ServerAPI.h b/LifeLog/LifeLog/ServerAPI.h index ae5eec1..c459837 100644 --- a/LifeLog/LifeLog/ServerAPI.h +++ b/LifeLog/LifeLog/ServerAPI.h @@ -34,6 +34,7 @@ extern NSString *const kNotificationToken; - (void) requestHistoryGraph:(NSString *)token withType:(int)type andMode:(int) mode CompletionHandler:(void (^)(HistoryGraphObject *, NSError *)) completion; - (void) requestHistoryList:(NSString *)token withType:(int)type andMode:(int) mode AtPage:(int) page CompletionHandler:(void (^)(NSArray *, NSError *)) completion; - (void) requestJoinGroup:(NSString *)token groupID: (int) groupID CompletionHandler:(void (^)(NSError *)) completion; +-(void) requestCreateGroup:(NSString *)token withGroup:(GroupObject *)group CompletionHandler:(void (^)(GroupObject *, NSError *)) completion; #pragma mark - SNS Screen Function /* diff --git a/LifeLog/LifeLog/ServerAPI.m b/LifeLog/LifeLog/ServerAPI.m index c0f94c9..bb69de2 100644 --- a/LifeLog/LifeLog/ServerAPI.m +++ b/LifeLog/LifeLog/ServerAPI.m @@ -647,6 +647,67 @@ NSURLSessionDataTask * searchTask; } #pragma mark - Group Function +-(void) requestCreateGroup:(NSString *)token withGroup:(GroupObject *)group CompletionHandler:(void (^)(GroupObject *, NSError *)) completion { + NSString *url = [kServerAddress stringByAppendingFormat:@"api/groups/newGroup"]; + NSLog(@"requestCreateGroup link %@", url); + NSDictionary * dict = @{@"group_name":group.name, + @"goal":group.goal, + @"walk_mode_active":[NSNumber numberWithBool:group.walkMode], + @"run_mode_active":[NSNumber numberWithBool:group.runMode], + @"bike_mode_active":[NSNumber numberWithBool:group.bikeMode], + @"step_mode_active":[NSNumber numberWithBool:group.stepMode], + @"gym_mode_active":[NSNumber numberWithBool:group.gymMode], + @"beginer_mode_active":[NSNumber numberWithBool:group.beginMode], + @"walk_mode_goal":[NSNumber numberWithBool:group.walkGoal], + @"run_mode_goal":[NSNumber numberWithBool:group.runGoal], + @"bike_mode_goal":[NSNumber numberWithBool:group.bikeGoal]}; + + [self _request:url method:@"POST" token:token paras:dict completion:^(NSData *data, NSError *error) { + + if (completion == NULL) { + return ; + } + + if (error == nil) + { + NSDictionary *dataResult = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingAllowFragments error: &error]; + NSLog(@"%@", dataResult); + int status = [dataResult[@"status"] intValue]; + if (status == 1) { // status = 1 success + if(dataResult[@"result"] != nil) { + NSDictionary * dict = dataResult[@"result"]; + group.groupID = [dict[@"group_id"] intValue]; + completion(group, nil); + } + else { + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":@"Unknown Error"}]; + completion(nil, errorObject); + } + } + else { + NSString *message = dataResult[@"message"]; + if (message == nil) { + message = @"Unknown error"; + } + + if ([message isEqualToString:@"Token is invalid"]) { + [self performSelectorOnMainThread:@selector(checkToken) withObject:nil waitUntilDone:YES]; + NSString *tokenNew = [[NSUserDefaults standardUserDefaults] objectForKey:kToken]; + [self requestCreateGroup:tokenNew withGroup:group CompletionHandler:completion]; + } + else { + NSError *errorObject = [NSError errorWithDomain:@"LifeLog_Domain" code:-1 userInfo:@{@"message":message}]; + completion(nil, errorObject); + } + } + } + else + { + completion(nil, error); + } + }]; +} + - (void) getGroupDetail:(NSString *)token withGroupID:(int)groupID CompletionHandler:(void (^)(GroupObject *, NSError *)) completion { NSString *url = [kServerAddress stringByAppendingFormat:@"api/sns/group/detail/%d", groupID]; NSLog(@"getGroupDetail link %@", url); -- 1.8.5.3