// // RulesViewController.m // kneet // // Created by Jason Lee on 3/18/15. // Copyright (c) 2015 ntels. All rights reserved. // #import "JDObject.h" #import "RequestHandler.h" #import "RuleModel.h" #import "CustomTableView.h" #import "CustomLabel.h" #import "CustomImageView.h" #import "JYRefreshController.h" #import "UIImageView+WebCache.h" #import "ImageUtil.h" #import "RulesViewController.h" #import "CustomCheckBox.h" #import "RulesDetailViewController.h" #import "RulesAddViewController.h" #import "CustomLabelButton.h" #import "HomeMemberViewController.h" #import "CustomSwitch.h" #define kfRulesTableViewCellHeight 101.0f @implementation RulesTableViewCell @end @implementation RulesCreateTableViewCell @end @interface RulesViewController () { NSMutableArray *_ruleList; NSString *_pagingType, *_pagingId; UIImage *_stateImageRun, *_stateImageStop; UIImage *_btnImageRun, *_btnImageStop; BOOL _isNotFirstLoading, _isDeleteMode; } @property (strong, nonatomic) JYPullToRefreshController *refreshController; @end #pragma mark - Class Definition @implementation RulesViewController - (void)viewDidLoad { [super viewDidLoad]; // _ruleList = (NSMutableArray *)[[NSMutableArray alloc] init]; [self initUI]; [self prepareViewDidLoad]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // if (_isNotFirstLoading) { [self performSelector:@selector(requestRules) withObject:nil afterDelay:0.0f]; // } } - (void)initUI { //initialize tableview [self initTableViewAsDefaultStyle:_tableView]; [_btnClose setHidden:YES]; [_btnOption setHidden:NO]; _btnImageRun = [UIImage imageNamed:@"img_rule_list_playbtn_active"]; _btnImageStop = [UIImage imageNamed:@"img_rule_list_playbtn_disable"]; _stateImageRun = [UIImage imageNamed:@"common_bullet_circle_red"]; _stateImageStop = [UIImage imageNamed:@"common_bullet_circle_gray"]; _tableView.backgroundColor = [UIColor clearColor]; //[self setThingsPopoverOptions]; [self setMoreBtnArray]; [self initRefreshController]; } - (void)initRefreshController { //set refresh controls __weak typeof(self) weakSelf = self; self.refreshController = [[JYPullToRefreshController alloc] initWithScrollView:self.tableView]; self.refreshController.pullToRefreshHandleAction = ^{ [weakSelf requestRules]; }; } - (void)setThingsPopoverOptions { // //set Popover Contents // __weak typeof(self) weakSelf = self; // _popooverOptionArray = [[NSMutableArray alloc] init]; // // [_popooverOptionArray addObject:@{@"menuName" : NSLocalizedString(@"새로고침",nil), // @"iconName": @"img_bg_morepopup_icon_refresh", // @"target": weakSelf, // @"selector": [NSValue valueWithPointer:@selector(refreshRuleList)]}]; // // if ([JDFacade facade].loginUser.level > 10) {//파워유저 이상일 경우, // [_popooverOptionArray addObject:@{@"menuName" : NSLocalizedString(@"만들기", @"만들기"), // @"iconName": @"img_bg_morepopup_icon_edit", // @"target": weakSelf, // @"selector": [NSValue valueWithPointer:@selector(addNewRule)]}]; // // [_popooverOptionArray addObject:@{@"menuName" : NSLocalizedString(@"삭제", @"삭제"), // @"iconName": @"img_bg_morepopup_icon_del", // @"target": weakSelf, // @"selector": [NSValue valueWithPointer:@selector(toggleEditMode)]}]; // } } - (void)setMoreBtnArray { _moreBtnArray = [NSMutableArray array]; // if (![[JDFacade facade].loginUser hasHomeHub]) { // [_btnOption setHidden:YES]; // } if([[JDFacade facade].loginUser.gradeCode isEqualToString:KNEET_MEMBER_MASTER]) { for (int i = 0; i < 3; i++) { MoreBtnModel *btnModel; switch (i) { case 0: btnModel = [[MoreBtnModel alloc] initWithTyep:Add isEnable:YES]; break; case 1: btnModel = [[MoreBtnModel alloc] initWithTyep:Del isEnable:_ruleList.count > 0]; break; case 2: btnModel = [[MoreBtnModel alloc] initWithTyep:Refresh isEnable:YES]; break; default: break; } [_moreBtnArray addObject:btnModel]; } } else { MoreBtnModel *btnModel = [[MoreBtnModel alloc] initWithTyep:Refresh isEnable:YES]; [_moreBtnArray addObject:btnModel]; } } - (void)prepareViewDidLoad { [self updateTitle]; [self performSelector:@selector(requestRules) withObject:nil afterDelay:0.0f]; } - (void)updateHomeHubStatusToRules { [self updateTitle]; } - (void)refreshRuleList { _pagingId = nil; _pagingType = nil; if (_ruleList && _ruleList.count) { [_ruleList removeAllObjects]; } [self performSelector:@selector(requestRules) withObject:nil afterDelay:0.0f]; } - (void)addNewRule { UIViewController *vc = [CommonUtil instantiateViewControllerWithIdentifier:@"RulesAddViewController" storyboardName:@"Rules"]; [self presentViewController:vc animated:YES completion:nil]; } - (void)toggleEditMode { _isDeleteMode = !_isDeleteMode; [_btnClose setHidden:!_isDeleteMode]; [_btnOption setHidden:_isDeleteMode]; if (_isDeleteMode) { _lblTitle.text = @"규칙 삭제"; _imgvHubAlert.hidden = YES; } else { [self updateTitle]; } [_tableView reloadData]; // _constraintEditModeRight.constant = _isDeleteMode ? 0 : -_editModeView.width; // // [UIView animateWithDuration:kfAnimationDur animations:^{ // [self.view layoutIfNeeded]; // }]; } #pragma mark - Main Logic //- (void)requestRuleListRecently { // // RuleModel *firstRule = [_ruleList firstObject]; // _pagingType = ksListPagingTypeUpward; // _pagingId = firstRule.ruleId; // // [self performSelector:@selector(requestRules) withObject:nil afterDelay:0.0f]; //} // //- (void)requestRuleListOlder { // // RuleModel *lastRule = [_ruleList lastObject]; // _pagingType = ksListPagingTypeDownward; // _pagingId = lastRule.ruleId; // // [self performSelector:@selector(requestRules) withObject:nil afterDelay:0.0f]; //} - (void)requestRules { if (![JDFacade facade].loginUser.hasHomeHub) { return; } NSString *path = [[JDFacade facade] getUrlWithCustAndGroupID:API_GET_RULE aditional:@""]; [[RequestHandler handler] sendAsyncGetRequestAPIPath:path parameters:nil modelClass:[RuleListModel class] completion:^(id responseObject) { if (!responseObject) {//응답결과가 잘못되었거나 없을 경우, return; } RuleListModel *fetchedRuleList = (RuleListModel *)responseObject; if (fetchedRuleList && fetchedRuleList.rules ) {//API 성공, _ruleList = [fetchedRuleList.rules mutableCopy]; if (!_ruleList.count) {//이미 로드된 데이터가 있을 경우는 출력하지 않음. _lblConnectHub.text = @"등록된 규칙이 없습니다"; _imgvConnectHub.image = [UIImage imageNamed:@"img_1depth_nodevice"]; } } [self updateTitle]; [self setMoreBtnArray]; [_tableView reloadData]; //refresh controller if (self.refreshController && self.refreshController.refreshState == JYRefreshStateLoading) { [self.refreshController stopRefreshWithAnimated:YES completion:nil]; } if (!_isNotFirstLoading) { _isNotFirstLoading = YES; } } failure:^(id errorObject) { JDErrorModel *error = (JDErrorModel *)errorObject; [[JDFacade facade] alert:error.errorMessage]; }]; } - (void)requestChangeRuleStatus:(RuleModel *)rule { //parameters NSDictionary *parameter = @{@"status_code" : [rule.useYn isEqualToString:@"Y"] ? @"03" : @"02"}; NSArray *arr = @[rule.ruleId]; NSString *path = [[JDFacade facade] getUrlWithCustAndGroupID:API_PUT_RULE_STATUS arguments:arr]; [[RequestHandler handler] sendAsyncPostRequestAPIPath:path parameters:parameter modelClass:[JDJSONModel class] completion:^(id responseObject) { rule.useYn = [rule.useYn boolValue] ? ksNO : ksYES; //toggle if ([rule.useYn boolValue]) { [[JDFacade facade] toast:@"규칙을 다시 시작합니다"]; } else { [[JDFacade facade] toast:@"규칙을 중단합니다"]; } // [self changeBtnRunStatus:[rule.useYn boolValue]]; [self updateTitle]; [_tableView reloadData]; } failure:^(id errorObject) { JDErrorModel *error = (JDErrorModel *)errorObject; [[JDFacade facade] alert:error.errorMessage]; }]; } - (void)requestDeleteRule:(RuleModel *)rule { NSArray *arr = @[rule.ruleId]; NSString *path = [[JDFacade facade] getUrlWithCustAndGroupID:API_DELETE_RULE arguments:arr]; [[RequestHandler handler] sendAsyncRequestAPIPath:path method:ksHTTPRequestDELETE parameters:nil modelClass:[JDJSONModel class] showLoadingView:YES completion:^(id responseObject) { [[JDFacade facade] toast:@"규칙을 삭제했습니다"]; [_ruleList removeObject:rule]; [self toggleEditMode]; [self updateTitle]; [_tableView reloadData]; } failure:^(id errorObject) { JDErrorModel *error = (JDErrorModel *)errorObject; [[JDFacade facade] alert:error.errorMessage]; }]; } - (void)updateRule:(RuleModel *)rule { for (RuleModel *tmpRule in _ruleList) { if ([rule.homegrpRuleId isEqualToString:tmpRule.homegrpRuleId]) { tmpRule.ruleName = rule.ruleName; tmpRule.useYn = rule.useYn; break; } } [_tableView reloadData]; } - (void)updateTitle { if (_isDeleteMode) { return; } NSInteger inactiveCount = [_ruleList filteredArrayUsingPredicateFormat:@"SELF.useYn != %@", ksYES].count; NSInteger activeCount = _ruleList.count > inactiveCount ? _ruleList.count - inactiveCount : inactiveCount - _ruleList.count; _lblTitle.text = [NSString stringWithFormat:@"적용 %zd / 미적용 %zd", activeCount, inactiveCount]; if (![JDFacade facade].loginUser.hasHomeHub) {//홈허브 아이디가 없는 경우, [_mainView bringSubviewToFront:_addHubContainerView]; _addHubContainerView.hidden = NO; _tableView.hidden = YES; _btnOption.hidden = YES; if (![JDFacade facade].loginUser.homegrpId) {//연결한 적이 없음 _lblConnectHub.text = @"초대를 받아서\n시작해 보세요"; _imgvHubAlert.hidden = YES; _imgvConnectHub.image = [UIImage imageNamed:@"img_1depth_invitation"]; _lblLeaveAccount.hidden = YES; _lblSimpleMemberInfo.hidden = YES; } else {//홈허브가 삭제됨. _lblTitle.text = @"홈허브 삭제됨"; _imgvHubAlert.hidden = NO; _lblConnectHub.text = @"홈허브를 다시 연결하려면\n고객센터에 문의해주세요"; _imgvConnectHub.image = [UIImage imageNamed:@"img_things_homehub_img_hubdelete_cscenter"]; if ([JDFacade facade].loginUser.level < 90) {//일반 유저일 경우, _imgvConnectHub.image = [UIImage imageNamed:@"img_things_homehub_img_hubdelete_wait"]; _lblLeaveAccount.hidden = NO; _lblSimpleMemberInfo.hidden = NO; [_lblLeaveAccount setUnderLine:_lblLeaveAccount.text]; if (!_lblLeaveAccount.touchHandler) { [_lblLeaveAccount addTouchEventHandler:^(id label) { [self leaveHomegroup]; }]; } } } } else { if (![JDFacade facade].loginUser.isHomehubOnline) { _imgvHubAlert.hidden = NO; _lblTitle.text = @"홈허브 오프라인"; [_lblTitle setColor:kUITextColor01 text:_lblTitle.text]; } else { _imgvHubAlert.hidden = YES; } [_mainView bringSubviewToFront:_tableView]; _addHubContainerView.hidden = YES; _tableView.hidden = NO; _btnOption.hidden = NO; } //활성/비활성 업데이트 if ([_lblTitle.text rangeOfString:@"활성"].location != NSNotFound) { [_lblTitle setColor:kUITextColor02 text:[NSString stringWithFormat:@"%zd", activeCount]]; [_lblTitle setColor:kUITextColor03 text:[NSString stringWithFormat:@"비활성 %zd", inactiveCount]]; } } - (void)leaveHomegroup { HomeMemberViewController *vc = [[HomeMemberViewController alloc] init]; [vc leaveHomegroup]; } #pragma mark - UITableView DataSource & Delegate - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { NSInteger auth = [JDFacade facade].loginUser.level == 90 && !_isDeleteMode; NSInteger count = _ruleList.count > 0 ? 1 + auth : 1; return count; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { NSInteger count = 1; if (_ruleList.count > 0 && section == 0) {//규칙이 있을 경우, count = _ruleList.count; } return count; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { CGFloat height = kfRulesTableViewCellHeight; NSInteger section = indexPath.section; if (_ruleList.count > 0 && section == 0) {//규칙이 있을 경우, height = 77.0f; } else if (_ruleList.count > 0 && section == 1) { height = 135.0f; } else { height = IPHONE_HEIGHT - kfNavigationBarHeight - 55.0f; //header, tabbar } // if (indexPath.row == _ruleList.count) { // height = _ruleList.count ? 190.0f : IPHONE_HEIGHT - kfNavigationBarHeight; // _tableView.scrollEnabled = _ruleList.count; // } return height; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSInteger section = indexPath.section; UITableViewCell *rcell = nil; if (_ruleList.count > 0 && section == 0) {//규칙이 있을 경우, RulesTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CellIdentifier"]; RuleModel *rule = _ruleList[indexPath.row]; cell.lblRuleName.text = rule.ruleName; cell.switchRulePlay.hidden = _isDeleteMode; cell.switchRulePlay.selected = EQUALS(rule.useYn, @"Y"); [cell.imgvTrigger sd_setImageWithURL:[NSURL URLWithString:rule.imageFileName] placeholderImage:nil options:SDWebImageRefreshCached]; cell.switchRulePlay.hidden = _isDeleteMode; cell.btnDelete.hidden = !_isDeleteMode; if (!cell.switchRulePlay.hidden) { cell.switchRulePlay.hidden = [JDFacade facade].loginUser.level < 90; cell.imgvStatus.highlighted = !EQUALS(rule.useYn, @"Y"); cell.switchRulePlay.tag = indexPath.row; if (![cell.switchRulePlay actionsForTarget:self forControlEvent:UIControlEventValueChanged]) { [cell.switchRulePlay addTarget:self action:@selector(changeSwitch:) forControlEvents:UIControlEventValueChanged]; } } else { cell.btnDelete.value = rule; if (![cell.btnDelete actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) { [cell.btnDelete addTarget:self action:@selector(btnDeleteTouched:) forControlEvents:UIControlEventTouchUpInside]; } } rcell = cell; } else { RulesCreateTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AddCellIdentifier"]; if (![cell.btnAdd actionsForTarget:self forControlEvent:UIControlEventTouchUpInside]) { [cell.btnAdd addTarget:self action:@selector(addNewRule) forControlEvents:UIControlEventTouchUpInside]; } rcell = cell; } return rcell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:YES]; NSInteger section = indexPath.section; if (indexPath.row == _ruleList.count || section > 0) { return; } if (!_isDeleteMode) {//go to detail //goto rule details RulesDetailViewController *vc = (RulesDetailViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RulesDetailViewController" storyboardName:@"Rules"]; vc.refRule = _ruleList[indexPath.row]; [self presentViewController:vc animated:YES completion:nil]; } } #pragma mark - TableView UI Events - (void)changeSwitch:(id)sender { UISwitch *sw = sender; RuleModel *rule = _ruleList[sw.tag]; if ([rule.useYn isEqualToString:ksKneetRulesDisable]) {//규칙 비활성화 일 경우, NSString *msg = [NSString stringWithFormat:@"삭제된 장치로 인해 \"%@\"규칙을 적용할 수 없습니다.",rule.ruleName]; CustomAlertView *alert = [[CustomAlertView alloc] initWithTitle:@"알림" message:msg delegate:nil OKButtonTitle:@"편집" cancelButtonTitle:@"취소"]; [alert showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) { if (buttonIndex == 0) {//OK dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{//RUN to background thread NSArray *arr = @[rule.ruleId]; NSString *path = [[JDFacade facade] getUrlWithCustAndGroupID:API_GET_RULE_DETAIL arguments:arr]; RuleDetailModel *ruleDetail = [[RequestHandler handler] sendSyncGetRequestAPIPath:path parameters:nil modelClass:[RuleDetailModel class] showLoadingView:YES]; RulesAddViewController *vc = (RulesAddViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RulesAddViewController" storyboardName:@"Rules"]; vc.refRuleDetail = ruleDetail; dispatch_async(dispatch_get_main_queue(), ^{ [self presentViewController:vc animated:YES completion:nil]; }); }); } }]; } else { [self requestChangeRuleStatus:rule]; } } //- (void)btnRulePlayTouched:(id)sender { // CustomButton *btnRulePlay = (CustomButton *)sender; // // RuleModel *rule = btnRulePlay.value; // if ([rule.useYn isEqualToString:ksKneetRulesDisable]) {//규칙 비활성화 일 경우, // // CustomAlertView *alert = [[CustomAlertView alloc] initWithTitle:@"알림" message:@"일부 장치가 삭제되었습니다.\n편집 후 실행하세요." delegate:nil OKButtonTitle:@"편집" cancelButtonTitle:@"취소"]; // [alert showWithCompletion:^(CustomAlertView *alertView, NSInteger buttonIndex) { // if (buttonIndex == 0) {//OK // // dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{//RUN to background thread // // NSString *path = [NSString stringWithFormat:API_GET_RULE_DETAIL, rule.homegrpRuleId]; // RuleDetailModel *ruleDetail = [[RequestHandler handler] sendSyncGetRequestAPIPath:path parameters:nil modelClass:[RuleDetailModel class] showLoadingView:YES]; // // RulesAddViewController *vc = (RulesAddViewController *)[CommonUtil instantiateViewControllerWithIdentifier:@"RulesAddViewController" storyboardName:@"Rules"]; // vc.refRuleDetail = ruleDetail; // // dispatch_async(dispatch_get_main_queue(), ^{ // [self presentViewController:vc animated:YES completion:nil]; // }); // }); // } // }]; // } else { // [self requestChangeRuleStatus:rule]; // } //} - (void)btnDeleteTouched:(id)sender { [[JDFacade facade] confirmTitle:@"규칙 삭제" message:@"규칙을 삭제하시겠습니까?" completion:^(CustomAlertView *alertView, NSInteger buttonIndex) { if (buttonIndex == 0) {//OK CustomButton *btnDelete = (CustomButton *)sender; RuleModel *rule = btnDelete.value; [self requestDeleteRule:rule]; } }]; } #pragma mark - UI Events - (IBAction)btnOptionTouched:(id)sender { //[self toggleOptions:sender]; [self toggleOptionsWithArray:sender btnArray:_moreBtnArray]; } - (IBAction)btnCloseTouched:(id)sender { [self toggleEditMode]; } - (IBAction)btnCloseOnEditModeTouched:(id)sender { [self toggleEditMode]; } #pragma mark - MemoryWarning - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - MoreButtonDelegate -(void)moreBtnAction:(id)sender { NSInteger tag = [(UIButton *)sender tag]; NSLog(@"MoreBtn Action : %li", (long)tag); switch (tag) { case Add: { [self addNewRule]; } break; case Del: { [self toggleEditMode]; } break; case Refresh: { } break; default: break; } } @end