PageRenderTime 24ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/Classes/UVWelcomeViewController.m

https://github.com/appsocial/uservoice-iphone-sdk
Objective C | 478 lines | 357 code | 100 blank | 21 comment | 48 complexity | b03114c6876405dbf7078d06e7992642 MD5 | raw file
  1. //
  2. // UVWelcomeViewController.m
  3. // UserVoice
  4. //
  5. // Created by UserVoice on 12/15/09.
  6. // Copyright 2009 UserVoice Inc. All rights reserved.
  7. //
  8. #import "UVWelcomeViewController.h"
  9. #import "UVStyleSheet.h"
  10. #import "UVFooterView.h"
  11. #import "UVSession.h"
  12. #import "UVForum.h"
  13. #import "UVClientConfig.h"
  14. #import "UVSubdomain.h"
  15. #import "UVQuestion.h"
  16. #import "UVAnswer.h"
  17. #import "UVNewTicketViewController.h"
  18. #import "UVSuggestionListViewController.h"
  19. #import "UVSignInViewController.h"
  20. #import "UVStreamPoller.h"
  21. #import <QuartzCore/QuartzCore.h>
  22. #define UV_FORUM_LIST_TAG_CELL_LABEL 1000
  23. #define UV_FORUM_LIST_TAG_CELL_IMAGE 1001
  24. #define UV_FORUM_LIST_TAG_CELL_QUESTION_SEGMENTS 1002
  25. #define UV_FORUM_LIST_TAG_CELL_MSG_TAG 1003
  26. #define UV_FORUM_LIST_SECTION_FORUMS 0
  27. #define UV_FORUM_LIST_SECTION_SUPPORT 1
  28. #define UV_FORUM_LIST_SECTION_QUESTIONS 2
  29. @implementation UVWelcomeViewController
  30. @synthesize forum = _forum,
  31. question = _question,
  32. questions = _questions,
  33. tableView = _tableView;
  34. - (NSString *)backButtonTitle {
  35. return @"Welcome";
  36. }
  37. - (void)questionSegmentChanged:(id)sender {
  38. UISegmentedControl *segments = (UISegmentedControl *)sender;
  39. [self showActivityIndicator];
  40. // still using single question hack of assigning a single current one
  41. [UVAnswer initWithQuestion:self.question andValue:(segments.selectedSegmentIndex + 1) andDelegate:self];
  42. }
  43. - (void)didCreateAnswer:(UVAnswer *)theAnswer {
  44. [self hideActivityIndicator];
  45. self.question.currentAnswer = theAnswer;
  46. // Prompt for app store review if the returned rating indicates this (driven by
  47. // server side logic based on rating value) and if we actually have an app id.
  48. if (theAnswer.value >= 4 && [UVSession currentSession].clientConfig.itunesApplicationId) {
  49. UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Rating"
  50. message:@"Would you like to add your rating to the iTunes store?"
  51. delegate:self
  52. cancelButtonTitle:@"Cancel"
  53. otherButtonTitles:@"OK", nil];
  54. [alert show];
  55. [alert release];
  56. }
  57. }
  58. #pragma mark ===== UIAlertViewDelegate Methods =====
  59. - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
  60. if (buttonIndex == alertView.firstOtherButtonIndex) {
  61. NSString *url = [NSString stringWithFormat:@"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%@",
  62. [UVSession currentSession].clientConfig.itunesApplicationId];
  63. NSLog(@"Attempting to open iTunes page: %@", url);
  64. [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
  65. }
  66. }
  67. - (void)pushNewTicketView {
  68. UVNewTicketViewController *next = [[UVNewTicketViewController alloc] init];
  69. [self.navigationController pushViewController:next animated:YES];
  70. [next release];
  71. }
  72. - (void)pushForumView {
  73. UVSuggestionListViewController *next = [[UVSuggestionListViewController alloc] initWithForum:self.forum];
  74. [self.navigationController pushViewController:next animated:YES];
  75. [next release];
  76. }
  77. #pragma mark ===== table cells =====
  78. - (void)initCellForForum:(UITableViewCell *)cell indexPath:(NSIndexPath *)indexPath {
  79. [self removeBackgroundFromCell:cell];
  80. cell.selectionStyle = UITableViewCellSelectionStyleNone;
  81. //CGRect screenRect = [[UIScreen mainScreen] bounds];
  82. //CGFloat screenWidth = screenRect.size.width;
  83. CGFloat screenWidth = [UVClientConfig getScreenWidth];
  84. UIView *bg = [[UILabel alloc] initWithFrame:CGRectMake(-10, -10, screenWidth, 55)];
  85. bg.backgroundColor = [UVStyleSheet lightBgColor];
  86. [cell.contentView addSubview:bg];
  87. [bg release];
  88. UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  89. myButton.tag = UV_FORUM_LIST_TAG_CELL_LABEL;
  90. myButton.frame = CGRectMake(0, 0, (screenWidth - 20), 44); // position in the parent view and set the size of the button
  91. [myButton setTitle:[_forum prompt] forState:UIControlStateNormal];
  92. [myButton addTarget:self action:@selector(pushForumView) forControlEvents:UIControlEventTouchUpInside];
  93. [myButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  94. [myButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
  95. UIEdgeInsets insets = UIEdgeInsetsMake(0,10,0,0);
  96. myButton.titleEdgeInsets = insets;
  97. myButton.titleLabel.font = [UIFont boldSystemFontOfSize: 16];
  98. myButton.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
  99. myButton.titleLabel.numberOfLines = 1;
  100. [cell.contentView addSubview:myButton];
  101. cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  102. }
  103. - (void)customizeCellForForum:(UITableViewCell *)cell indexPath:(NSIndexPath *)indexPath {
  104. UIButton *myButton = (UIButton *)[cell.contentView viewWithTag:UV_FORUM_LIST_TAG_CELL_LABEL];
  105. [myButton setTitle:[_forum prompt] forState:UIControlStateNormal];
  106. }
  107. - (CGFloat)heightForViewWithHeader:(NSString *)header subheader:(NSString *)subheader
  108. {
  109. CGFloat screenWidth = [UVClientConfig getScreenWidth];
  110. if (subheader) {
  111. CGSize subSize = [subheader sizeWithFont:[UIFont systemFontOfSize:14]
  112. constrainedToSize:CGSizeMake((screenWidth - 40), 9999)
  113. lineBreakMode:UILineBreakModeWordWrap];
  114. return subSize.height + 35 + 5 + 5; // (subheader + header + padding between/bottom)
  115. } else if (header) {
  116. return 35 + 5; // header + padding bottom only
  117. }
  118. return 10;
  119. }
  120. - (void)initCellForSupport:(UITableViewCell *)cell indexPath:(NSIndexPath *)indexPath {
  121. [self removeBackgroundFromCell:cell];
  122. cell.selectionStyle = UITableViewCellSelectionStyleNone;
  123. CGFloat screenWidth = [UVClientConfig getScreenWidth];
  124. UIView *bg = [[UILabel alloc] initWithFrame:CGRectMake(-10, -10, screenWidth, 55)];
  125. bg.backgroundColor = [UVStyleSheet lightBgColor];
  126. [cell.contentView addSubview:bg];
  127. [bg release];
  128. UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  129. myButton.frame = CGRectMake(0, 0, (screenWidth - 20), 44);
  130. [myButton addTarget:self action:@selector(pushNewTicketView) forControlEvents:UIControlEventTouchUpInside];
  131. [myButton setTitle:[NSString stringWithFormat:@"Contact %@", [UVSession currentSession].clientConfig.subdomain.name]
  132. forState:UIControlStateNormal];
  133. [myButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  134. [myButton setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft];
  135. UIEdgeInsets insets = UIEdgeInsetsMake (0,10,0,0);
  136. myButton.titleEdgeInsets = insets;
  137. myButton.titleLabel.font = [UIFont boldSystemFontOfSize: 16];
  138. myButton.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
  139. myButton.titleLabel.numberOfLines = 1;
  140. [cell.contentView addSubview:myButton];
  141. cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  142. }
  143. - (void)addQuestionCell:(UITableViewCell *)cell labelWithText:(NSString *)text alignment:(UITextAlignment)alignment {
  144. // Simply stack up all labels with the same frame. The alignment will take care of things.
  145. CGFloat screenWidth = [UVClientConfig getScreenWidth];
  146. UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 49, (screenWidth-40), 15)];
  147. label.backgroundColor = [UIColor clearColor];
  148. label.font = [UIFont systemFontOfSize:12];
  149. label.textColor = [UVStyleSheet tableViewHeaderColor];
  150. label.text = text;
  151. label.textAlignment = alignment;
  152. [cell.contentView addSubview:label];
  153. [label release];
  154. }
  155. - (void)updateSegmentsValue:(UISegmentedControl *)segments {
  156. if (self.question.currentAnswer && self.question.currentAnswer.value > 0) {
  157. // Answers are 1-5 (0 means none), indexes 0-4
  158. segments.selectedSegmentIndex = self.question.currentAnswer.value - 1;
  159. } else {
  160. segments.selectedSegmentIndex = UISegmentedControlNoSegment;
  161. }
  162. }
  163. - (void)initCellForQuestion:(UITableViewCell *)cell indexPath:(NSIndexPath *)indexPath {
  164. [self removeBackgroundFromCell:cell];
  165. cell.selectionStyle = UITableViewCellSelectionStyleNone;
  166. CGFloat screenWidth = [UVClientConfig getScreenWidth];
  167. UIView *bg = [[UILabel alloc] initWithFrame:CGRectMake(-10, -10, screenWidth, 80)];
  168. bg.backgroundColor = [UVStyleSheet lightBgColor];
  169. [cell.contentView addSubview:bg];
  170. [bg release];
  171. NSArray *items = [NSArray arrayWithObjects:@"1", @"2", @"3", @"4", @"5", nil];
  172. UISegmentedControl *segments = [[UISegmentedControl alloc] initWithItems:items];
  173. segments.tag = UV_FORUM_LIST_TAG_CELL_QUESTION_SEGMENTS;
  174. segments.frame = CGRectMake(0, 0, (screenWidth - 20), 44);
  175. [self updateSegmentsValue:segments]; // necessary to avoid triggering an update when we set it in the customize method
  176. [segments addTarget:self action:@selector(questionSegmentChanged:) forControlEvents:UIControlEventValueChanged];
  177. // add segments
  178. [cell.contentView addSubview:segments];
  179. [segments release];
  180. }
  181. - (void)customizeCellForQuestion:(UITableViewCell *)cell indexPath:(NSIndexPath *)indexPath {
  182. // disable unless user
  183. BOOL enabled = [UVSession currentSession].user != nil;
  184. UISegmentedControl *segments = (UISegmentedControl *)[cell.contentView viewWithTag:UV_FORUM_LIST_TAG_CELL_QUESTION_SEGMENTS];
  185. [segments setEnabled:enabled];
  186. if (enabled) {
  187. [[cell.contentView viewWithTag:UV_FORUM_LIST_TAG_CELL_MSG_TAG] setHidden:YES];
  188. [self addQuestionCell:cell labelWithText:@"Unlikely" alignment:UITextAlignmentLeft];
  189. [self addQuestionCell:cell labelWithText:@"Maybe" alignment:UITextAlignmentCenter];
  190. [self addQuestionCell:cell labelWithText:@"Absolutely" alignment:UITextAlignmentRight];
  191. } else {
  192. CGFloat screenWidth = [UVClientConfig getScreenWidth];
  193. UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 46, (screenWidth - 20), 20)];
  194. label.tag = UV_FORUM_LIST_TAG_CELL_MSG_TAG;
  195. label.textAlignment = UITextAlignmentCenter;
  196. label.font = [UIFont boldSystemFontOfSize:12];
  197. label.text = @"You will need to sign in to answer.";
  198. label.backgroundColor = [UIColor clearColor];
  199. label.textColor = [UVStyleSheet darkRedColor];
  200. [cell.contentView addSubview:label];
  201. [label release];
  202. }
  203. }
  204. - (void)initCellForSpacer:(UITableViewCell *)cell indexPath:(NSIndexPath *)indexPath {
  205. [self removeBackgroundFromCell:cell];
  206. cell.selectionStyle = UITableViewCellSelectionStyleNone;
  207. CGFloat screenWidth = [UVClientConfig getScreenWidth];
  208. UIView *bg = [[UILabel alloc] initWithFrame:CGRectMake(-10, -10, screenWidth, 11)];
  209. bg.backgroundColor = [UVStyleSheet lightBgColor];
  210. [cell.contentView addSubview:bg];
  211. [bg release];
  212. }
  213. - (UIView *)viewWithHeader:(NSString *)header subheader:(NSString *)subheader {
  214. CGFloat height = [self heightForViewWithHeader:header subheader:subheader];
  215. CGFloat screenWidth = [UVClientConfig getScreenWidth];
  216. UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, height)] autorelease];
  217. headerView.backgroundColor = [UVStyleSheet lightBgColor];
  218. UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(20, 5, (screenWidth - 40), 35)];
  219. title.text = header;
  220. title.font = [UIFont boldSystemFontOfSize:18];
  221. title.backgroundColor = [UIColor clearColor];
  222. title.textColor = [UVStyleSheet tableViewHeaderColor];
  223. [headerView addSubview:title];
  224. [title release];
  225. if (subheader) {
  226. UILabel *subtitle = [[UILabel alloc] initWithFrame:CGRectMake(20, 33, (screenWidth - 40), height - (33 + 5))];
  227. subtitle.text = subheader;
  228. subtitle.lineBreakMode = UILineBreakModeWordWrap;
  229. subtitle.numberOfLines = 0;
  230. subtitle.font = [UIFont systemFontOfSize:14];
  231. subtitle.backgroundColor = [UIColor clearColor];
  232. subtitle.textColor = [UVStyleSheet tableViewHeaderColor];
  233. [headerView addSubview:subtitle];
  234. [subtitle release];
  235. }
  236. return headerView;
  237. }
  238. - (NSString *)headerTextForSection:(NSInteger)section {
  239. if (section == 0) {
  240. return @"Suggestions";
  241. } else if (section == 1) {
  242. return [UVSession currentSession].clientConfig.ticketsEnabled ? @"Support" : nil;
  243. } else {
  244. return [UVSession currentSession].clientConfig.questionsEnabled ? @"Rating" : nil;
  245. }
  246. }
  247. - (NSString *)subHeaderTextForSection:(NSInteger)section {
  248. if (section <= UV_FORUM_LIST_SECTION_SUPPORT) {
  249. return nil;
  250. } else {
  251. NSArray *qs = [UVSession currentSession].clientConfig.questions;
  252. UVQuestion *q = [qs objectAtIndex:0];
  253. return [UVSession currentSession].clientConfig.questionsEnabled ? q.text : nil;
  254. }
  255. }
  256. #pragma mark ===== UITableViewDataSource Methods =====
  257. - (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  258. NSString *identifier = @"";
  259. BOOL selectable = NO;
  260. UITableViewCellStyle style = UITableViewCellStyleDefault;
  261. if (indexPath.section == UV_FORUM_LIST_SECTION_FORUMS) {
  262. identifier = @"Forum";
  263. } else if (indexPath.section == UV_FORUM_LIST_SECTION_SUPPORT) {
  264. if ([UVSession currentSession].clientConfig.ticketsEnabled) {
  265. identifier = @"Support";
  266. } else {
  267. identifier = @"Spacer";
  268. }
  269. } else if (indexPath.section == UV_FORUM_LIST_SECTION_QUESTIONS) {
  270. if ([UVSession currentSession].clientConfig.questionsEnabled) {
  271. identifier = @"Question";
  272. if ([UVSession currentSession].user == nil)
  273. selectable = YES;
  274. } else {
  275. identifier = @"Spacer";
  276. }
  277. }
  278. return [self createCellForIdentifier:identifier
  279. tableView:theTableView
  280. indexPath:indexPath
  281. style:style
  282. selectable:selectable];
  283. }
  284. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  285. return 3;
  286. }
  287. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  288. return 1;
  289. }
  290. - (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  291. [theTableView deselectRowAtIndexPath:indexPath animated:YES];
  292. switch (indexPath.section) {
  293. case UV_FORUM_LIST_SECTION_QUESTIONS: {
  294. if ([UVSession currentSession].user==nil) {
  295. UVSignInViewController *next = [[UVSignInViewController alloc] init];
  296. [self.navigationController pushViewController:next animated:YES];
  297. [next release];
  298. }
  299. break;
  300. }
  301. default:
  302. break;
  303. }
  304. }
  305. #pragma mark ===== UITableViewDelegate Methods =====
  306. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  307. if (indexPath.section == UV_FORUM_LIST_SECTION_FORUMS) {
  308. return 45;
  309. } else if (indexPath.section == UV_FORUM_LIST_SECTION_SUPPORT) {
  310. return [UVSession currentSession].clientConfig.ticketsEnabled ? 45 : 0.0;
  311. } else if (indexPath.section == UV_FORUM_LIST_SECTION_QUESTIONS) {
  312. return [UVSession currentSession].clientConfig.questionsEnabled ? 70 : 0.0;
  313. }
  314. return 0.0;
  315. }
  316. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  317. return [self heightForViewWithHeader:[self headerTextForSection:section]
  318. subheader:[self subHeaderTextForSection:section]];
  319. }
  320. - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  321. return [self viewWithHeader:[self headerTextForSection:section]
  322. subheader:[self subHeaderTextForSection:section]];
  323. }
  324. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  325. return 0.0;
  326. }
  327. #pragma mark ===== Basic View Methods =====
  328. // Implement loadView to create a view hierarchy programmatically, without using a nib.
  329. - (void)loadView {
  330. [super loadView];
  331. [self.navigationItem setHidesBackButton:YES animated:NO];
  332. CGRect frame = [self contentFrame];
  333. _tableView = [[UITableView alloc] initWithFrame:frame style:UITableViewStyleGrouped];
  334. _tableView.dataSource = self;
  335. _tableView.delegate = self;
  336. _tableView.contentInset = UIEdgeInsetsMake(-10, 0, 0, 0);
  337. _tableView.sectionFooterHeight = 0.0;
  338. _tableView.sectionHeaderHeight = 0.0;
  339. CGFloat screenWidth = [UVClientConfig getScreenWidth];
  340. UIView *topShadow = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 10)];
  341. UIImage *shadow = [UIImage imageNamed:@"dropshadow_top_20.png"];
  342. UIImageView *shadowView = [[UIImageView alloc] initWithImage:shadow];
  343. [topShadow addSubview:shadowView];
  344. _tableView.tableHeaderView = shadowView;
  345. [shadowView release];
  346. [topShadow release];
  347. _tableView.tableFooterView = [UVFooterView footerViewForController:self];
  348. self.view = _tableView;
  349. if ([UVSession currentSession].clientConfig.questionsEnabled) {
  350. _questions = [UVSession currentSession].clientConfig.questions;
  351. _question = [_questions objectAtIndex:0];
  352. }
  353. }
  354. - (void)viewWillAppear:(BOOL)animated {
  355. [super viewWillAppear:animated];
  356. _forum = [UVSession currentSession].clientConfig.forum;
  357. if ([self needsReload]) {
  358. NSLog(@"WelcomeView needs reload");
  359. UISegmentedControl *segments =
  360. (UISegmentedControl *)[_tableView viewWithTag:UV_FORUM_LIST_TAG_CELL_QUESTION_SEGMENTS];
  361. [(UVFooterView *)_tableView.tableFooterView reloadFooter];
  362. [self updateSegmentsValue:segments];
  363. }
  364. [_tableView reloadData];
  365. }
  366. - (void)didReceiveMemoryWarning {
  367. // Releases the view if it doesn't have a superview.
  368. [super didReceiveMemoryWarning];
  369. // Release any cached data, images, etc that aren't in use.
  370. }
  371. - (void)viewDidUnload {
  372. // Release any retained subviews of the main view.
  373. // e.g. self.myOutlet = nil;
  374. }
  375. - (void)dealloc {
  376. [super dealloc];
  377. }
  378. @end