Update the URL bar with a deeplink to the current game, and process these deeplinks when the app loads. Fixes #30.

This commit is contained in:
Andy Janata 2013-11-11 03:22:54 +00:00
parent 0cbf74b915
commit 844ce99cdb
5 changed files with 78 additions and 5 deletions

View File

@ -41,6 +41,8 @@ cah.ajax.ErrorHandlers[cah.$.AjaxOperation.REGISTER] = function(data) {
$("#nickname").focus();
};
// hacky way to avoid joining a game from the hash if the server told us to join a game.
cah.ajax.hasAutojoinedGame_ = false;
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.FIRST_LOAD] = function(data) {
cah.CardSet.populateCardSets(data[cah.$.AjaxResponse.CARD_SETS]);
@ -55,6 +57,7 @@ cah.ajax.SuccessHandlers[cah.$.AjaxOperation.FIRST_LOAD] = function(data) {
case cah.$.ReconnectNextAction.GAME:
cah.log.status("Reconnecting to game...");
cah.Game.joinGame(data[cah.$.AjaxResponse.GAME_ID]);
cah.ajax.hasAutojoinedGame_ = true;
break;
case cah.$.ReconnectNextAction.NONE:
// pass
@ -77,6 +80,8 @@ cah.ajax.ErrorHandlers[cah.$.AjaxOperation.FIRST_LOAD] = function(data) {
}
};
// another hack thing to trigger an auto-join after the first game list refresh
cah.ajax.autojoinGameId_ = undefined;
/**
* This should only be called after we have a valid registration with the server, as we start doing
* long polling here.
@ -92,6 +97,24 @@ cah.ajax.after_registered = function() {
cah.longpoll.longPoll();
// Dirty that we have to do this here... Oh well.
app_resize();
if (!cah.ajax.hasAutojoinedGame_) {
var hash = window.location.hash.substring(1);
if (hash && hash != '') {
// TODO find a better place for this if we ever have more than just game=id in the hash.
var params = hash.split('&');
var options = {};
for ( var i in params) {
var split = params[i].split('=');
var key = split[0];
var value = split[1];
options[key] = value;
}
if (options['game']) {
cah.ajax.autojoinGameId_ = options['game'];
}
}
}
};
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.CHAT] = function(data) {
@ -114,6 +137,16 @@ cah.ajax.SuccessHandlers[cah.$.AjaxOperation.NAMES] = function(data) {
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.GAME_LIST] = function(data) {
cah.GameList.instance.processUpdate(data);
if (cah.ajax.autojoinGameId_) {
try {
cah.GameList.instance.joinGame(cah.ajax.autojoinGameId_);
} catch (e) {
cah.log.error(e);
cah.updateHash('');
}
cah.ajax.autojoinGameId_ = undefined;
}
};
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.JOIN_GAME] = function(data, req) {

View File

@ -185,6 +185,7 @@ function chatsubmit_click(game_id, parent_element) {
function logout_click() {
if (confirm("Are you sure you wish to log out?")) {
cah.Ajax.build(cah.$.AjaxOperation.LOG_OUT).run();
cah.updateHash('');
}
}

View File

@ -308,6 +308,8 @@ cah.Game.joinGame = function(gameId) {
var game = new cah.Game(gameId);
cah.currentGames[gameId] = game;
game.insertIntoDocument();
cah.updateHash('game=' + gameId);
};
/**
@ -1099,6 +1101,8 @@ cah.Game.prototype.dispose = function() {
$("#leave_game").unbind().hide();
$("#start_game").unbind().hide();
$(window).off("resize.game_" + this.id_);
cah.updateHash('');
};
/**

View File

@ -38,12 +38,12 @@ cah.GameList = function() {
this.element_ = $("#game_list")[0];
/**
* Array of all game lobby objects.
* Map all game lobby objects, id -> game lobby.
*
* @type {Array[cah.GameListLobby]}
* @type {Object}
* @private
*/
this.games_ = new Array();
this.games_ = {};
$("#create_game").click(cah.bind(this, this.createGameClick_));
$("#refresh_games").click(cah.bind(this, this.refreshGamesClick_));
@ -99,7 +99,7 @@ cah.GameList.prototype.processUpdate = function(gameData) {
for ( var key in this.games_) {
this.games_[key].dispose();
}
this.games_ = new Array();
this.games_ = {};
// Sort the games into two lists, passworded and non-passworded.
var passworded = new Array();
@ -118,7 +118,7 @@ cah.GameList.prototype.processUpdate = function(gameData) {
for ( var i = 0; i < games.length; i++) {
var game = games[i];
var lobby = new cah.GameListLobby(this.element_, game);
this.games_.push(lobby);
this.games_[game[cah.$.GameInfo.ID]] = lobby;
}
if (gameData[cah.$.AjaxResponse.GAMES].length < gameData[cah.$.AjaxResponse.MAX_GAMES]) {
@ -128,6 +128,21 @@ cah.GameList.prototype.processUpdate = function(gameData) {
}
};
/**
* Join the given game.
*
* @param {Number}
* id The id of the game to join.
*/
cah.GameList.prototype.joinGame = function(id) {
var game = this.games_[Number(id)];
if (game) {
game.join();
} else {
throw 'Game ' + id + ' does not exist.';
}
};
/**
* Event handler for the clicking the Create Game button.
*
@ -237,6 +252,13 @@ cah.GameListLobby.prototype.joinClick = function() {
cah.Ajax.build(cah.$.AjaxOperation.JOIN_GAME).withGameId(this.id_).withPassword(password).run();
};
/**
* Join this game, by simulating a click of its join button.
*/
cah.GameListLobby.prototype.join = function() {
$('.gamelist_lobby_join', this.element_).click();
};
/**
* Remove the game lobby from the document and free up resources.
*/

View File

@ -108,3 +108,16 @@ cah.inherits = function(childCtor, parentCtor) {
childCtor.prototype = new tempCtor();
childCtor.prototype.constructor = childCtor;
};
/**
* Updates the hash in the browser's URL for deeplinks.
*
* TODO: If we ever want more than just game=id here, this will have to deal with a map somehow.
*
* @param {String}
* hash The hash to use in the URL.
*/
cah.updateHash = function(hash) {
window.location.replace(window.location.protocol + '//' + window.location.host
+ window.location.pathname.replace(/#$/g, '') + '#' + hash);
};