425 lines
15 KiB
Objective-C
425 lines
15 KiB
Objective-C
#import "ContactDetailViewController.h"
|
|
#import "ContactTableViewCell.h"
|
|
#import "Environment.h"
|
|
#import "InboxFeedFooterCell.h"
|
|
#import "InboxFeedViewController.h"
|
|
#import "LeftSideMenuViewController.h"
|
|
#import "LocalizableText.h"
|
|
#import "PreferencesUtil.h"
|
|
#import "RecentCall.h"
|
|
#import "RecentCallManager.h"
|
|
#import "RegisterViewController.h"
|
|
|
|
#import <UIViewController+MMDrawerController.h>
|
|
|
|
#define CONTACT_TABLE_VIEW_CELL_HEIGHT 44
|
|
#define FOOTER_CELL_HEIGHT 44
|
|
#define INBOX_TABLE_VIEW_CELL_HEIGHT 71
|
|
|
|
#define SEARCH_TABLE_SECTION_FEED 0
|
|
#define SEARCH_TABLE_SECTION_REGISTERED 1
|
|
#define SEARCH_TABLE_SECTION_UNREGISTERED 2
|
|
|
|
#define TABLE_VIEW_NUM_SECTIONS_DEFAULT 1
|
|
#define TABLE_VIEW_NUM_SECTIONS_SEARCHING 3
|
|
|
|
static NSString *const INBOX_FEED_TABLE_VIEW_CELL_IDENTIFIER = @"InboxFeedTableViewCell";
|
|
static NSString *const CONTACT_TABLE_VIEW_CELL_IDENTIFIER = @"ContactTableViewCell";
|
|
static NSString *const FOOTER_TABLE_CELL_IDENTIFIER = @"InboxFeedFooterCell";
|
|
|
|
@interface InboxFeedViewController () {
|
|
NSArray *_inboxFeed;
|
|
BOOL _tableViewContentMutating;
|
|
BOOL _isSearching;
|
|
|
|
NSArray *_searchInboxFeed;
|
|
NSArray *_searchRegisteredContacts;
|
|
NSArray *_searchUnregisteredContacts;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation InboxFeedViewController
|
|
|
|
- (void)viewDidLoad {
|
|
[super viewDidLoad];
|
|
|
|
[self observeRecentCalls];
|
|
[self observeKeyboardNotifications];
|
|
[self setupLabelLocalizationAndStyles];
|
|
|
|
if (![Environment isRegistered]) {
|
|
[Environment resetAppData];
|
|
RegisterViewController *registerViewController = [RegisterViewController registerViewController];
|
|
[self presentViewController:registerViewController animated:NO completion:nil];
|
|
}
|
|
_inboxFeedTableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
|
|
}
|
|
|
|
- (void)viewWillDisappear:(BOOL)animated {
|
|
[super viewWillDisappear:animated];
|
|
[self markMissedCallsAsViewed];
|
|
[self.navigationController setNavigationBarHidden:NO animated:YES];
|
|
}
|
|
|
|
- (void)viewWillAppear:(BOOL)animated {
|
|
[super viewWillAppear:animated];
|
|
[self.navigationController setNavigationBarHidden:YES animated:NO];
|
|
[_searchBarTitleView updateAutoCorrectionType];
|
|
[_inboxFeedTableView reloadData];
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
}
|
|
|
|
- (UIStatusBarStyle)preferredStatusBarStyle {
|
|
return UIStatusBarStyleLightContent;
|
|
}
|
|
|
|
- (void)observeRecentCalls {
|
|
ObservableValue *observableContacts = [[[Environment getCurrent] contactsManager] getObservableContacts];
|
|
|
|
[observableContacts watchLatestValue:^(id latestValue) {
|
|
|
|
ObservableValue *observableRecents = [[[Environment getCurrent] recentCallManager] getObservableRecentCalls];
|
|
|
|
[observableRecents watchLatestValue:^(NSArray *latestRecents) {
|
|
_inboxFeed = [[[Environment getCurrent] recentCallManager] recentsForSearchString:nil
|
|
andExcludeArchived:YES];
|
|
[self updateTutorialVisibility];
|
|
if (!_tableViewContentMutating) {
|
|
[_inboxFeedTableView reloadData];
|
|
}
|
|
if (_isSearching) {
|
|
[_searchBarTitleView textField:_searchBarTitleView.searchTextField
|
|
shouldChangeCharactersInRange:NSMakeRange(0, 0)
|
|
replacementString:SEARCH_BAR_DEFAULT_EMPTY_STRING];
|
|
}
|
|
} onThread:[NSThread mainThread] untilCancelled:nil];
|
|
|
|
|
|
} onThread:[NSThread mainThread] untilCancelled:nil];
|
|
}
|
|
|
|
- (void)observeKeyboardNotifications {
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(keyboardWillShow:)
|
|
name:UIKeyboardWillShowNotification
|
|
object:nil];
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
selector:@selector(keyboardWillHide:)
|
|
name:UIKeyboardWillHideNotification
|
|
object:nil];
|
|
}
|
|
|
|
- (void)setupLabelLocalizationAndStyles {
|
|
_freshAppTutorialTopLabel.text = INBOX_VIEW_TUTORIAL_LABEL_TOP;
|
|
_freshAppTutorialMiddleLabel.text = INBOX_VIEW_TUTORIAL_LABEL_MIDDLE;
|
|
}
|
|
|
|
#pragma mark - Viewed / Unviewed calls
|
|
|
|
- (void)markMissedCallsAsViewed {
|
|
BOOL needsSave = NO;
|
|
|
|
for (RecentCall *recent in _inboxFeed) {
|
|
if (!recent.userNotified) {
|
|
recent.userNotified = true;
|
|
needsSave = true;
|
|
}
|
|
}
|
|
if (needsSave) {
|
|
[[[Environment getCurrent] recentCallManager] saveContactsToDefaults];
|
|
[(TabBarParentViewController *)self.mm_drawerController.centerViewController updateMissedCallCountLabel];
|
|
[_inboxFeedTableView reloadData];
|
|
}
|
|
}
|
|
|
|
#pragma mark - Actions
|
|
|
|
- (void)showRecentCallViewControllerWithRecentCall:(RecentCall *)recent {
|
|
[(TabBarParentViewController *)self.mm_drawerController.centerViewController showDialerViewControllerWithNumber:recent.phoneNumber];
|
|
}
|
|
|
|
- (void)showContactViewControllerWithContact:(Contact *)contact {
|
|
ContactDetailViewController *vc = [ContactDetailViewController contactDetailViewControllerWithContact:contact];
|
|
[self.navigationController pushViewController:vc animated:YES];
|
|
}
|
|
|
|
- (void)removeNewsFeedCell:(InboxFeedTableViewCell *)cell willDelete:(BOOL)delete {
|
|
_tableViewContentMutating = YES;
|
|
NSIndexPath *indexPath = [_inboxFeedTableView indexPathForCell:cell];
|
|
|
|
[_inboxFeedTableView beginUpdates];
|
|
|
|
RecentCall *recent;
|
|
|
|
if (_isSearching) {
|
|
recent = _searchInboxFeed[(NSUInteger)indexPath.row];
|
|
} else {
|
|
recent = _inboxFeed[(NSUInteger)indexPath.row];
|
|
}
|
|
|
|
recent.userNotified = YES;
|
|
|
|
UITableViewRowAnimation animation;
|
|
|
|
if (delete) {
|
|
animation = UITableViewRowAnimationLeft;
|
|
[[[Environment getCurrent] recentCallManager] removeRecentCall:recent];
|
|
} else {
|
|
animation = UITableViewRowAnimationRight;
|
|
[[[Environment getCurrent] recentCallManager] archiveRecentCall:recent];
|
|
}
|
|
|
|
[_inboxFeedTableView deleteRowsAtIndexPaths:@[indexPath]
|
|
withRowAnimation:animation];
|
|
|
|
[_inboxFeedTableView endUpdates];
|
|
_tableViewContentMutating = NO;
|
|
}
|
|
|
|
- (void)updateTutorialVisibility {
|
|
_freshInboxView.hidden = ![[Environment preferences] getFreshInstallTutorialsEnabled];
|
|
_inboxFeedTableView.hidden = !_freshInboxView.hidden;
|
|
}
|
|
|
|
#pragma mark - UITableViewDelegate
|
|
|
|
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
|
|
if (_isSearching) {
|
|
return TABLE_VIEW_NUM_SECTIONS_SEARCHING;
|
|
} else {
|
|
return TABLE_VIEW_NUM_SECTIONS_DEFAULT;
|
|
}
|
|
}
|
|
|
|
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
|
|
if (section == SEARCH_TABLE_SECTION_FEED) {
|
|
return @"";
|
|
} else if (section == SEARCH_TABLE_SECTION_REGISTERED) {
|
|
return TABLE_SECTION_TITLE_REGISTERED;
|
|
} else {
|
|
return TABLE_SECTION_TITLE_UNREGISTERED;
|
|
}
|
|
}
|
|
|
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
|
|
|
if (_isSearching) {
|
|
if (section == SEARCH_TABLE_SECTION_FEED) {
|
|
return (NSInteger)_searchInboxFeed.count;
|
|
} else if (section == SEARCH_TABLE_SECTION_REGISTERED) {
|
|
return (NSInteger)_searchRegisteredContacts.count;
|
|
} else {
|
|
return (NSInteger)_searchUnregisteredContacts.count;
|
|
}
|
|
} else {
|
|
NSInteger inboxFeedAndInfoCellCount = (NSInteger)_inboxFeed.count + 1;
|
|
return inboxFeedAndInfoCellCount;
|
|
}
|
|
}
|
|
|
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
if (_isSearching) {
|
|
return [self searchCellForIndexPath:indexPath];
|
|
} else {
|
|
return [self inboxFeedCellForIndexPath:indexPath];
|
|
}
|
|
}
|
|
|
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
|
[_searchBarTitleView.searchTextField resignFirstResponder];
|
|
|
|
if (_isSearching) {
|
|
if (indexPath.section == SEARCH_TABLE_SECTION_FEED) {
|
|
[self showRecentCallViewControllerWithRecentCall:_searchInboxFeed[(NSUInteger)indexPath.row]];
|
|
} else if (indexPath.section == SEARCH_TABLE_SECTION_REGISTERED) {
|
|
[self showContactViewControllerWithContact:_searchRegisteredContacts[(NSUInteger)indexPath.row]];
|
|
} else {
|
|
[self showContactViewControllerWithContact:_searchUnregisteredContacts[(NSUInteger)indexPath.row]];
|
|
}
|
|
} else {
|
|
if (indexPath.row < (NSInteger)_inboxFeed.count) {
|
|
[self showRecentCallViewControllerWithRecentCall:_inboxFeed[(NSUInteger)indexPath.row]];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
|
|
if (indexPath.section == SEARCH_TABLE_SECTION_FEED) {
|
|
if ((NSUInteger)indexPath.row == _inboxFeed.count) {
|
|
return FOOTER_CELL_HEIGHT;
|
|
} else {
|
|
return INBOX_TABLE_VIEW_CELL_HEIGHT;
|
|
}
|
|
} else {
|
|
return CONTACT_TABLE_VIEW_CELL_HEIGHT;
|
|
}
|
|
}
|
|
|
|
#pragma mark - Table cell creation
|
|
|
|
- (UITableViewCell *)searchCellForIndexPath:(NSIndexPath *)indexPath {
|
|
if (indexPath.section == SEARCH_TABLE_SECTION_FEED) {
|
|
return [self inboxCellForIndexPath:indexPath andIsSearching:YES];
|
|
} else {
|
|
return [self contactCellForIndexPath:indexPath];
|
|
}
|
|
}
|
|
|
|
- (UITableViewCell *)inboxFeedCellForIndexPath:(NSIndexPath *)indexPath {
|
|
if (!_isSearching && (NSUInteger)[indexPath row] == _inboxFeed.count) {
|
|
return [self inboxFeedFooterCell];
|
|
} else {
|
|
return [self inboxCellForIndexPath:indexPath andIsSearching:NO];
|
|
}
|
|
}
|
|
|
|
- (UITableViewCell *)inboxCellForIndexPath:(NSIndexPath *)indexPath andIsSearching:(BOOL)isSearching {
|
|
InboxFeedTableViewCell *cell = [_inboxFeedTableView dequeueReusableCellWithIdentifier:INBOX_FEED_TABLE_VIEW_CELL_IDENTIFIER];
|
|
|
|
if (!cell) {
|
|
cell = [[InboxFeedTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
|
reuseIdentifier:INBOX_FEED_TABLE_VIEW_CELL_IDENTIFIER];
|
|
cell.delegate = self;
|
|
}
|
|
|
|
RecentCall *recent = isSearching ? _searchInboxFeed[(NSUInteger)indexPath.row] : _inboxFeed[(NSUInteger)indexPath.row];
|
|
[cell configureWithRecentCall:recent];
|
|
return cell;
|
|
}
|
|
|
|
- (UITableViewCell *)contactCellForIndexPath:(NSIndexPath *)indexPath {
|
|
ContactTableViewCell *cell = [_inboxFeedTableView dequeueReusableCellWithIdentifier:CONTACT_TABLE_VIEW_CELL_IDENTIFIER];
|
|
|
|
if (!cell) {
|
|
cell = [[ContactTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
|
reuseIdentifier:CONTACT_TABLE_VIEW_CELL_IDENTIFIER];
|
|
}
|
|
|
|
NSUInteger searchIndex = (NSUInteger)indexPath.row;
|
|
Contact *contact;
|
|
|
|
if (indexPath.section == SEARCH_TABLE_SECTION_REGISTERED) {
|
|
contact = _searchRegisteredContacts[searchIndex];
|
|
} else {
|
|
contact = _searchUnregisteredContacts[searchIndex];
|
|
}
|
|
|
|
[cell configureWithContact:contact];
|
|
|
|
return cell;
|
|
}
|
|
|
|
- (UITableViewCell *)inboxFeedFooterCell {
|
|
InboxFeedFooterCell *cell = [_inboxFeedTableView dequeueReusableCellWithIdentifier:FOOTER_TABLE_CELL_IDENTIFIER];
|
|
|
|
if (!cell) {
|
|
cell = [[InboxFeedFooterCell alloc] initWithStyle:UITableViewCellStyleDefault
|
|
reuseIdentifier:FOOTER_TABLE_CELL_IDENTIFIER];
|
|
}
|
|
|
|
return cell;
|
|
}
|
|
|
|
#pragma mark - HomeFeedTableViewCellDelegate
|
|
|
|
- (void)inboxFeedTableViewCellTappedDelete:(InboxFeedTableViewCell *)cell {
|
|
[self removeNewsFeedCell:cell willDelete:YES];
|
|
}
|
|
|
|
- (void)inboxFeedTableViewCellTappedArchive:(InboxFeedTableViewCell *)cell {
|
|
[self removeNewsFeedCell:cell willDelete:NO];
|
|
}
|
|
|
|
#pragma mark - SearchBarTitleViewDelegate
|
|
|
|
- (void)searchBarTitleView:(SearchBarTitleView *)view didSearchForTerm:(NSString *)term {
|
|
BOOL searching = term.length > 0;
|
|
_isSearching = searching;
|
|
|
|
if (searching) {
|
|
_freshInboxView.hidden = YES;
|
|
_inboxFeedTableView.hidden = NO;
|
|
_searchInboxFeed = [[[Environment getCurrent] recentCallManager] recentsForSearchString:term
|
|
andExcludeArchived:YES];
|
|
|
|
[self reloadSearchContactsForTerm:term];
|
|
} else {
|
|
[self updateTutorialVisibility];
|
|
_searchInboxFeed = nil;
|
|
_searchRegisteredContacts = nil;
|
|
}
|
|
[_inboxFeedTableView reloadData];
|
|
}
|
|
|
|
- (void)searchBarTitleViewDidTapMenu:(SearchBarTitleView *)view {
|
|
[self.mm_drawerController openDrawerSide:MMDrawerSideLeft
|
|
animated:YES
|
|
completion:nil];
|
|
}
|
|
|
|
- (void)searchBarTitleViewDidEndSearching:(SearchBarTitleView *)view {
|
|
_isSearching = false;
|
|
[self updateTutorialVisibility];
|
|
[_inboxFeedTableView reloadData];
|
|
}
|
|
|
|
- (void)reloadSearchContactsForTerm:(NSString *)term {
|
|
|
|
NSArray *contacts = [[[Environment getCurrent] contactsManager] latestContactsWithSearchString:term];
|
|
|
|
NSMutableArray *registeredContacts = [NSMutableArray array];
|
|
NSMutableArray *unregisteredContacts = [NSMutableArray array];
|
|
|
|
for (Contact *contact in contacts) {
|
|
BOOL registeredContact = NO;
|
|
|
|
for (PhoneNumber *phoneNumber in contact.parsedPhoneNumbers) {
|
|
if ([[[[Environment getCurrent] phoneDirectoryManager] getCurrentFilter] containsPhoneNumber:phoneNumber]) {
|
|
registeredContact = YES;
|
|
}
|
|
}
|
|
|
|
if (registeredContact) {
|
|
[registeredContacts addObject:contact];
|
|
} else {
|
|
[unregisteredContacts addObject:contact];
|
|
}
|
|
}
|
|
|
|
_searchRegisteredContacts = [registeredContacts copy];
|
|
_searchUnregisteredContacts = [unregisteredContacts copy];
|
|
}
|
|
|
|
#pragma mark - Keyboard
|
|
|
|
- (void)keyboardWillShow:(NSNotification *)notification {
|
|
double duration = [[notification userInfo][UIKeyboardAnimationDurationUserInfoKey] doubleValue];
|
|
[UIView animateWithDuration:duration animations:^{
|
|
CGSize keyboardSize = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
|
|
CGFloat height = CGRectGetHeight(_inboxFeedTableView.frame) - (keyboardSize.height-BOTTOM_TAB_BAR_HEIGHT);
|
|
_inboxFeedTableView.frame = CGRectMake(CGRectGetMinX(_inboxFeedTableView.frame),
|
|
CGRectGetMinY(_inboxFeedTableView.frame),
|
|
CGRectGetWidth(_inboxFeedTableView.frame),
|
|
height);
|
|
}];
|
|
}
|
|
|
|
- (void)keyboardWillHide:(NSNotification *)notification {
|
|
CGSize keyboardSize = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
|
|
CGFloat height = CGRectGetHeight(_inboxFeedTableView.frame) + (keyboardSize.height-BOTTOM_TAB_BAR_HEIGHT);
|
|
_inboxFeedTableView.frame = CGRectMake(CGRectGetMinX(_inboxFeedTableView.frame),
|
|
CGRectGetMinY(_inboxFeedTableView.frame),
|
|
CGRectGetWidth(_inboxFeedTableView.frame),
|
|
height);
|
|
if (!_searchInboxFeed) {
|
|
[self updateTutorialVisibility];
|
|
}
|
|
}
|
|
@end
|