Merge pull request #1 from charlesrgould/feature/vueify

Feature/vueify
This commit is contained in:
Charles Gould 2017-02-07 18:19:28 -05:00 committed by GitHub
commit 5d2db7eed0
4 changed files with 302 additions and 352 deletions

View File

@ -32,8 +32,7 @@ public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override @Override
public void registerStompEndpoints(StompEndpointRegistry registry) { public void registerStompEndpoints(StompEndpointRegistry registry) {
// Allow all origins: for JSFiddle, lol registry.addEndpoint("/stomp").withSockJS();
registry.addEndpoint("/stomp").setAllowedOrigins("*").withSockJS();
} }
} }

View File

@ -7,22 +7,6 @@ var SIDE = 50;
var MARGIN_TOP = 100; var MARGIN_TOP = 100;
var MARGIN_BOTTOM = 75; var MARGIN_BOTTOM = 75;
var myScore = 0;
var myGuess;
var myGuesses;
var myProgress;
var myResults;
var myUsername;
var opponentScore = 0;
var opponentResults;
var opponentUsername;
var lastWord;
var appDiv = document.getElementById('appDiv');
var canvasDiv = document.getElementById('canvasDiv');
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var client; var client;
var sessionId = null; var sessionId = null;
@ -30,14 +14,146 @@ var vm = new Vue({
el: '#vue-app', el: '#vue-app',
data: { data: {
games: [], games: [],
gameId: null gameId: null,
messages: [],
username: null,
usernameError: '',
myScore: 0,
myGuess: '',
myGuesses: [],
myProgress: [],
myResults: [],
opponentScore: 0,
opponentResults: [],
opponentUsername: null,
lastWord: null
}, },
computed: { computed: {
inGame: function() { inGame: function() {
return this.gameId !== null; return this.gameId !== null;
},
inStartedGame: function() {
var game = this.getGame(this.gameId);
return game !== null && game.started === true;
} }
}, },
methods: { methods: {
drawMyBoard: function(ctx) {
var x = 25, y = MARGIN_TOP;
this.drawUsername(ctx, x, y, this.username);
this.drawScore(ctx, x, y, this.myScore);
this.drawInput(ctx, x, y, this.myGuess);
var yStart = this.drawGuesses(ctx, x, y, this.myGuesses, this.myResults);
this.drawHint(ctx, x, yStart, this.myProgress);
this.drawGrid(ctx, x, y);
},
drawOpponentBoard: function(ctx) {
var x = 325, y = MARGIN_TOP;
this.drawUsername(ctx, x, y, this.opponentUsername);
this.drawScore(ctx, x, y, this.opponentScore);
this.drawResults(ctx, x, y, this.opponentResults);
this.drawGrid(ctx, x, y);
},
drawLastWord: function(canvas, ctx) {
if (this.lastWord) {
var x = canvas.width / 2;
var y = canvas.height - MARGIN_BOTTOM / 2;
ctx.fillStyle = 'black';
ctx.fillText('Previous word: ' + this.lastWord.toUpperCase(), x, y);
}
},
drawUsername: function(ctx, x, y, username) {
var usernameX = x + WIDTH / 2;
var usernameY = y - 60;
ctx.fillStyle = 'black';
ctx.fillText(username, usernameX, usernameY);
},
drawScore: function(ctx, x, y, score) {
var scoreX = x + WIDTH / 2;
var scoreY = y - 25;
ctx.fillStyle = 'black';
ctx.fillText(score, scoreX, scoreY);
},
drawGrid: function(ctx, xOrigin, yOrigin) {
ctx.beginPath();
for (var x = 0; x <= WIDTH; x += SIDE) {
ctx.moveTo(xOrigin + x, yOrigin);
ctx.lineTo(xOrigin + x, yOrigin + HEIGHT);
}
for (var y = 0; y <= HEIGHT; y += SIDE) {
ctx.moveTo(xOrigin, yOrigin + y);
ctx.lineTo(xOrigin + WIDTH, yOrigin + y);
}
ctx.strokeStyle = 'black';
ctx.stroke();
},
drawInput: function(ctx, xOrigin, yOrigin, input) {
ctx.fillStyle = 'green';
var x = xOrigin + SIDE * 0.5;
var y = yOrigin + SIDE * 0.5;
for (var i = 0; i < input.length; i++) {
ctx.fillText(input[i], x, y);
x += SIDE;
}
},
drawGuesses: function(ctx, xOrigin, yOrigin, guesses, results) {
var y = yOrigin + SIDE * 1.5;
var numGuesses = Math.min(4, guesses.length);
for (var i = 0; i < numGuesses; i++) {
var x = xOrigin + SIDE * 0.5;
var guess = guesses[guesses.length - numGuesses + i];
var result = results[results.length - numGuesses + i];
for (var j = 0; j < 5; j++) {
if (result[j] === 1) {
ctx.fillStyle = 'yellow';
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
} else if (result[j] === 2) {
ctx.fillStyle = 'orange';
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
}
ctx.fillStyle = 'green';
ctx.fillText(guess[j], x, y);
x += SIDE;
}
y += SIDE;
}
return y;
},
drawResults: function(ctx, xOrigin, yOrigin, results) {
var y = yOrigin + SIDE * 1.5;
var numResults = Math.min(4, results.length);
for (var i = 0; i < numResults; i++) {
var x = xOrigin + SIDE * 0.5;
var result = results[results.length - numResults + i];
for (var j = 0; j < 5; j++) {
if (result[j] === 1) {
ctx.fillStyle = 'yellow';
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
} else if (result[j] === 2) {
ctx.fillStyle = 'orange';
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
}
x += SIDE;
}
y += SIDE;
}
return y;
},
drawHint: function(ctx, xOrigin, yOrigin, progress) {
var x = xOrigin + SIDE * 0.5;
for (var i = 0; i < 5; i++) {
ctx.fillText(progress[i], x, yOrigin);
x += SIDE;
}
},
getGame: function(gameId) {
for (var i = 0; i < this.games.length; i++) {
if (this.games[i].id === gameId) {
return this.games[i];
}
}
return null;
},
hostGame: function(event) { hostGame: function(event) {
client.send('/app/hostGame'); client.send('/app/hostGame');
}, },
@ -49,6 +165,84 @@ var vm = new Vue({
}, },
leaveGame: function(event) { leaveGame: function(event) {
client.send('/app/leaveGame'); client.send('/app/leaveGame');
},
removeGame: function(gameId) {
var indexToRemove = null;
for (var i = 0; i < this.games.length; i++) {
if (this.games[i].id === gameId) {
indexToRemove = i;
break;
}
}
this.games.splice(indexToRemove, 1);
},
onCanvasKeydown: function(event) {
if (event.which === KEYCODE_BACKSPACE) {
event.preventDefault();
this.myGuess = this.myGuess.substr(0, this.myGuess.length - 1);
this.repaint();
}
else if (event.which === KEYCODE_RETURN) {
if (this.myGuess.length === 5) {
client.send("/app/guess", {}, this.myGuess);
this.myGuess = '';
this.repaint();
}
}
},
onCanvasKeypress: function(event) {
var charCode = event.charCode;
if (isCharacter(charCode)) {
if (isCharacterLowercase(charCode)) {
charCode = charCode - 32;
}
var char = String.fromCharCode(charCode);
if (this.myGuess.length < 5) {
this.myGuess += char;
this.repaint();
}
}
},
onChatKeypress: function(event) {
var messageInput = event.target;
if (event.which === KEYCODE_RETURN) {
// Shift+Enter -> new line
if (!event.shiftKey) {
event.preventDefault();
var text = messageInput.value.trim();
if (text.length === 0) {
return;
}
messageInput.value = '';
client.send('/app/chat', {}, text);
addChatMessage(this.username, text);
}
}
},
repaint: function() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.font = '25px Monospace';
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.drawMyBoard(ctx);
this.drawOpponentBoard(ctx);
this.drawLastWord(canvas, ctx);
},
reset: function(firstLetter, clearScore) {
if (!firstLetter) {
firstLetter = '';
}
this.myGuess = '';
this.myGuesses = [];
this.myProgress = [firstLetter, '', '', '', ''];
this.myResults = [];
this.opponentResults = [];
if (clearScore) {
this.myScore = 0;
this.opponentScore = 0;
}
} }
} }
}); });
@ -70,8 +264,6 @@ function main() {
client = Stomp.over(new SockJS('/stomp')); client = Stomp.over(new SockJS('/stomp'));
client.connect({}, afterConnected); client.connect({}, afterConnected);
var usernameDiv = document.getElementById('usernameDiv');
var usernameError = document.getElementById('usernameError');
var usernameInput = document.getElementById('nicknameInput'); var usernameInput = document.getElementById('nicknameInput');
var usernameTopic = '/user/topic/sessionUsername'; var usernameTopic = '/user/topic/sessionUsername';
@ -80,26 +272,23 @@ function main() {
var response = JSON.parse(message.body); var response = JSON.parse(message.body);
if (response.success === true) { if (response.success === true) {
console.log('Username: ' + response.username); console.log('Username: ' + response.username);
myUsername = response.username; vm.username = response.username;
start(); start();
usernameDiv.classList.add('hidden');
appDiv.classList.remove('hidden');
} else { } else {
usernameError.innerHTML = response.errorMessage; vm.usernameError = response.errorMessage;
} }
}; };
usernameInput.focus();
usernameInput.addEventListener('keydown', function(e) { usernameInput.addEventListener('keydown', function(e) {
if (e.keyCode === KEYCODE_RETURN) { if (event.keyCode === KEYCODE_RETURN) {
e.preventDefault(); event.preventDefault();
if (sessionId === null) { if (sessionId === null) {
usernameError.innerHTML = 'Not connected to server'; vm.usernameError = 'Not connected to server';
return; return;
} }
var usernameValue = usernameInput.value.trim(); var usernameValue = usernameInput.value.trim();
if (usernameValue.length === 0) { if (usernameValue.length === 0) {
usernameError.innerHTML = 'Name cannot be empty'; vm.usernameError = 'Name cannot be empty';
return; return;
} }
if (usernameSubscription === null) { if (usernameSubscription === null) {
@ -115,22 +304,12 @@ function main() {
} }
var usernameValue = usernameInput.value.trim(); var usernameValue = usernameInput.value.trim();
if (usernameValue.length !== 0) { if (usernameValue.length !== 0) {
usernameError.innerHTML = ''; vm.usernameError = '';
} }
}); });
} }
function start() { function start() {
ctx.font = '25px Monospace';
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
addKeydownListener();
addKeypressListener();
addChatMessageListener();
reset();
repaint();
// Load initial data // Load initial data
doHttpGet('/games', function(games) { doHttpGet('/games', function(games) {
@ -158,89 +337,23 @@ function start() {
client.subscribe('/user/topic/playerReports', onPlayerReport); client.subscribe('/user/topic/playerReports', onPlayerReport);
} }
// special keys function addChatAnnouncement(body) {
function addKeydownListener() { addMessageItem({
canvasDiv.addEventListener('keydown', function(e) { body: body
if (e.which === KEYCODE_BACKSPACE) { })
e.preventDefault();
myGuess = myGuess.substr(0, myGuess.length - 1);
repaint();
}
else if (e.which === KEYCODE_RETURN) {
if (myGuess.length === 5) {
client.send("/app/guess", {}, myGuess);
myGuess = '';
repaint();
}
}
});
}
// characters
function addKeypressListener() {
canvasDiv.addEventListener('keypress', function(e) {
var charCode = e.charCode;
if (isCharacter(charCode)) {
if (isCharacterLowercase(charCode)) {
charCode = charCode - 32;
}
var char = String.fromCharCode(charCode);
if (myGuess.length < 5) {
myGuess += char;
repaint();
}
}
});
}
function addChatMessageListener() {
var messageInput = document.getElementById('messageInput');
messageInput.addEventListener('keypress', function(e) {
if (e.which === KEYCODE_RETURN) {
// Shift+Enter -> new line
if (!e.shiftKey) {
e.preventDefault();
var text = messageInput.value.trim();
if (text.length === 0) {
return;
}
messageInput.value = '';
client.send('/app/chat', {}, text);
addChatMessage(myUsername, text);
}
}
});
} }
function addChatMessage(sender, body) { function addChatMessage(sender, body) {
var messageList = document.getElementById('messageList'); addMessageItem({
var usernameNode = document.createElement('strong'); sender: sender,
var usernameTextNode = document.createTextNode(sender); body: body
usernameNode.appendChild(usernameTextNode); })
var messageTextNode = document.createTextNode(' ' + body);
var messageItem = document.createElement('div');
messageItem.classList.add('message-item');
messageItem.appendChild(usernameNode);
messageItem.appendChild(messageTextNode);
addMessageItem(messageList, messageItem);
}
function addChatAnnouncement(body) {
var messageList = document.getElementById('messageList');
var messageTextNode = document.createTextNode(body);
var messageItem = document.createElement('div');
messageItem.classList.add('message-item');
messageItem.classList.add('log');
messageItem.appendChild(messageTextNode);
addMessageItem(messageList, messageItem);
} }
// Auto-scrolls the message list // Auto-scrolls the message list
function addMessageItem(messageList, messageItem) { function addMessageItem(messageItem) {
if (!messageList.hasChildNodes()) { vm.messages.push(messageItem);
messageItem.classList.add('first'); var messageList = document.getElementById('messageList');
}
messageList.appendChild(messageItem);
messageList.scrollTop = messageList.scrollHeight; messageList.scrollTop = messageList.scrollHeight;
} }
@ -256,124 +369,6 @@ function doHttpGet(url, callback) {
xhr.send(); xhr.send();
} }
function drawMyBoard() {
var x = 25, y = MARGIN_TOP;
drawUsername(x, y, myUsername);
drawScore(x, y, myScore);
drawInput(x, y, myGuess);
var yStart = drawGuesses(x, y, myGuesses, myResults);
drawHint(x, yStart, myProgress);
drawGrid(x, y);
}
function drawOpponentBoard() {
var x = 325, y = MARGIN_TOP;
drawUsername(x, y, opponentUsername);
drawScore(x, y, opponentScore);
drawResults(x, y, opponentResults);
drawGrid(x, y);
}
function drawLastWord() {
if (lastWord) {
var x = canvas.width / 2;
var y = canvas.height - MARGIN_BOTTOM / 2;
ctx.fillStyle = 'black';
ctx.fillText('Previous word: ' + lastWord.toUpperCase(), x, y);
}
}
function drawUsername(x, y, username) {
var usernameX = x + WIDTH / 2;
var usernameY = y - 60;
ctx.fillStyle = 'black';
ctx.fillText(username, usernameX, usernameY);
}
function drawScore(x, y, score) {
var scoreX = x + WIDTH / 2;
var scoreY = y - 25;
ctx.fillStyle = 'black';
ctx.fillText(score, scoreX, scoreY);
}
function drawGrid(xOrigin, yOrigin) {
ctx.beginPath();
for (var x = 0; x <= WIDTH; x += SIDE) {
ctx.moveTo(xOrigin + x, yOrigin);
ctx.lineTo(xOrigin + x, yOrigin + HEIGHT);
}
for (var y = 0; y <= HEIGHT; y += SIDE) {
ctx.moveTo(xOrigin, yOrigin + y);
ctx.lineTo(xOrigin + WIDTH, yOrigin + y);
}
ctx.strokeStyle = 'black';
ctx.stroke();
}
function drawInput(xOrigin, yOrigin, input) {
ctx.fillStyle = 'green';
var x = xOrigin + SIDE * 0.5;
var y = yOrigin + SIDE * 0.5;
for (var i = 0; i < myGuess.length; i++) {
ctx.fillText(myGuess[i], x, y);
x += SIDE;
}
}
function drawGuesses(xOrigin, yOrigin, guesses, results) {
var y = yOrigin + SIDE * 1.5;
var numGuesses = Math.min(4, guesses.length);
for (var i = 0; i < numGuesses; i++) {
var x = xOrigin + SIDE * 0.5;
var guess = guesses[guesses.length - numGuesses + i];
var result = results[results.length - numGuesses + i];
for (var j = 0; j < 5; j++) {
if (result[j] === 1) {
ctx.fillStyle = 'yellow';
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
} else if (result[j] === 2) {
ctx.fillStyle = 'orange';
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
}
ctx.fillStyle = 'green';
ctx.fillText(guess[j], x, y);
x += SIDE;
}
y += SIDE;
}
return y;
}
function drawResults(xOrigin, yOrigin, results) {
var y = yOrigin + SIDE * 1.5;
var numResults = Math.min(4, results.length);
for (var i = 0; i < numResults; i++) {
var x = xOrigin + SIDE * 0.5;
var result = results[results.length - numResults + i];
for (var j = 0; j < 5; j++) {
if (result[j] === 1) {
ctx.fillStyle = 'yellow';
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
} else if (result[j] === 2) {
ctx.fillStyle = 'orange';
ctx.fillRect(x - SIDE * 0.5, y - SIDE * 0.5, SIDE, SIDE);
}
x += SIDE;
}
y += SIDE;
}
return y;
}
function drawHint(xOrigin, yOrigin, progress) {
var x = xOrigin + SIDE * 0.5;
for (var i = 0; i < 5; i++) {
ctx.fillText(progress[i], x, yOrigin);
x += SIDE;
}
}
function isCharacter(charCode) { function isCharacter(charCode) {
return isCharacterLowercase(charCode) || isCharacterUppercase(charCode); return isCharacterLowercase(charCode) || isCharacterUppercase(charCode);
} }
@ -395,64 +390,13 @@ function isValidResult(result) {
return true; return true;
} }
function removeGame(gameId) {
var indexToRemove = null;
for (var i = 0; i < vm.games.length; i++) {
if (vm.games[i].id === gameId) {
indexToRemove = i;
break;
}
}
vm.games.splice(indexToRemove, 1);
}
function repaint() {
// clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw the components
drawMyBoard();
drawOpponentBoard();
drawLastWord();
}
function reset(firstLetter, clearScore) {
if (!firstLetter) {
firstLetter = '';
}
myGuess = '';
myGuesses = [];
myProgress = [firstLetter, '', '', '', ''];
myResults = [];
opponentResults = [];
if (clearScore) {
myScore = 0;
opponentScore = 0;
}
}
function toggleView() {
var lobbyColumn = document.getElementById('lobbyColumn');
var gameColumn = document.getElementById('gameColumn')
if (lobbyColumn.classList.contains('primary')) {
lobbyColumn.classList.remove('primary');
} else {
lobbyColumn.classList.add('primary');
}
if (gameColumn.classList.contains('primary')) {
gameColumn.classList.remove('primary');
} else {
gameColumn.classList.add('primary');
}
}
function onChat(message) { function onChat(message) {
var chatMessage = JSON.parse(message.body); var chatMessage = JSON.parse(message.body);
var messageSender = chatMessage.username; var messageSender = chatMessage.username;
var messageBody = chatMessage.message; var messageBody = chatMessage.message;
if (messageSender === null) { if (messageSender === null) {
addChatAnnouncement(messageBody); addChatAnnouncement(messageBody);
} else if (messageSender === myUsername) { } else if (messageSender === vm.username) {
// Ignore messages sent by yourself // Ignore messages sent by yourself
} else { } else {
console.log('Message from ' + messageSender + ": " + messageBody); console.log('Message from ' + messageSender + ": " + messageBody);
@ -464,22 +408,26 @@ function onGameClosed(message) {
var game = JSON.parse(message.body); var game = JSON.parse(message.body);
var gameId = game.id; var gameId = game.id;
var playerOne = game.playerOne.username; var playerOne = game.playerOne.username;
if (playerOne === myUsername) { console.log(playerOne + ' closed Game ' + gameId);
if (playerOne === vm.username) {
vm.gameId = null; vm.gameId = null;
} }
console.log(playerOne + ' closed Game ' + gameId); vm.removeGame(gameId);
removeGame(gameId);
} }
function onGameHosted(message) { function onGameHosted(message) {
var game = JSON.parse(message.body); var game = JSON.parse(message.body);
var gameId = game.id; var gameId = game.id;
var playerOne = game.playerOne.username; var playerOne = game.playerOne.username;
if (playerOne === myUsername) { console.log(playerOne + ' hosted Game ' + gameId);
vm.games.push({
id: gameId,
playerOne: playerOne,
started: false
});
if (playerOne === vm.username) {
vm.gameId = gameId; vm.gameId = gameId;
} }
console.log(playerOne + ' hosted Game ' + gameId);
vm.games.push({ id: gameId, playerOne: playerOne, started: false });
} }
function onGameJoined(message) { function onGameJoined(message) {
@ -487,9 +435,6 @@ function onGameJoined(message) {
var gameId = game.id; var gameId = game.id;
var playerOne = game.playerOne.username; var playerOne = game.playerOne.username;
var playerTwo = game.playerTwo.username; var playerTwo = game.playerTwo.username;
if (playerTwo === myUsername) {
vm.gameId = gameId;
}
console.log(playerTwo + ' joined ' + playerOne + "'s game"); console.log(playerTwo + ' joined ' + playerOne + "'s game");
for (var i = 0; i < vm.games.length; i++) { for (var i = 0; i < vm.games.length; i++) {
if (vm.games[i].id === gameId) { if (vm.games[i].id === gameId) {
@ -498,8 +443,8 @@ function onGameJoined(message) {
break; break;
} }
} }
if (playerOne === myUsername || playerTwo === myUsername) { if (playerTwo === vm.username) {
toggleView(); vm.gameId = gameId;
} }
} }
@ -509,6 +454,7 @@ function onGameLeft(message) {
var gameId = game.id; var gameId = game.id;
var playerOne = game.playerOne.username; var playerOne = game.playerOne.username;
var gameLeaver = report.gameLeaver.username; var gameLeaver = report.gameLeaver.username;
console.log(gameLeaver + ' left ' + playerOne + "'s game");
var previousPlayers = []; var previousPlayers = [];
for (var i = 0; i < vm.games.length; i++) { for (var i = 0; i < vm.games.length; i++) {
if (vm.games[i].id === gameId) { if (vm.games[i].id === gameId) {
@ -520,13 +466,11 @@ function onGameLeft(message) {
break; break;
} }
} }
console.log(gameLeaver + ' left ' + playerOne + "'s game"); if (gameLeaver === vm.username) {
if (gameLeaver === myUsername) {
vm.gameId = null; vm.gameId = null;
} }
if (previousPlayers.indexOf(myUsername) != -1) { if (previousPlayers.indexOf(vm.username) != -1) {
onOpponentLeft(); onOpponentLeft();
toggleView();
} }
} }
@ -534,9 +478,9 @@ function onGameStarted(message) {
var report = JSON.parse(message.body); var report = JSON.parse(message.body);
var playerOne = report[0]; var playerOne = report[0];
var playerTwo = report[1]; var playerTwo = report[1];
if (playerOne === myUsername) { if (playerOne === vm.username) {
addChatAnnouncement('You are playing with ' + playerTwo); addChatAnnouncement('You are playing with ' + playerTwo);
} else if (playerTwo === myUsername) { } else if (playerTwo === vm.username) {
addChatAnnouncement('You are playing with ' + playerOne); addChatAnnouncement('You are playing with ' + playerOne);
} else { } else {
addChatAnnouncement(playerOne + ' is playing with ' + playerTwo); addChatAnnouncement(playerOne + ' is playing with ' + playerTwo);
@ -546,18 +490,16 @@ function onGameStarted(message) {
function onOpponentJoined(message) { function onOpponentJoined(message) {
var report = JSON.parse(message.body); var report = JSON.parse(message.body);
var firstLetter = report[0]; var firstLetter = report[0];
opponentUsername = report[1]; vm.opponentUsername = report[1];
console.log('Opponent username: ' + opponentUsername); console.log('Opponent username: ' + vm.opponentUsername);
reset(firstLetter, true); vm.reset(firstLetter, true);
canvasDiv.classList.remove('hidden'); vm.repaint();
repaint();
} }
function onOpponentLeft(message) { function onOpponentLeft(message) {
opponentUsername = null; vm.opponentUsername = null;
lastWord = null; vm.lastWord = null;
canvasDiv.classList.add('hidden'); vm.repaint();
repaint();
} }
function onOpponentReport(message) { function onOpponentReport(message) {
@ -566,15 +508,15 @@ function onOpponentReport(message) {
var guess = report.guess; var guess = report.guess;
var firstLetter = report.firstLetter; var firstLetter = report.firstLetter;
console.log('Opponent guessed correctly! ' + guess); console.log('Opponent guessed correctly! ' + guess);
opponentScore = opponentScore + 100; vm.opponentScore = vm.opponentScore + 100;
lastWord = guess; vm.lastWord = guess;
reset(firstLetter, false); vm.reset(firstLetter, false);
repaint(); vm.repaint();
} else { } else {
var result = report.result; var result = report.result;
console.log('Opponent result: ' + result); console.log('Opponent result: ' + result);
opponentResults.push(result); vm.opponentResults.push(result);
repaint(); vm.repaint();
} }
} }
@ -585,27 +527,27 @@ function onPlayerReport(message) {
var guess = report.guess; var guess = report.guess;
var firstLetter = report.firstLetter; var firstLetter = report.firstLetter;
console.log('I guessed correctly!'); console.log('I guessed correctly!');
myScore = myScore + 100; vm.myScore = vm.myScore + 100;
lastWord = guess; vm.lastWord = guess;
reset(firstLetter, false); vm.reset(firstLetter, false);
repaint(); vm.repaint();
} else { } else {
var guess = report.guess; var guess = report.guess;
var result = report.result; var result = report.result;
console.log('My result: ' + result); console.log('My result: ' + result);
// TODO: use isValidResult function // TODO: use isValidResult function
if (result[0] === 9) { if (result[0] === 9) {
myGuesses.push('-----'); vm.myGuesses.push('-----');
} else { } else {
for (var i = 0; i < 5; i++) { for (var i = 0; i < 5; i++) {
if (result[i] === 2) { if (result[i] === 2) {
myProgress[i] = guess[i]; vm.myProgress[i] = guess[i];
} }
} }
myGuesses.push(guess); vm.myGuesses.push(guess);
} }
myResults.push(result); vm.myResults.push(result);
repaint(); vm.repaint();
} }
} }
@ -613,7 +555,7 @@ function onUserJoined(message) {
var report = JSON.parse(message.body); var report = JSON.parse(message.body);
var username = report[0]; var username = report[0];
var numUsers = report[1]; var numUsers = report[1];
if (username === myUsername) { if (username === vm.username) {
addChatAnnouncement('Welcome to Lingo!'); addChatAnnouncement('Welcome to Lingo!');
if (numUsers === 1) { if (numUsers === 1) {
addChatAnnouncement('You are the only player online'); addChatAnnouncement('You are the only player online');

View File

@ -8,19 +8,19 @@
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js"></script>
</head> </head>
<body> <body>
<div> <div id="vue-app" v-cloak>
<div class="main column"> <div class="main column">
<div class="header row">Lingo</div> <div class="header row">Lingo</div>
<div class="body row nofooter"> <div class="body row nofooter">
<div id="usernameDiv" class="form"> <div v-show="!username" class="form">
<h2>What is your name?</h2> <h2>What is your name?</h2>
<input id="nicknameInput" type="text" class="form-control" maxlength="16"> <input id="nicknameInput" type="text" class="form-control" maxlength="16" autofocus>
<p id="usernameError" class="error-message"></p> <p class="error-message">{{ usernameError }}</p>
</div> </div>
<div id="appDiv" class="hidden"> <div v-show="username">
<div id="lobbyColumn" class="lobby column primary"> <div v-bind:class="{ primary: !inStartedGame }" class="lobby column">
<div id="vue-app" class="body row noheader nofooter scroll-y"> <div class="body row noheader nofooter scroll-y">
<div class="panel panel-default"> <div class="panel">
<div class="panel-heading"> <div class="panel-heading">
<h3 class="panel-title">Games</h3> <h3 class="panel-title">Games</h3>
</div> </div>
@ -40,9 +40,9 @@
<button v-show="!inGame" @click="hostGame" type="button" class="create button">Create game</button> <button v-show="!inGame" @click="hostGame" type="button" class="create button">Create game</button>
</div> </div>
</div> </div>
<div id="gameColumn" class="game column"> <div v-bind:class="{ primary: inStartedGame }" class="game column">
<div class="body row noheader nofooter"> <div class="body row noheader nofooter">
<div id="canvasDiv" class="hidden"> <div v-show="inStartedGame" @keydown="onCanvasKeydown" @keypress="onCanvasKeypress">
<canvas id="canvas" class="centered" width="600" height="475" tabindex="1"></canvas> <canvas id="canvas" class="centered" width="600" height="475" tabindex="1"></canvas>
</div> </div>
</div> </div>
@ -52,9 +52,18 @@
</div> </div>
<div class="chat column"> <div class="chat column">
<div class="header row">Chat</div> <div class="header row">Chat</div>
<div id="messageList" class="body row scroll-y"></div> <div id="messageList" class="body row scroll-y">
<template v-for="message in messages">
<div v-if="message.sender" class="message-item">
<strong>{{ message.sender }}</strong> {{ message.body }}
</div>
<div v-else class="log message-item">
{{ message.body }}
</div>
</template>
</div>
<div class="footer row"> <div class="footer row">
<textarea id="messageInput" placeholder="Send a message" tabindex="2"></textarea> <textarea @keypress="onChatKeypress" placeholder="Send a message" tabindex="2"></textarea>
</div> </div>
</div> </div>
</div> </div>

View File

@ -9,6 +9,10 @@
display: none; display: none;
} }
[v-cloak] {
display: none;
}
body { body {
font-family: sans-serif; font-family: sans-serif;
background: linen; background: linen;
@ -46,15 +50,15 @@ button:hover:disabled {
word-wrap: break-word; word-wrap: break-word;
} }
.message-item.first { .message-item:first-child {
border: none; border-top: none;
} }
.log { .log {
color: green; color: green;
} }
#messageInput { .chat.column textarea {
width: 100%; width: 100%;
height: 100%; height: 100%;
font-size: 14px; font-size: 14px;
@ -66,15 +70,15 @@ button:hover:disabled {
resize: none; resize: none;
} }
#messageInput::-webkit-input-placeholder { .chat.column textarea::-webkit-input-placeholder {
color: steelblue; color: steelblue;
} }
#messageInput::-moz-placeholder { .chat.column textarea::-moz-placeholder {
color: steelblue; color: steelblue;
} }
#messageInput:-ms-input-placeholder { .chat.column textarea:-ms-input-placeholder {
color: steelblue; color: steelblue;
} }
@ -104,10 +108,6 @@ button:hover:disabled {
margin-bottom: 0; margin-bottom: 0;
} }
.panel-heading+.list-group .list-group-item:first-item {
border-top-width: 0;
}
.panel>.list-group .list-group-item { .panel>.list-group .list-group-item {
font-size: 1em; font-size: 1em;
border-width: 1px 0; border-width: 1px 0;