124 lines
3.5 KiB
JavaScript
Executable File
124 lines
3.5 KiB
JavaScript
Executable File
$(function () {
|
|
//We'll use message to tell the user what's happening
|
|
var $message = $('#message');
|
|
|
|
//Get handle to the game board buttons
|
|
var $buttons = $('#board .board-row button');
|
|
|
|
//Manages the state of our access token we got from the server
|
|
var accessManager;
|
|
|
|
//Our interface to the Sync service
|
|
var syncClient;
|
|
|
|
//We're going to use a single Sync document, our simplest
|
|
//synchronisation primitive, for this demo
|
|
var syncDoc;
|
|
|
|
//Get an access token for the current user, passing a device ID
|
|
//In browser-based apps, every tab is like its own unique device
|
|
//synchronizing state -- so we'll use a random UUID to identify
|
|
//this tab.
|
|
$.getJSON('/token', {
|
|
device: getDeviceId()
|
|
}, function (tokenResponse) {
|
|
//Initialize the Sync client
|
|
syncClient = new Twilio.Sync.Client(tokenResponse.token);
|
|
|
|
//Let's pop a message on the screen to show that Sync is ready
|
|
$message.html('Sync initialized!');
|
|
|
|
//Now that Sync is active, lets enable our game board
|
|
$buttons.attr('disabled', false);
|
|
|
|
//This code will create and/or open a Sync document
|
|
//Note the use of promises
|
|
syncClient.document('SyncGame').then(function(doc) {
|
|
//Lets store it in our global variable
|
|
syncDoc = doc;
|
|
|
|
//Initialize game board UI to current state (if it exists)
|
|
var data = syncDoc.get();
|
|
if (data.board) {
|
|
updateUserInterface(data);
|
|
}
|
|
|
|
//Let's subscribe to changes on this document, so when something
|
|
//changes on this document, we can trigger our UI to update
|
|
syncDoc.on('updated', updateUserInterface);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
//Whenever a board button is clicked:
|
|
$buttons.on('click', function (e) {
|
|
//Toggle the value: X, O, or empty
|
|
toggleCellValue($(e.target));
|
|
|
|
//Update the document
|
|
var data = readGameBoardFromUserInterface();
|
|
|
|
//Send updated document to Sync
|
|
//This should trigger "updated" events on other clients
|
|
syncDoc.set(data);
|
|
|
|
});
|
|
|
|
//Toggle the value: X, O, or empty ( for UI)
|
|
function toggleCellValue($cell) {
|
|
var cellValue = $cell.html();
|
|
|
|
if (cellValue === 'X') {
|
|
$cell.html('O');
|
|
} else if (cellValue === 'O') {
|
|
$cell.html(' ');
|
|
} else {
|
|
$cell.html('X');
|
|
}
|
|
}
|
|
|
|
//Generate random UUID to identify this browser tab
|
|
//For a more robust solution consider a library like
|
|
//fingerprintjs2: https://github.com/Valve/fingerprintjs2
|
|
function getDeviceId() {
|
|
return 'browser-' +
|
|
'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
|
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
|
return v.toString(16);
|
|
});
|
|
}
|
|
|
|
//Read the state of the UI and create a new document
|
|
function readGameBoardFromUserInterface() {
|
|
var board = [
|
|
['', '', ''],
|
|
['', '', ''],
|
|
['', '', '']
|
|
];
|
|
|
|
for (var row = 0; row < 3; row++) {
|
|
for (var col = 0; col < 3; col++) {
|
|
var selector = '[data-row="' + row + '"]' +
|
|
'[data-col="' + col + '"]';
|
|
board[row][col] = $(selector).html().replace(' ', '');
|
|
}
|
|
}
|
|
|
|
return {board: board};
|
|
}
|
|
|
|
//Update the buttons on the board to match our document
|
|
function updateUserInterface(data) {
|
|
for (var row = 0; row < 3; row++) {
|
|
for (var col = 0; col < 3; col++) {
|
|
var selector = '[data-row="' + row + '"]' +
|
|
'[data-col="' + col + '"]';
|
|
var cellValue = data.board[row][col];
|
|
$(selector).html(cellValue === '' ? ' ' : cellValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
});
|