LocalStorageListener

This commit is contained in:
s-prechtl 2023-01-20 15:04:51 +01:00
parent b6ad404555
commit a0ab1b7f56
4 changed files with 70 additions and 16 deletions

View file

@ -9,6 +9,9 @@ export const gameRoute = express.Router()
gameRoute.use(express.json()) gameRoute.use(express.json())
/**
* Test
*/
gameRoute.post( gameRoute.post(
'/add', '/add',
body('playtime') body('playtime')
@ -18,6 +21,8 @@ gameRoute.post(
body('userId') body('userId')
.isInt({min: 1}) .isInt({min: 1})
.custom(userWithIdExists), .custom(userWithIdExists),
body('score')
.isInt({min: 0}),
/** /**
* After processing the errors of express-validator, inserts the game into the DB * After processing the errors of express-validator, inserts the game into the DB
* @param req * @param req

View file

@ -7,9 +7,10 @@
<UserScores :userScores="userScores"></UserScores> <UserScores :userScores="userScores"></UserScores>
</div> </div>
<div class="row"> <div class="row">
<Game v-if="user" class="col"> <Game v-if="user" v-bind:user-id=this.userId class="col"
@gameFinished="this.updateUserScores()">
</Game> </Game>
<Login v-else @userChange="(event) => this.user = event"> <Login v-else @userChange="(event) => {this.user = event; this.userId = this.user.id}">
</Login> </Login>
</div> </div>
<div class="row"> <div class="row">
@ -33,7 +34,6 @@ import Header from './components/Header.vue';
import "bootstrap/dist/css/bootstrap.min.css"; import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.min.js"; import "bootstrap/dist/js/bootstrap.min.js";
import Login from "@/components/Login.vue"; import Login from "@/components/Login.vue";
import {User} from "@/model/User";
export default defineComponent({ export default defineComponent({
name: 'App', name: 'App',
@ -49,19 +49,25 @@ export default defineComponent({
userScores: {}, userScores: {},
userId: 1, userId: 1,
user: null, user: null,
restUrl:'http://localhost:3000',
} }
}, },
methods: { methods: {
async fetchFromApi(path: string, method: "GET" | "POST") { async fetchFromApi(path: string, method: "GET" | "POST") {
let res: Response = await fetch("http://localhost:3000" + path, {method: method,}); let res: Response = await fetch(this.restUrl + path, {method: method,});
return await res.json(); return await res.json();
}, },
async fetchUserScores() { async fetchUserScores() {
return await this.fetchFromApi(`/user/${this.userId}/scores`, "GET"); return await this.fetchFromApi(`/user/${this.userId}/scores`, "GET");
}, },
async updateUserScores() {
this.userScores = await this.fetchUserScores();
},
}, },
async created() { async created() {
this.userScores = await this.fetchUserScores(); await this.updateUserScores();
} }
}); });
</script> </script>

View file

@ -4,8 +4,50 @@
</div> </div>
</template> </template>
<script lang="ts"> <script>
import App from "@/App.vue";
export default { export default {
name: "Game" name: "Game",
props: {
userId: null
},
emits: ['gameFinished'],
created() {
window.addEventListener('storage', this.localStorageHandler, false);
},
methods: {
localStorageHandler() {
if (localStorage.getItem('game-isRunning') !== 'true') {
let playTime = this.msToHMS(Number(localStorage.getItem('game-playTime')));
let score = Number(localStorage.getItem('game-score'));
this.submitGame(score, playTime);
}
},
msToHMS(ms) {
// 1- Convert to seconds:
let seconds = ms / 1000;
// 2- Extract hours:
const hours = parseInt(String(seconds / 3600)); // 3,600 seconds in 1 hour
seconds = seconds % 3600; // seconds remaining after extracting hours
// 3- Extract minutes:
const minutes = parseInt(String(seconds / 60)); // 60 seconds in 1 minute
// 4- Keep only seconds not extracted to minutes:
seconds = seconds % 60;
return hours + ":" + minutes + ":" + seconds;
},
async submitGame(score, playTime) {
let body = {
score: score,
playtime: playTime,
date: new Date(),
userId: this.userId,
}
await fetch(App.data().restUrl + '/game/add', {method: 'POST', body: JSON.stringify(body)});
this.$emit('gameFinished');
}
},
} }
</script> </script>

View file

@ -19,6 +19,7 @@
import LeaderboardEntry from "@/components/LeaderboardEntry.vue"; import LeaderboardEntry from "@/components/LeaderboardEntry.vue";
import RRButton from "@/components/RRButton.vue"; import RRButton from "@/components/RRButton.vue";
import App from "@/App.vue";
export default { export default {
name: "Leaderboard", name: "Leaderboard",
@ -44,7 +45,7 @@ export default {
}, },
methods: { methods: {
async fetchPage() { async fetchPage() {
let res = await fetch(`http://localhost:3000/leaderboard/${this.type}?pagination=true&entriesPerPage=${this.entriesPerPage}&page=${this.pageNumber}`, {method: "GET"}); let res = await fetch(`${App.data().restUrl}/leaderboard/${this.type}?pagination=true&entriesPerPage=${this.entriesPerPage}&page=${this.pageNumber}`, {method: "GET"});
return await res.json(); return await res.json();
}, },
title() { title() {