initial pfp in Join and Lobby

This commit is contained in:
EisiBaer 2023-09-26 18:46:42 +02:00
parent 53edb8c7da
commit 31db2f0fc1
12 changed files with 70 additions and 47 deletions

View File

@ -5,10 +5,11 @@ const PlayerModel = require("../models/PlayerModel");
* @param {String} hostName * @param {String} hostName
* @returns A promise which resolves when a new player has been created. Rejects if an error occurs * @returns A promise which resolves when a new player has been created. Rejects if an error occurs
*/ */
exports.addPlayer = (playerName) => { exports.addPlayer = (playerName, playerImage) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let newPlayer = new PlayerModel({ let newPlayer = new PlayerModel({
name: playerName, name: playerName,
pfpFilename: playerImage,
points: 0, points: 0,
}); });

View File

@ -6,6 +6,7 @@ const PlayerSchema = new Schema({
name: { type: String, required: true, maxLength: 100 }, name: { type: String, required: true, maxLength: 100 },
points: { type: Number }, points: { type: Number },
acceptAnswers: { type: Boolean, default: false }, acceptAnswers: { type: Boolean, default: false },
pfpFilename: { type: String, default: null, required: false },
}); });
// Export model // Export model

View File

@ -11,7 +11,7 @@ const UserSchema = new Schema({
}, },
password: { type: String, required: true, }, password: { type: String, required: true, },
boards: [{ type: Schema.Types.ObjectId, ref: "Board" }], boards: [{ type: Schema.Types.ObjectId, ref: "Board" }],
pfpFilename: [{ type: String, required: false, default: null }], pfpFilename: { type: String, required: false, default: null },
}); });
// Virtual for player's URL // Virtual for player's URL

View File

@ -21,24 +21,24 @@ app.use(cors({
credentials: true, credentials: true,
})); }));
app.use(helmet( // app.use(helmet(
{ // {
contentSecurityPolicy: { // contentSecurityPolicy: {
// useDefaults: false, // // useDefaults: false,
directives: { // directives: {
"default-src": ["'self'"], // "default-src": ["'self'"],
"object-src": ["'none'"], // "object-src": ["'none'"],
"script-src": ["'unsafe-inline'", "'unsafe-eval'", "'self'" ], // "script-src": ["'unsafe-inline'", "'unsafe-eval'", "'self'" ],
"base-uri": ["'none'"], // "base-uri": ["'none'"],
"frame-src": ["'none'"], // "frame-src": ["'none'"],
"media-src": ["'self'", "data:"], // "media-src": ["'self'", "data:"],
"style-src-elem": ["'self'", "'unsafe-inline'"], // "style-src-elem": ["'self'", "'unsafe-inline'"],
"connect-src": ["'self'", "ws:"], // "connect-src": ["'self'", "ws:"],
"img-src": ["'self'", "blob:", "data:"], // "img-src": ["'self'", "blob:", "data:"],
} // }
} // }
} // }
)); // ));
const mongoDB = process.env.API_MONGO_CONN_URI; const mongoDB = process.env.API_MONGO_CONN_URI;

View File

@ -28,7 +28,7 @@ exports.handleMessage = ( gameSocketList, socket, dataRaw ) => {
switch( data.event ){ switch( data.event ){
case "joinGame": case "joinGame":
if( payload.gameCode !== undefined && payload.playerName !== undefined ){ if( payload.gameCode !== undefined && payload.playerName !== undefined ){
playerController.addPlayer( payload.playerName ) playerController.addPlayer( payload.playerName, payload.playerImage )
.then( ( player ) => { .then( ( player ) => {
if( socket.locals === undefined ){ if( socket.locals === undefined ){
socket.locals = {}; socket.locals = {};

View File

@ -194,4 +194,6 @@ $utilities: map-merge(
.pfp{ .pfp{
object-fit: cover; object-fit: cover;
max-width: 100vw;
max-height: 100vh;
} }

View File

@ -9,9 +9,9 @@ const props = defineProps({
default: null, default: null,
required: false, required: false,
}, },
sizingClasses: { sizing: {
type: Array, type: String,
default: () => ["pfp-sizing"], default: "10rem",
required: false, required: false,
}, },
isPreview: { isPreview: {
@ -47,7 +47,7 @@ const pfpSrc = computed( () => {
<template> <template>
<div> <div>
<div class="border border-1 border-white rounded-3 overflow-hidden"> <div class="border border-1 border-white rounded-3 overflow-hidden">
<img :src="pfpSrc" alt="Profile Picture of the user" class="pfp" :class="sizingClasses" /> <img :src="pfpSrc" alt="Profile Picture of the user" class="pfp" :style="[ { 'width': props.sizing }, { 'height': props.sizing } ]" />
<div v-show="props.isPreview" class="position-relative"> <div v-show="props.isPreview" class="position-relative">
<span class="position-absolute bottom-0 end-0 bg-black bg-opacity-50 px-1 rounded-2"> <span class="position-absolute bottom-0 end-0 bg-black bg-opacity-50 px-1 rounded-2">
Preview Preview
@ -56,17 +56,4 @@ const pfpSrc = computed( () => {
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<style scoped>
.pfp-sizing{
height: 10rem;
width: 10rem;
max-height: 100vh;
max-width: 100vw;
}
.pfp-sizing-navbar{
height: 2em;
width: 2em;
}
</style>

View File

@ -72,7 +72,7 @@ function logoutButtonClicked(_event){
<font-awesome-icon icon="fa-solid fa-angle-down" size="sm" class="me-2"/> <font-awesome-icon icon="fa-solid fa-angle-down" size="sm" class="me-2"/>
<span class="me-1">{{ userStore.username }}</span> <span class="me-1">{{ userStore.username }}</span>
<ProfilePicture <ProfilePicture
:sizingClasses="['pfp-sizing-navbar']" :sizing="'2em'"
/> />
</div> </div>
</a> </a>
@ -107,7 +107,7 @@ function logoutButtonClicked(_event){
<font-awesome-icon icon="fa-solid fa-angle-down" size="sm" class="me-2"/> <font-awesome-icon icon="fa-solid fa-angle-down" size="sm" class="me-2"/>
<span class="me-1">{{ userStore.username }}</span> <span class="me-1">{{ userStore.username }}</span>
<ProfilePicture <ProfilePicture
:sizingClasses="['pfp-sizing-navbar']" :sizing="'2em'"
/> />
</div> </div>
</a> </a>

View File

@ -1,8 +1,10 @@
<script setup> <script setup>
import { useRouter, useRoute } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import { ref } from "vue";
import { useUserStore } from "@/stores/UserStore"; import { useUserStore } from "@/stores/UserStore";
import { useGameStore } from "@/stores/GameStore"; import { useGameStore } from "@/stores/GameStore";
import { ref } from "vue"; import ProfilePicture from "@/components/blocks/ProfilePicture.vue";
let errorMessage = ref(""); let errorMessage = ref("");
let playerName = ref(""); let playerName = ref("");
@ -12,13 +14,14 @@ let forwardTo = { name: "gameLobby", params: { gameId: -1 } };
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
const gameStore = useGameStore(); const gameStore = useGameStore();
const userStore = useUserStore();
function joinButtonClicked(_event) { function joinButtonClicked(_event) {
if( joinRequest.value === true ){ if( joinRequest.value === true ){
return; return;
} }
joinRequest.value = true; joinRequest.value = true;
gameStore.joinGame( playerName.value ) gameStore.joinGame( playerName.value, userStore.pfpFilename )
.then( ( gameId ) => { .then( ( gameId ) => {
forwardTo.params.gameId = gameId; forwardTo.params.gameId = gameId;
router.push( forwardTo ); router.push( forwardTo );
@ -31,6 +34,10 @@ function joinButtonClicked(_event) {
}); });
} }
if( userStore.loggedIn ){
playerName.value = userStore.username;
}
let gameId = route.params.gameId; let gameId = route.params.gameId;
if( gameId ){ if( gameId ){
joinRequest.value = true; joinRequest.value = true;
@ -91,6 +98,11 @@ if( gameId ){
</div> </div>
<div class="card-body text-center"> <div class="card-body text-center">
<div class="d-flex flex-column h-100 w-100 align-items-center justify-content-center"> <div class="d-flex flex-column h-100 w-100 align-items-center justify-content-center">
<div>
<ProfilePicture
:sizing="'8rem'"
/>
</div>
<div class="d-flex px-3 w-100"> <div class="d-flex px-3 w-100">
<div class="w-100 text-start"> <div class="w-100 text-start">
<label for="username" class="fs-5 mb-1">Username</label> <label for="username" class="fs-5 mb-1">Username</label>

View File

@ -3,8 +3,8 @@ import { onMounted, onUnmounted, ref } from 'vue';
import { useRouter, onBeforeRouteLeave, useRoute } from 'vue-router'; import { useRouter, onBeforeRouteLeave, useRoute } from 'vue-router';
import { useGameStore } from '@/stores/GameStore'; import { useGameStore } from '@/stores/GameStore';
import BoardListView from "@/components/views/BoardListView.vue"; import BoardListView from "@/components/views/BoardListView.vue";
import ProfilePicture from '@/components/blocks/ProfilePicture.vue';
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
@ -13,6 +13,13 @@ const gameStore = useGameStore();
let selectedBoardId = ref("0"); let selectedBoardId = ref("0");
let showBoardMessage = ref( false ); let showBoardMessage = ref( false );
let protocol = ('https:' == document.location.protocol ? 'https://' : 'http://');
let hostname = window.location.hostname;
if( window.location.hostname.includes("localhost" ) ){
hostname += ':3000';
}
const API_URL = `${protocol}${hostname}/api`;
function startGame(){ function startGame(){
if( selectedBoardId.value !== "0" ){ if( selectedBoardId.value !== "0" ){
@ -127,7 +134,15 @@ onBeforeRouteLeave((to, from) => {
<div class="col-4 my-3"> <div class="col-4 my-3">
<div class="card bg-primary"> <div class="card bg-primary">
<div class="card-body fs-4 text-center"> <div class="card-body fs-4 text-center">
{{ playerIdx + 1 }} - {{ player.name }} <div class="d-flex justify-content-center align-items-center">
<ProfilePicture
:srcOverride="API_URL + '/user/pfp/' + player.pfpFilename"
:sizing="'2.5em'"
/>
<span class="ms-3">
{{ playerIdx + 1 }} - {{ player.name }}
</span>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -135,7 +135,7 @@ export const useGameStore = defineStore('game', {
} }
}); });
}, },
joinGame( playerName ){ joinGame( playerName, playerImage ){
return new Promise( ( resolve, reject ) =>{ return new Promise( ( resolve, reject ) =>{
if( this.websocketConnection.readyState === 1 ){ if( this.websocketConnection.readyState === 1 ){
@ -160,6 +160,7 @@ export const useGameStore = defineStore('game', {
payload: { payload: {
gameCode: this.gameCode, gameCode: this.gameCode,
playerName: this.playerName, playerName: this.playerName,
playerImage: playerImage,
} }
} }
this.websocketConnection.send( JSON.stringify( sendObj ) ); this.websocketConnection.send( JSON.stringify( sendObj ) );

View File

@ -44,7 +44,11 @@ export const useUserStore = defineStore('user', {
setUser( user ){ setUser( user ){
this.loggedIn = true; this.loggedIn = true;
this.username = user.username; this.username = user.username;
this.pfpFilename = user.pfpFilename; if( user.pfpFilename ){
this.pfpFilename = user.pfpFilename;
} else {
this.pfpFilename = null;
}
}, },
resetInitialUserDataPromise(){ resetInitialUserDataPromise(){
this.initialUserPromise = new Promise( (resolve, reject ) => { this.initialUserPromise = new Promise( (resolve, reject ) => {