2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell/*
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell * The contents of this file are subject to the terms of the Common Development and
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell * Distribution License (the License). You may not use this file except in compliance with the
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell * License.
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell *
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell * specific language governing permission and limitations under the License.
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell *
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell * When distributing Covered Software, include this CDDL Header Notice in each file and include
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell * Header, with the fields enclosed by brackets [] replaced by your own identifying
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell * information: "Portions copyright [year] [name of copyright owner]".
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell *
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell * Copyright 2016 ForgeRock AS.
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell */
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell#import "FRAIdentityDatabase.h"
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell#import "FRANotification.h"
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell#import "FRANotificationsTableViewController.h"
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell#import "FRANotificationViewController.h"
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell#import "FRANotificationTableViewCell.h"
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell#import "FRAPushMechanism.h"
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnellNSString * const FRANotificationsTableViewControllerStoryboardIdentifer = @"NotificationsTableViewController";
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnellNSString * const FRANotificationsTableViewControllerShowNotificationsSegue = @"showNotificationSegue";
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnellstatic const NSInteger NUMBER_OF_SECTIONS = 2;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnellstatic const NSInteger PENDING_SECTION_INDEX = 0;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnellstatic const NSInteger COMPLETED_SECTION_INDEX = 1;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell/*!
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell * Private interface.
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell */
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell@interface FRANotificationsTableViewController ()
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell/*!
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell * Timer for updating age of notifications.
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell */
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell@property (strong, nonatomic) NSTimer *timer;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell@end
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell@implementation FRANotificationsTableViewController
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell#pragma mark -
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell#pragma mark UIViewController
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell- (void)viewWillAppear:(BOOL)animated {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [super viewWillAppear:animated];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [self.tableView reloadData];
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni if ([self numberOfNotifications] == 0) {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni [self addLabelToTableViewBackground];
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni } else {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni [self clearTableViewBackground];
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni }
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleIdentityDatabaseChanged:) name:FRAIdentityDatabaseChangedNotification object:nil];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell if (!self.timer) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerCallback:) userInfo:nil repeats:YES];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell }
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell}
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell- (void)viewWillDisappear:(BOOL)animated {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [self.timer invalidate];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell self.timer = nil;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [[NSNotificationCenter defaultCenter] removeObserver:self];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell}
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
916ef74523ecddc8140815c084ab6971ee366bcfCraig McDonnell if ([segue.identifier isEqualToString:FRANotificationsTableViewControllerShowNotificationsSegue]) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell FRANotificationViewController *controller = (FRANotificationViewController *)segue.destinationViewController;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell NSArray *selection = [self.tableView indexPathsForSelectedRows];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell NSIndexPath *indexPath = [selection objectAtIndex:0];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell controller.notification = [[self pendingNotifications] objectAtIndex:indexPath.row];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell }
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell}
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell#pragma mark -
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell#pragma mark UITableViewDataSource
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni if ([self completedNotifications].count == 0) {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni return 1;
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni }
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell return NUMBER_OF_SECTIONS;
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell}
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell if (section == PENDING_SECTION_INDEX) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell return [self pendingNotifications].count;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell } else {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell return [self completedNotifications].count;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell }
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell}
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni return section == PENDING_SECTION_INDEX ? @"" : NSLocalizedString(@"notifications_completed_section_title", nil);
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell}
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell UIColor* seaGreen = [UIColor colorWithRed:48.0/255.0 green:160.0/255.0 blue:157.0/255.0 alpha:1.0];
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell UIColor* dashboardRed = [UIColor colorWithRed:169.0/255.0 green:68.0/255.0 blue:66.0/255.0 alpha:1.0];
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell static NSString *CellIdentifier = @"NotificationCell";
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell if (indexPath.section == PENDING_SECTION_INDEX) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell FRANotificationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell FRANotification *notification = [[self pendingNotifications] objectAtIndex:indexPath.row];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni cell.status.text = NSLocalizedString(@"notifications_pending_status", nil);
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell cell.image.image = [[UIImage imageNamed:@"PendingIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell cell.image.tintColor = [UIColor grayColor];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell cell.time.text = [notification age];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell // enable selection/segue from pending notifications
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell cell.selectionStyle = UITableViewCellSelectionStyleDefault;
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell [cell setUserInteractionEnabled:YES];
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell return cell;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell } else if (indexPath.section == COMPLETED_SECTION_INDEX) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell FRANotificationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell FRANotification *notification = [[self completedNotifications] objectAtIndex:indexPath.row];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell if (notification.isApproved) {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni cell.status.text = NSLocalizedString(@"notifications_approved_status", nil);
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell cell.image.image = [[UIImage imageNamed:@"ApprovedIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell cell.image.tintColor = seaGreen;
3cb6a584a87fa8fec140b0bb20dd91731d13e751Diego Colantoni } else if (notification.isDenied) {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni cell.status.text = NSLocalizedString(@"notifications_denied_status", nil);
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell cell.image.image = [[UIImage imageNamed:@"DeniedIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell cell.image.tintColor = dashboardRed;
3cb6a584a87fa8fec140b0bb20dd91731d13e751Diego Colantoni } else if (notification.isExpired) {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni cell.status.text = NSLocalizedString(@"notifications_expired_status", nil);
3cb6a584a87fa8fec140b0bb20dd91731d13e751Diego Colantoni cell.image.image = [[UIImage imageNamed:@"DeniedIcon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
3cb6a584a87fa8fec140b0bb20dd91731d13e751Diego Colantoni cell.image.tintColor = dashboardRed;
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell }
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell cell.time.text = [notification age];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell // don't enable selection/segue from completed notifications
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell cell.selectionStyle = UITableViewCellSelectionStyleNone;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [cell setUserInteractionEnabled:NO];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell cell.accessoryType = UITableViewCellAccessoryNone;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell return cell;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell } else {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell return [super tableView:tableView cellForRowAtIndexPath:indexPath];
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell }
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell}
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell#pragma mark -
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell#pragma mark UITableViewDelegate
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell if (indexPath.section == PENDING_SECTION_INDEX) {
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell // only enable selection/segue from pending notifications
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell return indexPath;
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell } else {
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell return nil;
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell }
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell}
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell // make table cell separator lines full width (normally, they leave a ~10% gap at the left edge)
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell [cell setSeparatorInset:UIEdgeInsetsZero];
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell }
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell [cell setLayoutMargins:UIEdgeInsetsZero];
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell }
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell}
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell#pragma mark -
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell#pragma mark FRANotificationsTableViewController
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell- (NSArray *)pendingNotifications {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell NSMutableArray *pendingNotifications = [NSMutableArray array];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell for (FRANotification *notification in [self.pushMechanism notifications]) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell if (notification.isPending) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [pendingNotifications addObject:notification];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell }
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell }
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [self sortNotifications:pendingNotifications];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell return pendingNotifications;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell}
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell/*!
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell * Sorts notifications in reverse chronological order.
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell */
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell- (void)sortNotifications:(NSMutableArray *)notifications {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [notifications sortUsingComparator:^NSComparisonResult(FRANotification* first, FRANotification* second) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell return [second.timeReceived compare:first.timeReceived];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell }];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell}
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell- (NSArray *)completedNotifications {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell NSMutableArray *completedNotifications = [NSMutableArray array];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell for (FRANotification *notification in [self.pushMechanism notifications]) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell if (!notification.isPending) {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [completedNotifications addObject:notification];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell }
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell }
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [self sortNotifications:completedNotifications];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell return completedNotifications;
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell}
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell- (void)handleIdentityDatabaseChanged:(NSNotification *)notification {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [self.tableView reloadData];
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell}
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell- (void)timerCallback:(NSTimer*)timer {
a3970d0ea62388e4ede01470a6436eb5c6c92353Craig McDonnell [self.tableView reloadData];
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell}
fb63998ce7684bddab24e10c0b593809df1b7bffCraig McDonnell
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni- (NSUInteger)numberOfNotifications {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni return [self pendingNotifications].count + [self completedNotifications].count;
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni}
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni- (void)addLabelToTableViewBackground {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, self.tableView.bounds.size.height)];
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni label.text = NSLocalizedString(@"notifications_no_notifications", nil);
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni label.textColor = [UIColor grayColor];
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni label.textAlignment = NSTextAlignmentCenter;
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni self.tableView.backgroundView = label;
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni}
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni- (void)clearTableViewBackground {
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni self.tableView.backgroundView = nil;
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni}
12e7a579c676ce6e5d1a822557813542d7687d11Diego Colantoni
2229ffbfe08c2cd606c305f8934e627548002c9eCraig McDonnell@end