Initial commit
This commit is contained in:
12
local_pod_repo/objcTox/iOSDemo/AppDelegate.h
Normal file
12
local_pod_repo/objcTox/iOSDemo/AppDelegate.h
Normal file
@ -0,0 +1,12 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
|
||||
@end
|
60
local_pod_repo/objcTox/iOSDemo/AppDelegate.m
Normal file
60
local_pod_repo/objcTox/iOSDemo/AppDelegate.m
Normal file
@ -0,0 +1,60 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "OCTStartDemoViewController.h"
|
||||
#import "DDLog.h"
|
||||
#import "DDASLLogger.h"
|
||||
#import "DDTTYLogger.h"
|
||||
|
||||
@interface AppDelegate ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
self.window.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
[DDLog addLogger:[DDASLLogger sharedInstance]];
|
||||
[DDLog addLogger:[DDTTYLogger sharedInstance]];
|
||||
|
||||
self.window.rootViewController = [OCTStartDemoViewController new];
|
||||
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application
|
||||
{
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
{
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||
{
|
||||
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application
|
||||
{
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application
|
||||
{
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
@end
|
41
local_pod_repo/objcTox/iOSDemo/Base.lproj/LaunchScreen.xib
Normal file
41
local_pod_repo/objcTox/iOSDemo/Base.lproj/LaunchScreen.xib
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text=" Copyright (c) 2015 dvor. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
|
||||
<rect key="frame" x="20" y="439" width="441" height="21"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="iOSDemo" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
|
||||
<rect key="frame" x="20" y="140" width="441" height="43"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
|
||||
<constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
|
||||
<constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
|
||||
<constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
|
||||
<constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
|
||||
<constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="548" y="455"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
@ -0,0 +1,93 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "20x20",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "76x76",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "ipad",
|
||||
"size" : "83.5x83.5",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
45
local_pod_repo/objcTox/iOSDemo/Info.plist
Normal file
45
local_pod_repo/objcTox/iOSDemo/Info.plist
Normal file
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>me.dvor.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
9
local_pod_repo/objcTox/iOSDemo/OCTCallsViewController.h
Normal file
9
local_pod_repo/objcTox/iOSDemo/OCTCallsViewController.h
Normal file
@ -0,0 +1,9 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import "OCTTableViewController.h"
|
||||
|
||||
@interface OCTCallsViewController : OCTTableViewController
|
||||
|
||||
@end
|
244
local_pod_repo/objcTox/iOSDemo/OCTCallsViewController.m
Normal file
244
local_pod_repo/objcTox/iOSDemo/OCTCallsViewController.m
Normal file
@ -0,0 +1,244 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
#import <BlocksKit/UIActionSheet+BlocksKit.h>
|
||||
#import <BlocksKit/UIAlertView+BlocksKit.h>
|
||||
#import <BlocksKit/UIBarButtonItem+BlocksKit.h>
|
||||
|
||||
#import "OCTCallsViewController.h"
|
||||
#import "OCTSubmanagerCalls.h"
|
||||
#import "OCTSubmanagerObjects.h"
|
||||
#import "OCTCall.h"
|
||||
#import "OCTVideoViewController.h"
|
||||
|
||||
@interface OCTCallsViewController ()
|
||||
|
||||
@property (strong, nonatomic) RLMResults<OCTCall *> *calls;
|
||||
@property (strong, nonatomic) RLMNotificationToken *callsNotificationToken;
|
||||
@property (strong, nonatomic) OCTCall *selectedCall;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OCTCallsViewController
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (instancetype)initWithManager:(id<OCTManager>)manager
|
||||
{
|
||||
self = [super initWithManager:manager];
|
||||
|
||||
if (! self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_calls = [self.manager.objects objectsForType:OCTFetchRequestTypeCall predicate:nil];
|
||||
|
||||
self.title = @"Calls";
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self.callsNotificationToken invalidate];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
__weak typeof(self)weakSelf = self;
|
||||
|
||||
self.callsNotificationToken = [self.calls addNotificationBlock:^(RLMResults *results, RLMCollectionChange *changes, NSError *error) {
|
||||
if (error) {
|
||||
NSLog(@"Failed to open Realm on background worker: %@", error);
|
||||
return;
|
||||
}
|
||||
|
||||
UITableView *tableView = weakSelf.tableView;
|
||||
|
||||
// Initial run of the query will pass nil for the change information
|
||||
if (! changes) {
|
||||
[tableView reloadData];
|
||||
return;
|
||||
}
|
||||
|
||||
// Query results have changed, so apply them to the UITableView
|
||||
[tableView beginUpdates];
|
||||
[tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[tableView insertRowsAtIndexPaths:[changes insertionsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[tableView endUpdates];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
self.selectedCall = self.calls[indexPath.row];
|
||||
|
||||
[self showActionDialog];
|
||||
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell *cell = [self cellForIndexPath:indexPath];
|
||||
|
||||
OCTCall *call = self.calls[indexPath.row];
|
||||
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"Call\n"
|
||||
@"Chat identifier %@\n"
|
||||
@"call status: %ld\n"
|
||||
@"callDuration: %f\n"
|
||||
@"friend sending audio: %d\n"
|
||||
@"friend receiving audio: %d\n"
|
||||
@"friend sending video: %d\n"
|
||||
@"friend receiving Video: %d\n",
|
||||
call.chat.uniqueIdentifier, (long)call.status, call.callDuration, call.friendSendingAudio, call.friendAcceptingAudio,
|
||||
call.friendSendingVideo, call.friendAcceptingVideo];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return self.calls.count;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)showActionDialog
|
||||
{
|
||||
__weak OCTCallsViewController *weakSelf = self;
|
||||
|
||||
[self showActionSheet:^(UIActionSheet *sheet) {
|
||||
[sheet bk_addButtonWithTitle:@"Send call controls" handler:^{
|
||||
[weakSelf showSendControlDialog];
|
||||
}];
|
||||
|
||||
[sheet bk_addButtonWithTitle:@"Mute/Unmute Mic" handler:^{
|
||||
[weakSelf toggleMuteMic];
|
||||
}];
|
||||
|
||||
[sheet bk_addButtonWithTitle:@"Use speaker phone" handler:^{
|
||||
[weakSelf useSpeaker];
|
||||
}];
|
||||
|
||||
[sheet bk_addButtonWithTitle:@"Use default speakers" handler:^{
|
||||
[weakSelf useDefaultSpeaker];
|
||||
}];
|
||||
|
||||
[sheet bk_addButtonWithTitle:@"Show video" handler:^{
|
||||
[weakSelf showVideo];
|
||||
}];
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
- (void)showSendControlDialog
|
||||
{
|
||||
__weak OCTCallsViewController *weakSelf = self;
|
||||
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Call control"
|
||||
message:@"Pick call control to send to friend"
|
||||
preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
|
||||
UIAlertAction *pauseAction = [UIAlertAction actionWithTitle:@"Pause"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {[weakSelf pause];
|
||||
}];
|
||||
|
||||
UIAlertAction *resumeAction = [UIAlertAction actionWithTitle:@"Resume"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {[weakSelf resume];
|
||||
}];
|
||||
|
||||
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"End/Reject Call"
|
||||
style:UIAlertActionStyleDestructive
|
||||
handler:^(UIAlertAction *action) {[weakSelf cancel];
|
||||
}];
|
||||
|
||||
UIAlertAction *muteAction = [UIAlertAction actionWithTitle:@"Mute Audio"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {[weakSelf muteFriend];
|
||||
}];
|
||||
|
||||
UIAlertAction *unmuteAction = [UIAlertAction actionWithTitle:@"Unmute Audio"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {[weakSelf unmuteFriend];
|
||||
}];
|
||||
|
||||
[alertController addAction:pauseAction];
|
||||
[alertController addAction:resumeAction];
|
||||
[alertController addAction:cancelAction];
|
||||
[alertController addAction:muteAction];
|
||||
[alertController addAction:unmuteAction];
|
||||
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Call methods
|
||||
|
||||
- (void)cancel
|
||||
{
|
||||
NSError *error;
|
||||
if (! [self.manager.calls sendCallControl:OCTToxAVCallControlCancel toCall:self.selectedCall error:&error]) {
|
||||
NSLog(@"%@ Error %@", self, error.localizedDescription);
|
||||
NSLog(@"%@ Reason: %@", self, error.localizedFailureReason);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)useSpeaker
|
||||
{
|
||||
[self.manager.calls routeAudioToSpeaker:YES error:nil];
|
||||
}
|
||||
|
||||
- (void)useDefaultSpeaker
|
||||
{
|
||||
[self.manager.calls routeAudioToSpeaker:NO error:nil];
|
||||
}
|
||||
|
||||
- (void)toggleMuteMic
|
||||
{
|
||||
BOOL currentStatus = self.manager.calls.enableMicrophone;
|
||||
self.manager.calls.enableMicrophone = ! currentStatus;
|
||||
}
|
||||
|
||||
- (void)pause
|
||||
{
|
||||
[self.manager.calls sendCallControl:OCTToxAVCallControlPause toCall:self.selectedCall error:nil];
|
||||
}
|
||||
|
||||
- (void)resume
|
||||
{
|
||||
[self.manager.calls sendCallControl:OCTToxAVCallControlResume toCall:self.selectedCall error:nil];
|
||||
}
|
||||
|
||||
- (void)muteFriend
|
||||
{
|
||||
[self.manager.calls sendCallControl:OCTToxAVCallControlMuteAudio toCall:self.selectedCall error:nil];
|
||||
}
|
||||
|
||||
- (void)unmuteFriend
|
||||
{
|
||||
[self.manager.calls sendCallControl:OCTToxAVCallControlUnmuteAudio toCall:self.selectedCall error:nil];
|
||||
}
|
||||
|
||||
- (void)showVideo
|
||||
{
|
||||
[self.manager.calls enableVideoSending:YES forCall:self.selectedCall error:nil];
|
||||
|
||||
OCTVideoViewController *videoViewController = [[OCTVideoViewController alloc] initWithCallManager:self.manager.calls call:self.selectedCall];
|
||||
videoViewController.modalInPopover = YES;
|
||||
videoViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
||||
|
||||
[self presentViewController:videoViewController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
@end
|
9
local_pod_repo/objcTox/iOSDemo/OCTChatsViewController.h
Normal file
9
local_pod_repo/objcTox/iOSDemo/OCTChatsViewController.h
Normal file
@ -0,0 +1,9 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import "OCTTableViewController.h"
|
||||
|
||||
@interface OCTChatsViewController : OCTTableViewController
|
||||
|
||||
@end
|
106
local_pod_repo/objcTox/iOSDemo/OCTChatsViewController.m
Normal file
106
local_pod_repo/objcTox/iOSDemo/OCTChatsViewController.m
Normal file
@ -0,0 +1,106 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import "OCTChatsViewController.h"
|
||||
#import "OCTConversationViewController.h"
|
||||
#import "OCTChat.h"
|
||||
#import "OCTSubmanagerObjects.h"
|
||||
|
||||
@interface OCTChatsViewController ()
|
||||
|
||||
@property (strong, nonatomic) RLMResults<OCTChat *> *chats;
|
||||
@property (strong, nonatomic) RLMNotificationToken *chatsNotificationToken;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OCTChatsViewController
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (instancetype)initWithManager:(id<OCTManager>)manager
|
||||
{
|
||||
self = [super initWithManager:manager];
|
||||
|
||||
if (! self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_chats = [self.manager.objects objectsForType:OCTFetchRequestTypeChat predicate:nil];
|
||||
self.title = @"Chats";
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self.chatsNotificationToken invalidate];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
__weak typeof(self)weakSelf = self;
|
||||
|
||||
self.chatsNotificationToken = [self.chats addNotificationBlock:^(RLMResults *results, RLMCollectionChange *changes, NSError *error) {
|
||||
if (error) {
|
||||
NSLog(@"Failed to open Realm on background worker: %@", error);
|
||||
return;
|
||||
}
|
||||
|
||||
UITableView *tableView = weakSelf.tableView;
|
||||
|
||||
// Initial run of the query will pass nil for the change information
|
||||
if (! changes) {
|
||||
[tableView reloadData];
|
||||
return;
|
||||
}
|
||||
|
||||
// Query results have changed, so apply them to the UITableView
|
||||
[tableView beginUpdates];
|
||||
[tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[tableView insertRowsAtIndexPaths:[changes insertionsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[tableView endUpdates];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
||||
OCTChat *chat = self.chats[indexPath.row];
|
||||
|
||||
OCTConversationViewController *cv = [[OCTConversationViewController alloc] initWithManager:self.manager chat:chat];
|
||||
[self.navigationController pushViewController:cv animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return self.chats.count;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell *cell = [self cellForIndexPath:indexPath];
|
||||
|
||||
OCTChat *chat = self.chats[indexPath.row];
|
||||
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"Chat\n"
|
||||
@"uniqueIdentifier %@\n"
|
||||
@"friends %@\n"
|
||||
@"enteredText %@\n"
|
||||
@"lastReadDate %@\n"
|
||||
@"hasUnreadMessages %d\n"
|
||||
@"lastMessage: %@",
|
||||
chat.uniqueIdentifier, chat.friends, chat.enteredText, chat.lastReadDate, [chat hasUnreadMessages], chat.lastMessage];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,13 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import "OCTTableViewController.h"
|
||||
|
||||
@class OCTChat;
|
||||
|
||||
@interface OCTConversationViewController : OCTTableViewController
|
||||
|
||||
- (instancetype)initWithManager:(id<OCTManager>)manager chat:(OCTChat *)chat;
|
||||
|
||||
@end
|
159
local_pod_repo/objcTox/iOSDemo/OCTConversationViewController.m
Normal file
159
local_pod_repo/objcTox/iOSDemo/OCTConversationViewController.m
Normal file
@ -0,0 +1,159 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import <BlocksKit/UIActionSheet+BlocksKit.h>
|
||||
#import <BlocksKit/UIAlertView+BlocksKit.h>
|
||||
#import <BlocksKit/UIBarButtonItem+BlocksKit.h>
|
||||
|
||||
#import "OCTConversationViewController.h"
|
||||
#import "OCTChat.h"
|
||||
#import "OCTMessageAbstract.h"
|
||||
#import "OCTSubmanagerObjects.h"
|
||||
#import "OCTSubmanagerChats.h"
|
||||
#import "OCTSubmanagerCalls.h"
|
||||
|
||||
@interface OCTConversationViewController ()
|
||||
|
||||
@property (strong, nonatomic) OCTChat *chat;
|
||||
@property (strong, nonatomic) RLMResults<OCTMessageAbstract *> *messages;
|
||||
@property (strong, nonatomic) RLMNotificationToken *messagesNotificationToken;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OCTConversationViewController
|
||||
|
||||
- (instancetype)initWithManager:(id<OCTManager>)manager chat:(OCTChat *)chat
|
||||
{
|
||||
self = [super initWithManager:manager];
|
||||
|
||||
if (! self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_chat = chat;
|
||||
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"chatUniqueIdentifier == %@", chat.uniqueIdentifier];
|
||||
_messages = [self.manager.objects objectsForType:OCTFetchRequestTypeMessageAbstract predicate:predicate];
|
||||
|
||||
self.title = [NSString stringWithFormat:@"%@", chat.uniqueIdentifier];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self.messagesNotificationToken invalidate];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
__weak typeof(self)weakSelf = self;
|
||||
|
||||
self.messagesNotificationToken = [self.messages addNotificationBlock:^(RLMResults *results, RLMCollectionChange *changes, NSError *error) {
|
||||
if (error) {
|
||||
NSLog(@"Failed to open Realm on background worker: %@", error);
|
||||
return;
|
||||
}
|
||||
|
||||
UITableView *tableView = weakSelf.tableView;
|
||||
|
||||
// Initial run of the query will pass nil for the change information
|
||||
if (! changes) {
|
||||
[tableView reloadData];
|
||||
return;
|
||||
}
|
||||
|
||||
// Query results have changed, so apply them to the UITableView
|
||||
[tableView beginUpdates];
|
||||
[tableView deleteRowsAtIndexPaths:[changes deletionsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[tableView insertRowsAtIndexPaths:[changes insertionsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[tableView reloadRowsAtIndexPaths:[changes modificationsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[tableView endUpdates];
|
||||
}];
|
||||
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
|
||||
bk_initWithBarButtonSystemItem:UIBarButtonSystemItemAdd handler:^(id handler) {
|
||||
[weakSelf showSendDialog];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return self.messages.count;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell *cell = [self cellForIndexPath:indexPath];
|
||||
|
||||
OCTMessageAbstract *message = self.messages[indexPath.row];
|
||||
|
||||
cell.textLabel.text = [message description];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)showSendDialog
|
||||
{
|
||||
__weak OCTConversationViewController *weakSelf = self;
|
||||
|
||||
[self showActionSheet:^(UIActionSheet *sheet) {
|
||||
[sheet bk_addButtonWithTitle:@"Send message" handler:^{
|
||||
[weakSelf sendMessage];
|
||||
}];
|
||||
|
||||
[sheet bk_addButtonWithTitle:@"Call friend" handler:^{
|
||||
[weakSelf callFriend];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
|
||||
- (void)sendMessage
|
||||
{
|
||||
UIAlertView *alert = [UIAlertView bk_alertViewWithTitle:@"Send message" message:nil];
|
||||
|
||||
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
|
||||
UITextField *messageField = [alert textFieldAtIndex:0];
|
||||
messageField.placeholder = @"Message";
|
||||
|
||||
__weak OCTConversationViewController *weakSelf = self;
|
||||
[alert bk_addButtonWithTitle:@"OK" handler:^{
|
||||
[weakSelf.manager.chats sendMessageToChat:weakSelf.chat text:messageField.text type:OCTToxMessageTypeNormal successBlock:^(OCTMessageAbstract *_) {
|
||||
[weakSelf.tableView reloadData];
|
||||
} failureBlock:nil];
|
||||
}];
|
||||
|
||||
[alert bk_setCancelButtonWithTitle:@"Cancel" handler:nil];
|
||||
|
||||
[alert show];
|
||||
}
|
||||
|
||||
#pragma mark - Call methods
|
||||
|
||||
- (void)callFriend
|
||||
{
|
||||
NSError *error;
|
||||
OCTCall *call = [self.manager.calls callToChat:self.chat enableAudio:YES enableVideo:NO error:&error];
|
||||
|
||||
if (! call) {
|
||||
NSLog(@"Unable to create call, %@", error.localizedFailureReason);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,9 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import "OCTTableViewController.h"
|
||||
|
||||
@interface OCTFriendsViewController : OCTTableViewController
|
||||
|
||||
@end
|
264
local_pod_repo/objcTox/iOSDemo/OCTFriendsViewController.m
Normal file
264
local_pod_repo/objcTox/iOSDemo/OCTFriendsViewController.m
Normal file
@ -0,0 +1,264 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import <BlocksKit/UIActionSheet+BlocksKit.h>
|
||||
#import <BlocksKit/UIAlertView+BlocksKit.h>
|
||||
#import <BlocksKit/UIBarButtonItem+BlocksKit.h>
|
||||
|
||||
#import "OCTFriendsViewController.h"
|
||||
#import "OCTFriend.h"
|
||||
#import "OCTFriendRequest.h"
|
||||
#import "OCTSubmanagerObjects.h"
|
||||
#import "OCTSubmanagerChats.h"
|
||||
#import "OCTSubmanagerFriends.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, SectionType) {
|
||||
SectionTypeFriends = 0,
|
||||
SectionTypeFriendRequests,
|
||||
SectionTypeCount,
|
||||
};
|
||||
|
||||
@interface OCTFriendsViewController ()
|
||||
|
||||
@property (strong, nonatomic) RLMResults<OCTFriend *> *friends;
|
||||
@property (strong, nonatomic) RLMNotificationToken *friendsNotificationToken;
|
||||
@property (strong, nonatomic) RLMResults<OCTFriendRequest *> *friendRequests;
|
||||
@property (strong, nonatomic) RLMNotificationToken *friendRequestsNotificationToken;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OCTFriendsViewController
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (instancetype)initWithManager:(id<OCTManager>)manager
|
||||
{
|
||||
self = [super initWithManager:manager];
|
||||
|
||||
if (! self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_friends = [self.manager.objects objectsForType:OCTFetchRequestTypeFriend predicate:nil];
|
||||
_friendRequests = [self.manager.objects objectsForType:OCTFetchRequestTypeFriendRequest predicate:nil];
|
||||
|
||||
self.title = @"Friends";
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self.friendsNotificationToken invalidate];
|
||||
[self.friendRequestsNotificationToken invalidate];
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
__weak typeof(self)weakSelf = self;
|
||||
|
||||
self.friendsNotificationToken = [self.friends addNotificationBlock:^(RLMResults *results, RLMCollectionChange *changes, NSError *error) {
|
||||
[weakSelf realmWasUpdated:changes sectionType:SectionTypeFriends error:error];
|
||||
}];
|
||||
|
||||
self.friendRequestsNotificationToken = [self.friendRequests addNotificationBlock:^(RLMResults *results, RLMCollectionChange *changes, NSError *error) {
|
||||
[weakSelf realmWasUpdated:changes sectionType:SectionTypeFriendRequests error:error];
|
||||
}];
|
||||
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
|
||||
bk_initWithBarButtonSystemItem:UIBarButtonSystemItemAdd handler:^(id handler) {
|
||||
[weakSelf sendFriendRequest];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
||||
SectionType type = indexPath.section;
|
||||
|
||||
switch (type) {
|
||||
case SectionTypeFriends:
|
||||
[self didSelectFriend:self.friends[indexPath.row]];
|
||||
break;
|
||||
case SectionTypeFriendRequests:
|
||||
[self didSelectFriendRequest:self.friendRequests[indexPath.row]];
|
||||
break;
|
||||
case SectionTypeCount:
|
||||
// nop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
{
|
||||
return SectionTypeCount;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
SectionType type = section;
|
||||
|
||||
switch (type) {
|
||||
case SectionTypeFriends:
|
||||
return self.friends.count;
|
||||
case SectionTypeFriendRequests:
|
||||
return self.friendRequests.count;
|
||||
case SectionTypeCount:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
SectionType type = section;
|
||||
|
||||
switch (type) {
|
||||
case SectionTypeFriends:
|
||||
return @"Friends";
|
||||
case SectionTypeFriendRequests:
|
||||
return @"FriendRequests";
|
||||
case SectionTypeCount:
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
SectionType type = indexPath.section;
|
||||
|
||||
switch (type) {
|
||||
case SectionTypeFriends:
|
||||
return [self friendCellAtIndexPath:indexPath];
|
||||
case SectionTypeFriendRequests:
|
||||
return [self friendRequestCellAtIndexPath:indexPath];
|
||||
case SectionTypeCount:
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (UITableViewCell *)friendCellAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell *cell = [self cellForIndexPath:indexPath];
|
||||
OCTFriend *friend = self.friends[indexPath.row];
|
||||
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"Friend\n"
|
||||
@"friendNumber %u\n"
|
||||
@"publicKey %@\n"
|
||||
@"name %@\n"
|
||||
@"nickname %@\n"
|
||||
@"statusMessage %@\n"
|
||||
@"status %@\n"
|
||||
@"isConnected %d\n"
|
||||
@"connectionStatus %@\n"
|
||||
@"lastSeenOnline %@\n"
|
||||
@"isTyping %d",
|
||||
friend.friendNumber,
|
||||
friend.publicKey,
|
||||
friend.name,
|
||||
friend.nickname,
|
||||
friend.statusMessage,
|
||||
[self stringFromUserStatus:friend.status],
|
||||
friend.isConnected,
|
||||
[self stringFromConnectionStatus:friend.connectionStatus],
|
||||
friend.lastSeenOnline,
|
||||
friend.isTyping];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)friendRequestCellAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell *cell = [self cellForIndexPath:indexPath];
|
||||
OCTFriendRequest *request = self.friendRequests[indexPath.row];
|
||||
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"Friend request\n"
|
||||
@"publicKey %@\n"
|
||||
@"message %@\n",
|
||||
request.publicKey, request.message];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)didSelectFriend:(OCTFriend *)friend
|
||||
{
|
||||
__weak OCTFriendsViewController *weakSelf = self;
|
||||
|
||||
[self showActionSheet:^(UIActionSheet *sheet) {
|
||||
[sheet bk_addButtonWithTitle:@"Create chat" handler:^{
|
||||
[weakSelf.manager.chats getOrCreateChatWithFriend:friend];
|
||||
}];
|
||||
|
||||
[sheet bk_addButtonWithTitle:@"Remove" handler:^{
|
||||
[weakSelf.manager.friends removeFriend:friend error:nil];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)didSelectFriendRequest:(OCTFriendRequest *)request
|
||||
{
|
||||
__weak OCTFriendsViewController *weakSelf = self;
|
||||
|
||||
[self showActionSheet:^(UIActionSheet *sheet) {
|
||||
[sheet bk_addButtonWithTitle:@"Add" handler:^{
|
||||
[weakSelf.manager.friends approveFriendRequest:request error:nil];
|
||||
}];
|
||||
|
||||
[sheet bk_addButtonWithTitle:@"Remove" handler:^{
|
||||
[weakSelf.manager.friends removeFriendRequest:request];
|
||||
}];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)sendFriendRequest
|
||||
{
|
||||
UIAlertView *alert = [UIAlertView bk_alertViewWithTitle:@"Send friend request" message:nil];
|
||||
|
||||
alert.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
|
||||
UITextField *addressField = [alert textFieldAtIndex:0];
|
||||
addressField.placeholder = @"Address";
|
||||
UITextField *messageField = [alert textFieldAtIndex:1];
|
||||
messageField.placeholder = @"Message";
|
||||
messageField.secureTextEntry = NO;
|
||||
|
||||
__weak OCTFriendsViewController *weakSelf = self;
|
||||
[alert bk_addButtonWithTitle:@"OK" handler:^{
|
||||
[weakSelf.manager.friends sendFriendRequestToAddress:addressField.text message:messageField.text error:nil];
|
||||
[weakSelf.tableView reloadData];
|
||||
}];
|
||||
|
||||
[alert bk_setCancelButtonWithTitle:@"Cancel" handler:nil];
|
||||
|
||||
[alert show];
|
||||
}
|
||||
|
||||
- (void)realmWasUpdated:(RLMCollectionChange *)changes sectionType:(SectionType)sectionType error:(NSError *)error
|
||||
{
|
||||
if (error) {
|
||||
NSLog(@"Failed to open Realm on background worker: %@", error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Initial run of the query will pass nil for the change information
|
||||
if (! changes) {
|
||||
[self.tableView reloadData];
|
||||
return;
|
||||
}
|
||||
|
||||
[self.tableView beginUpdates];
|
||||
[self.tableView deleteRowsAtIndexPaths:[changes deletionsInSection:sectionType] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[self.tableView insertRowsAtIndexPaths:[changes insertionsInSection:sectionType] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[self.tableView reloadRowsAtIndexPaths:[changes modificationsInSection:sectionType] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[self.tableView endUpdates];
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,9 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import "OCTTableViewController.h"
|
||||
|
||||
@interface OCTStartDemoViewController : OCTTableViewController
|
||||
|
||||
@end
|
158
local_pod_repo/objcTox/iOSDemo/OCTStartDemoViewController.m
Normal file
158
local_pod_repo/objcTox/iOSDemo/OCTStartDemoViewController.m
Normal file
@ -0,0 +1,158 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import <Masonry/Masonry.h>
|
||||
|
||||
#import "OCTStartDemoViewController.h"
|
||||
#import "OCTUserViewController.h"
|
||||
#import "OCTFriendsViewController.h"
|
||||
#import "OCTChatsViewController.h"
|
||||
#import "OCTCallsViewController.h"
|
||||
#import "OCTTabBarControllerViewController.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "OCTManagerConfiguration.h"
|
||||
#import "OCTManagerFactory.h"
|
||||
#import "OCTSubmanagerBootstrap.h"
|
||||
|
||||
#define NAVIGATION_WITH_CONTROLLER(class) \
|
||||
[[UINavigationController alloc] initWithRootViewController:[[class alloc] initWithManager:manager]]
|
||||
|
||||
static NSString *const kLoginIdentifier = @"kLoginIdentifier";
|
||||
|
||||
typedef NS_ENUM(NSUInteger, Row) {
|
||||
RowBootstrap,
|
||||
RowIPv6Enabled,
|
||||
RowUDPEnabled,
|
||||
__RowCount,
|
||||
};
|
||||
|
||||
@interface OCTStartDemoViewController ()
|
||||
|
||||
@property (strong, nonatomic) OCTManagerConfiguration *configuration;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OCTStartDemoViewController
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.title = @"Start";
|
||||
self.configuration = [OCTManagerConfiguration defaultConfiguration];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
||||
Row row = indexPath.row;
|
||||
|
||||
switch (row) {
|
||||
case RowBootstrap:
|
||||
[self bootstrap];
|
||||
break;
|
||||
case RowIPv6Enabled:
|
||||
case RowUDPEnabled:
|
||||
[self showActionSheetForRow:row];
|
||||
break;
|
||||
case __RowCount:
|
||||
// nop
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return __RowCount;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell *cell = [self cellForIndexPath:indexPath];
|
||||
|
||||
Row row = indexPath.row;
|
||||
cell.textLabel.textColor = [UIColor blackColor];
|
||||
cell.textLabel.textAlignment = NSTextAlignmentLeft;
|
||||
cell.textLabel.font = [UIFont boldSystemFontOfSize:16.0];
|
||||
|
||||
switch (row) {
|
||||
case RowBootstrap:
|
||||
cell.textLabel.text = @"Bootstrap";
|
||||
cell.textLabel.textColor = [UIColor blueColor];
|
||||
cell.textLabel.textAlignment = NSTextAlignmentCenter;
|
||||
cell.textLabel.font = [UIFont boldSystemFontOfSize:20.0];
|
||||
break;
|
||||
|
||||
case RowIPv6Enabled:
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"IPv6Enabled %u", self.configuration.options.ipv6Enabled];
|
||||
break;
|
||||
case RowUDPEnabled:
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"UDPEnabled %u", self.configuration.options.udpEnabled];
|
||||
break;
|
||||
case __RowCount:
|
||||
// nop
|
||||
break;
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)bootstrap
|
||||
{
|
||||
[OCTManagerFactory managerWithConfiguration:self.configuration encryptPassword:@"123" successBlock:^(id < OCTManager > manager) {
|
||||
OCTTabBarControllerViewController *tabBar = [OCTTabBarControllerViewController new];
|
||||
tabBar.viewControllers = @[
|
||||
NAVIGATION_WITH_CONTROLLER(OCTUserViewController),
|
||||
NAVIGATION_WITH_CONTROLLER(OCTFriendsViewController),
|
||||
NAVIGATION_WITH_CONTROLLER(OCTChatsViewController),
|
||||
NAVIGATION_WITH_CONTROLLER(OCTCallsViewController),
|
||||
];
|
||||
|
||||
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
delegate.window.rootViewController = tabBar;
|
||||
manager.calls.delegate = tabBar;
|
||||
|
||||
[manager.bootstrap addPredefinedNodes];
|
||||
[manager.bootstrap bootstrap];
|
||||
} failureBlock:nil];
|
||||
}
|
||||
|
||||
- (void)showActionSheetForRow:(Row)row
|
||||
{
|
||||
__weak OCTStartDemoViewController *weakSelf = self;
|
||||
|
||||
[self showActionSheet:^(UIActionSheet *sheet) {
|
||||
switch (row) {
|
||||
case RowIPv6Enabled:
|
||||
{
|
||||
[weakSelf addToSheet:sheet multiEditButtonWithOptions:@[ @"NO", @"YES" ] block:^(NSUInteger index) {
|
||||
weakSelf.configuration.options.ipv6Enabled = (BOOL)index;
|
||||
}];
|
||||
break;
|
||||
}
|
||||
case RowUDPEnabled:
|
||||
{
|
||||
[weakSelf addToSheet:sheet multiEditButtonWithOptions:@[ @"NO", @"YES" ] block:^(NSUInteger index) {
|
||||
weakSelf.configuration.options.udpEnabled = (BOOL)index;
|
||||
}];
|
||||
break;
|
||||
}
|
||||
case RowBootstrap:
|
||||
case __RowCount:
|
||||
// nop
|
||||
break;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,10 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "OCTSubmanagerCalls.h"
|
||||
|
||||
@interface OCTTabBarControllerViewController : UITabBarController <OCTSubmanagerCallDelegate>
|
||||
|
||||
@end
|
@ -0,0 +1,53 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import "OCTTabBarControllerViewController.h"
|
||||
|
||||
@interface OCTTabBarControllerViewController ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation OCTTabBarControllerViewController
|
||||
|
||||
#pragma mark - OCTSubmanagerCalls Delegate
|
||||
|
||||
- (void)callSubmanager:(id<OCTSubmanagerCalls>)callSubmanager receiveCall:(OCTCall *)call audioEnabled:(BOOL)audioEnabled videoEnabled:(BOOL)videoEnabled
|
||||
{
|
||||
NSString *title = [NSString stringWithFormat:@"audio: %d video: %d", audioEnabled, videoEnabled];
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Receiving call" message:title preferredStyle:UIAlertControllerStyleAlert];
|
||||
|
||||
UIAlertAction *rejectAction = [UIAlertAction actionWithTitle:@"Reject Call"
|
||||
style:UIAlertActionStyleCancel
|
||||
handler:^(UIAlertAction *action) {
|
||||
NSError *error;
|
||||
BOOL status = [callSubmanager sendCallControl:OCTToxAVCallControlCancel toCall:call error:&error];
|
||||
if (! status) {
|
||||
NSLog(@"End call error: %@, %@", error.localizedDescription
|
||||
, error.localizedFailureReason);
|
||||
}
|
||||
}];
|
||||
|
||||
UIAlertAction *acceptAction = [UIAlertAction actionWithTitle:@"Accept"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
NSError *error;
|
||||
BOOL status = [callSubmanager answerCall:call
|
||||
enableAudio:YES
|
||||
enableVideo:YES
|
||||
error:&error];
|
||||
if (! status) {
|
||||
NSLog(@"Accept call error: %@, %@", error.localizedDescription
|
||||
, error.localizedFailureReason);
|
||||
}
|
||||
}];
|
||||
|
||||
[alertController addAction:rejectAction];
|
||||
[alertController addAction:acceptAction];
|
||||
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)callSubmanager:(id<OCTSubmanagerCalls>)callSubmanager audioBitRateChanged:(OCTToxAVAudioBitRate)bitRate stable:(BOOL)stable forCall:(OCTCall *)call
|
||||
{}
|
||||
@end
|
32
local_pod_repo/objcTox/iOSDemo/OCTTableViewController.h
Normal file
32
local_pod_repo/objcTox/iOSDemo/OCTTableViewController.h
Normal file
@ -0,0 +1,32 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "OCTManager.h"
|
||||
|
||||
@interface OCTTableViewController : UIViewController
|
||||
|
||||
@property (strong, nonatomic, readonly) UITableView *tableView;
|
||||
@property (strong, nonatomic, readonly) id<OCTManager> manager;
|
||||
|
||||
- (instancetype)initWithManager:(id<OCTManager>)manager;
|
||||
|
||||
- (UITableViewCell *)cellForIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
- (void)showActionSheet:(void (^)(UIActionSheet *sheet))block;
|
||||
- (void)addToSheet:(UIActionSheet *)sheet copyButtonWithValue:(id)value;
|
||||
- (void)addToSheet:(UIActionSheet *)sheet textEditButtonWithValue:(id)value block:(void (^)(NSString *string))block;
|
||||
- (void) addToSheet:(UIActionSheet *)sheet
|
||||
multiEditButtonWithOptions:(NSArray *)options
|
||||
block:(void (^)(NSUInteger index))block;
|
||||
|
||||
// Value can be NSString or NSNumber
|
||||
- (NSString *)stringFromValue:(id)value;
|
||||
- (NSString *)stringFromUserStatus:(OCTToxUserStatus)status;
|
||||
- (NSString *)stringFromConnectionStatus:(OCTToxConnectionStatus)status;
|
||||
|
||||
// Shows error if it isn't nil.
|
||||
- (void)maybeShowError:(NSError *)error;
|
||||
|
||||
@end
|
203
local_pod_repo/objcTox/iOSDemo/OCTTableViewController.m
Normal file
203
local_pod_repo/objcTox/iOSDemo/OCTTableViewController.m
Normal file
@ -0,0 +1,203 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import <BlocksKit/UIActionSheet+BlocksKit.h>
|
||||
#import <BlocksKit/UIAlertView+BlocksKit.h>
|
||||
#import <Masonry/Masonry.h>
|
||||
|
||||
#import "OCTTableViewController.h"
|
||||
|
||||
static NSString *const kUITableViewCellIdentifier = @"kUITableViewCellIdentifier";
|
||||
|
||||
@interface OCTTableViewController () <UITableViewDelegate, UITableViewDataSource>
|
||||
|
||||
@property (strong, nonatomic) UITableView *tableView;
|
||||
@property (strong, nonatomic) id<OCTManager> manager;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OCTTableViewController
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (instancetype)initWithManager:(id<OCTManager>)manager
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (! self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_manager = manager;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
|
||||
self.tableView.delegate = self;
|
||||
self.tableView.dataSource = self;
|
||||
self.tableView.rowHeight = UITableViewAutomaticDimension;
|
||||
self.tableView.estimatedRowHeight = 44.0;
|
||||
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:kUITableViewCellIdentifier];
|
||||
[self.view addSubview:self.tableView];
|
||||
|
||||
[self installConstraints];
|
||||
}
|
||||
|
||||
#pragma mark - Public
|
||||
|
||||
- (UITableViewCell *)cellForIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kUITableViewCellIdentifier
|
||||
forIndexPath:indexPath];
|
||||
cell.textLabel.numberOfLines = 0;
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (void)showActionSheet:(void (^)(UIActionSheet *sheet))block
|
||||
{
|
||||
if (! block) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIActionSheet *sheet = [UIActionSheet bk_actionSheetWithTitle:@"Select action"];
|
||||
[sheet bk_setCancelButtonWithTitle:@"Cancel" handler:nil];
|
||||
|
||||
block(sheet);
|
||||
|
||||
[sheet showInView:self.view];
|
||||
}
|
||||
|
||||
- (void)addToSheet:(UIActionSheet *)sheet copyButtonWithValue:(id)value
|
||||
{
|
||||
[sheet bk_addButtonWithTitle:@"Copy" handler:^{
|
||||
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
|
||||
pasteboard.string = [self stringFromValue:value];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)addToSheet:(UIActionSheet *)sheet textEditButtonWithValue:(id)value block:(void (^)(NSString *string))block
|
||||
{
|
||||
NSParameterAssert(block);
|
||||
|
||||
__weak OCTTableViewController *weakSelf = self;
|
||||
|
||||
[sheet bk_addButtonWithTitle:@"Edit" handler:^{
|
||||
UIAlertView *alert = [UIAlertView bk_alertViewWithTitle:@"" message:nil];
|
||||
|
||||
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
|
||||
[[alert textFieldAtIndex:0] setText:[self stringFromValue:value]];
|
||||
|
||||
[alert bk_addButtonWithTitle:@"OK" handler:^{
|
||||
block([alert textFieldAtIndex:0].text);
|
||||
|
||||
[weakSelf.tableView reloadData];
|
||||
}];
|
||||
|
||||
[alert bk_setCancelButtonWithTitle:@"Cancel" handler:nil];
|
||||
|
||||
[alert show];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void) addToSheet:(UIActionSheet *)sheet
|
||||
multiEditButtonWithOptions:(NSArray *)options
|
||||
block:(void (^)(NSUInteger index))block
|
||||
{
|
||||
NSParameterAssert(block);
|
||||
|
||||
__weak OCTTableViewController *weakSelf = self;
|
||||
|
||||
[sheet bk_addButtonWithTitle:@"Edit" handler:^{
|
||||
UIActionSheet *editSheet = [UIActionSheet bk_actionSheetWithTitle:@"Select action"];
|
||||
|
||||
for (NSUInteger index = 0; index < options.count; index++) {
|
||||
[editSheet bk_addButtonWithTitle:options[index] handler:^{
|
||||
block(index);
|
||||
[weakSelf.tableView reloadData];
|
||||
}];
|
||||
}
|
||||
|
||||
[editSheet bk_setCancelButtonWithTitle:@"Cancel" handler:nil];
|
||||
[editSheet showInView:weakSelf.view];
|
||||
}];
|
||||
}
|
||||
- (NSString *)stringFromValue:(id)value
|
||||
{
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if ([value isKindOfClass:[NSNumber class]]) {
|
||||
return [NSString stringWithFormat:@"%@", value];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *)stringFromUserStatus:(OCTToxUserStatus)status
|
||||
{
|
||||
switch (status) {
|
||||
case OCTToxUserStatusNone:
|
||||
return @"None";
|
||||
case OCTToxUserStatusAway:
|
||||
return @"Away";
|
||||
case OCTToxUserStatusBusy:
|
||||
return @"Busy";
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)stringFromConnectionStatus:(OCTToxConnectionStatus)status
|
||||
{
|
||||
switch (status) {
|
||||
case OCTToxConnectionStatusNone:
|
||||
return @"None";
|
||||
case OCTToxConnectionStatusTCP:
|
||||
return @"TCP";
|
||||
case OCTToxConnectionStatusUDP:
|
||||
return @"UDP";
|
||||
}
|
||||
}
|
||||
|
||||
- (void)maybeShowError:(NSError *)error
|
||||
{
|
||||
if (! error) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIAlertView *alert = [UIAlertView bk_alertViewWithTitle:error.localizedDescription
|
||||
message:error.localizedFailureReason];
|
||||
[alert bk_setCancelButtonWithTitle:@"OK" handler:nil];
|
||||
[alert show];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
NSAssert(NO, @"Implement in subclass");
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSAssert(NO, @"Implement in subclass");
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)installConstraints
|
||||
{
|
||||
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.equalTo(self.view);
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
9
local_pod_repo/objcTox/iOSDemo/OCTUserViewController.h
Normal file
9
local_pod_repo/objcTox/iOSDemo/OCTUserViewController.h
Normal file
@ -0,0 +1,9 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import "OCTTableViewController.h"
|
||||
|
||||
@interface OCTUserViewController : OCTTableViewController
|
||||
|
||||
@end
|
189
local_pod_repo/objcTox/iOSDemo/OCTUserViewController.m
Normal file
189
local_pod_repo/objcTox/iOSDemo/OCTUserViewController.m
Normal file
@ -0,0 +1,189 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import <BlocksKit/UIActionSheet+BlocksKit.h>
|
||||
|
||||
#import "OCTUserViewController.h"
|
||||
#import "OCTStartDemoViewController.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "OCTSubmanagerUser.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, Row) {
|
||||
RowConnectionStatus,
|
||||
RowAddress,
|
||||
RowPublicKey,
|
||||
RowNospam,
|
||||
RowStatus,
|
||||
RowName,
|
||||
RowStatusMessage,
|
||||
RowLogOut,
|
||||
};
|
||||
|
||||
@interface OCTUserViewController () <OCTSubmanagerUserDelegate>
|
||||
|
||||
@property (strong, nonatomic) NSArray *userData;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OCTUserViewController
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (instancetype)initWithManager:(id<OCTManager>)manager
|
||||
{
|
||||
self = [super initWithManager:manager];
|
||||
|
||||
if (! self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
manager.user.delegate = self;
|
||||
|
||||
_userData = @[
|
||||
@(RowConnectionStatus),
|
||||
@(RowAddress),
|
||||
@(RowPublicKey),
|
||||
@(RowNospam),
|
||||
@(RowStatus),
|
||||
@(RowName),
|
||||
@(RowStatusMessage),
|
||||
@(RowLogOut),
|
||||
];
|
||||
|
||||
self.title = @"User";
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDelegate
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
||||
__weak OCTUserViewController *weakSelf = self;
|
||||
|
||||
[self showActionSheet:^(UIActionSheet *sheet) {
|
||||
switch (indexPath.row) {
|
||||
case RowConnectionStatus:
|
||||
// nop
|
||||
break;
|
||||
case RowAddress:
|
||||
[weakSelf addToSheet:sheet copyButtonWithValue:weakSelf.manager.user.userAddress];
|
||||
break;
|
||||
case RowPublicKey:
|
||||
[weakSelf addToSheet:sheet copyButtonWithValue:weakSelf.manager.user.publicKey];
|
||||
break;
|
||||
case RowNospam:
|
||||
{
|
||||
[weakSelf addToSheet:sheet copyButtonWithValue:@(weakSelf.manager.user.nospam)];
|
||||
[weakSelf addToSheet:sheet textEditButtonWithValue:@(weakSelf.manager.user.nospam) block:^(NSString *string) {
|
||||
weakSelf.manager.user.nospam = (OCTToxNoSpam)[string integerValue];
|
||||
}];
|
||||
break;
|
||||
}
|
||||
case RowStatus:
|
||||
{
|
||||
[weakSelf addToSheet:sheet multiEditButtonWithOptions:@[
|
||||
[weakSelf stringFromUserStatus:0],
|
||||
[weakSelf stringFromUserStatus:1],
|
||||
[weakSelf stringFromUserStatus:2],
|
||||
|
||||
] block:^(NSUInteger index) {
|
||||
weakSelf.manager.user.userStatus = index;
|
||||
}];
|
||||
break;
|
||||
}
|
||||
case RowName:
|
||||
{
|
||||
[weakSelf addToSheet:sheet copyButtonWithValue:weakSelf.manager.user.userName];
|
||||
[weakSelf addToSheet:sheet textEditButtonWithValue:weakSelf.manager.user.userName block:^(NSString *string) {
|
||||
NSError *error;
|
||||
[weakSelf.manager.user setUserName:string error:&error];
|
||||
[self maybeShowError:error];
|
||||
}];
|
||||
break;
|
||||
}
|
||||
case RowStatusMessage:
|
||||
{
|
||||
[weakSelf addToSheet:sheet copyButtonWithValue:weakSelf.manager.user.userStatusMessage];
|
||||
[weakSelf addToSheet:sheet textEditButtonWithValue:weakSelf.manager.user.userStatusMessage block:^(NSString *string) {
|
||||
NSError *error;
|
||||
[weakSelf.manager.user setUserStatusMessage:string error:&error];
|
||||
[self maybeShowError:error];
|
||||
}];
|
||||
break;
|
||||
}
|
||||
case RowLogOut:
|
||||
{
|
||||
[sheet bk_addButtonWithTitle:@"Log out" handler:^{
|
||||
[weakSelf logOut];
|
||||
}];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return self.userData.count;
|
||||
}
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell *cell = [self cellForIndexPath:indexPath];
|
||||
|
||||
Row row = indexPath.row;
|
||||
|
||||
switch (row) {
|
||||
case RowConnectionStatus:
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"connectionStatus: %@",
|
||||
[self stringFromConnectionStatus:self.manager.user.connectionStatus]];
|
||||
break;
|
||||
case RowAddress:
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"userAddress: %@", self.manager.user.userAddress];
|
||||
break;
|
||||
case RowPublicKey:
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"publicKey: %@", self.manager.user.publicKey];
|
||||
break;
|
||||
case RowNospam:
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"nospam: %u", self.manager.user.nospam];
|
||||
break;
|
||||
case RowStatus:
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"userStatus: %@",
|
||||
[self stringFromUserStatus:self.manager.user.userStatus]];
|
||||
break;
|
||||
case RowName:
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"userName: %@", self.manager.user.userName];
|
||||
break;
|
||||
case RowStatusMessage:
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"userStatusMessage: %@", self.manager.user.userStatusMessage];
|
||||
break;
|
||||
case RowLogOut:
|
||||
cell.textLabel.text = @"Log Out";
|
||||
break;
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
#pragma mark - OCTSubmanagerUserDelegate
|
||||
|
||||
- (void)submanagerUser:(id<OCTSubmanagerUser>)submanager connectionStatusUpdate:(OCTToxConnectionStatus)connectionStatus
|
||||
{
|
||||
[self.tableView reloadData];
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)logOut
|
||||
{
|
||||
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
delegate.window.rootViewController = [OCTStartDemoViewController new];
|
||||
}
|
||||
|
||||
@end
|
14
local_pod_repo/objcTox/iOSDemo/OCTVideoViewController.h
Normal file
14
local_pod_repo/objcTox/iOSDemo/OCTVideoViewController.h
Normal file
@ -0,0 +1,14 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@protocol OCTSubmanagerCalls;
|
||||
@class OCTCall;
|
||||
|
||||
@interface OCTVideoViewController : UIViewController
|
||||
|
||||
- (instancetype)initWithCallManager:(id<OCTSubmanagerCalls>)manager call:(OCTCall *)call;
|
||||
|
||||
@end
|
248
local_pod_repo/objcTox/iOSDemo/OCTVideoViewController.m
Normal file
248
local_pod_repo/objcTox/iOSDemo/OCTVideoViewController.m
Normal file
@ -0,0 +1,248 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import "OCTVideoViewController.h"
|
||||
#import "OCTSubmanagerCalls.h"
|
||||
#import "OCTTableViewController.h"
|
||||
|
||||
static const CGFloat kEdgeInsets = 25.0;
|
||||
|
||||
@interface OCTVideoViewController ()
|
||||
|
||||
@property (nonatomic, strong) id<OCTSubmanagerCalls> manager;
|
||||
@property (nonatomic, strong) UIButton *menuActionButton;
|
||||
@property (nonatomic, strong) UIView *previewView;
|
||||
@property (nonatomic, weak) CALayer *previewLayer;
|
||||
@property (nonatomic, strong) UIView *videoFeed;
|
||||
@property (nonatomic, strong) OCTCall *call;
|
||||
@end
|
||||
|
||||
@implementation OCTVideoViewController
|
||||
|
||||
- (instancetype)initWithCallManager:(id<OCTSubmanagerCalls>)manager call:(OCTCall *)call
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (! self) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
_manager = manager;
|
||||
_call = call;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self createDismissVCButton];
|
||||
[self createPreviewView];
|
||||
[self createVideoFeedView];
|
||||
|
||||
[self createPreviewViewConstraints];
|
||||
}
|
||||
|
||||
- (void)viewDidLayoutSubviews
|
||||
{
|
||||
[self adjustPreviewLayer];
|
||||
}
|
||||
|
||||
- (void)createVideoViewConstraints
|
||||
{
|
||||
NSLayoutConstraint *videoViewTop = [NSLayoutConstraint constraintWithItem:self.videoFeed
|
||||
attribute:NSLayoutAttributeTop
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.view
|
||||
attribute:NSLayoutAttributeTop
|
||||
multiplier:1.0
|
||||
constant:kEdgeInsets];
|
||||
|
||||
NSLayoutConstraint *videoViewRight = [NSLayoutConstraint constraintWithItem:self.videoFeed
|
||||
attribute:NSLayoutAttributeRight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.view
|
||||
attribute:NSLayoutAttributeRight
|
||||
multiplier:1.0
|
||||
constant:-kEdgeInsets];
|
||||
|
||||
NSLayoutConstraint *videoViewLeft = [NSLayoutConstraint constraintWithItem:self.videoFeed
|
||||
attribute:NSLayoutAttributeLeft
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.view
|
||||
attribute:NSLayoutAttributeLeft
|
||||
multiplier:1.0
|
||||
constant:kEdgeInsets];
|
||||
|
||||
NSLayoutConstraint *videoViewBottom = [NSLayoutConstraint constraintWithItem:self.videoFeed
|
||||
attribute:NSLayoutAttributeBottom
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.previewView
|
||||
attribute:NSLayoutAttributeTop
|
||||
multiplier:1.0
|
||||
constant:0];
|
||||
|
||||
[self.view addConstraints:@[videoViewBottom, videoViewLeft, videoViewRight, videoViewTop]];
|
||||
}
|
||||
|
||||
- (void)createPreviewViewConstraints
|
||||
{
|
||||
NSLayoutConstraint *previewViewBottom = [NSLayoutConstraint constraintWithItem:self.previewView
|
||||
attribute:NSLayoutAttributeBottom
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.view
|
||||
attribute:NSLayoutAttributeBottom
|
||||
multiplier:1.0
|
||||
constant:-kEdgeInsets];
|
||||
|
||||
NSLayoutConstraint *previewViewLeft = [NSLayoutConstraint constraintWithItem:self.previewView
|
||||
attribute:NSLayoutAttributeLeft
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.view
|
||||
attribute:NSLayoutAttributeLeft
|
||||
multiplier:1.0
|
||||
constant:kEdgeInsets];
|
||||
|
||||
NSLayoutConstraint *previewViewRight = [NSLayoutConstraint constraintWithItem:self.previewView
|
||||
attribute:NSLayoutAttributeRight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.view
|
||||
attribute:NSLayoutAttributeRight
|
||||
multiplier:1.0
|
||||
constant:-kEdgeInsets];
|
||||
|
||||
NSLayoutConstraint *previewViewHeight = [NSLayoutConstraint constraintWithItem:self.previewView
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.view
|
||||
attribute:NSLayoutAttributeHeight
|
||||
multiplier:0.5
|
||||
constant:-kEdgeInsets];
|
||||
|
||||
[self.view addConstraints:@[previewViewBottom, previewViewHeight, previewViewLeft, previewViewRight]];
|
||||
}
|
||||
|
||||
- (void)createPreviewView
|
||||
{
|
||||
self.previewView = [UIView new];
|
||||
self.previewView.userInteractionEnabled = NO;
|
||||
self.previewView.backgroundColor = [UIColor blackColor];
|
||||
self.previewView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
|
||||
[self.view addSubview:self.previewView];
|
||||
}
|
||||
|
||||
- (void)adjustPreviewLayer
|
||||
{
|
||||
if (! self.previewLayer) {
|
||||
__weak OCTVideoViewController *weakSelf = self;
|
||||
|
||||
[self.previewView.layer addSublayer:self.previewLayer];
|
||||
[self.manager getVideoCallPreview:^(CALayer *layer) {
|
||||
OCTVideoViewController *strongSelf = weakSelf;
|
||||
[strongSelf.previewView.layer addSublayer:layer];
|
||||
strongSelf.previewLayer = layer;
|
||||
strongSelf.previewLayer.frame = strongSelf.previewView.bounds;
|
||||
}];
|
||||
}
|
||||
else {
|
||||
self.previewLayer.frame = self.previewView.bounds;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)createVideoFeedView
|
||||
{
|
||||
self.videoFeed = [self.manager videoFeed];
|
||||
self.videoFeed.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
self.videoFeed.userInteractionEnabled = NO;
|
||||
[self.view addSubview:self.videoFeed];
|
||||
[self createVideoViewConstraints];
|
||||
}
|
||||
|
||||
- (void)createDismissVCButton
|
||||
{
|
||||
self.menuActionButton = [[UIButton alloc] initWithFrame:self.view.bounds];
|
||||
self.menuActionButton.backgroundColor = [UIColor clearColor];
|
||||
[self.menuActionButton addTarget:self
|
||||
action:@selector(showActionDialog)
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
[self.view addSubview:self.menuActionButton];
|
||||
}
|
||||
|
||||
- (void)showActionDialog
|
||||
{
|
||||
__weak OCTVideoViewController *weakSelf = self;
|
||||
|
||||
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Video"
|
||||
message:@"actions"
|
||||
preferredStyle:UIAlertControllerStyleActionSheet];
|
||||
|
||||
UIAlertAction *stopSendingVideoAction = [UIAlertAction actionWithTitle:@"Stop sending video"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
[weakSelf stopSendingVideo];
|
||||
}];
|
||||
|
||||
UIAlertAction *startSendingVideoAction = [UIAlertAction actionWithTitle:@"Start sending video"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
[weakSelf startSendingVideo];
|
||||
}];
|
||||
|
||||
UIAlertAction *switchToRearAction = [UIAlertAction actionWithTitle:@"Use rear camera"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
[weakSelf switchToBack];
|
||||
}];
|
||||
|
||||
UIAlertAction *switchToFrontAction = [UIAlertAction actionWithTitle:@"Use front camera"
|
||||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *action) {
|
||||
[weakSelf switchToFront];
|
||||
}];
|
||||
|
||||
UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:@"Dismiss view"
|
||||
style:UIAlertActionStyleDestructive
|
||||
handler:^(UIAlertAction *action) {
|
||||
[weakSelf dismissViewButtonPressed];
|
||||
}];
|
||||
|
||||
[alertController addAction:stopSendingVideoAction];
|
||||
[alertController addAction:startSendingVideoAction];
|
||||
[alertController addAction:switchToRearAction];
|
||||
[alertController addAction:switchToFrontAction];
|
||||
[alertController addAction:dismissAction];
|
||||
|
||||
[self presentViewController:alertController animated:YES completion:nil];
|
||||
}
|
||||
|
||||
#pragma mark - Touch actions
|
||||
|
||||
- (void)dismissViewButtonPressed
|
||||
{
|
||||
[self dismissViewControllerAnimated:YES completion:nil];
|
||||
}
|
||||
|
||||
- (void)stopSendingVideo
|
||||
{
|
||||
[self.manager enableVideoSending:NO forCall:self.call error:nil];
|
||||
}
|
||||
|
||||
- (void)startSendingVideo
|
||||
{
|
||||
[self.manager enableVideoSending:YES forCall:self.call error:nil];
|
||||
}
|
||||
|
||||
- (void)switchToFront
|
||||
{
|
||||
[self.manager switchToCameraFront:YES error:nil];
|
||||
}
|
||||
|
||||
- (void)switchToBack
|
||||
{
|
||||
[self.manager switchToCameraFront:NO error:nil];
|
||||
}
|
||||
@end
|
13
local_pod_repo/objcTox/iOSDemo/main.m
Normal file
13
local_pod_repo/objcTox/iOSDemo/main.m
Normal file
@ -0,0 +1,13 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user