first commit

This commit is contained in:
2024-02-23 20:48:46 +01:00
commit 15fe7fa703
56 changed files with 18071 additions and 0 deletions

357
src/app.css Normal file
View File

@@ -0,0 +1,357 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
/* Global */
html {
@apply h-screen;
}
body {
@apply min-h-screen text-gray-600 mb-16 md:mb-0;
@apply dark:text-gray-300 dark:bg-gray-900;
margin-top:65px;
}
h1, h2, h3 {
@apply text-cyan-700 font-bold uppercase mb-3;
}
h1 {
@apply text-4xl;
}
h2 {
@apply text-3xl;
}
h3 {
@apply text-2xl;
}
p {
@apply mb-1;
}
.fixed-top {
@apply fixed w-full z-10 top-0;
}
.fixed-bottom {
@apply fixed w-full z-10 bottom-0;
}
.container {
@apply px-4 mx-auto md:px-0;
}
/* Section nav */
.navbar {
@apply flex flex-wrap items-center justify-between mx-auto;
@apply bg-white border-gray-300;
@apply dark:bg-gray-800 dark:border-slate-700;
}
.navbar-brand {
@apply py-3 flex items-center;
}
.navbar-brand img {
@apply h-8 mr-3;
}
.navbar-item {
@apply flex flex-col gap-x-2 p-3 border-t-2 text-center;
@apply md:flex-row md:text-left md:border-0 md:border-t-0 md:border-b-2;
@apply text-gray-900 hover:text-cyan-600 border-transparent;
@apply dark:text-white;
}
.navbar-item > svg {
@apply w-6 h-6 mx-auto;
}
.navbar-item.active {
@apply border-cyan-600;
}
.navbar-item.active > svg {
@apply text-cyan-600;
}
.navbar-item.active > span {
@apply text-sm text-center;
@apply text-cyan-600;
}
#navheader {
@apply navbar fixed-top md:relative border-b md:border-0;
}
#navheader div:first-child {
@apply container mx-auto flex justify-between items-center;
}
#navheader .navbar-brand span {
@apply font-semibold whitespace-nowrap uppercase dark:text-white
}
#navheader ul {
@apply font-medium flex md:p-0 bg-inherit md:flex-row md:space-x-8 md:mt-0 md:border-0 dark:bg-inherit;
}
#navheader ul li a {
@apply block text-gray-900 md:bg-transparent md:text-gray-900 md:dark:text-white md:border-0 md:hover:text-cyan-600 md:p-0 dark:text-white md:dark:hover:text-blue-500 dark:hover:text-white md:dark:hover:bg-transparent;
}
#navheader ul li a svg{
@apply w-6 h-6;
}
#navmenu {
@apply z-50 navbar fixed-bottom md:relative border-t md:border-0 md:border-b;
}
#navmenu ul {
@apply container mx-auto font-medium bg-white grid grid-flow-col md:justify-start md:p-0 md:flex-row md:space-x-8 md:mt-0 md:border-0 dark:bg-inherit;
}
#navmenu ul li a {
@apply navbar-item;
}
/* Section Page */
section {
@apply container pb-40 md:pb-4 pt-2 md:pt-4 mx-auto;
}
.section-title {
@apply flex gap-1 py-2 mb-4 border-b justify-between md:justify-start md:gap-2 items-center;
@apply border-gray-600 text-gray-600;
@apply dark:border-gray-300 dark:text-gray-300;
}
.section-title svg {
@apply w-6 h-6;
@apply text-gray-600;
@apply dark:text-gray-300;
}
.section-title span {
@apply uppercase;
}
.matrice {
@apply flex flex-wrap ;
}
.matrice a {
@apply flex flex-col items-center max-w-sm bg-inherit p-6;
}
.matrice a img {
@apply w-16 h-16 mb-3 rounded-full shadow-lg;
}
.matrice a p {
@apply mb-2 font-bold tracking-tight text-center;
@apply text-gray-900;
@apply dark:text-white;
}
/* button */
.btn {
@apply font-medium rounded-lg text-sm text-center px-5 py-2.5 mr-2 mb-2;
}
.btn-primary {
@apply text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800;
}
.btn-alternative {
@apply text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700;
}
.btn-dark {
@apply text-white bg-gray-800 hover:bg-gray-900 focus:outline-none focus:ring-4 focus:ring-gray-300 dark:bg-gray-800 dark:hover:bg-gray-700 dark:focus:ring-gray-700 dark:border-gray-700;
}
.btn-light {
@apply text-gray-900 bg-white border border-gray-300 focus:outline-none hover:bg-gray-100 focus:ring-4 focus:ring-gray-200 dark:bg-gray-800 dark:text-white dark:border-gray-600 dark:hover:bg-gray-700 dark:hover:border-gray-600 dark:focus:ring-gray-700;
}
.btn-success {
@apply focus:outline-none text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800;
}
.btn-danger {
@apply focus:outline-none text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-900;
}
.btn-warning {
@apply focus:outline-none text-white bg-yellow-400 hover:bg-yellow-500 focus:ring-4 focus:ring-yellow-300 dark:focus:ring-yellow-900;
}
/* SectionAction */
.btn-dial {
@apply fixed md:static md:inline-block right-6 bottom-6 md:bottom-6 z-40;
}
.btn-add {
@apply md:btn btn-success;
@apply flex justify-center items-center w-[52px] h-[52px] md:w-full md:h-auto rounded-full md:rounded-lg shadow-sm;
@apply hover:text-white !important;
}
.btn-add svg {
@apply w-6 h-6 md:hidden;
@apply hover:text-white;
}
.btn-add span {
@apply hidden md:inline-block;
}
.btn-submit {
@apply md:btn btn-success rounded-none md:rounded py-4 md:py-2 right-0 w-full md:w-fit fixed md:static bottom-0 block md:inline-block;
@apply h-20 md:h-auto z-40;
@apply hover:text-white !important;
}
.btn-delete {
@apply ml-auto btn btn-danger mr-0;
@apply hover:text-white !important;
}
.btn-cancel {
@apply btn btn-alternative;
@apply hover:text-gray-900 !important;
@apply dark:hover:text-white !important;
}
/* Link */
a {
@apply cursor-pointer;
}
a:hover:not(.btn) {
@apply hover:text-cyan-700;
}
/* Form */
.form-group {
@apply mb-3;
}
.form-group label,
.form-group input,
.form-group select,
.form-group textarea {
@apply block;
}
.form-group label {
@apply font-semibold py-1;
}
.form-group label.required::after {
content: ' (requis)';
@apply text-sm font-normal text-red-500;
}
.form-action {
@apply flex flex-wrap;
}
form {
@apply relative;
}
form label {
@apply w-full;
}
form label.required{
@apply font-bold;
}
form label.required:after{
content:" *";
}
form input, form textarea, form select {
@apply w-full mb-3 text-gray-900;
border-radius: 0.25rem !important;
}
/* Section table */
.table-container {
@apply overflow-x-auto;
}
table {
@apply w-full text-sm text-left;
}
table thead {
@apply text-xs uppercase bg-gray-50 dark:bg-gray-700;
}
table thead th {
@apply px-6 py-3;
}
table tbody tr {
@apply bg-white border-b dark:bg-gray-800 dark:border-gray-700;
}
table tbody tr th {
@apply px-6 py-4 font-medium whitespace-nowrap;
}
table tbody tr td {
@apply px-6 py-4;
}
table th.optional {
@apply hidden md:block;
}
table td.optional {
@apply hidden md:block;
}
/* Section alert */
.alert {
@apply p-4 mb-4 text-sm rounded-lg font-medium text-gray-800 bg-gray-50 border border-gray-500;
}
.alert-info {
@apply text-blue-800 bg-blue-50 dark:bg-blue-200 border border-blue-500 dark:border-blue-800;
}
.alert-danger {
@apply text-red-800 bg-red-50 dark:bg-red-200 border border-red-500 dark:border-red-800;
}
.alert-success {
@apply text-green-800 bg-green-50 dark:bg-green-200 border border-green-500 dark:border-green-800;
}
.alert-warning {
@apply text-yellow-800 bg-yellow-50 dark:bg-yellow-100 border border-yellow-500 dark:border-yellow-800;
}
}
.sortable > span {
-webkit-touch-callout:none;
-ms-touch-action:none; touch-action:none;
-moz-user-select:none; -webkit-user-select:none; -ms-user-select:none; user-select:none;
}
span.ui-sortable-placeholder { background-color:#cdcdcd !important; }
#waiting {
display:none;
}
.loader {
border-top-color: #3498db;
-webkit-animation: spinner 1.5s linear infinite;
animation: spinner 1.5s linear infinite;
}
@-webkit-keyframes spinner {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@keyframes spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#app {
height: 100%;
}

9
src/app.d.ts vendored Normal file
View File

@@ -0,0 +1,9 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
// and what to do when importing types
declare namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface Platform {}
}

17
src/app.html Normal file
View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="/edge/sdk/client.js"></script>
<script>
Edge.Client.connect();
Edge.Menu.setAppTitle("La Rue de la Soif").setAppIconUrl("/medias/logo/logo.png");
</script>
%sveltekit.head%
</head>
<body id="body" data-sveltekit-preload-data="hover" edge-auto-padding="false">
<div id="app">%sveltekit.body%</div>
</body>
</html>

33
src/lib/Dice.svelte Normal file
View File

@@ -0,0 +1,33 @@
<script>
import { createEventDispatcher } from 'svelte';
export let id;
export let selected;
export let value;
const dispatch = createEventDispatcher();
let dice="";
let nbroll=0
let intervalId;
function rolling() {
value=Math.floor(Math.random() * 6) + 1;
nbroll=nbroll+1;
if(nbroll==10) {
dispatch('diceresult', {"id":id,"value":value});
clearInterval(intervalId);
nbroll=0;
}
}
export function roll() {
intervalId = setInterval(rolling, 50);
}
</script>
{#if !selected}
<span id={id} class="dice cursor-pointer text-3xl flex justify-center items-center bg-red-600 text-white rounded-lg m-1 w-14 h-14">
{value}
</span>
{/if}

10
src/routes/+layout.js Normal file
View File

@@ -0,0 +1,10 @@
export async function load() {
let authid=await Edge.Client.rpc("getAuthid");
let authpseudo=await Edge.Client.rpc("getAuthpseudo");
let authisuser=await Edge.Client.rpc("getAuthisuser");
let player=await Edge.Client.rpc("initPlayer",{"_id":authid,"name":authpseudo,"isuser":(authisuser!="anon")});
return {
player,
};
}

15
src/routes/+layout.svelte Normal file
View File

@@ -0,0 +1,15 @@
<script>
import "../app.css";
import { goto } from '$app/navigation';
export let data;
if(data.player.partyid)
goto("/game");
</script>
<div class="p-3">
<slot />
</div>

11
src/routes/+page.js Normal file
View File

@@ -0,0 +1,11 @@
export async function load() {
let authid=await Edge.Client.rpc("getAuthid");
let authpseudo=await Edge.Client.rpc("getAuthpseudo");
let authisuser=await Edge.Client.rpc("getAuthisuser");
let player=await Edge.Client.rpc("initPlayer",{"_id":authid,"name":authpseudo,"isuser":(authisuser!="anon")});
return {
player,
};
}

16
src/routes/+page.svelte Normal file
View File

@@ -0,0 +1,16 @@
<script>
import { goto } from '$app/navigation';
export let data;
if(data.player.partyid)
goto("/game");
else {
goto("/party");
}
</script>
<a class="btn btn-success w-full text-3xl p-3 block" href="/party">
<span>Voir les parties en cours</span>
</a>

66
src/routes/game/+page.js Normal file
View File

@@ -0,0 +1,66 @@
export async function load({ params }) {
let authid=await Edge.Client.rpc("getAuthid");
let authpseudo=await Edge.Client.rpc("getAuthpseudo");
let authisuser=await Edge.Client.rpc("getAuthisuser");
let player=await Edge.Client.rpc("initPlayer",{"_id":authid,"name":authpseudo,"isuser":(authisuser!="anon")});
let party;
let players;
if(player.partyid) {
party = await Edge.Client.rpc("getParty",player.partyid).catch(err => console.error(err));
players= await Edge.Client.rpc("getPartyplayers",party._id).catch(err => console.error(err));
}
else window.location.href = '/';
if(party.status=="playerwait") {
let plateau=[
{"_id":0 ,"type":"week" ,"buyable":false,"value":50 ,"owner":[],update:0,"name":"WEEK END"},
{"_id":1 ,"type":"bar" ,"buyable":true ,"value":2 ,"owner":[],update:0,"name":"BAR 1-1"},
{"_id":2 ,"type":"bar" ,"buyable":true ,"value":2 ,"owner":[],update:0,"name":"BAR 1-2"},
{"_id":3 ,"type":"question" ,"buyable":false,"value":null ,"owner":[],update:0,"name":"Chance - Malchance"},
{"_id":4 ,"type":"bar" ,"buyable":true ,"value":4 ,"owner":[],update:0,"name":"BAR 3-1"},
{"_id":5 ,"type":"bar" ,"buyable":true ,"value":4 ,"owner":[],update:0,"name":"BAR 3-2"},
{"_id":6 ,"type":"bar" ,"buyable":true ,"value":4 ,"owner":[],update:0,"name":"BAR 3-3"},
{"_id":7 ,"type":"happy" ,"buyable":false,"value":null ,"owner":[],update:0,"name":"Happy Hour"},
{"_id":8 ,"type":"bar" ,"buyable":true ,"value":6 ,"owner":[],update:0,"name":"BAR 3-1"},
{"_id":9 ,"type":"bar" ,"buyable":true ,"value":6 ,"owner":[],update:0,"name":"BAR 3-2"},
{"_id":10,"type":"bar" ,"buyable":true ,"value":6 ,"owner":[],update:0,"name":"BAR 3-3"},
{"_id":11,"type":"prison" ,"buyable":false,"value":null ,"owner":[],update:0,"name":"Cellule de Dégrissement"},
{"_id":12,"type":"bar" ,"buyable":true ,"value":8 ,"owner":[],update:0,"name":"BAR 4-1"},
{"_id":13,"type":"bar" ,"buyable":true ,"value":8 ,"owner":[],update:0,"name":"BAR 4-2"},
{"_id":14,"type":"bar" ,"buyable":true ,"value":8 ,"owner":[],update:0,"name":"BAR 4-3"},
{"_id":15,"type":"happy" ,"buyable":false,"value":null ,"owner":[],update:0,"name":"Happy Hour"},
{"_id":16,"type":"bar" ,"buyable":true ,"value":10 ,"owner":[],update:0,"name":"BAR 5-1"},
{"_id":17,"type":"bar" ,"buyable":true ,"value":10 ,"owner":[],update:0,"name":"BAR 5-2"},
{"_id":18,"type":"bar" ,"buyable":true ,"value":10 ,"owner":[],update:0,"name":"BAR 5-3"},
{"_id":19,"type":"question" ,"buyable":false,"value":null ,"owner":[],update:0,"name":"Chance - Malchance"},
{"_id":20,"type":"bar" ,"buyable":true ,"value":12 ,"owner":[],update:0,"name":"BAR 6-1"},
{"_id":21,"type":"bar" ,"buyable":true ,"value":12 ,"owner":[],update:0,"name":"BAR 6-2"},
];
let score=[];
players.forEach(async(player) => {
score.push({"_id":player._id,"money":100,"plateauid":0});
});
party.score=score;
let dices=[
{"id":1,"value":""},
{"id":2,"value":""},
];
party.dices=dices;
}
let data = {
params,
party,
players,
player,
};
Edge.Client.send({ [party._id]: data });
// Return data
return data;
}

View File

@@ -0,0 +1,355 @@
<script>
import Dice from '$lib/Dice.svelte';
import { goto } from '$app/navigation';
import { enableBodyScroll, disableBodyScroll } from 'body-scroll-lock';
import { sortable } from 'svelte-agnostic-draggable' ;
import mapTouchToMouseFor from 'svelte-touch-to-mouse';
export let data;
// Si aucune party en cours retour home
let my;
if(!data.party)
goto("/");
else {
my=data.player;
}
// % de taille des colonne de resultat =
// type de dés = 2
// nombre de jour
// +1 taille pour la colonne du joueur
let colwidth=(data.players.length+3)/100;
let dice1;
let dice2;
let dice3;
let dice4;
let dice5;
let results=[];
Edge.Client.addEventListener("message", function(evt) {
if(evt.detail.hasOwnProperty(data.party._id)) {
console.log("RECEPTION MESSAGE");
data=evt.detail[data.party._id];
// Le propriétaire kill la partie
if(data.party.status=="partykill") {
my.partyid=null;
Edge.Client.rpc("upsertPlayer",my);
Edge.Client.rpc("deleteParty", data.party._id).catch(err => console.error(err));
Edge.Client.send({ "cmd": "REFRESH"});
goto("/");
}
// Le joueur est-il tjr dans le game
let ingame=false;
data.players.forEach(async(player) => {
if(player._id===my._id) ingame=true;
});
if(!ingame) {
window.location.href = '/';
}
// Action retour
if(my._id===data.party.playercurrent._id) {
console.log("here");
switch (data.party.playerstatus) {
case "":
break;
case "diceroll":
data.party.playerdice+=data.party.dices[0].value+data.party.dices[1].value;
// si resulat > 0 et non double = on passe à l'étape suivant sinon on peut rejeter
if(data.party.playerdice&&data.party.dices[0].value!=data.party.dices[1].value)
data.party.playerstatus="move";
else
data.party.playerstatus="dice";
sendMessage("DICEROLL to "+data.party.playerstatus);
break;
}
}
console.log(data);
}
});
function sendMessage(log) {
console.log(log);
Edge.Client.rpc("upsertParty", data.party).catch(err => console.error(err));
Edge.Client.send({ [data.party._id]: data });
}
async function partyplay() {
data.party.status="partyplay";
data.party.playercurrent=data.players[0];
sendMessage("START PARTY");
Edge.Client.send({ "cmd": "REFRESH"});
}
function diceresult(event) {
data.party.dices.forEach(async (dice,id) => {
if(dice.id===event.detail.id) {
data.party.dices[id].value=event.detail.value;
}
});
sendMessage("RESULT ROLL");
}
async function roll() {
await data.party.dices.forEach(async (dice) => {
if(!dice.selected||data.party.round==0) {
switch (dice.id) {
case 1: await dice1.roll(); break;
case 2: await dice2.roll(); break;
case 3: await dice3.roll(); break;
case 4: await dice4.roll(); break;
case 5: await dice5.roll(); break;
}
}
});
data.party.playerstatus="diceroll";
sendMessage("NEXT ROLL");
window.scrollTo(0, 0);
}
function playernext() {
// Rechercher le player suivant
let nextplayer=0;
data.players.forEach(async (player,i) => {
if(player._id===data.party.playercurrent._id) {
if(data.players.hasOwnProperty(i+1))
nextplayer=i+1;
else
nextplayer=0;
}
});
// Passer sur le player suivant
data.party.playercurrent=data.players[nextplayer];
// Reint des dices
var dices=[
{"id":1,"value":""},
{"id":2,"value":""}
];
data.party.dices=dices;
// Reinit du score du dice
data.party.playerdice=0;
// Reinit du statut du player
data.party.playerstatus="dice"
sendMessage("NEXT PLAYER");
window.scrollTo(0, 0);
}
async function partysave() {
let myresult=0;
results.forEach(async (result) => {
if(result.player._id===my._id) myresult=result.value;
});
my.nbparty=(my.nbparty?my.nbparty:0)+1;
my.scorecumul=(my.scorecumul?my.scorecumul:0)+myresult;
my.scoremax=(my.scoremax?my.scorecumul:0);
my.scoremax=(my.scoremax<myresult?myresult:my.scoremax);
my.partyid=null;
await Edge.Client.rpc("upsertPlayer", my).catch(err => console.error(err));
goto("/");
}
async function playerkill(id) {
if (window.confirm("Voulez-vous êtes sure de vous ?")) {
// On supprime son resultat
// Si le player courrant et celui killé on passe au suivant
if(data.party.playercurrent._id==id) {
// Rechercher le player suivant
let nextplayer=0;
data.players.forEach(async (player,i) => {
if(player._id===data.party.playercurrent._id) {
if(data.players.hasOwnProperty(i+1))
nextplayer=i+1;
else
nextplayer=0;
}
});
// Passer sur le player suivant
data.party.playercurrent=data.players[nextplayer];
// Reint les dices et round et diceresultchoiced
var dices=[
{"id":1,"value":"","selected":false,"order":1},
{"id":2,"value":"","selected":false,"order":2},
{"id":3,"value":"","selected":false,"order":3},
{"id":4,"value":"","selected":false,"order":4},
{"id":5,"value":"","selected":false,"order":5}
];
data.party.round=0;
data.party.dices=dices;
data.party.diceresultchoiced=false;
}
// On supprime le player de la liste des players et on lui enlève la partie courrante
data.players.forEach(async (player,i) => {
if(player._id===id) {
player.partyid=null;
Edge.Client.rpc("upsertPlayer",player);
data.players.splice(i,1);
}
});
// Si la partie est wait on libère une place
if(data.party.status=="playerwait") {
data.party.playernb-=1;
Edge.Client.rpc("upsertParty",data.party);
Edge.Client.send({ "cmd": "REFRESH"});
}
sendMessage("KILL PLAYER");
}
}
async function partykill() {
if (window.confirm("Voulez-vous vraiment supprimer la partie ?")) {
data.party.status="partykill";
sendMessage("KILL PARTY");
}
}
</script>
{#if data.party }
<div class="sticky bg-white dark:bg-gray-900 pt-3" style="top:65px">
<!-- LISTE DES JOUEURS -->
<div class="flex wrap mb-3 items-center justify-center">
{#each data.players as player}
{#if player._id===data.party.playercurrent._id && data.party.status!="partyend"}
<div class="flex flex-col p-1 w-20 h-20 md:w-28 md:h-28 items-center justify-center bg-lime-500 mx-1 text-black">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="hidden md:block w-10 h-10 text-cyan-950">
<path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<span class="text-xs text-center">Joueur<br><span class="{(player._id==my._id?"text-3xl":"")}">{(player._id==my._id?"MOI":player.name)}</span></span>
{#if my._id===data.party.playerid && my._id!==player._id}
<button on:click={playerkill(player._id)}>sortir</button>
{/if}
</div>
{:else}
<div class="flex flex-col p-1 w-20 h-20 md:w-28 md:h-28 items-center justify-center bg-gray-200 mx-1 text-black">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="hidden md:block w-10 h-10">
<path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<span class="text-xs text-center">Joueur<br><span class="{(player._id==my._id?"text-3xl":"")}">{(player._id==my._id?"MOI":player.name)}</span></span>
{#if my._id===data.party.playerid && my._id!==player._id}
<button on:click={playerkill(player._id)}>sortir</button>
{/if}
</div>
{/if}
{/each}
</div>
<!-- PARTIE EN ATTENTE -->
{#if data.party.status==="playerwait"}
<div class="text-center">
en attente de joueurs<br>
<span class="text-3xl">{data.party.playernb} sur {data.party.playernbmax}</span>
{#if my._id===data.party.playerid }
<button class="w-full bg-lime-500 hover:bg-lime-400 mt-3 text-black text-3xl p-3" on:click={partyplay}>
Démarrer la Partie
</button>
<button class="w-full bg-red-500 hover:bg-red-400 mt-3 text-black text-3xl p-3" on:click={partykill}>
Supprimer la Partie
</button>
{/if}
</div>
<!-- FIN DE PARTIE -->
{:else if data.party.status==="partyend"}
<div class="text-center">
FIN de PARTIE
<button class="w-full bg-lime-500 hover:bg-lime-400 mt-3 text-black md:text-3xl p-3" on:click={partysave}>
Enregistrer mon score et sortir
</button>
</div>
<!-- ACTION DU JEU -->
{:else if data.party.playercurrent._id===my._id}
<div class="md:text-3xl text-center">
MON TOUR
</div>
<div class="mt-3">
{#if data.party.playerstatus=="dice"}
<button class="w-full bg-lime-500 hover:bg-lime-400 text-2xl md:text-3xl mb-3 text-black" on:click={roll}>
<div>Jetter les dés</div>
</button>
{:else}
<button class="w-full bg-lime-500 hover:bg-lime-400 md:text-3xl mb-3 text-black p-3" on:click={playernext}>
Prochain Joueur
</button>
{/if}
</div>
{:else}
<div class="md:text-3xl text-center">TOUR du Joueur = {data.party.playercurrent.name}</div>
{/if}
</div>
<!-- DICE -->
{#if data.party.status==="partyplay"}
{#if data.party.playercurrent._id===my._id}
<div class="flex flex-wrap">
<div class="w-1/2 flex flex-wrap mb-3 my-auto">
<div use:sortable={{cursor:'grabbing', zIndex:100}} class="w-full flex flex-wrap p-1 bg-lime-500 items-center justify-center rounded-lg border-8 border-black">
{#each data.party.dices as mydice}
{#if mydice.id === 1}
<Dice bind:this={dice1} {...mydice} on:diceresult={diceresult} />
{:else if mydice.id === 2}
<Dice bind:this={dice2} {...mydice} on:diceresult={diceresult} />
{/if}
{/each}
</div>
</div>
</div>
{:else}
<div class="flex flex-wrap">
<div class="w-full md:w-1/2 flex flex-wrap mb-3 md:pr-3">
<div class="w-full flex flex-wrap p-1 md:p-5 bg-lime-500 items-center justify-center rounded-lg border-8 border-black">
{#each data.party.dices as mydice}
{#if !mydice.selected}
<span class="cursor-pointer text-3xl flex justify-center items-center bg-red-600 text-white rounded-lg m-1 w-14 h-14 md:m-3 md:w-20 md:h-20">
{mydice.value}
</span>
{/if}
{/each}
</div>
</div>
</div>
{/if}
{/if}
<!-- KILL -->
{#if data.party.status==="partyplay" && my._id===data.party.playerid }
<button class="w-full bg-red-500 hover:bg-red-400 mt-3 text-black md:text-3xl p-1 md:p-3" on:click={partykill}>
Supprimer la Partie
</button>
{/if}
<!-- SORTIR -->
{#if my._id!==data.party.playerid }
<button class="w-full bg-red-500 hover:bg-red-400 mt-3 text-black md:text-3xl p-1 md:p-3" on:click={playerkill(my._id)}>
Quitter la Partie
</button>
{/if}
{/if}

17
src/routes/party/+page.js Normal file
View File

@@ -0,0 +1,17 @@
export async function load({ params }) {
let authid=await Edge.Client.rpc("getAuthid");
let authpseudo=await Edge.Client.rpc("getAuthpseudo");
let authisuser=await Edge.Client.rpc("getAuthisuser");
let player=await Edge.Client.rpc("initPlayer",{"_id":authid,"name":authpseudo,"isuser":(authisuser!="anon")});
let partys = await Edge.Client.rpc("getPartyswait").catch(err => console.error(err));
// Return data
return {
params,
partys,
player,
};
}

View File

@@ -0,0 +1,55 @@
<script>
export let data;
Edge.Client.addEventListener("message", function(evt) {
if(evt.detail.hasOwnProperty("cmd")) {
console.log(evt.detail.cmd);
if(evt.detail.cmd=="REFRESH") {
location.reload();
}
}
});
</script>
<div data-dial-init class="btn-dial">
<a class="btn-add" href="/party/submit" data-tooltip-target="tooltip-share" data-tooltip-placement="left">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
</svg>
<span>Ajouter</span>
</a>
</div>
<h1 class="text-center">La Rue de la Soif</h1>
<img class="w-20 md:w-28 block m-auto mb-2" src="./medias/logo/logo.png" alt="logo"/>
<div class="tablecontainer mt-3">
<table>
<thead>
<tr>
<th>Liste des parties en attente de joueurs</th>
</tr>
</thead>
<tbody>
{#each data.partys as party}
<tr>
<td>
<a href="/party/{party._id}">
{party.name}
</a>
</td>
</tr>
{/each}
</tbody>
</table>
</div>
<div class="mt-5 text-xs">
Mon meilleur score = {(data.player.scoremax?data.player.scoremax:0)}<br>
Nombre de parties = {(data.player.nbparty?data.player.nbparty:0)}<br>
Score moyen = {(data.player.nbparty&&data.player.scorecumul?(data.player.scorecumul/data.player.nbparty):0)}<br>
</div>

View File

@@ -0,0 +1,33 @@
export async function load({ params }) {
let authid=await Edge.Client.rpc("getAuthid");
let authpseudo=await Edge.Client.rpc("getAuthpseudo");
let authisuser=await Edge.Client.rpc("getAuthisuser");
let player=await Edge.Client.rpc("initPlayer",{"_id":authid,"name":authpseudo,"isuser":(authisuser!="anon")});
// Déclaration party
let party = {
"name": "Partie de "+player.name,
"playerid": player._id,
"playernb":0,
"playernbmax": 3,
"status": "playerwait",
"playercurrent": player,
"playerstatus": "dice",
"playerdice": null,
};
let partyplayer=player;
if(params.id!=="submit") {
party= await Edge.Client.rpc("getParty",params.id).catch(err => console.error(err));
partyplayer=await Edge.Client.rpc("getPlayer",party.playerid).catch(err => console.error(err));
}
// Return data
return {
params,
party,
player,
partyplayer,
};
}

View File

@@ -0,0 +1,87 @@
<script>
import { page } from '$app/stores';
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
// Data
export let data;
// Focus
let partyname;
onMount(() => {
if(data.party.status!="playerwait") goto("/party")
});
Edge.Client.addEventListener("message", function(evt) {
if(evt.detail.hasOwnProperty("cmd")) {
console.log(evt.detail.cmd);
if(evt.detail.cmd=="REFRESH") {
location.reload();
}
}
});
// Upsert
async function upsert(event) {
// Affecter la party au player submiter
if(data.params.id==='submit')
data.party.playerid=data.player._id;
// Ajouter un player à la party
data.party.playernb=data.party.playernb+1;
// Si playernb ne depasse pas playernbmax = on affecte le jour à la party
if(data.party.playernb<=data.party.playernbmax&&data.party.status==="playerwait") {
data.party.status="playerwait";
// Submit de la party
let party=await Edge.Client.rpc("upsertParty", data.party).catch(err => console.error(err));
// On affecte la party au player submiter
data.player.partyid=party._id;
await Edge.Client.rpc("upsertPlayer", data.player).catch(err => console.error(err));
}
// refresh des party
Edge.Client.send({ "cmd": "REFRESH" });
// Goto game
goto("/game");
}
</script>
{#if $page.params.id==='submit'}
<h1>Création Partie</h1>
{:else}
<h1>Rejoindre une Partie</h1>
{/if}
<form on:submit|preventDefault={upsert} method="POST">
<div class="form-action">
{#if $page.params.id==='submit'}
<button type="submit" class="btn-submit">Valider</button>
{:else}
<button type="submit" class="btn-submit">Rejoindre la partie</button>
{/if}
<a href="/party" class="btn btn-cancel">Annuler</a>
</div>
{#if $page.params.id==='submit'}
<label class="required" for="partyname">Titre</label><br>
<input id="partyname" name="partyname" required type="text" bind:value={data.party.name} bind:this={partyname}>
<label class="required" for="playernbmax">Nombre de joueur maximum</label><br>
<input id="playernbmax" name="playernbmax" required type="number" bind:value={data.party.playernbmax}>
{:else}
Titre = {data.party.name}<br>
Créateur de la Partie = {data.partyplayer.name}<br>
Nombre de Jouers = {data.party.playernb} sur {data.party.playernbmax}<br>
{/if}
</form>