diff --git a/Classes/VoiceBase/MGMAddons.m b/Classes/VoiceBase/MGMAddons.m index d4782e7..5c4192d 100644 --- a/Classes/VoiceBase/MGMAddons.m +++ b/Classes/VoiceBase/MGMAddons.m @@ -70,6 +70,8 @@ - (NSString *)escapeSMS { NSString *escaped = [self replace:@"\\" with:@"\\\\"]; escaped = [escaped replace:@"'" with:@"\\'"]; + escaped = [escaped replace:@"\n" with:@"
"]; + escaped = [escaped replace:@"\r" with:@""]; return escaped; } diff --git a/Classes/VoiceBase/MGMInbox.m b/Classes/VoiceBase/MGMInbox.m index 97c9dca..4fb0052 100644 --- a/Classes/VoiceBase/MGMInbox.m +++ b/Classes/VoiceBase/MGMInbox.m @@ -355,7 +355,10 @@ const BOOL MGMInboxInvisible = YES; range = [string rangeOfString:@""]; if (range.location==NSNotFound) NSLog(@"failed 0011"); - [message setObject:[[string substringWithRange:NSMakeRange(0, range.location)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] forKey:MGMIText]; + NSString *messageText = [[string substringWithRange:NSMakeRange(0, range.location)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + messageText = [messageText replace:@"\n" with:@"
"]; + messageText = [messageText replace:@"\r" with:@""]; + [message setObject:messageText forKey:MGMIText]; } range = [theHTML rangeOfString:@""]; if (range.location!=NSNotFound) { diff --git a/Classes/VoiceBase/SIP/MGMSIP.h b/Classes/VoiceBase/SIP/MGMSIP.h index fd6c45a..f657bc8 100644 --- a/Classes/VoiceBase/SIP/MGMSIP.h +++ b/Classes/VoiceBase/SIP/MGMSIP.h @@ -103,6 +103,8 @@ typedef enum { NSMutableArray *restartAccounts; #if !TARGET_OS_IPHONE NSArray *audioDevices; + int lastInputDevice; + int lastOutputDevice; #endif int ringbackCount; diff --git a/Classes/VoiceBase/SIP/MGMSIP.m b/Classes/VoiceBase/SIP/MGMSIP.m index 2f0c94a..02387c0 100644 --- a/Classes/VoiceBase/SIP/MGMSIP.m +++ b/Classes/VoiceBase/SIP/MGMSIP.m @@ -251,6 +251,8 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void state = MGMSIPStoppedState; NATType = MGMSIPNATUnknownType; accounts = [NSMutableArray new]; + lastInputDevice = -1; + lastOutputDevice = -1; shouldRestart = NO; #if !TARGET_OS_IPHONE @@ -513,6 +515,14 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void state = MGMSIPStartedState; + [accounts makeObjectsPerformSelector:@selector(login)]; + + if (delegate!=nil && [delegate respondsToSelector:@selector(SIPStarted)]) [delegate SIPStarted]; + + NSLog(@"MGMSIP Started"); + + [lock unlock]; + pjsua_conf_adjust_tx_level(0, [defaults floatForKey:MGMSIPVolume]); pjsua_conf_adjust_rx_level(0, [defaults floatForKey:MGMSIPMicVolume]); #if !TARGET_OS_IPHONE @@ -522,13 +532,6 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void [self updateAudioDevices]; #endif - [accounts makeObjectsPerformSelector:@selector(login)]; - - if (delegate!=nil && [delegate respondsToSelector:@selector(SIPStarted)]) [delegate SIPStarted]; - - NSLog(@"MGMSIP Started"); - - [lock unlock]; [pool drain]; } - (void)stop { @@ -841,6 +844,9 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void pj_thread_desc PJThreadDesc; [self registerThread:&PJThreadDesc]; + lastInputDevice = theInputDevice; + lastOutputDevice = theOutputDevice; + pjsua_set_null_snd_dev(); pj_status_t status = pjsua_set_snd_dev(theInputDevice, theOutputDevice); bzero(&PJThreadDesc, sizeof(pj_thread_desc)); @@ -862,6 +868,7 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void return; NSAutoreleasePool *pool = [NSAutoreleasePool new]; + [lock lock]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; OSStatus error = noErr; @@ -876,6 +883,7 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void error = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &size, &writable); if (error!=noErr) { [pool drain]; + [lock unlock]; return; } @@ -904,16 +912,22 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void int currentInput = -1; int currentOutput = -1; + int defaultInputIndex = -1; + int defaultOutputIndex = -1; for (int d=0; d=1) { + [SMSManager closeSMSMessage:[[SMSManager SMSMessages] lastObject]]; + } + quitting = YES; [contactsControllers removeAllObjects]; } diff --git a/Classes/VoiceMac/MGMVoiceUser.m b/Classes/VoiceMac/MGMVoiceUser.m index 1845a32..0b4003d 100644 --- a/Classes/VoiceMac/MGMVoiceUser.m +++ b/Classes/VoiceMac/MGMVoiceUser.m @@ -66,15 +66,15 @@ NSString *MGMLastUserPhoneKey = @"MGMLastUserPhone"; progressFadeAnimation = nil; } [super dealloc]; + if (inboxWindow!=nil) { + [inboxWindow closeWindow]; + [inboxWindow release]; + } if (instance!=nil) { [instance setDelegate:nil]; [instance stop]; [instance release]; } - if (inboxWindow!=nil) { - [inboxWindow closeWindow]; - [inboxWindow release]; - } if (progressView!=nil) { [progressView removeFromSuperview]; [progressView release]; diff --git a/Classes/VoiceMac/Preferences/MGMSMSThemesPane.m b/Classes/VoiceMac/Preferences/MGMSMSThemesPane.m index 2481bce..b33d786 100644 --- a/Classes/VoiceMac/Preferences/MGMSMSThemesPane.m +++ b/Classes/VoiceMac/Preferences/MGMSMSThemesPane.m @@ -38,7 +38,7 @@ NSString * const MGMTestTTPhoto = @"tPhoto"; [testMessages addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"That sounds good.", MGMIText, @"6:06 PM", MGMITime, [NSNumber numberWithBool:YES], MGMIYou, nil]]; [testMessages addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"Great, meet you then.", MGMIText, @"6:07 PM", MGMITime, [NSNumber numberWithBool:NO], MGMIYou, nil]]; testMessageInfo = [NSMutableDictionary new]; - [testMessageInfo setObject:[NSDate dateWithNaturalLanguageString:@"8/31/20 6:07:25 PM"] forKey:MGMITime]; + [testMessageInfo setObject:[NSDate dateWithTimeIntervalSince1970:1598915245] forKey:MGMITime]; [testMessageInfo setObject:@"Noah Jonson" forKey:MGMTInName]; [testMessageInfo setObject:@"+15555555555" forKey:MGMIPhoneNumber]; [testMessageInfo setObject:@"+17204325686" forKey:MGMTUserNumber]; diff --git a/Classes/VoiceMac/SMS/MGMSMSManager.m b/Classes/VoiceMac/SMS/MGMSMSManager.m index b2134b1..abda4c2 100644 --- a/Classes/VoiceMac/SMS/MGMSMSManager.m +++ b/Classes/VoiceMac/SMS/MGMSMSManager.m @@ -161,10 +161,12 @@ const float updateTimeInterval = 300.0; break; } } - if (!tab && ![[[theMessages objectAtIndex:i] objectForKey:MGMIRead] boolValue]) { + if (![[[theMessages objectAtIndex:i] objectForKey:MGMIRead] boolValue]) { newMessage = YES; - newTab = YES; - [SMSMessages addObject:[MGMSMSMessageView viewWithManager:self messages:messages messageInfo:messageInfo instance:theInstance]]; + if (!tab) { + newTab = YES; + [SMSMessages addObject:[MGMSMSMessageView viewWithManager:self messages:messages messageInfo:messageInfo instance:theInstance]]; + } } if ([newestDate earlierDate:[[theMessages objectAtIndex:i] objectForKey:MGMITime]]==newestDate) newestDate = [[theMessages objectAtIndex:i] objectForKey:MGMITime]; diff --git a/Classes/VoiceMob/MGMAccountController.h b/Classes/VoiceMob/MGMAccountController.h index d4f1245..31c9969 100644 --- a/Classes/VoiceMob/MGMAccountController.h +++ b/Classes/VoiceMob/MGMAccountController.h @@ -41,6 +41,7 @@ - (MGMController *)controller; - (UIView *)view; - (UIToolbar *)toolbar; +- (void)setItems:(NSArray *)theItems animated:(BOOL)isAnimated; - (NSArray *)accountsItems; - (NSArray *)accountItems; diff --git a/Classes/VoiceMob/MGMAccountController.m b/Classes/VoiceMob/MGMAccountController.m index 4d5b236..0469ed0 100644 --- a/Classes/VoiceMob/MGMAccountController.m +++ b/Classes/VoiceMob/MGMAccountController.m @@ -52,12 +52,12 @@ NSString * const MGMAccountsTitle = @"Accounts"; accountsItems = [[NSArray arrayWithObjects:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL] autorelease], [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addAccount:)] autorelease], nil] retain]; accountItems = [[toolbar items] copy]; if ([contactsControllers count]==0 || currentContactsController==-1) { - [toolbar setItems:accountsItems animated:NO]; + [self setItems:accountsItems animated:NO]; [contentView addSubview:[accounts view]]; [self setTitle:MGMAccountsTitle]; } else { id contactsController = [contactsControllers objectAtIndex:currentContactsController]; - [toolbar setItems:accountItems animated:NO]; + [self setItems:accountItems animated:NO]; [contentView addSubview:[contactsController view]]; [self setTitle:[contactsController title]]; @@ -100,6 +100,10 @@ NSString * const MGMAccountsTitle = @"Accounts"; - (UIToolbar *)toolbar { return toolbar; } +- (void)setItems:(NSArray *)theItems animated:(BOOL)isAnimated { + if ([toolbar items]!=theItems) + [toolbar setItems:theItems animated:isAnimated]; +} - (NSArray *)accountsItems { return accountsItems; } @@ -122,10 +126,10 @@ NSString * const MGMAccountsTitle = @"Accounts"; id contactsController = [contactsControllers objectAtIndex:currentContactsController]; currentContactsController = -1; [[NSUserDefaults standardUserDefaults] setInteger:currentContactsController forKey:MGMLastContactsController]; - [toolbar setItems:accountsItems animated:YES]; + [self setItems:accountsItems animated:YES]; [self setTitle:MGMAccountsTitle]; CGRect inViewFrame = [[accounts view] frame]; - inViewFrame.origin.x -= inViewFrame.size.width; + inViewFrame.origin.x = -inViewFrame.size.width; [[accounts view] setFrame:inViewFrame]; [contentView addSubview:[accounts view]]; [UIView beginAnimations:nil context:contactsController]; @@ -135,7 +139,7 @@ NSString * const MGMAccountsTitle = @"Accounts"; [UIView setAnimationDidStopSelector:@selector(contactsControllerAnimationDidStop:finished:contactsController:)]; [[accounts view] setFrame:[[contactsController view] frame]]; CGRect outViewFrame = [[contactsController view] frame]; - outViewFrame.origin.x += outViewFrame.size.width; + outViewFrame.origin.x = +outViewFrame.size.width; [[contactsController view] setFrame:outViewFrame]; [UIView commitAnimations]; } @@ -210,11 +214,11 @@ NSString * const MGMAccountsTitle = @"Accounts"; currentContactsController = [contactsControllers indexOfObject:contactsController]; [[NSUserDefaults standardUserDefaults] setInteger:currentContactsController forKey:MGMLastContactsController]; } - [toolbar setItems:nil animated:YES]; + [self setItems:nil animated:YES]; [self setTitle:[contactsController title]]; CGRect inViewFrame = [[contactsController view] frame]; - inViewFrame.origin.x += inViewFrame.size.width; + inViewFrame.origin.x = +inViewFrame.size.width; [[contactsController view] setFrame:inViewFrame]; [contentView addSubview:[contactsController view]]; [UIView beginAnimations:nil context:accounts]; @@ -224,7 +228,7 @@ NSString * const MGMAccountsTitle = @"Accounts"; [UIView setAnimationDidStopSelector:@selector(contactsControllerAnimationDidStop:finished:contactsController:)]; [[contactsController view] setFrame:[[accounts view] frame]]; CGRect outViewFrame = [[accounts view] frame]; - outViewFrame.origin.x -= outViewFrame.size.width; + outViewFrame.origin.x = -outViewFrame.size.width; [[accounts view] setFrame:outViewFrame]; [UIView commitAnimations]; } @@ -232,7 +236,7 @@ NSString * const MGMAccountsTitle = @"Accounts"; [[theContactsController view] removeFromSuperview]; [theContactsController releaseView]; if ([theContactsController isKindOfClass:[MGMAccounts class]]) { - [toolbar setItems:accountItems animated:YES]; + [self setItems:accountItems animated:YES]; } else { if (![[theContactsController user] isStarted]) [contactsControllers removeObject:theContactsController]; diff --git a/Classes/VoiceMob/MGMAccountSetup.m b/Classes/VoiceMob/MGMAccountSetup.m index a784437..cfdf2d3 100644 --- a/Classes/VoiceMob/MGMAccountSetup.m +++ b/Classes/VoiceMob/MGMAccountSetup.m @@ -240,7 +240,7 @@ NSString * const MGMSIPDefaultDomain = @"proxy01.sipphone.com"; displaying = YES; if (goingBack) { CGRect inViewFrame = [nextView frame]; - inViewFrame.origin.x -= inViewFrame.size.width; + inViewFrame.origin.x = -inViewFrame.size.width; [nextView setFrame:inViewFrame]; [view addSubview:nextView]; [UIView beginAnimations:nil context:nil]; @@ -250,12 +250,12 @@ NSString * const MGMSIPDefaultDomain = @"proxy01.sipphone.com"; [UIView setAnimationDidStopSelector:@selector(displayAnimationDidStop:finished:context:)]; [nextView setFrame:[lastView frame]]; CGRect outViewFrame = [lastView frame]; - outViewFrame.origin.x += outViewFrame.size.width; + outViewFrame.origin.x = +outViewFrame.size.width; [lastView setFrame:outViewFrame]; [UIView commitAnimations]; } else { CGRect inViewFrame = [nextView frame]; - inViewFrame.origin.x += inViewFrame.size.width; + inViewFrame.origin.x = +inViewFrame.size.width; [nextView setFrame:inViewFrame]; [view addSubview:nextView]; [UIView beginAnimations:nil context:nil]; @@ -265,7 +265,7 @@ NSString * const MGMSIPDefaultDomain = @"proxy01.sipphone.com"; [UIView setAnimationDidStopSelector:@selector(displayAnimationDidStop:finished:context:)]; [nextView setFrame:[lastView frame]]; CGRect outViewFrame = [lastView frame]; - outViewFrame.origin.x -= outViewFrame.size.width; + outViewFrame.origin.x = -outViewFrame.size.width; [lastView setFrame:outViewFrame]; [UIView commitAnimations]; } diff --git a/Classes/VoiceMob/MGMController.m b/Classes/VoiceMob/MGMController.m index 1b29eb2..5fa4a90 100644 --- a/Classes/VoiceMob/MGMController.m +++ b/Classes/VoiceMob/MGMController.m @@ -34,7 +34,7 @@ MGMAccountSetup *accountSetup = [[MGMAccountSetup alloc] initWithController:self]; [accountSetup setSetupOnly:YES]; CGRect inViewFrame = [[accountSetup view] frame]; - inViewFrame.origin.y += inViewFrame.size.height; + inViewFrame.origin.y = +inViewFrame.size.height; [[accountSetup view] setFrame:inViewFrame]; [[self view] addSubview:[accountSetup view]]; [UIView beginAnimations:nil context:nil]; @@ -52,7 +52,7 @@ [UIView setAnimationDelegate:self]; [UIView setAnimationDidStopSelector:@selector(dismissAnimationDidStop:finished:accountSetup:)]; CGRect outViewFrame = [[theAccountSetup view] frame]; - outViewFrame.origin.y += outViewFrame.size.height; + outViewFrame.origin.y = +outViewFrame.size.height; [[theAccountSetup view] setFrame:outViewFrame]; [UIView commitAnimations]; } diff --git a/Classes/VoiceMob/Views/MGMGradientButton.m b/Classes/VoiceMob/Views/MGMGradientButton.m index d99890c..ebf6dce 100644 --- a/Classes/VoiceMob/Views/MGMGradientButton.m +++ b/Classes/VoiceMob/Views/MGMGradientButton.m @@ -43,6 +43,10 @@ [super touchesCancelled:touches withEvent:event]; [self setTouching:NO]; } +- (void)setEnabled:(BOOL)isEnabled { + [super setEnabled:isEnabled]; + [self setNeedsDisplay]; +} - (UIEdgeInsets)titleEdgeInsets { return UIEdgeInsetsMake(-2.0, 0.0, 0.0, 0.0); diff --git a/Classes/VoiceMob/Views/MGMSMSTextView.h b/Classes/VoiceMob/Views/MGMSMSTextView.h index 7908c42..e01cb2f 100644 --- a/Classes/VoiceMob/Views/MGMSMSTextView.h +++ b/Classes/VoiceMob/Views/MGMSMSTextView.h @@ -9,7 +9,7 @@ #import @interface MGMSMSTextView : UITextView { - + CGFloat lastHeight; } @end \ No newline at end of file diff --git a/Classes/VoiceMob/Views/MGMSMSTextView.m b/Classes/VoiceMob/Views/MGMSMSTextView.m index bd90ded..f0a10e5 100644 --- a/Classes/VoiceMob/Views/MGMSMSTextView.m +++ b/Classes/VoiceMob/Views/MGMSMSTextView.m @@ -12,7 +12,33 @@ @implementation MGMSMSTextView - (void)awakeFromNib { [self setBackgroundColor:[UIColor clearColor]]; - [self setContentInset:UIEdgeInsetsMake(-6.0, 3.0, 0.0, -3.0)]; + [self setContentInset:UIEdgeInsetsMake(-6.0, 3.0, -6.0, -3.0)]; +} + +- (void)setContentOffset:(CGPoint)theOffset { + if ([self isTracking] || [self isDecelerating]) { + if ([self contentSize].height>=130.0) { + [self setContentInset:UIEdgeInsetsMake(-6.0, 3.0, -4.0, -3.0)]; + } else { + [self setContentInset:UIEdgeInsetsMake(-6.0, 3.0, -6.0, -3.0)]; + } + [super setContentOffset:theOffset]; + } else { + [super setContentOffset:theOffset]; + if ([self contentSize].height>=130.0) { + [self setScrollEnabled:YES]; + [self setContentInset:UIEdgeInsetsMake(-6.0, 3.0, -2.0, -3.0)]; + if (lastHeight!=[self contentSize].height) { + lastHeight = [self contentSize].height; + [self scrollRectToVisible:CGRectMake(0, [self contentSize].height-10, 320, 10) animated:NO]; + [self flashScrollIndicators]; + } + } else { + lastHeight = 0; + [self setScrollEnabled:NO]; + [self setContentInset:UIEdgeInsetsMake(-6.0, 3.0, -6.0, -3.0)]; + } + } } - (void)drawRect:(CGRect)theRect { diff --git a/Classes/VoiceMob/Voice/MGMVoiceContacts.m b/Classes/VoiceMob/Voice/MGMVoiceContacts.m index 685bf5b..cf7ca57 100644 --- a/Classes/VoiceMob/Voice/MGMVoiceContacts.m +++ b/Classes/VoiceMob/Voice/MGMVoiceContacts.m @@ -8,6 +8,7 @@ #import "MGMVoiceContacts.h" #import "MGMVoiceUser.h" +#import "MGMVoiceSMS.h" #import "MGMVMAddons.h" #import @@ -64,6 +65,8 @@ - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { if (buttonIndex==0) { [voiceUser call:[selectedContact objectForKey:MGMCNumber]]; + } else if (buttonIndex==1) { + [[[voiceUser tabObjects] objectAtIndex:MGMSMSTabIndex] messageWithNumber:[selectedContact objectForKey:MGMCNumber] instance:[voiceUser instance]]; } selectedContact = nil; [contactsTable deselectRowAtIndexPath:[contactsTable indexPathForSelectedRow] animated:YES]; diff --git a/Classes/VoiceMob/Voice/MGMVoiceInbox.h b/Classes/VoiceMob/Voice/MGMVoiceInbox.h index 4aa4175..e8fe920 100644 --- a/Classes/VoiceMob/Voice/MGMVoiceInbox.h +++ b/Classes/VoiceMob/Voice/MGMVoiceInbox.h @@ -18,7 +18,6 @@ MGMProgressView *progressView; int currentView; - NSArray *inboxItems; NSArray *messagesItems; int progressStartCount; diff --git a/Classes/VoiceMob/Voice/MGMVoiceInbox.m b/Classes/VoiceMob/Voice/MGMVoiceInbox.m index 1208074..38538d2 100644 --- a/Classes/VoiceMob/Voice/MGMVoiceInbox.m +++ b/Classes/VoiceMob/Voice/MGMVoiceInbox.m @@ -9,6 +9,7 @@ #import "MGMVoiceInbox.h" #import "MGMVoiceUser.h" #import "MGMAccountController.h" +#import "MGMVoiceSMS.h" #import "MGMInboxMessageView.h" #import "MGMProgressView.h" #import "MGMVMAddons.h" @@ -48,7 +49,6 @@ NSString * const MGMInboxMessageLoadCellIdentifier = @"MGMInboxMessageLoadCellId maxResults = 10; start = 0; resultsCount = 0; - inboxItems = [[NSArray arrayWithObjects:[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL] autorelease], [[[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleBordered target:[voiceUser accountController] action:@selector(showSettings:)] autorelease], nil] retain]; messagesItems = [[NSArray arrayWithObjects:[[[UIBarButtonItem alloc] initWithTitle:@"Inboxes" style:UIBarButtonItemStyleBordered target:self action:@selector(showInboxes:)] autorelease], [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL] autorelease], [[[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleBordered target:[voiceUser accountController] action:@selector(showSettings:)] autorelease], nil] retain]; currentData = [NSMutableArray new]; } @@ -79,9 +79,10 @@ NSString * const MGMInboxMessageLoadCellIdentifier = @"MGMInboxMessageLoadCellId [progressView setProgressTitle:@"Loading..."]; [progressView setHidden:(progressStartCount<=0)]; if (currentView==1) - [[[voiceUser accountController] toolbar] setItems:messagesItems animated:YES]; + [[voiceUser accountController] setItems:messagesItems animated:YES]; else - [[[voiceUser accountController] toolbar] setItems:inboxItems animated:YES]; + [[voiceUser accountController] setItems:[[voiceUser accountController] accountItems] animated:YES]; + } } if (currentView==1) @@ -124,7 +125,7 @@ NSString * const MGMInboxMessageLoadCellIdentifier = @"MGMInboxMessageLoadCellId - (IBAction)showInboxes:(id)sender { CGRect inViewFrame = [inboxesTable frame]; - inViewFrame.origin.x -= inViewFrame.size.width; + inViewFrame.origin.x = -inViewFrame.size.width; [inboxesTable setFrame:inViewFrame]; [[voiceUser tabView] addSubview:inboxesTable]; [UIView beginAnimations:nil context:nil]; @@ -134,10 +135,10 @@ NSString * const MGMInboxMessageLoadCellIdentifier = @"MGMInboxMessageLoadCellId [UIView setAnimationDidStopSelector:@selector(inboxesAnimationDidStop:finished:context:)]; [inboxesTable setFrame:[messagesTable frame]]; CGRect outViewFrame = [messagesTable frame]; - outViewFrame.origin.x += outViewFrame.size.width; + outViewFrame.origin.x = +outViewFrame.size.width; [messagesTable setFrame:outViewFrame]; [UIView commitAnimations]; - [[[voiceUser accountController] toolbar] setItems:inboxItems animated:YES]; + [[voiceUser accountController] setItems:[[voiceUser accountController] accountItems] animated:YES]; currentView = 0; } - (void)inboxesAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { @@ -147,7 +148,6 @@ NSString * const MGMInboxMessageLoadCellIdentifier = @"MGMInboxMessageLoadCellId resultsCount = 0; [currentData removeAllObjects]; [messagesTable reloadData]; - [[messagesItems objectAtIndex:1] setEnabled:YES]; } - (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section { @@ -211,11 +211,11 @@ NSString * const MGMInboxMessageLoadCellIdentifier = @"MGMInboxMessageLoadCellId - (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (theTableView==inboxesTable) { currentInbox = [[[MGMInboxItems objectAtIndex:[indexPath indexAtPosition:1]] objectForKey:MGMSID] intValue]; - [[messagesItems objectAtIndex:1] setEnabled:NO]; - [[[voiceUser accountController] toolbar] setItems:messagesItems animated:YES]; + [[messagesItems objectAtIndex:0] setEnabled:NO]; + [[voiceUser accountController] setItems:messagesItems animated:YES]; CGRect inViewFrame = [messagesTable frame]; - inViewFrame.origin.x += inViewFrame.size.width; + inViewFrame.origin.x = +inViewFrame.size.width; [messagesTable setFrame:inViewFrame]; [[voiceUser tabView] addSubview:messagesTable]; [UIView beginAnimations:nil context:nil]; @@ -225,7 +225,7 @@ NSString * const MGMInboxMessageLoadCellIdentifier = @"MGMInboxMessageLoadCellId [UIView setAnimationDidStopSelector:@selector(messagesAnimationDidStop:finished:context:)]; [messagesTable setFrame:[inboxesTable frame]]; CGRect outViewFrame = [inboxesTable frame]; - outViewFrame.origin.x -= outViewFrame.size.width; + outViewFrame.origin.x = -outViewFrame.size.width; [inboxesTable setFrame:outViewFrame]; [UIView commitAnimations]; currentView = 1; @@ -235,14 +235,27 @@ NSString * const MGMInboxMessageLoadCellIdentifier = @"MGMInboxMessageLoadCellId start += maxResults; [self loadInbox]; } else { - + NSDictionary *data = [currentData objectAtIndex:[indexPath indexAtPosition:1]]; + int type = [[data objectForKey:MGMIType] intValue]; + if (type==MGMIVoicemailType) { + + } else if (type==MGMIRecordedType) { + + } else if (type==MGMISMSIn || type==MGMISMSOut) { + [[[voiceUser tabObjects] objectAtIndex:MGMSMSTabIndex] messageWithData:data instance:[voiceUser instance]]; + } else { + + } + if (![[data objectForKey:MGMIRead] boolValue]) { + + } } } } - (void)messagesAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { [inboxesTable removeFromSuperview]; [inboxesTable deselectRowAtIndexPath:[inboxesTable indexPathForSelectedRow] animated:NO]; - [[messagesItems objectAtIndex:1] setEnabled:YES]; + [[messagesItems objectAtIndex:0] setEnabled:YES]; } - (void)loadInbox { @@ -291,11 +304,10 @@ NSString * const MGMInboxMessageLoadCellIdentifier = @"MGMInboxMessageLoadCellId [self stopProgress]; } - (void)inboxGotInfo:(NSArray *)theInfo instance:(MGMInstance *)theInstance { - if (theInfo!=nil) { + if (theInfo!=nil) [self addData:theInfo]; - } else { + else NSLog(@"Error 234554: Hold on, this should never happen."); - } [self stopProgress]; } - (void)addData:(NSArray *)theData { diff --git a/Classes/VoiceMob/Voice/MGMVoiceSMS.h b/Classes/VoiceMob/Voice/MGMVoiceSMS.h index 910b4cd..3227289 100644 --- a/Classes/VoiceMob/Voice/MGMVoiceSMS.h +++ b/Classes/VoiceMob/Voice/MGMVoiceSMS.h @@ -8,12 +8,28 @@ #import -@class MGMVoiceUser; +@class MGMVoiceUser, MGMSMSTextView, MGMInstance; -@interface MGMVoiceSMS : NSObject { +@interface MGMVoiceSMS : NSObject { MGMVoiceUser *voiceUser; + NSArray *messageItems; + + NSMutableArray *SMSMessages; + int currentSMSMessage; + NSDate *lastDate; + NSTimer *updateTimer; + BOOL sendingMessage; + BOOL marking; + + IBOutlet UITableView *messagesTable; IBOutlet UIView *messageView; + IBOutlet UIWebView *SMSView; + CGRect SMSViewStartFrame; + IBOutlet UIView *SMSBottomView; + IBOutlet MGMSMSTextView *SMSTextView; + IBOutlet UILabel *SMSTextCountField; + IBOutlet UIButton *SMSSendButton; } + (id)tabWithVoiceUser:(MGMVoiceUser *)theVoiceUser; - (id)initWithVoiceUser:(MGMVoiceUser *)theVoiceUser; @@ -22,4 +38,23 @@ - (UIView *)view; - (void)releaseView; + +- (void)checkSMSMessages; +- (void)messageWithNumber:(NSString *)theNumber instance:(MGMInstance *)theInstance; +- (void)messageWithData:(NSDictionary *)theData instance:(MGMInstance *)theInstance; + +- (IBAction)showMessages:(id)sender; + +- (void)setMessage:(int)theMessage read:(BOOL)isRead; + +- (BOOL)updateMessage:(int)theMessage messageInfo:(NSDictionary *)theMessageInfo; + +- (void)textViewDidChange:(UITextView *)textView; + +- (void)buildHTML; +- (void)addMessage:(NSDictionary *)theMessage withInfo:(NSMutableDictionary *)theMessageInfo; + +- (IBAction)sendMessage:(id)sender; + +- (BOOL)shouldClose; @end \ No newline at end of file diff --git a/Classes/VoiceMob/Voice/MGMVoiceSMS.m b/Classes/VoiceMob/Voice/MGMVoiceSMS.m index 0842617..48a53d3 100644 --- a/Classes/VoiceMob/Voice/MGMVoiceSMS.m +++ b/Classes/VoiceMob/Voice/MGMVoiceSMS.m @@ -8,9 +8,20 @@ #import "MGMVoiceSMS.h" #import "MGMVoiceUser.h" +#import "MGMAccountController.h" +#import "MGMController.h" +#import "MGMSMSTextView.h" +#import "MGMInboxMessageView.h" #import "MGMVMAddons.h" #import +NSString * const MGMMessageViewText = @"MGMMessageViewText"; +NSString * const MGMKeyboardBounds = @"UIKeyboardBoundsUserInfoKey"; + +NSString * const MGMMessageCellIdentifier = @"MGMMessageCellIdentifier"; + +const float updateTimeInterval = 300.0; + @implementation MGMVoiceSMS + (id)tabWithVoiceUser:(MGMVoiceUser *)theVoiceUser { return [[[self alloc] initWithVoiceUser:theVoiceUser] autorelease]; @@ -18,6 +29,12 @@ - (id)initWithVoiceUser:(MGMVoiceUser *)theVoiceUser { if (self = [super init]) { voiceUser = theVoiceUser; + + messageItems = [[NSArray arrayWithObjects:[[[UIBarButtonItem alloc] initWithTitle:@"Messages" style:UIBarButtonItemStyleBordered target:self action:@selector(showMessages:)] autorelease], [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:NULL] autorelease], [[[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleBordered target:[voiceUser accountController] action:@selector(showSettings:)] autorelease], nil] retain]; + + SMSMessages = [NSMutableArray new]; + currentSMSMessage = -1; + updateTimer = [[NSTimer scheduledTimerWithTimeInterval:updateTimeInterval target:self selector:@selector(update) userInfo:nil repeats:YES] retain]; } return self; } @@ -29,6 +46,9 @@ - (MGMVoiceUser *)voiceUser { return voiceUser; } +- (MGMThemeManager *)themeManager { + return [[[voiceUser accountController] controller] themeManager]; +} - (UIView *)view { if (messageView==nil) { @@ -37,15 +57,546 @@ [self release]; self = nil; } else { - + [SMSTextCountField setHidden:YES]; + [SMSView setDelegate:self]; + if (currentSMSMessage!=-1) { + if ([[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]!=nil) + [SMSTextView setText:[[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]]; + [self buildHTML]; + [[voiceUser accountController] setItems:messageItems animated:YES]; + } else { + [[voiceUser accountController] setItems:[[voiceUser accountController] accountItems] animated:YES]; + } + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } } - return messageView; + if (currentSMSMessage!=-1) + return messageView; + return messagesTable; } - (void)releaseView { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + if (messagesTable!=nil) { + [messagesTable release]; + messagesTable = nil; + } if (messageView!=nil) { + if (currentSMSMessage!=-1) { + NSMutableDictionary *messageInfo = [[SMSMessages objectAtIndex:currentSMSMessage] mutableCopy]; + [messageInfo setObject:[SMSTextView text] forKey:MGMMessageViewText]; + [SMSMessages replaceObjectAtIndex:currentSMSMessage withObject:messageInfo]; + [messageInfo release]; + } [messageView release]; messageView = nil; + SMSView = nil; + SMSBottomView = nil; + SMSTextView = nil; + SMSTextCountField = nil; } } + + +- (void)update { + if ([SMSMessages count]>0) + [self checkSMSMessages]; +} + +- (void)checkSMSMessages { + [[[voiceUser instance] inbox] getSMSForPage:1 delegate:self]; +} +- (void)inbox:(NSDictionary *)theInfo didFailWithError:(NSError *)theError instance:(MGMInstance *)theInstance { + NSLog(@"SMS Error: %@ for instance: %@", theError, theInstance); +} +- (void)inboxGotInfo:(NSArray *)theMessages instance:(MGMInstance *)theInstance { + if (updateTimer!=nil) { + [updateTimer invalidate]; + [updateTimer release]; + updateTimer = [[NSTimer scheduledTimerWithTimeInterval:updateTimeInterval target:self selector:@selector(update) userInfo:nil repeats:YES] retain]; + } + NSDate *newestDate = [NSDate distantPast]; + BOOL newMessage = NO; + BOOL newTab = NO; + for (unsigned int i=0; i<[theMessages count]; i++) { + if (lastDate==nil || (![lastDate isEqual:[[theMessages objectAtIndex:i] objectForKey:MGMITime]] && [lastDate earlierDate:[[theMessages objectAtIndex:i] objectForKey:MGMITime]]==lastDate)) { + NSMutableDictionary *messageInfo = [NSMutableDictionary dictionaryWithDictionary:[theMessages objectAtIndex:i]]; + [messageInfo setObject:[[theInstance contacts] nameForNumber:[messageInfo objectForKey:MGMIPhoneNumber]] forKey:MGMTInName]; + [messageInfo setObject:[theInstance userNumber] forKey:MGMTUserNumber]; + BOOL tab = NO; + for (unsigned int m=0; m<[SMSMessages count]; m++) { + if ([[[SMSMessages objectAtIndex:m] objectForKey:MGMIPhoneNumber] isEqual:[messageInfo objectForKey:MGMIPhoneNumber]] && ([[[SMSMessages objectAtIndex:m] objectForKey:MGMIID] isEqual:[messageInfo objectForKey:MGMIID]] || [[[SMSMessages objectAtIndex:m] objectForKey:MGMIID] isEqual:@""])) { + tab = YES; + if ([self updateMessage:m messageInfo:messageInfo]) + newMessage = YES; + break; + } + } + if (![[[theMessages objectAtIndex:i] objectForKey:MGMIRead] boolValue]) { + newMessage = YES; + if (!tab) { + newTab = YES; + [SMSMessages addObject:messageInfo]; + } + } + if ([newestDate earlierDate:[[theMessages objectAtIndex:i] objectForKey:MGMITime]]==newestDate) + newestDate = [[theMessages objectAtIndex:i] objectForKey:MGMITime]; + } + } + if (newMessage) { + if (lastDate!=nil) [lastDate release]; + lastDate = [newestDate copy]; + [[self themeManager] playSound:MGMTSSMSMessage]; + if (currentSMSMessage==-1 && messagesTable!=nil) + [messagesTable reloadData]; + } +} +- (void)messageWithNumber:(NSString *)theNumber instance:(MGMInstance *)theInstance { + if (currentSMSMessage!=-1 && SMSTextView!=nil) { + NSMutableDictionary *messageInfo = [[SMSMessages objectAtIndex:currentSMSMessage] mutableCopy]; + [messageInfo setObject:[SMSTextView text] forKey:MGMMessageViewText]; + [SMSMessages replaceObjectAtIndex:currentSMSMessage withObject:messageInfo]; + [messageInfo release]; + [SMSTextView setText:@""]; + [self textViewDidChange:SMSTextView]; + currentSMSMessage = -1; + [SMSView loadHTMLString:@"" baseURL:nil]; + } + [self view]; + NSMutableDictionary *messageInfo = [NSMutableDictionary dictionary]; + [messageInfo setObject:[NSArray array] forKey:MGMIMessages]; + [messageInfo setObject:[NSNumber numberWithInt:MGMISMSOut] forKey:MGMIType]; + [messageInfo setObject:[NSDate date] forKey:MGMITime]; + [messageInfo setObject:[[theInstance contacts] nameForNumber:theNumber] forKey:MGMTInName]; + [messageInfo setObject:theNumber forKey:MGMIPhoneNumber]; + [messageInfo setObject:[theInstance userNumber] forKey:MGMTUserNumber]; + [messageInfo setObject:@"" forKey:MGMIID]; + [messageInfo setObject:[NSNumber numberWithBool:YES] forKey:MGMIRead]; + BOOL window = NO; + for (unsigned int m=0; m<[SMSMessages count]; m++) { + if ([[[SMSMessages objectAtIndex:m] objectForKey:MGMIPhoneNumber] isEqual:[messageInfo objectForKey:MGMIPhoneNumber]] && [[[SMSMessages objectAtIndex:m] objectForKey:MGMIID] isEqual:@""]) { + window = YES; + currentSMSMessage = m; + if ([[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]!=nil) + [SMSTextView setText:[[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]]; + [self buildHTML]; + UITabBarItem *thisTab = [[[voiceUser tabBar] items] objectAtIndex:MGMSMSTabIndex]; + [[voiceUser tabBar] setSelectedItem:thisTab]; + [voiceUser tabBar:[voiceUser tabBar] didSelectItem:thisTab]; + [[voiceUser tabView] addSubview:messageView]; + [messagesTable removeFromSuperview]; + break; + } + } + if (!window) { + [SMSMessages addObject:messageInfo]; + [messagesTable reloadData]; + currentSMSMessage = [SMSMessages count]-1; + if ([[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]!=nil) + [SMSTextView setText:[[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]]; + [self buildHTML]; + UITabBarItem *thisTab = [[[voiceUser tabBar] items] objectAtIndex:MGMSMSTabIndex]; + [[voiceUser tabBar] setSelectedItem:thisTab]; + [voiceUser tabBar:[voiceUser tabBar] didSelectItem:thisTab]; + [[voiceUser tabView] addSubview:messageView]; + [messagesTable removeFromSuperview]; + } + [[voiceUser accountController] setItems:messageItems animated:YES]; +} +- (void)messageWithData:(NSDictionary *)theData instance:(MGMInstance *)theInstance { + if (currentSMSMessage!=-1 && SMSTextView!=nil) { + NSMutableDictionary *messageInfo = [[SMSMessages objectAtIndex:currentSMSMessage] mutableCopy]; + [messageInfo setObject:[SMSTextView text] forKey:MGMMessageViewText]; + [SMSMessages replaceObjectAtIndex:currentSMSMessage withObject:messageInfo]; + [messageInfo release]; + [SMSTextView setText:@""]; + [self textViewDidChange:SMSTextView]; + currentSMSMessage = -1; + [SMSView loadHTMLString:@"" baseURL:nil]; + } + [self view]; + NSMutableDictionary *messageInfo = [NSMutableDictionary dictionaryWithDictionary:theData]; + [messageInfo setObject:[[theInstance contacts] nameForNumber:[messageInfo objectForKey:MGMIPhoneNumber]] forKey:MGMTInName]; + [messageInfo setObject:[theInstance userNumber] forKey:MGMTUserNumber]; + BOOL window = NO; + for (unsigned int m=0; m<[SMSMessages count]; m++) { + if ([[[SMSMessages objectAtIndex:m] objectForKey:MGMIPhoneNumber] isEqual:[messageInfo objectForKey:MGMIPhoneNumber]] && ([[[SMSMessages objectAtIndex:m] objectForKey:MGMIID] isEqual:[messageInfo objectForKey:MGMIID]] || [[[SMSMessages objectAtIndex:m] objectForKey:MGMIID] isEqual:@""])) { + window = YES; + [self updateMessage:m messageInfo:messageInfo]; + currentSMSMessage = m; + if ([[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]!=nil) + [SMSTextView setText:[[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]]; + [self buildHTML]; + UITabBarItem *thisTab = [[[voiceUser tabBar] items] objectAtIndex:MGMSMSTabIndex]; + [[voiceUser tabBar] setSelectedItem:thisTab]; + [voiceUser tabBar:[voiceUser tabBar] didSelectItem:thisTab]; + [[voiceUser tabView] addSubview:messageView]; + [messagesTable removeFromSuperview]; + break; + } + } + if (!window) { + [SMSMessages addObject:messageInfo]; + [messagesTable reloadData]; + currentSMSMessage = [SMSMessages count]-1; + if ([[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]!=nil) + [SMSTextView setText:[[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]]; + [self buildHTML]; + UITabBarItem *thisTab = [[[voiceUser tabBar] items] objectAtIndex:MGMSMSTabIndex]; + [[voiceUser tabBar] setSelectedItem:thisTab]; + [voiceUser tabBar:[voiceUser tabBar] didSelectItem:thisTab]; + [[voiceUser tabView] addSubview:messageView]; + [messagesTable removeFromSuperview]; + } + [[voiceUser accountController] setItems:messageItems animated:YES]; +} + +- (IBAction)showMessages:(id)sender { + if (sendingMessage) { + UIAlertView *theAlert = [[UIAlertView new] autorelease]; + [theAlert setTitle:@"Sending a SMS Message"]; + [theAlert setMessage:@"Your SMS Message is currently being sent, please wait for it to be sent."]; + [theAlert addButtonWithTitle:MGMOkButtonTitle]; + [theAlert show]; + } else if (marking) { + + } else if (![[[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMIRead] boolValue]) { + marking = YES; + [[[voiceUser instance] inbox] markEntries:[NSArray arrayWithObject:[[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMIID]] read:YES delegate:self]; + } else { + [messagesTable reloadData]; + CGRect inViewFrame = [messagesTable frame]; + inViewFrame.origin.x = -inViewFrame.size.width; + [messagesTable setFrame:inViewFrame]; + [[voiceUser tabView] addSubview:messagesTable]; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.5]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(messagesAnimationDidStop:finished:context:)]; + [messagesTable setFrame:[messageView frame]]; + CGRect outViewFrame = [messageView frame]; + outViewFrame.origin.x = +outViewFrame.size.width; + [messageView setFrame:outViewFrame]; + [UIView commitAnimations]; + [[voiceUser accountController] setItems:[[voiceUser accountController] accountItems] animated:YES]; + } +} +- (void)mark:(NSDictionary *)theInfo didFailWithError:(NSError *)theError instance:(MGMInstance *)theInstance { + marking = NO; + UIAlertView *theAlert = [[UIAlertView new] autorelease]; + [theAlert setTitle:@"Error marking as read"]; + [theAlert setMessage:[theError localizedDescription]]; + [theAlert addButtonWithTitle:MGMOkButtonTitle]; + [theAlert show]; +} +- (void)markDidFinish:(NSDictionary *)theInfo instance:(MGMInstance *)theInstance { + marking = NO; + [self setMessage:currentSMSMessage read:YES]; + [self showMessages:self]; +} +- (void)messagesAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { + [messageView removeFromSuperview]; + NSMutableDictionary *messageInfo = [[SMSMessages objectAtIndex:currentSMSMessage] mutableCopy]; + [messageInfo setObject:[SMSTextView text] forKey:MGMMessageViewText]; + [SMSMessages replaceObjectAtIndex:currentSMSMessage withObject:messageInfo]; + [messageInfo release]; + [SMSTextView setText:@""]; + [self textViewDidChange:SMSTextView]; + currentSMSMessage = -1; + [SMSView loadHTMLString:@"" baseURL:nil]; +} + +- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section { + return [SMSMessages count]; +} +- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + MGMInboxMessageView *cell = (MGMInboxMessageView *)[messagesTable dequeueReusableCellWithIdentifier:MGMMessageCellIdentifier]; + if (cell==nil) { + cell = [[[MGMInboxMessageView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MGMMessageCellIdentifier] autorelease]; + [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; + [cell setInstance:[voiceUser instance]]; + } + [cell setMessageData:[SMSMessages objectAtIndex:[indexPath indexAtPosition:1]]]; + return cell; +} +- (BOOL)tableView:(UITableView *)theTableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + return YES; +} +- (UITableViewCellEditingStyle)tableView:(UITableView *)theTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { + return UITableViewCellEditingStyleDelete; +} +- (NSString *)tableView:(UITableView *)theTableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath { + return @"Close"; +} +- (void)tableView:(UITableView *)theTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + [SMSMessages removeObjectAtIndex:[indexPath indexAtPosition:1]]; + [messagesTable reloadData]; +} +- (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + currentSMSMessage = [indexPath indexAtPosition:1]; + if ([[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]!=nil) + [SMSTextView setText:[[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMMessageViewText]]; + [self buildHTML]; + [[messageItems objectAtIndex:0] setEnabled:NO]; + [[voiceUser accountController] setItems:messageItems animated:YES]; + + CGRect inViewFrame = [messageView frame]; + inViewFrame.origin.x = +inViewFrame.size.width; + [messageView setFrame:inViewFrame]; + [[voiceUser tabView] addSubview:messageView]; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.5]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + [UIView setAnimationDelegate:self]; + [UIView setAnimationDidStopSelector:@selector(messageAnimationDidStop:finished:context:)]; + [messageView setFrame:[messagesTable frame]]; + CGRect outViewFrame = [messagesTable frame]; + outViewFrame.origin.x = -outViewFrame.size.width; + [messagesTable setFrame:outViewFrame]; + [UIView commitAnimations]; +} +- (void)messageAnimationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { + [messagesTable removeFromSuperview]; + [messagesTable deselectRowAtIndexPath:[messagesTable indexPathForSelectedRow] animated:NO]; + [[messageItems objectAtIndex:0] setEnabled:YES]; +} + +- (void)setMessage:(int)theMessage read:(BOOL)isRead { + NSMutableDictionary *messageInfo = [[SMSMessages objectAtIndex:theMessage] mutableCopy]; + [messageInfo setObject:[NSNumber numberWithBool:isRead] forKey:MGMIRead]; + [SMSMessages replaceObjectAtIndex:theMessage withObject:messageInfo]; + [messageInfo release]; +} + +- (BOOL)updateMessage:(int)theMessage messageInfo:(NSDictionary *)theMessageInfo { + BOOL newIncomingMessages = NO; + NSMutableDictionary *messageInfo = [[SMSMessages objectAtIndex:theMessage] mutableCopy]; + if (![[theMessageInfo objectForKey:MGMITime] isEqual:[messageInfo objectForKey:MGMITime]]) { + NSMutableDictionary *inMessageInfo = [theMessageInfo mutableCopy]; + [inMessageInfo removeObjectForKey:MGMIMessages]; + [messageInfo addEntriesFromDictionary:inMessageInfo]; + [inMessageInfo release]; + [self setMessage:theMessage read:[[messageInfo objectForKey:MGMIRead] boolValue]]; + NSArray *theMessages = [theMessageInfo objectForKey:MGMIMessages]; + + if (theMessage!=currentSMSMessage) { + [messageInfo setObject:theMessages forKey:MGMIMessages]; + [SMSMessages replaceObjectAtIndex:theMessage withObject:messageInfo]; + } else { + NSMutableArray *messages = [[messageInfo objectForKey:MGMIMessages] mutableCopy]; + BOOL rebuild = [[[[self themeManager] variant] objectForKey:MGMTRebuild] boolValue]; + BOOL newMessages = NO; + for (unsigned int i=[messages count]; i<[theMessages count]; i++) { + newMessages = YES; + [messages addObject:[theMessages objectAtIndex:i]]; + + if (![[[theMessages objectAtIndex:i] objectForKey:MGMIYou] boolValue]) + newIncomingMessages = YES; + if (!rebuild) { + [messageInfo setObject:messages forKey:MGMIMessages]; + [self addMessage:[messages lastObject] withInfo:messageInfo]; + } + } + if (rebuild) + [messageInfo setObject:messages forKey:MGMIMessages]; + [messages release]; + + [SMSMessages replaceObjectAtIndex:theMessage withObject:messageInfo]; + + if (newMessages && rebuild) { + NSLog(@"Rebuilding HTML!"); + [self buildHTML]; + } + } + } + [messageInfo release]; + return newIncomingMessages; +} + +- (void)keyboardWillShow:(NSNotification *)theNotification { + CGSize keyboardSize = CGSizeZero; + if ([[theNotification userInfo] objectForKey:MGMKeyboardBounds]!=nil) + keyboardSize = [[[theNotification userInfo] objectForKey:MGMKeyboardBounds] CGRectValue].size; + else + keyboardSize = [[[theNotification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; + keyboardSize.height -= 49.0; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.1358]; + [UIView setAnimationDelay:0.1642]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + CGRect SMSBottomFrame = [SMSBottomView frame]; + SMSBottomFrame.origin.y -= keyboardSize.height; + [SMSBottomView setFrame:SMSBottomFrame]; + CGRect SMSViewFrame = [SMSView frame]; + SMSViewFrame.size.height -= keyboardSize.height; + SMSViewStartFrame = SMSViewFrame; + [SMSView setFrame:SMSViewFrame]; + UIScrollView *SMSScrollView = [[SMSView subviews] objectAtIndex:0]; + [SMSScrollView setContentInset:UIEdgeInsetsZero]; + [SMSScrollView setScrollIndicatorInsets:UIEdgeInsetsZero]; + [SMSScrollView scrollRectToVisible:CGRectMake(0, [SMSScrollView contentSize].height-44, 320, 44) animated:YES]; + [UIView commitAnimations]; +} +- (void)textViewDidChange:(UITextView *)textView { + CGFloat newHeight = [SMSTextView contentSize].height+3; + if ([SMSTextView contentSize].height<40.0 || [SMSTextView contentSize].height<=55.0) + newHeight = 40.0; + if (newHeight>124.0) + newHeight = 124.0; + if (newHeight!=[SMSBottomView frame].size.height) { + if (newHeight==40.0) + [SMSTextCountField setHidden:YES]; + else + [SMSTextCountField setHidden:NO]; + CGRect SMSBottomFrame = [SMSBottomView frame]; + CGFloat heightDifference = SMSBottomFrame.size.height-newHeight; + SMSBottomFrame.origin.y += heightDifference; + SMSBottomFrame.size.height = newHeight; + [SMSBottomView setFrame:SMSBottomFrame]; + CGRect SMSViewFrame = [SMSView frame]; + SMSViewFrame.size.height = ([messageView frame].size.height-SMSBottomFrame.size.height)-(heightDifference<0 ? 166 : 167); + [SMSView setFrame:SMSViewFrame]; + UIScrollView *SMSScrollView = [[SMSView subviews] objectAtIndex:0]; + [SMSScrollView setContentInset:UIEdgeInsetsZero]; + [SMSScrollView setScrollIndicatorInsets:UIEdgeInsetsZero]; + if (heightDifference<0) { + [SMSScrollView scrollRectToVisible:CGRectMake(0, [SMSScrollView contentSize].height-44, 320, 44) animated:NO]; + } + } + if (![SMSTextCountField isHidden]) + [SMSTextCountField setText:[[NSNumber numberWithInt:160-[[SMSTextView text] length]] stringValue]]; +} +- (void)keyboardWillHide:(NSNotification *)theNotification { + CGSize keyboardSize = CGSizeZero; + if ([[theNotification userInfo] objectForKey:MGMKeyboardBounds]!=nil) + keyboardSize = [[[theNotification userInfo] objectForKey:MGMKeyboardBounds] CGRectValue].size; + else + keyboardSize = [[[theNotification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; + keyboardSize.height -= 49.0; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.256]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + CGRect SMSBottomFrame = [SMSBottomView frame]; + SMSBottomFrame.origin.y += keyboardSize.height; + [SMSBottomView setFrame:SMSBottomFrame]; + CGRect SMSViewFrame = [SMSView frame]; + CGFloat SMSViewHeightDifference = SMSViewFrame.size.height-SMSViewStartFrame.size.height; + SMSViewFrame.size.height += keyboardSize.height; + [SMSView setFrame:SMSViewFrame]; + UIScrollView *SMSScrollView = [[SMSView subviews] objectAtIndex:0]; + UIEdgeInsets SMSScrollContentInset = [SMSScrollView contentInset]; + SMSScrollContentInset.bottom += (keyboardSize.height-SMSBottomFrame.size.height)-SMSViewHeightDifference; + [SMSScrollView setContentInset:SMSScrollContentInset]; + UIEdgeInsets SMSScrollInset = [SMSScrollView scrollIndicatorInsets]; + SMSScrollInset.bottom += (keyboardSize.height-SMSBottomFrame.size.height)-SMSViewHeightDifference; + [SMSScrollView setScrollIndicatorInsets:SMSScrollContentInset]; + [SMSScrollView scrollRectToVisible:CGRectMake(0, [SMSScrollView contentSize].height-44, 320, 44) animated:YES]; + [UIView commitAnimations]; +} + +- (void)buildHTML { + NSDictionary *messageInfo = [SMSMessages objectAtIndex:currentSMSMessage]; + NSString *yPhotoPath = [[[voiceUser instance] contacts] cachedPhotoForNumber:[messageInfo objectForKey:MGMTUserNumber]]; + if (yPhotoPath==nil) + yPhotoPath = [[[self themeManager] outgoingIconPath] filePath]; + NSString *tPhotoPath = [[[voiceUser instance] contacts] cachedPhotoForNumber:[messageInfo objectForKey:MGMIPhoneNumber]]; + if (tPhotoPath==nil) + tPhotoPath = [[[self themeManager] incomingIconPath] filePath]; + NSArray *messages = [messageInfo objectForKey:MGMIMessages]; + NSMutableArray *messageArray = [NSMutableArray array]; + for (unsigned int i=0; i<[messages count]; i++) { + NSMutableDictionary *message = [NSMutableDictionary dictionaryWithDictionary:[messages objectAtIndex:i]]; + [message setObject:[[NSNumber numberWithInt:i] stringValue] forKey:MGMIID]; + if ([[message objectForKey:MGMIYou] boolValue]) { + [message setObject:yPhotoPath forKey:MGMTPhoto]; + [message setObject:NSFullUserName() forKey:MGMTName]; + [message setObject:[messageInfo objectForKey:MGMTUserNumber] forKey:MGMIPhoneNumber]; + } else { + [message setObject:tPhotoPath forKey:MGMTPhoto]; + [message setObject:[messageInfo objectForKey:MGMTInName] forKey:MGMTName]; + [message setObject:[messageInfo objectForKey:MGMIPhoneNumber] forKey:MGMIPhoneNumber]; + } + [messageArray addObject:message]; + }NSString *html = [[self themeManager] buildHTMLWithMessages:messageArray messageInfo:messageInfo]; + [SMSView loadHTMLString:html baseURL:[NSURL fileURLWithPath:[[self themeManager] currentThemeVariantPath]]]; +} +- (void)webViewDidFinishLoad:(UIWebView *)webView { + [SMSView stringByEvaluatingJavaScriptFromString:@"scrollToBottom();"]; +} +- (void)addMessage:(NSDictionary *)theMessage withInfo:(NSMutableDictionary *)theMessageInfo { + NSArray *messages = [theMessageInfo objectForKey:MGMIMessage]; + NSString *yPhotoPath = [[[voiceUser instance] contacts] cachedPhotoForNumber:[theMessageInfo objectForKey:MGMTUserNumber]]; + if (yPhotoPath==nil) + yPhotoPath = [[[self themeManager] outgoingIconPath] filePath]; + NSString *tPhotoPath = [[[voiceUser instance] contacts] cachedPhotoForNumber:[theMessageInfo objectForKey:MGMIPhoneNumber]]; + if (tPhotoPath==nil) + tPhotoPath = [[[self themeManager] incomingIconPath] filePath]; + NSMutableDictionary *message = [NSMutableDictionary dictionaryWithDictionary:theMessage]; + [message setObject:[[NSNumber numberWithInt:[messages count]-1] stringValue] forKey:MGMIID]; + int type = 1; + if ([[message objectForKey:MGMIYou] boolValue]) { + type = (([[message objectForKey:MGMIID] intValue]==0 || ![[[messages objectAtIndex:[[message objectForKey:MGMIID] intValue]-1] objectForKey:MGMIYou] boolValue]) ? 1 : 2); + [message setObject:yPhotoPath forKey:MGMTPhoto]; + [message setObject:NSFullUserName() forKey:MGMTName]; + [message setObject:[theMessageInfo objectForKey:MGMTUserNumber] forKey:MGMIPhoneNumber]; + } else { + type = (([[message objectForKey:MGMIID] intValue]==0 || [[[messages objectAtIndex:[[message objectForKey:MGMIID] intValue]-1] objectForKey:MGMIYou] boolValue]) ? 3 : 4); + [message setObject:tPhotoPath forKey:MGMTPhoto]; + [message setObject:[theMessageInfo objectForKey:MGMTInName] forKey:MGMTName]; + [message setObject:[theMessageInfo objectForKey:MGMIPhoneNumber] forKey:MGMIPhoneNumber]; + } + NSDateFormatter *formatter = [[NSDateFormatter new] autorelease]; + [formatter setDateFormat:[[[self themeManager] variant] objectForKey:MGMTDate]]; + [SMSView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"newMessage('%@', '%@', '%@', %@, '%@', '%@', '%@', %d);", [[message objectForKey:MGMIText] escapeSMS], [[message objectForKey:MGMTPhoto] escapeSMS], [[message objectForKey:MGMITime] escapeSMS], [message objectForKey:MGMIID], [[message objectForKey:MGMTName] escapeSMS], [[[message objectForKey:MGMIPhoneNumber] readableNumber] escapeSMS], [formatter stringFromDate:[theMessageInfo objectForKey:MGMITime]], type]]; + [SMSView stringByEvaluatingJavaScriptFromString:@"scrollToBottom();"]; +} + +- (IBAction)sendMessage:(id)sender { + if ([[SMSTextView text] isEqual:@""]) + return; + sendingMessage = YES; + [SMSSendButton setEnabled:NO]; + [[[voiceUser instance] inbox] sendMessage:[SMSTextView text] phoneNumbers:[NSArray arrayWithObject:[[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMIPhoneNumber]] smsID:[[SMSMessages objectAtIndex:currentSMSMessage] objectForKey:MGMIID] delegate:self]; + [SMSTextView setText:@""]; + [self textViewDidChange:SMSTextView]; +} +- (void)message:(NSDictionary *)theInfo didFailWithError:(NSError *)theError instance:(MGMInstance *)theInstance { + sendingMessage = NO; + [SMSSendButton setEnabled:YES]; + [SMSTextView setText:[[theInfo objectForKey:MGMIMessage] stringByAppendingFormat:@" %@", [SMSTextView text]]]; + [self textViewDidChange:SMSTextView]; + [SMSTextView becomeFirstResponder]; + UIAlertView *theAlert = [[UIAlertView new] autorelease]; + [theAlert setTitle:@"Error sending a SMS Message"]; + [theAlert setMessage:[theError localizedDescription]]; + [theAlert addButtonWithTitle:MGMOkButtonTitle]; + [theAlert show]; +} +- (void)messageDidFinish:(NSDictionary *)theInfo instance:(MGMInstance *)theInstance { + sendingMessage = NO; + NSDateFormatter *formatter = [[NSDateFormatter new] autorelease]; + [formatter setDateFormat:@"h:mm a"]; + NSMutableDictionary *messageInfo = [[SMSMessages objectAtIndex:currentSMSMessage] mutableCopy]; + NSMutableArray *messages = [[messageInfo objectForKey:MGMIMessages] mutableCopy]; + NSDictionary *message = [NSDictionary dictionaryWithObjectsAndKeys:[theInfo objectForKey:MGMIMessage], MGMIText, [formatter stringFromDate:[NSDate date]], MGMITime, [NSNumber numberWithBool:YES], MGMIYou, nil]; + [messages addObject:message]; + [messageInfo setObject:messages forKey:MGMIMessages]; + [messageInfo setObject:[NSDate date] forKey:MGMITime]; + [SMSMessages replaceObjectAtIndex:currentSMSMessage withObject:messageInfo]; + if ([[[[self themeManager] variant] objectForKey:MGMTRebuild] boolValue]) { + [self buildHTML]; + } else { + [self addMessage:message withInfo:messageInfo]; + } + [messages release]; + [messageInfo release]; + [SMSSendButton setEnabled:YES]; + [SMSTextView becomeFirstResponder]; + [self setMessage:currentSMSMessage read:YES]; +} + +- (BOOL)shouldClose { + return (!sendingMessage); +} @end \ No newline at end of file diff --git a/Classes/VoiceMob/Voice/MGMVoiceUser.h b/Classes/VoiceMob/Voice/MGMVoiceUser.h index 2e1fdde..33cf462 100644 --- a/Classes/VoiceMob/Voice/MGMVoiceUser.h +++ b/Classes/VoiceMob/Voice/MGMVoiceUser.h @@ -10,6 +10,11 @@ @class MGMVoiceUser, MGMAccountController, MGMUser, MGMInstance, MGMProgressView; +extern const int MGMKeypadTabIndex; +extern const int MGMContactsTabIndex; +extern const int MGMSMSTabIndex; +extern const int MGMInboxTabIndex; + @protocol MGMVoiceUserTabProtocol + (id)tabWithVoiceUser:(MGMVoiceUser *)theVoiceUser; - (id)initWithVoiceUser:(MGMVoiceUser *)theVoiceUser; @@ -20,7 +25,6 @@ - (void)releaseView; @end - @interface MGMVoiceUser : NSObject { MGMAccountController *accountController; MGMUser *user; @@ -48,6 +52,7 @@ - (NSString *)areaCode; - (UIView *)view; +- (NSArray *)tabObjects; - (UIView *)tabView; - (UITabBar *)tabBar; - (void)releaseView; @@ -57,4 +62,6 @@ - (BOOL)isPlacingCall; - (void)call:(NSString *)theNumber; + +- (void)tabBar:(UITabBar *)theTabBar didSelectItem:(UITabBarItem *)item; @end \ No newline at end of file diff --git a/Classes/VoiceMob/Voice/MGMVoiceUser.m b/Classes/VoiceMob/Voice/MGMVoiceUser.m index 17d4586..03acb82 100644 --- a/Classes/VoiceMob/Voice/MGMVoiceUser.m +++ b/Classes/VoiceMob/Voice/MGMVoiceUser.m @@ -17,6 +17,11 @@ #import #import +const int MGMKeypadTabIndex = 0; +const int MGMContactsTabIndex = 1; +const int MGMSMSTabIndex = 2; +const int MGMInboxTabIndex = 3; + @implementation MGMVoiceUser + (id)voiceUser:(MGMUser *)theUser accountController:(MGMAccountController *)theAccountController { return [[[self alloc] initWithUser:theUser accountController:theAccountController] autorelease]; @@ -26,15 +31,15 @@ accountController = theAccountController; user = [theUser retain]; - currentTab = 2; + currentTab = 0; tabObjects = [NSMutableArray new]; [tabObjects addObject:[MGMVoicePad tabWithVoiceUser:self]]; [tabObjects addObject:[MGMVoiceContacts tabWithVoiceUser:self]]; [tabObjects addObject:[MGMVoiceSMS tabWithVoiceUser:self]]; [tabObjects addObject:[MGMVoiceInbox tabWithVoiceUser:self]]; - //if ([user isStarted]) - //instance = [[MGMInstance instanceWithUser:user delegate:self] retain]; + if ([user isStarted]) + instance = [[MGMInstance instanceWithUser:user delegate:self] retain]; } return self; } @@ -74,7 +79,7 @@ } else { [tabView addSubview:[[tabObjects objectAtIndex:currentTab] view]]; [tabBar setSelectedItem:[[tabBar items] objectAtIndex:currentTab]]; - /*if (![instance isLoggedIn]) { + if (![instance isLoggedIn]) { CGSize contentSize = [view frame].size; progressView = [[MGMProgressView alloc] initWithFrame:CGRectMake(0, 0, contentSize.width, contentSize.height)]; [progressView setProgressTitle:@"Logging In"]; @@ -83,11 +88,14 @@ [progressView becomeFirstResponder]; } else { [self setInstanceInfo]; - }*/ + } } } return view; } +- (NSArray *)tabObjects { + return tabObjects; +} - (UIView *)tabView { return tabView; } @@ -149,7 +157,10 @@ } - (void)updatedContacts { - [[tabObjects objectAtIndex:1] updatedContacts]; + [[tabObjects objectAtIndex:MGMContactsTabIndex] updatedContacts]; +} +- (void)updateSMS { + [[tabObjects objectAtIndex:MGMSMSTabIndex] checkSMSMessages]; } - (BOOL)isPlacingCall { @@ -213,9 +224,8 @@ int tabIndex = [[tabBar items] indexOfObject:item]; if (tabIndex==currentTab) return; - if ([[accountController toolbar] items]!=[accountController accountItems]) { - [[accountController toolbar] setItems:[accountController accountItems] animated:YES]; - } + if (tabIndex!=MGMSMSTabIndex && tabIndex!=MGMInboxTabIndex) + [accountController setItems:[accountController accountItems] animated:YES]; id tab = [tabObjects objectAtIndex:currentTab]; currentTab = tabIndex; diff --git a/Resources/VoiceMob/AccountController_iPhone.xib b/Resources/VoiceMob/AccountController_iPhone.xib index 3c855a4..bdedc1f 100644 --- a/Resources/VoiceMob/AccountController_iPhone.xib +++ b/Resources/VoiceMob/AccountController_iPhone.xib @@ -88,7 +88,7 @@ 292 - {{80, 10}, {160, 24}} + {{85, 10}, {150, 24}} NO YES @@ -189,8 +189,8 @@ YES - + diff --git a/Resources/VoiceMob/Voice/VoiceSMS_iPhone.xib b/Resources/VoiceMob/Voice/VoiceSMS_iPhone.xib index 256091a..ab6b380 100644 --- a/Resources/VoiceMob/Voice/VoiceSMS_iPhone.xib +++ b/Resources/VoiceMob/Voice/VoiceSMS_iPhone.xib @@ -43,35 +43,34 @@ 274 YES - + 266 YES - - + + 274 {{7, 8}, {238, 26}} - - + + 1 MSAxIDEAA YES YES IBCocoaTouchFramework - NO 2 IBCocoaTouchFramework - - + + 265 {{252, 8}, {61, 26}} - + 1 MC4xMTc2NDcwNTkzIDAuMzgwMzkyMTY0IDAuNzg0MzEzNzM4MwA @@ -86,21 +85,21 @@ 16 Send - + 3 MQA - + 3 MCAwAA - - - 292 - {{265, -21}, {29, 21}} - + + + 265 + {{252, -14}, {60, 21}} + NO YES 7 @@ -119,9 +118,10 @@ 1 10 + 2 - {{0, 329}, {320, 40}} + {{0, 327}, {320, 40}} 3 @@ -132,28 +132,28 @@ IBCocoaTouchFramework - + 292 - {320, 329} + {320, 327} - + IBCocoaTouchFramework 1 YES - {320, 369} + {320, 367} - + IBCocoaTouchFramework - + 274 - {320, 369} + {320, 367} - + YES IBCocoaTouchFramework YES @@ -174,6 +174,87 @@ 14 + + + SMSView + + + + 21 + + + + messagesTable + + + + 22 + + + + delegate + + + + 23 + + + + SMSTextView + + + + 24 + + + + SMSBottomView + + + + 25 + + + + SMSTextCountField + + + + 28 + + + + dataSource + + + + 29 + + + + delegate + + + + 30 + + + + sendMessage: + + + 7 + + 31 + + + + SMSSendButton + + + + 32 + @@ -200,48 +281,48 @@ YES - - + + Message View 5 - + SMS Messages 15 - + YES - - - + + + 12 - - + + 16 - - - - - 19 - - + + 20 - - + + + + + 19 + + @@ -276,9 +357,9 @@ com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin - {{525, 192}, {320, 369}} + {{525, 194}, {320, 367}} com.apple.InterfaceBuilder.IBCocoaTouchPlugin - {{177, 335}, {320, 369}} + {{177, 337}, {320, 367}} com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -298,7 +379,7 @@ - 20 + 32 @@ -330,15 +411,103 @@ MGMVoiceSMS NSObject + + YES + + YES + sendMessage: + showMessages: + + + YES + id + id + + + + YES + + YES + sendMessage: + showMessages: + + + YES + + sendMessage: + id + + + showMessages: + id + + + - messageView - UIView + YES + + YES + SMSBottomView + SMSSendButton + SMSTextCountField + SMSTextView + SMSView + messageView + messagesTable + + + YES + UIView + UIButton + UILabel + MGMSMSTextView + UIWebView + UIView + UITableView + - messageView - - messageView - UIView + YES + + YES + SMSBottomView + SMSSendButton + SMSTextCountField + SMSTextView + SMSView + messageView + messagesTable + + + YES + + SMSBottomView + UIView + + + SMSSendButton + UIButton + + + SMSTextCountField + UILabel + + + SMSTextView + MGMSMSTextView + + + SMSView + UIWebView + + + messageView + UIView + + + messagesTable + UITableView +