-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split game controls off into separate component
- Loading branch information
Showing
5 changed files
with
287 additions
and
263 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
import m from 'mithril'; | ||
import ClipboardJS from 'clipboard'; | ||
|
||
class DashboardControlsComponent { | ||
|
||
oninit({ attrs: { game, session } }) { | ||
this.game = game; | ||
this.session = session; | ||
} | ||
|
||
// Prepare game players by creating new players (if necessary) and deciding | ||
// which player has the starting move | ||
setPlayers(gameType) { | ||
if (this.game.players.length > 0) { | ||
// Reset new games before choosing number of players (no need to reset | ||
// the very first game) | ||
this.game.resetGame(); | ||
} | ||
this.game.setPlayers(gameType); | ||
} | ||
|
||
startGame(newStartingPlayer) { | ||
this.game.startGame({ | ||
startingPlayer: newStartingPlayer | ||
}); | ||
} | ||
|
||
endGame(roomCode) { | ||
if (roomCode) { | ||
// The local player ID and room code will be automatically passed by the | ||
// session.emit() function | ||
this.session.emit('end-game'); | ||
} else { | ||
this.game.endGame(); | ||
} | ||
} | ||
|
||
returnToHome() { | ||
this.session.disconnect(); | ||
// Redirect to homepage and clear all app state | ||
window.location.href = '/'; | ||
} | ||
|
||
closeRoom() { | ||
this.session.status = 'closingRoom'; | ||
this.session.emit('close-room', {}, () => { | ||
this.returnToHome(); | ||
}); | ||
} | ||
|
||
declineNewGame() { | ||
this.session.status = 'decliningNewGame'; | ||
this.session.emit('decline-new-game', {}, () => { | ||
this.returnToHome(); | ||
}); | ||
} | ||
|
||
createNewPlayer() { | ||
this.session.status = 'newPlayer'; | ||
} | ||
|
||
setNewPlayerName(inputEvent) { | ||
this.newPlayerName = inputEvent.target.value; | ||
inputEvent.redraw = false; | ||
} | ||
|
||
submitNewPlayer(submitEvent, roomCode) { | ||
submitEvent.preventDefault(); | ||
if (roomCode) { | ||
this.addNewPlayerToGame(roomCode); | ||
} else { | ||
this.startOnlineGame(); | ||
} | ||
} | ||
|
||
addNewPlayerToGame(roomCode) { | ||
this.session.status = 'connecting'; | ||
const submittedPlayer = { name: this.newPlayerName, color: 'blue' }; | ||
this.session.emit('add-player', { roomCode, player: submittedPlayer }, ({ game, localPlayer }) => { | ||
this.game.restoreFromServer({ game, localPlayer }); | ||
m.redraw(); | ||
}); | ||
} | ||
|
||
startOnlineGame() { | ||
this.session.connect(); | ||
// Construct a placeholder player with the name we entered and the default | ||
// first player color | ||
const submittedPlayer = { name: this.newPlayerName, color: 'red' }; | ||
// Request a new room and retrieve the room code returned from the server | ||
this.session.emit('open-room', { player: submittedPlayer }, ({ roomCode, game, localPlayer }) => { | ||
this.game.restoreFromServer({ game, localPlayer }); | ||
console.log('new room', roomCode); | ||
m.route.set(`/room/${roomCode}`); | ||
}); | ||
} | ||
|
||
requestNewOnlineGame() { | ||
this.session.status = 'connecting'; | ||
this.session.emit('request-new-game', { winner: this.game.winner }, ({ localPlayer }) => { | ||
if (this.session.status === 'requestingNewGame') { | ||
this.game.requestingPlayer = localPlayer; | ||
} | ||
m.redraw(); | ||
}); | ||
} | ||
|
||
configureCopyControl({ dom }) { | ||
this.shareLinkCopier = new ClipboardJS(dom); | ||
} | ||
|
||
view({ attrs: { roomCode } }) { | ||
return m('div#dashboard-controls', [ | ||
|
||
// Prompt a player to enter their name when starting an online game, or | ||
// when joining an existing game for the first time | ||
this.session.status === 'newPlayer' ? m('form', { | ||
onsubmit: (submitEvent) => this.submitNewPlayer(submitEvent, roomCode) | ||
}, [ | ||
m('input[type=text][autocomplete=off]#new-player-name', { | ||
name: 'new-player-name', | ||
autofocus: true, | ||
required: true, | ||
oninput: (inputEvent) => this.setNewPlayerName(inputEvent) | ||
}), | ||
m('button[type=submit]', roomCode ? 'Join Game' : 'Start Game') | ||
]) : | ||
|
||
this.session.status === 'waitingForPlayers' ? [ | ||
m('div#share-controls', [ | ||
m('input[type=text]#share-link', { | ||
value: window.location.href, | ||
onclick: ({ target }) => target.select() | ||
}), | ||
m('button#copy-share-link', { | ||
'data-clipboard-text': window.location.href, | ||
oncreate: ({ dom }) => this.configureCopyControl({ dom }) | ||
}, 'Copy') | ||
]), | ||
// If P1 is still waiting for players, offer P1 the option to close | ||
// room | ||
m('button.warn', { onclick: () => this.closeRoom() }, 'Close Room') | ||
] : | ||
|
||
// If game is in progress, allow user to end game at any time | ||
this.game.inProgress && this.session.status !== 'watchingGame' && !this.session.disconnected ? [ | ||
m('button.warn', { onclick: () => this.endGame(roomCode) }, 'End Game') | ||
] : | ||
|
||
// If an online game is not in progress (i.e. it was ended early, or there | ||
// is a winner/tie), allow the user to play again | ||
this.session.socket && this.game.players.length === 2 && this.session.status !== 'connecting' && this.session.status !== 'watchingGame' && !this.session.disconnectedPlayer && !this.session.reconnectedPlayer && !this.session.disconnected ? [ | ||
|
||
// Play Again / Yes | ||
m('button', { | ||
onclick: () => this.requestNewOnlineGame(), | ||
disabled: this.session.status === 'requestingNewGame' | ||
}, this.session.status === 'newGameRequested' ? 'Yes!' : this.session.status === 'requestingNewGame' ? 'Pending' : 'Play Again'), | ||
|
||
// No Thanks | ||
this.session.status !== 'requestingNewGame' ? m('button.warn', { | ||
onclick: () => this.declineNewGame(), | ||
disabled: this.session.status === 'requestingNewGame' | ||
}, this.session.status === 'newGameRequested' ? 'Nah' : this.session.status !== 'requestingNewGame' ? 'No Thanks' : null) : null | ||
|
||
] : | ||
|
||
!this.session.socket ? [ | ||
|
||
// If number of players has been chosen, ask user to choose starting player | ||
this.game.type !== null ? | ||
this.game.players.map((player) => { | ||
return m('button', { | ||
onclick: () => this.startGame(player) | ||
}, player.name); | ||
}) : | ||
|
||
// Select a number of human players | ||
[ | ||
m('button', { | ||
onclick: () => this.setPlayers({ gameType: '1P' }) | ||
}, '1 Player'), | ||
m('button', { | ||
onclick: () => this.setPlayers({ gameType: '2P' }) | ||
}, '2 Players'), | ||
m('button', { | ||
onclick: () => this.createNewPlayer() | ||
}, 'Online') | ||
] | ||
|
||
] : null | ||
]); | ||
} | ||
|
||
} | ||
|
||
export default DashboardControlsComponent; |
Oops, something went wrong.