Merge branch 'upstream' into blanks

This commit is contained in:
uecasm 2013-11-21 22:18:56 +13:00
commit d0e8e1e33f
8 changed files with 95 additions and 7 deletions

View File

@ -582,3 +582,10 @@ span.debug, span.admin {
.nowrap { .nowrap {
white-space: nowrap; white-space: nowrap;
} }
.cardnum {
position: absolute;
right: 10px;
bottom: 19px;
font-size: 8pt;
}

View File

@ -95,8 +95,12 @@ HttpSession hSession = request.getSession(true);
If this is your first time playing, you may wish to read <a href="/">the changelog and list of If this is your first time playing, you may wish to read <a href="/">the changelog and list of
known issues</a>. known issues</a>.
</p> </p>
<p tabindex="0">Most recent update: 7 August 2013:</p> <p tabindex="0">Most recent update: 3 September 2013:</p>
<ul> <ul>
<li tabindex="0">The Box Expansion and PAX Prime 2013 cards have been added. <strong>If you have
any spares of these card numbers and are willing to part with them, it would be awesome if you'd
<a href="mailto:ajanata@socialgamer.net?subject=13PAX+cards">email me</a> and send them to me,
as I was unable to acquire them at PAX:</strong> 29, 30, 33, 34, 35, 36, 37</li>
<li tabindex="0"><strong>The game list will not automatically update all the time now.</strong> <li tabindex="0"><strong>The game list will not automatically update all the time now.</strong>
You will need to start using the Refresh Games button. The game list will automatically update You will need to start using the Refresh Games button. The game list will automatically update
for new games, removed games, when games become passworded, or when you leave a game.</li> for new games, removed games, when games become passworded, or when you leave a game.</li>
@ -383,13 +387,13 @@ HttpSession hSession = request.getSession(true);
<input type="text" id="game_password_template" class="game_password" <input type="text" id="game_password_template" class="game_password"
aria-label="Game password. You must tab outside of the box to apply the password."/> aria-label="Game password. You must tab outside of the box to apply the password."/>
<input type="password" id="game_fake_password_template" class="game_fake_password hide" /> <input type="password" id="game_fake_password_template" class="game_fake_password hide" />
You must click outside the box to apply the password.
<input type="checkbox" id="game_hide_password_template" class="game_hide_password" /> <input type="checkbox" id="game_hide_password_template" class="game_hide_password" />
<label id="game_hide_password_template_label" for="game_hide_password_template" <label id="game_hide_password_template_label" for="game_hide_password_template"
aria-label="Hide password from your screen." aria-label="Hide password from your screen."
title="Hides the password from your screen, so people watching your stream can't see it."> title="Hides the password from your screen, so people watching your stream can't see it.">
Hide password. Hide password.
</label> </label>
You must click outside the box to apply the password.
</fieldset> </fieldset>
</div> </div>
</div> </div>

View File

@ -54,6 +54,12 @@ to, for instance, display the number of connected players.
</p> </p>
<p>Recent Changes:</p> <p>Recent Changes:</p>
<ul> <ul>
<li>5 September 2013:<ul>
<li tabindex="0">The Box Expansion and PAX Prime 2013 cards have been added. <strong>If you have
any spares of these card numbers and are willing to part with them, it would be awesome if you'd
<a href="mailto:ajanata@socialgamer.net?subject=13PAX+cards">email me</a> and send them to me,
as I was unable to acquire them at PAX:</strong> 29, 30, 33, 34, 35, 36, 37</li>
</ul></li>
<li>7 August 2013:<ul> <li>7 August 2013:<ul>
<li tabindex="0"><strong>The game list will not automatically update all the time now.</strong> <li tabindex="0"><strong>The game list will not automatically update all the time now.</strong>
You will need to start using the Refresh Games button. The game list will automatically update You will need to start using the Refresh Games button. The game list will automatically update

View File

@ -41,6 +41,8 @@ cah.ajax.ErrorHandlers[cah.$.AjaxOperation.REGISTER] = function(data) {
$("#nickname").focus(); $("#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.ajax.SuccessHandlers[cah.$.AjaxOperation.FIRST_LOAD] = function(data) {
cah.CardSet.populateCardSets(data[cah.$.AjaxResponse.CARD_SETS]); 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: case cah.$.ReconnectNextAction.GAME:
cah.log.status("Reconnecting to game..."); cah.log.status("Reconnecting to game...");
cah.Game.joinGame(data[cah.$.AjaxResponse.GAME_ID]); cah.Game.joinGame(data[cah.$.AjaxResponse.GAME_ID]);
cah.ajax.hasAutojoinedGame_ = true;
break; break;
case cah.$.ReconnectNextAction.NONE: case cah.$.ReconnectNextAction.NONE:
// pass // 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 * This should only be called after we have a valid registration with the server, as we start doing
* long polling here. * long polling here.
@ -92,6 +97,22 @@ cah.ajax.after_registered = function() {
cah.longpoll.longPoll(); cah.longpoll.longPoll();
// Dirty that we have to do this here... Oh well. // Dirty that we have to do this here... Oh well.
app_resize(); app_resize();
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) { cah.ajax.SuccessHandlers[cah.$.AjaxOperation.CHAT] = function(data) {
@ -114,6 +135,16 @@ cah.ajax.SuccessHandlers[cah.$.AjaxOperation.NAMES] = function(data) {
cah.ajax.SuccessHandlers[cah.$.AjaxOperation.GAME_LIST] = function(data) { cah.ajax.SuccessHandlers[cah.$.AjaxOperation.GAME_LIST] = function(data) {
cah.GameList.instance.processUpdate(data); cah.GameList.instance.processUpdate(data);
if (cah.ajax.autojoinGameId_ && !cah.ajax.hasAutojoinedGame_) {
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) { 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() { function logout_click() {
if (confirm("Are you sure you wish to log out?")) { if (confirm("Are you sure you wish to log out?")) {
cah.Ajax.build(cah.$.AjaxOperation.LOG_OUT).run(); cah.Ajax.build(cah.$.AjaxOperation.LOG_OUT).run();
cah.updateHash('');
} }
} }

View File

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

View File

@ -38,12 +38,12 @@ cah.GameList = function() {
this.element_ = $("#game_list")[0]; 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 * @private
*/ */
this.games_ = new Array(); this.games_ = {};
$("#create_game").click(cah.bind(this, this.createGameClick_)); $("#create_game").click(cah.bind(this, this.createGameClick_));
$("#refresh_games").click(cah.bind(this, this.refreshGamesClick_)); $("#refresh_games").click(cah.bind(this, this.refreshGamesClick_));
@ -99,7 +99,7 @@ cah.GameList.prototype.processUpdate = function(gameData) {
for ( var key in this.games_) { for ( var key in this.games_) {
this.games_[key].dispose(); this.games_[key].dispose();
} }
this.games_ = new Array(); this.games_ = {};
// Sort the games into two lists, passworded and non-passworded. // Sort the games into two lists, passworded and non-passworded.
var passworded = new Array(); var passworded = new Array();
@ -118,7 +118,7 @@ cah.GameList.prototype.processUpdate = function(gameData) {
for ( var i = 0; i < games.length; i++) { for ( var i = 0; i < games.length; i++) {
var game = games[i]; var game = games[i];
var lobby = new cah.GameListLobby(this.element_, game); 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]) { 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. * 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(); 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. * 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 = new tempCtor();
childCtor.prototype.constructor = childCtor; 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);
};