Finished SMS stuff, fixed issue with VoiceMail having more than one line, fixed issue with multiple lines on SMS, fixed issue with quitting with SMS and inbox open, tried to fix issues with MGMSIP, and fixed issue with SMS sound notification not being played if the SMS is already open.

This commit is contained in:
GRMrGecko 2010-10-02 22:00:01 -05:00
parent ce445dcff2
commit 5dc36cc158
25 changed files with 982 additions and 131 deletions

View File

@ -70,6 +70,8 @@
- (NSString *)escapeSMS {
NSString *escaped = [self replace:@"\\" with:@"\\\\"];
escaped = [escaped replace:@"'" with:@"\\'"];
escaped = [escaped replace:@"\n" with:@"<br />"];
escaped = [escaped replace:@"\r" with:@""];
return escaped;
}

View File

@ -355,7 +355,10 @@ const BOOL MGMInboxInvisible = YES;
range = [string rangeOfString:@"</span>"];
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:@"<br />"];
messageText = [messageText replace:@"\r" with:@""];
[message setObject:messageText forKey:MGMIText];
}
range = [theHTML rangeOfString:@"<span class=\"gc-message-sms-time\">"];
if (range.location!=NSNotFound) {

View File

@ -103,6 +103,8 @@ typedef enum {
NSMutableArray *restartAccounts;
#if !TARGET_OS_IPHONE
NSArray *audioDevices;
int lastInputDevice;
int lastOutputDevice;
#endif
int ringbackCount;

View File

@ -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<deviceCount; d++) {
NSMutableDictionary *deviceInfo = [NSMutableDictionary dictionary];
[deviceInfo setObject:[NSNumber numberWithUnsignedLong:devices[d]] forKey:MGMSIPADeviceIdentifier];
[deviceInfo setObject:[NSNumber numberWithInt:d] forKey:MGMSIPADeviceIndex];
if (devices[d]==defaultInput)
if (devices[d]==defaultInput) {
defaultInputIndex = d;
[deviceInfo setObject:[NSNumber numberWithBool:YES] forKey:MGMSIPADeviceIsDefaultInput];
if (devices[d]==defaultOutput)
}
if (devices[d]==defaultOutput) {
defaultOutputIndex = d;
[deviceInfo setObject:[NSNumber numberWithBool:YES] forKey:MGMSIPADeviceIsDefaultOutput];
}
CFStringRef UIDString = NULL;
size = sizeof(CFStringRef);
@ -972,6 +986,7 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
if (audioDevices!=nil) [audioDevices release];
audioDevices = [devicesArray copy];
if ((currentInput==-1 ? defaultInputIndex!=lastInputDevice : currentInput!=lastInputDevice) && (currentOutput==-1 ? defaultOutputIndex!=lastOutputDevice : currentOutput!=lastOutputDevice)) {
pj_thread_desc PJThreadDesc;
[self registerThread:&PJThreadDesc];
@ -980,9 +995,12 @@ static OSStatus MGMAudioDevicesChanged(AudioHardwarePropertyID propertyID, void
pjmedia_snd_init(pjsua_get_pool_factory());
[self setInputSoundDevice:currentInput outputSoundDevice:currentOutput];
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
}
[[NSNotificationCenter defaultCenter] postNotificationName:MGMSIPAudioChangedNotification object:audioDevices];
bzero(&PJThreadDesc, sizeof(pj_thread_desc));
[lock unlock];
[pool drain];
}
- (NSArray *)audioDevices {

View File

@ -426,10 +426,9 @@ NSString * const MGMSID = @"id";
} else {
[(MGMVoiceUser *)[instance delegate] runAction:sender];
}
if (![[data objectForKey:MGMIRead] boolValue]) {
if (![[data objectForKey:MGMIRead] boolValue])
[self markRead:self];
}
}
- (float)splitView:(NSSplitView *)sender constrainMinCoordinate:(float)proposedMin ofSubviewAt:(int)offset {
leftMax = [[[sender subviews] objectAtIndex:0] frame].size.width;

View File

@ -619,6 +619,10 @@ NSString * const MGMLoading = @"Loading...";
}
#endif
if (response==NSTerminateNow) {
while ([[SMSManager SMSMessages] count]>=1) {
[SMSManager closeSMSMessage:[[SMSManager SMSMessages] lastObject]];
}
quitting = YES;
[contactsControllers removeAllObjects];
}

View File

@ -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];

View File

@ -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];

View File

@ -161,11 +161,13 @@ const float updateTimeInterval = 300.0;
break;
}
}
if (!tab && ![[[theMessages objectAtIndex:i] objectForKey:MGMIRead] boolValue]) {
if (![[[theMessages objectAtIndex:i] objectForKey:MGMIRead] boolValue]) {
newMessage = YES;
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];
}

View File

@ -41,6 +41,7 @@
- (MGMController *)controller;
- (UIView *)view;
- (UIToolbar *)toolbar;
- (void)setItems:(NSArray *)theItems animated:(BOOL)isAnimated;
- (NSArray *)accountsItems;
- (NSArray *)accountItems;

View File

@ -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<MGMAccountProtocol> 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];

View File

@ -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];
}

View File

@ -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];
}

View File

@ -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);

View File

@ -9,7 +9,7 @@
#import <UIKit/UIKit.h>
@interface MGMSMSTextView : UITextView {
CGFloat lastHeight;
}
@end

View File

@ -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 {

View File

@ -8,6 +8,7 @@
#import "MGMVoiceContacts.h"
#import "MGMVoiceUser.h"
#import "MGMVoiceSMS.h"
#import "MGMVMAddons.h"
#import <VoiceBase/VoiceBase.h>
@ -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];

View File

@ -18,7 +18,6 @@
MGMProgressView *progressView;
int currentView;
NSArray *inboxItems;
NSArray *messagesItems;
int progressStartCount;

View File

@ -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 {

View File

@ -8,12 +8,28 @@
#import <UIKit/UIKit.h>
@class MGMVoiceUser;
@class MGMVoiceUser, MGMSMSTextView, MGMInstance;
@interface MGMVoiceSMS : NSObject {
@interface MGMVoiceSMS : NSObject <UIWebViewDelegate> {
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

View File

@ -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 <VoiceBase/VoiceBase.h>
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];
}
}
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

View File

@ -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 <NSObject>
+ (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

View File

@ -17,6 +17,11 @@
#import <MGMUsers/MGMUsers.h>
#import <VoiceBase/VoiceBase.h>
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;

View File

@ -88,7 +88,7 @@
<object class="IBUILabel" id="837703426">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{80, 10}, {160, 24}}</string>
<string key="NSFrame">{{85, 10}, {150, 24}}</string>
<reference key="NSSuperview" ref="191373211"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
@ -189,8 +189,8 @@
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="199768012"/>
<reference ref="837703426"/>
<reference ref="592196657"/>
<reference ref="837703426"/>
</object>
<reference key="parent" ref="0"/>
</object>

View File

@ -43,35 +43,34 @@
<int key="NSvFlags">274</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUIView" id="545711008">
<object class="IBUIView" id="1046088304">
<reference key="NSNextResponder" ref="355112807"/>
<int key="NSvFlags">266</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBUITextView" id="826280752">
<reference key="NSNextResponder" ref="545711008"/>
<object class="IBUITextView" id="388287938">
<reference key="NSNextResponder" ref="1046088304"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{7, 8}, {238, 26}}</string>
<reference key="NSSuperview" ref="545711008"/>
<object class="NSColor" key="IBUIBackgroundColor" id="136061801">
<reference key="NSSuperview" ref="1046088304"/>
<object class="NSColor" key="IBUIBackgroundColor" id="527773708">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MSAxIDEAA</bytes>
</object>
<bool key="IBUIClipsSubviews">YES</bool>
<bool key="IBUIMultipleTouchEnabled">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIScrollEnabled">NO</bool>
<string key="IBUIText"/>
<object class="IBUITextInputTraits" key="IBUITextInputTraits">
<int key="IBUIAutocapitalizationType">2</int>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</object>
<object class="IBUIButton" id="853973562">
<reference key="NSNextResponder" ref="545711008"/>
<object class="IBUIButton" id="786956623">
<reference key="NSNextResponder" ref="1046088304"/>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{252, 8}, {61, 26}}</string>
<reference key="NSSuperview" ref="545711008"/>
<reference key="NSSuperview" ref="1046088304"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MC4xMTc2NDcwNTkzIDAuMzgwMzkyMTY0IDAuNzg0MzEzNzM4MwA</bytes>
@ -86,21 +85,21 @@
<int key="NSfFlags">16</int>
</object>
<string key="IBUINormalTitle">Send</string>
<object class="NSColor" key="IBUIHighlightedTitleColor" id="338535607">
<object class="NSColor" key="IBUIHighlightedTitleColor" id="780412671">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<reference key="IBUINormalTitleColor" ref="338535607"/>
<reference key="IBUINormalTitleColor" ref="780412671"/>
<object class="NSColor" key="IBUINormalTitleShadowColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MCAwAA</bytes>
</object>
</object>
<object class="IBUILabel" id="1055111431">
<reference key="NSNextResponder" ref="545711008"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{265, -21}, {29, 21}}</string>
<reference key="NSSuperview" ref="545711008"/>
<object class="IBUILabel" id="383414162">
<reference key="NSNextResponder" ref="1046088304"/>
<int key="NSvFlags">265</int>
<string key="NSFrame">{{252, -14}, {60, 21}}</string>
<reference key="NSSuperview" ref="1046088304"/>
<bool key="IBUIOpaque">NO</bool>
<bool key="IBUIClipsSubviews">YES</bool>
<int key="IBUIContentMode">7</int>
@ -119,9 +118,10 @@
<nil key="IBUIHighlightedColor"/>
<int key="IBUIBaselineAdjustment">1</int>
<float key="IBUIMinimumFontSize">10</float>
<int key="IBUITextAlignment">2</int>
</object>
</object>
<string key="NSFrame">{{0, 329}, {320, 40}}</string>
<string key="NSFrame">{{0, 327}, {320, 40}}</string>
<reference key="NSSuperview" ref="355112807"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
@ -132,28 +132,28 @@
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIWebView" id="394150452">
<object class="IBUIWebView" id="320314397">
<reference key="NSNextResponder" ref="355112807"/>
<int key="NSvFlags">292</int>
<string key="NSFrameSize">{320, 329}</string>
<string key="NSFrameSize">{320, 327}</string>
<reference key="NSSuperview" ref="355112807"/>
<reference key="IBUIBackgroundColor" ref="136061801"/>
<reference key="IBUIBackgroundColor" ref="527773708"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIDataDetectorTypes">1</int>
<bool key="IBUIDetectsPhoneNumbers">YES</bool>
</object>
</object>
<string key="NSFrameSize">{320, 369}</string>
<string key="NSFrameSize">{320, 367}</string>
<reference key="NSSuperview"/>
<reference key="IBUIBackgroundColor" ref="338535607"/>
<reference key="IBUIBackgroundColor" ref="780412671"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUITableView" id="908766037">
<object class="IBUITableView" id="134583931">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{320, 369}</string>
<string key="NSFrameSize">{320, 367}</string>
<reference key="NSSuperview"/>
<reference key="IBUIBackgroundColor" ref="338535607"/>
<reference key="IBUIBackgroundColor" ref="780412671"/>
<bool key="IBUIClipsSubviews">YES</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIAlwaysBounceVertical">YES</bool>
@ -174,6 +174,87 @@
</object>
<int key="connectionID">14</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">SMSView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="320314397"/>
</object>
<int key="connectionID">21</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">messagesTable</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="134583931"/>
</object>
<int key="connectionID">22</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="388287938"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">23</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">SMSTextView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="388287938"/>
</object>
<int key="connectionID">24</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">SMSBottomView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="1046088304"/>
</object>
<int key="connectionID">25</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">SMSTextCountField</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="383414162"/>
</object>
<int key="connectionID">28</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">dataSource</string>
<reference key="source" ref="134583931"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">29</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="134583931"/>
<reference key="destination" ref="372490531"/>
</object>
<int key="connectionID">30</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchEventConnection" key="connection">
<string key="label">sendMessage:</string>
<reference key="source" ref="786956623"/>
<reference key="destination" ref="372490531"/>
<int key="IBEventType">7</int>
</object>
<int key="connectionID">31</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">SMSSendButton</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="786956623"/>
</object>
<int key="connectionID">32</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@ -200,48 +281,48 @@
<reference key="object" ref="355112807"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="545711008"/>
<reference ref="394150452"/>
<reference ref="1046088304"/>
<reference ref="320314397"/>
</object>
<reference key="parent" ref="0"/>
<string key="objectName">Message View</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">5</int>
<reference key="object" ref="908766037"/>
<reference key="object" ref="134583931"/>
<reference key="parent" ref="0"/>
<string key="objectName">SMS Messages</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">15</int>
<reference key="object" ref="545711008"/>
<reference key="object" ref="1046088304"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="826280752"/>
<reference ref="853973562"/>
<reference ref="1055111431"/>
<reference ref="388287938"/>
<reference ref="786956623"/>
<reference ref="383414162"/>
</object>
<reference key="parent" ref="355112807"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">12</int>
<reference key="object" ref="826280752"/>
<reference key="parent" ref="545711008"/>
<reference key="object" ref="388287938"/>
<reference key="parent" ref="1046088304"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">16</int>
<reference key="object" ref="853973562"/>
<reference key="parent" ref="545711008"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">19</int>
<reference key="object" ref="394150452"/>
<reference key="parent" ref="355112807"/>
<reference key="object" ref="786956623"/>
<reference key="parent" ref="1046088304"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">20</int>
<reference key="object" ref="1055111431"/>
<reference key="parent" ref="545711008"/>
<reference key="object" ref="383414162"/>
<reference key="parent" ref="1046088304"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">19</int>
<reference key="object" ref="320314397"/>
<reference key="parent" ref="355112807"/>
</object>
</object>
</object>
@ -276,9 +357,9 @@
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>{{525, 192}, {320, 369}}</string>
<string>{{525, 194}, {320, 367}}</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string>{{177, 335}, {320, 369}}</string>
<string>{{177, 337}, {320, 367}}</string>
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</object>
</object>
@ -298,7 +379,7 @@
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">20</int>
<int key="maxID">32</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@ -330,16 +411,104 @@
<object class="IBPartialClassDescription">
<string key="className">MGMVoiceSMS</string>
<string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="actions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>sendMessage:</string>
<string>showMessages:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>id</string>
<string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>sendMessage:</string>
<string>showMessages:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBActionInfo">
<string key="name">sendMessage:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">showMessages:</string>
<string key="candidateClassName">id</string>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">messageView</string>
<string key="NS.object.0">UIView</string>
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>SMSBottomView</string>
<string>SMSSendButton</string>
<string>SMSTextCountField</string>
<string>SMSTextView</string>
<string>SMSView</string>
<string>messageView</string>
<string>messagesTable</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>UIView</string>
<string>UIButton</string>
<string>UILabel</string>
<string>MGMSMSTextView</string>
<string>UIWebView</string>
<string>UIView</string>
<string>UITableView</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">messageView</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>SMSBottomView</string>
<string>SMSSendButton</string>
<string>SMSTextCountField</string>
<string>SMSTextView</string>
<string>SMSView</string>
<string>messageView</string>
<string>messagesTable</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">SMSBottomView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">SMSSendButton</string>
<string key="candidateClassName">UIButton</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">SMSTextCountField</string>
<string key="candidateClassName">UILabel</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">SMSTextView</string>
<string key="candidateClassName">MGMSMSTextView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">SMSView</string>
<string key="candidateClassName">UIWebView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">messageView</string>
<string key="candidateClassName">UIView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">messagesTable</string>
<string key="candidateClassName">UITableView</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>