Implement board view and improve chat
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Paul Brinkmeier 2023-01-17 18:32:21 +01:00
parent 52a6bb0389
commit c2e834a67a
2 changed files with 160 additions and 25 deletions

View File

@ -10,10 +10,10 @@ export default {
components: { components: {
Game Game
}, },
data() { data(): { ws: WebSocket, model: any } {
return { return {
ws: new WebSocket(import.meta.env.VITE_GLEBBY_SERVER_URL), ws: new WebSocket(import.meta.env.VITE_GLEBBY_SERVER_URL),
model: null as any model: null
} }
}, },
created() { created() {
@ -30,7 +30,8 @@ export default {
} }
this.model = { this.model = {
yourId: payload.state.yourId, yourId: payload.state.yourId,
players players,
board: payload.state.board
} }
this.ws.removeEventListener('message', messageListener) this.ws.removeEventListener('message', messageListener)
} }

View File

@ -8,7 +8,8 @@ interface Player {
interface Model { interface Model {
yourId: number, yourId: number,
players: Map<number, Player> players: Map<number, Player>,
board: string[4][4]
} }
function getPlayer(model: Model, id: number): Player | undefined { function getPlayer(model: Model, id: number): Player | undefined {
@ -26,13 +27,16 @@ export default defineComponent({
}, },
data() { data() {
return { return {
chatMessages: [] as string[], chatMessages: [] as { from: number, message: string }[],
playerName: '', playerName: '',
chatMessage: '' chatMessage: ''
} }
}, },
created() { created() {
console.log(this.model.board)
console.log(this.model)
console.log(this.model.players)
this.ws.addEventListener('message', (ev) => { this.ws.addEventListener('message', (ev) => {
const message = JSON.parse(ev.data) const message = JSON.parse(ev.data)
const payload = message.payload const payload = message.payload
@ -50,12 +54,20 @@ export default defineComponent({
this.model.players.delete(message.from) this.model.players.delete(message.from)
break break
case 'chat': case 'chat':
this.chatMessages.push(payload.message) this.chatMessages.push({
from: message.from,
message: payload.message
})
break break
case 'set-name': case 'set-name':
getPlayer(this.model, message.from)!.name = payload.name getPlayer(this.model, message.from)!.name = payload.name
break break
case 'roll':
this.model.board = payload.board
break
} }
console.log(this.model)
}) })
}, },
methods: { methods: {
@ -75,28 +87,150 @@ export default defineComponent({
message: this.chatMessage message: this.chatMessage
})) }))
this.chatMessage = '' this.chatMessage = ''
},
roll() {
this.ws.send(JSON.stringify({
type: 'roll'
}))
} }
} }
}) })
</script> </script>
<template> <template>
<pre>{{ model }}</pre> <div class="glebby-game">
<h1>I am #{{ model.yourId }}</h1> <div class="topbar">
<h1>Glebby</h1>
</div>
<div class="game">
<h2>board</h2>
<button @click="roll">roll</button>
<div v-if="model.board" class="game-board">
<div v-for="row in model.board" class="game-row">
<div v-for="die in row" class="game-die">{{ die.toUpperCase() }}</div>
</div>
</div>
</div>
<div class="playerlist">
<h2>players</h2>
<form @submit.prevent="setName"> <form @submit.prevent="setName">
<input v-model="playerName" placeholder="enter your name..."> <input v-model="playerName" placeholder="enter your name...">
<button >set name</button> <button>set name</button>
</form> </form>
<ul v-if="model">
<li v-for="[id, player] in model.players" :key="id">
<code>{{ player.name }}#{{ player.id }}</code>
</li>
</ul>
</div>
<div class="chatbox">
<h2>chat</h2>
<div class="chatbox-scroller">
<div class="chatbox-scroller-content">
<div v-for="message in chatMessages" class="chatbox-message">
<code>{{ model.players.get(message.from)!.name }}#{{ message.from }}:</code> {{ message.message }}
</div>
</div>
</div>
<form @submit.prevent="sendChat"> <form @submit.prevent="sendChat">
<input v-model="chatMessage"> <input v-model="chatMessage">
<button>Post</button> <button>Post</button>
</form> </form>
<h2>players</h2> </div>
<ul v-if="model"> </div>
<li v-for="[id, player] in model.players" :key="id">{{ player.name }}#{{ player.id }}</li>
</ul>
<h2>chat</h2>
<ul v-if="model">
<li v-for="message in chatMessages">{{ message }}</li>
</ul>
</template> </template>
<style>
body {
margin: 0;
}
.glebby-game {
width: 100vw;
height: 100vh;
display: grid;
grid-template-columns: 1fr 20em;
grid-template-rows: min-content 1fr 12em;
grid-template-areas:
"topbar topbar"
"game playerlist"
"chatbox playerlist";
gap: .5em;
padding: .5em;
box-sizing: border-box;
}
.topbar,
.game,
.playerlist,
.chatbox {
background-color: #f0f0f0;
padding: .5em;
}
.topbar {
grid-area: topbar;
}
.game {
grid-area: game;
}
.playerlist {
grid-area: playerlist;
}
.chatbox {
grid-area: chatbox;
}
h1, h2 {
margin: 0;
font-family: monospace;
}
.game-board {
display: flex;
gap: 1em;
flex-direction: column;
align-items: center;
}
.game-row {
display: flex;
gap: 1em;
}
.game-die {
width: 2em;
height: 2em;
display: flex;
justify-content: center;
align-items: center;
background-color: white;
font-family: monospace;
font-size: 1.5em;
font-weight: bold;
}
.chatbox {
display: grid;
grid-template-rows: min-content 1fr min-content;
}
.chatbox-scroller {
overflow-y: scroll;
display: flex;
flex-direction: column-reverse;
}
.chatbox-scroller {
border: 1px dashed #888;
margin: .25em 0;
padding: .25em;
}
.chatbox-message code {
color: #888;
}
</style>