add: game history

This commit is contained in:
starnakin 2024-03-05 10:53:32 +01:00 committed by AdrienLSH
parent 90ce697a3a
commit d8e767405a
8 changed files with 201 additions and 24 deletions

View File

@ -0,0 +1,15 @@
#game-list {
justify-content: flex-start;
display: flex;
flex-wrap: wrap;
}
#game-list .game-item {
display: flex;
flex-direction: column;
height: 160px;
width: 160px;
margin: 10px;
border-radius: 5%;
}

View File

@ -1,4 +1,5 @@
import { Client } from "./Client.js";
import { Game } from "./game/Game.js";
class Profile
{
@ -59,6 +60,36 @@ class Profile
}
/**
* @returns {[Game]}
*/
async getGameHistory()
{
let response = await this.client._get(`/api/games/history/${this.id}`);
let response_data = await response.json();
let games = [];
response_data.forEach(game_data => {
games.push(new Game(this.client,
game_data.id,
null,
null,
null,
game_data.winner_id,
game_data.state,
game_data.started,
game_data.finished,
game_data.players,
game_data.start_timestamp,
game_data.stop_timestamp
)
);
});
return games;
}
async getBlock() {
let block_response = await this.client._get("/api/profiles/block");

View File

@ -42,6 +42,11 @@ class Profiles
return profile;
}
/**
*
* @param {Number} id
* @returns {Profile}
*/
async getProfileId(id)
{
let profile = new Profile(this.client, undefined, id);

View File

@ -13,8 +13,16 @@ class Game
* @param {CallableFunction} goal_handler
* @param {CallableFunction} finish_handler
* @param {CallableFunction} disconnect_handler
* @param {Boolean} finished
* @param {Number} id
* @param {[Object]} players_data
* @param {Number} start_timestamp
* @param {Number} stop_timestamp
* @param {Boolean} started
* @param {Number} winner_id
* @param {String} state
*/
constructor(client, id, disconnect_handler, goal_handler, finish_handler)
constructor(client, id, disconnect_handler, goal_handler, finish_handler, winner_id, state, started, finished, players_data, start_timestamp, stop_timestamp)
{
/**
* @type {Client}
@ -40,6 +48,50 @@ class Game
* @type {CallableFunction}
*/
this.disconnect_handler = disconnect_handler;
/**
* @type {String}
*/
this.state = state;
/**
* @type {Boolean}
*/
this.started = started;
/**
* @type {Boolean}
*/
this.finished = finished;
/**
* @type {Number}
*/
this.winner_id = this.finished ? winner_id : undefined;
/**
* @type {Number}
*/
this.start_timestamp = start_timestamp;
/**
* @type {Number}
*/
this.stop_timestamp = stop_timestamp;
/**
* @type {[Player]}
*/
this.players = [];
players_data.forEach(player_data => {
this.players.push(new Player(this,
player_data.player_id,
player_data.username,
player_data.score
)
);
});
}
/**
@ -55,9 +107,6 @@ class Game
let response_data = await response.json();
/**
* @type {[Player]}
*/
this.players = [];
response_data.players.forEach(player_data => {
@ -69,34 +118,14 @@ class Game
);
});
/**
* @type {String}
*/
this.state = response_data.state;
/**
* @type {Boolean}
*/
this.started = response_data.started;
/**
* @type {Boolean}
*/
this.finished = response_data.finished;
/**
* @type {Number}
*/
this.winner_id = this.finished ? response_data.winner_id : undefined;
/**
* @type {Number}
*/
this.start_timestamp = response_data.start_timestamp;
/**
* @type {Number}
*/
this.stop_timestamp = response_data.stop_timestamp;
if (this.finished === true)

View File

@ -19,6 +19,7 @@ import TournamentsView from "./views/tournament/TournamentsListView.js";
import TournamentCreateView from "./views/tournament/TournamentCreateView.js";
import AuthenticationView from "./views/accounts/AuthenticationView.js";
import TicTacToeView from "./views/TicTacToeView.js";
import GameHistoryView from "./views/GameHistoryView.js";
let client = new Client(location.origin);
let lang = client.lang;
@ -77,6 +78,7 @@ const router = async(uri) => {
const routes = [
{ path: "/", view: Dashboard },
{ path: "/profiles/:id/history", view: GameHistoryView },
{ path: "/profiles/:username", view: ProfilePageView },
{ path: "/tournaments/create", view: TournamentCreateView },
{ path: "/tournaments/:id", view: TournamentPageView },

View File

@ -0,0 +1,66 @@
import { client, lang } from "../index.js";
import AbstractAuthenticatedView from "./abstracts/AbstractAuthenticatedView.js";
export default class extends AbstractAuthenticatedView
{
constructor(params)
{
super(params, 'homeWindowTitle');
this.id = params.id;
}
async postInit()
{
this.profile = await client.profiles.getProfileId(this.id);
if (this.profile === null)
return 404;
await this.fillHistory();
}
async fillHistory()
{
let games = await this.profile.getGameHistory();
let game_list = document.getElementById("game-list");
games.forEach(game => {
let a = document.createElement("a");
a.href = `/games/${game.id}/0`;
a.setAttribute("data-link", true);
let game_item = document.createElement("div");
game_item.className = "game-item";
game_item.style.backgroundColor = "grey";
if (game.started)
game_item.style.backgroundColor = "yellow";
if (game.finished)
game_item.style.backgroundColor = this.profile.id === game.winner_id ? "green" : "red";
game.players.forEach(player => {
let player_score = document.createElement("a");
player_score.href = `/profiles/${player.username}`;
player_score.innerText = `${player.username}: ${player.score.length}`;
player_score.setAttribute("data-link", true);
game_item.appendChild(player_score);
});
a.appendChild(game_item);
game_list.appendChild(a);
});
}
async getHtml()
{
return /* HTML */ `
<link rel="stylesheet" href="/static/css/gameHistory.css">
<h1>Game History</h1>
<div id="game-list">
</div>
`;
}
}

27
games/GameHistoryView.py Normal file
View File

@ -0,0 +1,27 @@
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import permissions, status
from django.http import HttpRequest
from .models import GameMembersModel, GameModel
from .serializers import GameSerializer
from . import config
class GameHistoryView(APIView):
permission_classes = (permissions.AllowAny,)
def get(self, request: HttpRequest, pk: int = None):
member_game_model_list: list[GameMembersModel] = GameMembersModel.objects.filter(player_id = pk)
game_model_list: list[GameModel] = []
for member_game_model in member_game_model_list:
game_model_list.append(GameModel.objects.get(pk = member_game_model.game_id))
games_data: list[dict] = [GameSerializer(game_model).data for game_model in game_model_list]
return Response(games_data)

View File

@ -3,9 +3,11 @@ from django.conf import settings
from django.conf.urls.static import static
from .GameViewSet import GameViewSet
from .GameHistoryView import GameHistoryView
from .GameConfigView import GameConfigView
urlpatterns = [
path("<int:pk>", GameViewSet.as_view({"get": "retrieve"}), name="game_page"),
path("history/<int:pk>", GameHistoryView.as_view(), name="history_page"),
path("", GameConfigView.as_view(), name = "game_config")
]