Update SDK Versions for Chat and Video

This commit is contained in:
Jeffrey Linwood
2018-09-28 05:51:28 -05:00
parent afa9372657
commit 3ea1eaf402
11 changed files with 307 additions and 268 deletions

View File

@@ -8,10 +8,10 @@
</head> </head>
<body> <body>
<header> <header>
<a href="https://www.twilio.com/docs/api/chat/guides/quickstart-js" <a href="https://www.twilio.com/docs/api/chat/guides/quickstart-js"
target="_blank">Read the getting started guide target="_blank">Read the getting started guide
<i class="fa fa-fw fa-external-link"></i> <i class="fa fa-fw fa-external-link"></i>
</a> </a>
</header> </header>
<section> <section>
@@ -19,7 +19,8 @@
<input id="chat-input" type="text" placeholder="say anything" autofocus/> <input id="chat-input" type="text" placeholder="say anything" autofocus/>
</section> </section>
<script src="https://media.twiliocdn.com/sdk/js/chat/v1.0/twilio-chat.js"></script> <script src="https://media.twiliocdn.com/sdk/js/common/v0.1/twilio-common.min.js"></script>
<script src="https://media.twiliocdn.com/sdk/js/chat/v3.0/twilio-chat.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="index.js"></script> <script src="index.js"></script>
</body> </body>

View File

@@ -1,106 +1,111 @@
$(function() { $(function() {
// Get handle to the chat div // Get handle to the chat div
var $chatWindow = $('#messages'); var $chatWindow = $('#messages');
// Our interface to the Chat service // Our interface to the Chat service
var chatClient; var chatClient;
// A handle to the "general" chat channel - the one and only channel we // A handle to the "general" chat channel - the one and only channel we
// will have in this sample app // will have in this sample app
var generalChannel; var generalChannel;
// The server will assign the client a random username - store that value // The server will assign the client a random username - store that value
// here // here
var username; var username;
// Helper function to print info messages to the chat window // Helper function to print info messages to the chat window
function print(infoMessage, asHtml) { function print(infoMessage, asHtml) {
var $msg = $('<div class="info">'); var $msg = $('<div class="info">');
if (asHtml) { if (asHtml) {
$msg.html(infoMessage); $msg.html(infoMessage);
} else { } else {
$msg.text(infoMessage); $msg.text(infoMessage);
}
$chatWindow.append($msg);
} }
$chatWindow.append($msg);
}
// Helper function to print chat message to the chat window // Helper function to print chat message to the chat window
function printMessage(fromUser, message) { function printMessage(fromUser, message) {
var $user = $('<span class="username">').text(fromUser + ':'); var $user = $('<span class="username">').text(fromUser + ':');
if (fromUser === username) { if (fromUser === username) {
$user.addClass('me'); $user.addClass('me');
}
var $message = $('<span class="message">').text(message);
var $container = $('<div class="message-container">');
$container.append($user).append($message);
$chatWindow.append($container);
$chatWindow.scrollTop($chatWindow[0].scrollHeight);
} }
var $message = $('<span class="message">').text(message);
var $container = $('<div class="message-container">');
$container.append($user).append($message);
$chatWindow.append($container);
$chatWindow.scrollTop($chatWindow[0].scrollHeight);
}
// Alert the user they have been assigned a random username
print('Logging in...');
// Get an access token for the current user, passing a username (identity)
// and a device ID - for browser-based apps, we'll always just use the
// value "browser"
$.getJSON('/token', {
device: 'browser'
}, function(data) {
// Alert the user they have been assigned a random username // Alert the user they have been assigned a random username
print('Logging in...'); username = data.identity;
print('You have been assigned a random username of: '
+ '<span class="me">' + username + '</span>', true);
// Get an access token for the current user, passing a username (identity) // Initialize the Chat client
// and a device ID - for browser-based apps, we'll always just use the Twilio.Chat.Client.create(data.token).then(client => {
// value "browser" chatClient = client;
$.getJSON('/token', { chatClient.getSubscribedChannels().then(createOrJoinGeneralChannel);
device: 'browser' });
}, function(data) { });
// Alert the user they have been assigned a random username
username = data.identity;
print('You have been assigned a random username of: '
+ '<span class="me">' + username + '</span>', true);
// Initialize the Chat client function createOrJoinGeneralChannel() {
chatClient = new Twilio.Chat.Client(data.token); // Get the general chat channel, which is where all the messages are
chatClient.getSubscribedChannels().then(createOrJoinGeneralChannel); // sent in this simple application
print('Attempting to join "general" chat channel...');
chatClient.getChannelByUniqueName('general')
.then(function(channel) {
generalChannel = channel;
console.log('Found general channel:');
console.log(generalChannel);
setupChannel();
}).catch(function() {
// If it doesn't exist, let's create it
console.log('Creating general channel');
chatClient.createChannel({
uniqueName: 'general',
friendlyName: 'General Chat Channel'
}).then(function(channel) {
console.log('Created general channel:');
console.log(channel);
generalChannel = channel;
setupChannel();
}).catch(function(channel) {
console.log('Channel could not be created:');
console.log(channel);
});
});
}
// Set up channel after it has been found
function setupChannel() {
// Join the general channel
generalChannel.join().then(function(channel) {
print('Joined channel as '
+ '<span class="me">' + username + '</span>.', true);
}); });
function createOrJoinGeneralChannel() { // Listen for new messages sent to the channel
// Get the general chat channel, which is where all the messages are generalChannel.on('messageAdded', function(message) {
// sent in this simple application printMessage(message.author, message.body);
print('Attempting to join "general" chat channel...');
var promise = chatClient.getChannelByUniqueName('general');
promise.then(function(channel) {
generalChannel = channel;
console.log('Found general channel:');
console.log(generalChannel);
setupChannel();
}).catch(function() {
// If it doesn't exist, let's create it
console.log('Creating general channel');
chatClient.createChannel({
uniqueName: 'general',
friendlyName: 'General Chat Channel'
}).then(function(channel) {
console.log('Created general channel:');
console.log(channel);
generalChannel = channel;
setupChannel();
});
});
}
// Set up channel after it has been found
function setupChannel() {
// Join the general channel
generalChannel.join().then(function(channel) {
print('Joined channel as '
+ '<span class="me">' + username + '</span>.', true);
});
// Listen for new messages sent to the channel
generalChannel.on('messageAdded', function(message) {
printMessage(message.author, message.body);
});
}
// Send a new message to the general channel
var $input = $('#chat-input');
$input.on('keydown', function(e) {
if (e.keyCode == 13 && generalChannel) {
generalChannel.sendMessage($input.val())
$input.val('');
}
}); });
}
// Send a new message to the general channel
var $input = $('#chat-input');
$input.on('keydown', function(e) {
if (e.keyCode == 13) {
generalChannel.sendMessage($input.val())
$input.val('');
}
});
}); });

View File

@@ -1,61 +1,58 @@
$(function() { $(function() {
$.get('/config', function(response) { $.get('/config', function(response) {
configureField(response, 'TWILIO_ACCOUNT_SID', 'twilioAccountSID', false); Object.keys(fields).forEach(configureField(fields, response));
configureField(response, 'TWILIO_API_KEY', 'twilioAPIKey', false); Object.keys(buttons).forEach(configureButton(buttons, response));
configureField(response, 'TWILIO_API_SECRET', 'twilioAPISecret', true); });
configureField(response, 'TWILIO_NOTIFICATION_SERVICE_SID', 'twilioNotificationServiceSID', false);
configureField(response, 'TWILIO_CHAT_SERVICE_SID', 'twilioChatServiceSID', false);
configureField(response, 'TWILIO_SYNC_SERVICE_SID', 'twilioSyncServiceSID', false);
//configure individual product buttons // Button Ids' and Config Keys
if (response.TWILIO_ACCOUNT_SID && response.TWILIO_ACCOUNT_SID != '' && var buttons = {
response.TWILIO_API_KEY && response.TWILIO_API_KEY != '' && response.TWILIO_API_SECRET) { videoDemoButton: 'TwilioApiSecret',
chatDemoButton: 'TwilioChatServiceSid',
syncDemoButton: 'TwilioSyncServiceSid',
notifyDemoButton: 'TwilioNotificationServiceSid'
};
$('#videoDemoButton').addClass('btn-success'); // Field Ids' and Masked Flag
var fields = {
twilioAccountSid: false,
twilioApiKey: false,
twilioApiSecret: true,
twilioNotificationServiceSid: false,
twilioChatServiceSid: false,
twilioSyncServiceSid: false
};
if (response.TWILIO_CHAT_SERVICE_SID && response.TWILIO_CHAT_SERVICE_SID != '') { var configureField = function(fields, response) {
$('#chatDemoButton').addClass('btn-success'); var htmlContent = 'Not configured in .env';
} else { var cssClass = 'unset';
$('#chatDemoButton').addClass('btn-danger'); return function(fieldId) {
} var configKey = strToConfig(fieldId);
var isMasked = fields[fieldId];
if (response.TWILIO_SYNC_SERVICE_SID && response.TWILIO_SYNC_SERVICE_SID != '') { if (!!response[configKey]) {
$('#syncDemoButton').addClass('btn-success'); htmlContent = isMasked ? 'Configured properly' : response[configKey];
} else { cssClass = 'set';
$('#syncDemoButton').addClass('btn-danger'); }
} $('#' + fieldId).html(htmlContent).addClass(cssClass);
if (response.TWILIO_NOTIFICATION_SERVICE_SID && response.TWILIO_NOTIFICATION_SERVICE_SID != '') {
$('#notifyDemoButton').addClass('btn-success');
} else {
$('#notifyDemoButton').addClass('btn-danger');
}
}
else {
$('#videoDemoButton').addClass('btn-danger');
$('#chatDemoButton').addClass('btn-danger');
$('#syncDemoButton').addClass('btn-danger');
$('#notifyDemoButton').addClass('btn-danger');
}
});
var configureField = function(response, keyName, elementId, masked) {
if (masked) {
if (response[keyName]) {
$('#' + elementId).html('Configured properly');
$('#' + elementId).addClass('set');
} else {
$('#' + elementId).html('Not configured in .env');
$('#' + elementId).addClass('unset');
}
} else {
if (response[keyName] && response[keyName] != '') {
$('#' + elementId).html(response[keyName]);
$('#' + elementId).addClass('set');
} else {
$('#' + elementId).html('Not configured in .env');
$('#' + elementId).addClass('unset');
}
}
}; };
}); };
var configureButton = function(buttons, response) {
var hasBasicConfig = !!response.TWILIO_ACCOUNT_SID &&
!!response.TWILIO_API_KEY &&
!!response.TWILIO_API_SECRET;
return function(buttonId) {
var configKey = strToConfig(buttons[buttonId]);
var cssClass = hasBasicConfig && !!response[configKey]
? 'btn-success'
: 'btn-danger';
$('#' + buttonId).addClass(cssClass);
};
};
var strToConfig = function(string) {
return string
.split(/(?=[A-Z])/)
.map(function(e) { return e.toUpperCase(); })
.join('_');
}
});

View File

@@ -1,59 +1,64 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>Twilio Server Starter Kit</title> <title>Twilio Server Starter Kit</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <link rel="stylesheet" crossorigin="anonymous"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u">
<link rel="stylesheet" href="index.css"> <link rel="stylesheet" href="index.css">
</head>
<body>
<div class="container">
<h1>Twilio Server Starter Kit Environment Setup</h1>
</head> <h2>Account Information</h2>
<body> <table class="table table-striped">
<div class="container"> <tr>
<h1>Twilio Server Starter Kit Environment Setup</h1> <td class="config-key">TWILIO_ACCOUNT_SID</td>
<h2>Account Information</h2> <td class="config-value" id="twilioAccountSid"></td>
<table class="table table-striped"> </tr>
<tr> <tr>
<td class="config-key">TWILIO_ACCOUNT_SID</td> <td class="config-key">TWILIO_API_KEY</td>
<td class="config-value" id="twilioAccountSID"></td> <td class="config-value" id="twilioApiKey"></td>
</tr> </tr>
<tr> <tr>
<td class="config-key">TWILIO_API_KEY</td> <td class="config-key">TWILIO_API_SECRET</td>
<td class="config-value" id="twilioAPIKey"></td> <td class="config-value" id="twilioApiSecret"></td>
</tr> </tr>
<tr> </table>
<td class="config-key">TWILIO_API_SECRET</td>
<td class="config-value" id="twilioAPISecret"></td>
</tr>
</table>
<h2>Products</h2>
<table class="table table-striped">
<tr>
<td class="config-product">Notify</td>
<td class="config-key">TWILIO_NOTIFICATION_SERVICE_SID</td>
<td class="config-value" id="twilioNotificationServiceSID"></td>
</tr>
<tr>
<td class="config-product">Chat</td>
<td class="config-key">TWILIO_CHAT_SERVICE_SID</td>
<td class="config-value" id="twilioChatServiceSID"></td>
</tr>
<tr>
<td class="config-product">Sync</td>
<td class="config-key">TWILIO_SYNC_SERVICE_SID</td>
<td class="config-value" id="twilioSyncServiceSID"></td>
</tr>
</table>
<h1>Demos</h1> <h2>Products</h2>
<a id="videoDemoButton" class="btn btn-lg btn-success" href="/video/">Video</a> <table class="table table-striped">
<a id="syncDemoButton" class="btn btn-lg" href="/sync/">Sync</a> <tr>
<a id="notifyDemoButton" class="btn btn-lg" href="/notify/">Notify</a> <td class="config-product">Notify</td>
<a id="chatDemoButton" class="btn btn-lg" href="/chat/">Chat</a> <td class="config-key">TWILIO_NOTIFICATION_SERVICE_SID</td>
</div> <!-- container --> <td class="config-value" id="twilioNotificationServiceSid"></td>
</tr>
<tr>
<td class="config-product">Chat</td>
<td class="config-key">TWILIO_CHAT_SERVICE_SID</td>
<td class="config-value" id="twilioChatServiceSid"></td>
</tr>
<tr>
<td class="config-product">Sync</td>
<td class="config-key">TWILIO_SYNC_SERVICE_SID</td>
<td class="config-value" id="twilioSyncServiceSid"></td>
</tr>
</table>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <h1>Demos</h1>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <a id="videoDemoButton" class="btn btn-lg" href="/video/">Video</a>
<script src="/config-check.js"></script> <a id="syncDemoButton" class="btn btn-lg" href="/sync/">Sync</a>
</body> <a id="notifyDemoButton" class="btn btn-lg" href="/notify/">Notify</a>
<a id="chatDemoButton" class="btn btn-lg" href="/chat/">Chat</a>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script crossorigin="anonymous"
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"></script>
<script src="config-check.js"></script>
</body>
</script> </script>

View File

@@ -0,0 +1,34 @@
<body>
<script>
window.fbAsyncInit = function() {
FB.init({
appId: "<YOUR-APP-ID>",
xfbml: true,
cookie: true,
version: "v2.8"
});
FB.Event.subscribe('send_to_messenger', function(e) {
console.log("Plug-in reported event: " + e.event);
});
};
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) { return; }
js = d.createElement(s); js.id = id;
js.src = "https://connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
<div class="fb-send-to-messenger"
messenger_app_id="<YOUR-APP-ID>"
page_id="<YOUR-PAGE-ID>"
color="blue"
size="standard">
</div>
</body>

View File

@@ -1,17 +1,15 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Hello App! - Notify Quickstart</title> <title>Hello App! - Notify Quickstart</title>
<link rel="shortcut icon" href="//www.twilio.com/marketing/bundles/marketing/img/favicons/favicon.ico"> <link rel="shortcut icon" href="//www.twilio.com/marketing/bundles/marketing/img/favicons/favicon.ico">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css"> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
<link rel="stylesheet" href="notify.css"> <link rel="stylesheet" href="notify.css">
</head> </head>
<body> <body>
<header> <header>
<a href="https://www.twilio.com/docs/api/notifications" <a href="https://www.twilio.com/docs/api/notifications" target="_blank">
target="_blank"> Read the Twilio Notify guide<i class="fa fa-fw fa-external-link"></i>
Read the Twilio Notify guide
<i class="fa fa-fw fa-external-link"></i>
</a> </a>
</header> </header>
@@ -22,14 +20,11 @@
<p/> <p/>
<input type="submit" id="sendNotificationButton" value="Send Notification"/> <input type="submit" id="sendNotificationButton" value="Send Notification"/>
<div id="message"> <div id="message">Welcome to Notify!</div>
Welcome to Notify!
</div>
<p>After you set up a notification binding, go ahead and send a notification to that identity!</p> <p>After you set up a notification binding, go ahead and send a notification to that identity!</p>
</section> </section>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="notify.js"></script> <script src="notify.js"></script>
</body> </body>

View File

@@ -1,13 +1,12 @@
$(function() { $(function() {
$('#sendNotificationButton').on('click', function() {
$('#sendNotificationButton').on('click', function() { $.post('/send-notification', {
$.post('/send-notification', { identity: $('#identityInput').val(),
identity: $('#identityInput').val(), body: "Hello, world!"
body: "Hello, World!" }, function(response) {
}, function(response) { $('#identityInput').val('');
$('#identityInput').val(''); $('#message').html(response.message);
$('#message').html(response.message); console.log(response);
console.log(response);
});
}); });
});
}); });

View File

@@ -19,31 +19,30 @@
<h1>Tic-Tac-Twilio</h1> <h1>Tic-Tac-Twilio</h1>
<div id="board"> <div id="board">
<div class="board-row"> <div class="board-row">
<button type="button" data-row="0" data-col="0" disabled>&nbsp;</button> <button type="button" data-row="0" data-col="0" disabled>&nbsp;</button>
<button type="button" data-row="0" data-col="1" disabled>&nbsp;</button> <button type="button" data-row="0" data-col="1" disabled>&nbsp;</button>
<button type="button" data-row="0" data-col="2" disabled>&nbsp;</button> <button type="button" data-row="0" data-col="2" disabled>&nbsp;</button>
</div> </div>
<div class="board-row"> <div class="board-row">
<button type="button" data-row="1" data-col="0" disabled>&nbsp;</button> <button type="button" data-row="1" data-col="0" disabled>&nbsp;</button>
<button type="button" data-row="1" data-col="1" disabled>&nbsp;</button> <button type="button" data-row="1" data-col="1" disabled>&nbsp;</button>
<button type="button" data-row="1" data-col="2" disabled>&nbsp;</button> <button type="button" data-row="1" data-col="2" disabled>&nbsp;</button>
</div> </div>
<div class="board-row"> <div class="board-row">
<button type="button" data-row="2" data-col="0" disabled>&nbsp;</button> <button type="button" data-row="2" data-col="0" disabled>&nbsp;</button>
<button type="button" data-row="2" data-col="1" disabled>&nbsp;</button> <button type="button" data-row="2" data-col="1" disabled>&nbsp;</button>
<button type="button" data-row="2" data-col="2" disabled>&nbsp;</button> <button type="button" data-row="2" data-col="2" disabled>&nbsp;</button>
</div> </div>
</div> </div>
<div id="message"> <div id="message">
Welcome! Initializing Sync... Welcome! Initializing Sync...
</div> </div>
<p>Open this page in a few tabs to test!</p> <p>Open this page in a few tabs to test!</p>
</section> </section>
<script src="//media.twiliocdn.com/sdk/js/sync/v0.8/twilio-sync.min.js"></script> <script src="//media.twiliocdn.com/sdk/js/sync/v0.8/twilio-sync.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="index.js"></script> <script src="index.js"></script>

View File

@@ -8,53 +8,57 @@ $(function () {
//Our interface to the Sync service //Our interface to the Sync service
var syncClient; var syncClient;
//Get an access token for the current user, passing a device ID // Every browser Sync client relies on FPA tokens to authenticate and authorize it
//In browser-based apps, every tab is like its own unique device // for access to your Sync data.
//synchronizing state -- so we'll use a random UUID to identify //
//this tab. // In this quickstart, we're using our own token generator. You can generate a token
// in any backend language that Twilio supports, or generate a Twilio Function so
// Twilio can host it for you. See the docs for more details.
//
$.getJSON('/token', function (tokenResponse) { $.getJSON('/token', function (tokenResponse) {
//Initialize the Sync client
// Once we have the token, we can initialize the Sync client and start subscribing
// to data. The client will initialize asynchronously while we load the rest of
// the user interface.
//
syncClient = new Twilio.Sync.Client(tokenResponse.token, { logLevel: 'info' }); syncClient = new Twilio.Sync.Client(tokenResponse.token, { logLevel: 'info' });
syncClient.on('connectionStateChanged', function(state) { syncClient.on('connectionStateChanged', function(state) {
if (state != 'connected') { if (state != 'connected') {
$message.html('Sync is not live (websocket connection <span style="color: red">' + state + '</span>)…'); $message.html('Sync is not live (websocket connection <span style="color: red">' + state + '</span>)…');
} else { } else {
// Now that we're connected, lets light up our board and play!
$buttons.attr('disabled', false);
$message.html('Sync is live!'); $message.html('Sync is live!');
} }
}); });
//Let's pop a message on the screen to show that Sync is ready // Let's pop a message on the screen to show that Sync is working
$message.html('Sync initialized!'); $message.html('Loading board data…');
//Now that Sync is active, lets enable our game board // Our game state is stored in a Sync document. Here, we'll attach to that document
$buttons.attr('disabled', false); // (or create it, if it doesn't exist) and connect the necessary event handlers.
//
//This code will create and/or open a Sync document
//Note the use of promises
syncClient.document('SyncGame').then(function(syncDoc) { syncClient.document('SyncGame').then(function(syncDoc) {
//Initialize game board UI to current state (if it exists)
var data = syncDoc.value; var data = syncDoc.value;
if (data.board) { if (data.board) {
updateUserInterface(data); updateUserInterface(data);
} }
//Let's subscribe to changes on this document, so when something // Any time the board changes, we want to show the new state. The 'updated'
//changes on this document, we can trigger our UI to update // event is for this.
syncDoc.on('updated', function(event) { syncDoc.on('updated', function(event) {
console.debug("Board was updated", event.isLocal? "locally." : "by the other guy."); console.debug("Board was updated", event.isLocal? "locally." : "by the other guy.");
updateUserInterface(event.value); updateUserInterface(event.value);
}); });
//Whenever a board button is clicked, update that document. // Let's make our buttons control the game state in Sync…
$buttons.on('click', function (e) { $buttons.on('click', function (e) {
//Toggle the value: X, O, or empty // Toggle the value: X, O, or empty
toggleCellValue($(e.target)); toggleCellValue($(e.target));
//Send updated document to Sync // Send updated document to Sync. This will trigger "updated" events for all players.
//This should trigger "updated" events on other clients
var data = readGameBoardFromUserInterface(); var data = readGameBoardFromUserInterface();
syncDoc.set(data); syncDoc.set(data);
}); });
}); });
@@ -84,7 +88,7 @@ $(function () {
for (var row = 0; row < 3; row++) { for (var row = 0; row < 3; row++) {
for (var col = 0; col < 3; col++) { for (var col = 0; col < 3; col++) {
var selector = '[data-row="' + row + '"]' + var selector = '[data-row="' + row + '"]' +
'[data-col="' + col + '"]'; '[data-col="' + col + '"]';
board[row][col] = $(selector).html().replace('&nbsp;', ''); board[row][col] = $(selector).html().replace('&nbsp;', '');
} }
} }
@@ -96,12 +100,10 @@ $(function () {
function updateUserInterface(data) { function updateUserInterface(data) {
for (var row = 0; row < 3; row++) { for (var row = 0; row < 3; row++) {
for (var col = 0; col < 3; col++) { for (var col = 0; col < 3; col++) {
var selector = '[data-row="' + row + '"]' + var this_cell = '[data-row="' + row + '"]' + '[data-col="' + col + '"]';
'[data-col="' + col + '"]';
var cellValue = data.board[row][col]; var cellValue = data.board[row][col];
$(selector).html(cellValue === '' ? '&nbsp;' : cellValue); $(this_cell).html(cellValue === '' ? '&nbsp;' : cellValue);
} }
} }
} }
});
});

View File

@@ -12,17 +12,19 @@
<div id="local-media"></div> <div id="local-media"></div>
<button id="button-preview">Preview My Camera</button> <button id="button-preview">Preview My Camera</button>
</div> </div>
<div id="room-controls"> <div id="room-controls">
<p class="instructions">Room Name:</p> <p class="instructions">Room Name:</p>
<input id="room-name" type="text" placeholder="Enter a room name" /> <input id="room-name" type="text" placeholder="Enter a room name" />
<button id="button-join">Join Room</button> <button id="button-join">Join Room</button>
<button id="button-leave">Leave Room</button> <button id="button-leave">Leave Room</button>
</div> </div>
<div id="log"></div> <div id="log"></div>
</div> </div>
<script src="//media.twiliocdn.com/sdk/js/common/v0.1/twilio-common.min.js"></script> <script src="//media.twiliocdn.com/sdk/js/common/v0.1/twilio-common.min.js"></script>
<script src="//media.twiliocdn.com/sdk/js/video/releases/1.0.0/twilio-video.js"></script> <script src="//media.twiliocdn.com/sdk/js/video/releases/1.14.0/twilio-video.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="quickstart.js"></script> <script src="quickstart.js"></script>
</body> </body>

View File

@@ -124,8 +124,8 @@ function roomJoined(room) {
// Local video preview // Local video preview
document.getElementById('button-preview').onclick = function() { document.getElementById('button-preview').onclick = function() {
var localTracksPromise = previewTracks var localTracksPromise = previewTracks
? Promise.resolve(previewTracks) ? Promise.resolve(previewTracks)
: Twilio.Video.createLocalTracks(); : Twilio.Video.createLocalTracks();
localTracksPromise.then(function(tracks) { localTracksPromise.then(function(tracks) {
previewTracks = tracks; previewTracks = tracks;