merged
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
import Header from '../../pieces/Header.svelte';
|
||||
import { fade, fly } from 'svelte/transition';
|
||||
|
||||
|
||||
import Header from '../../pieces/Header.svelte';
|
||||
import { fetchAvatar } from "../../pieces/utils";
|
||||
|
||||
import * as pong from "./client/pong";
|
||||
import { gameState } from "./client/ws";
|
||||
@@ -12,6 +13,9 @@
|
||||
let user;
|
||||
let allUsers;
|
||||
|
||||
let playerOneAvatar;
|
||||
let playerTwoAvatar;
|
||||
|
||||
//Game's stuff
|
||||
const options = new pong.InitOptions();
|
||||
const gameAreaId = "game_area";
|
||||
@@ -26,9 +30,10 @@
|
||||
let showWaitPage = false;
|
||||
|
||||
let invitations = [];
|
||||
|
||||
let watchGameStateInterval;
|
||||
const watchGameStateIntervalRate = 142;
|
||||
let watchMatchStartInterval;
|
||||
const watchMatchStartIntervalRate = 111;
|
||||
|
||||
onMount( async() => {
|
||||
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
|
||||
@@ -39,6 +44,7 @@
|
||||
})
|
||||
|
||||
onDestroy( async() => {
|
||||
clearInterval(watchMatchStartInterval);
|
||||
clearInterval(watchGameStateInterval);
|
||||
pong.destroy();
|
||||
})
|
||||
@@ -76,6 +82,7 @@
|
||||
showWaitPage = false;
|
||||
if (response.ok && token)
|
||||
{
|
||||
watchMatchStartInterval = setInterval(watchMatchStart, watchMatchStartIntervalRate);
|
||||
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
|
||||
pong.init(matchOptions, options, gameAreaId, token);
|
||||
hiddenGame = false;
|
||||
@@ -106,6 +113,7 @@
|
||||
console.log(invitation);
|
||||
if (invitation.token)
|
||||
{
|
||||
watchMatchStartInterval = setInterval(watchMatchStart, watchMatchStartIntervalRate);
|
||||
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
|
||||
options.playerOneUsername = invitation.playerOneUsername;
|
||||
options.playerTwoUsername = invitation.playerTwoUsername;
|
||||
@@ -117,16 +125,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function watchMatchStart()
|
||||
{
|
||||
if (gameState.matchStarted)
|
||||
{
|
||||
clearInterval(watchMatchStartInterval);
|
||||
playerOneAvatar = await fetchAvatar(gameState.playerOneUsername);
|
||||
playerTwoAvatar = await fetchAvatar(gameState.playerTwoUsername);
|
||||
gameState.matchStarted = gameState.matchStarted; // trigger Svelte reactivity
|
||||
}
|
||||
}
|
||||
|
||||
const watchGameState = () => {
|
||||
console.log("watchGameState");
|
||||
if (gameState) { // trigger Svelte reactivity
|
||||
gameState.matchStarted = gameState.matchStarted;
|
||||
gameState.matchEnded = gameState.matchEnded;
|
||||
gameState.matchAborted = gameState.matchAborted;
|
||||
}
|
||||
if (gameState.matchAborted || gameState.matchEnded)
|
||||
{
|
||||
clearInterval(watchGameStateInterval);
|
||||
gameState.matchEnded = gameState.matchEnded; // trigger Svelte reactivity
|
||||
gameState.matchAborted = gameState.matchAborted; // trigger Svelte reactivity
|
||||
console.log("watchGameState, end");
|
||||
setTimeout(() => {
|
||||
resetPage();
|
||||
@@ -176,6 +192,7 @@
|
||||
}
|
||||
|
||||
function leaveMatch() {
|
||||
clearInterval(watchMatchStartInterval);
|
||||
clearInterval(watchGameStateInterval);
|
||||
resetPage();
|
||||
};
|
||||
@@ -213,6 +230,14 @@
|
||||
</div>
|
||||
|
||||
{#if !hiddenGame}
|
||||
{#if gameState.matchStarted}
|
||||
<div class="div_game">
|
||||
<img class="avatar" src="{playerOneAvatar}" alt="player one avatar">
|
||||
'{gameState.playerOneUsername}' VS '{gameState.playerTwoUsername}'
|
||||
<img class="avatar" src="{playerTwoAvatar}" alt="player two avatar">
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if gameState.matchStarted && !gameState.matchEnded}
|
||||
<div class="div_game">
|
||||
<button class="pong_button" on:click={leaveMatch}>forfeit</button>
|
||||
@@ -356,5 +381,11 @@ canvas {
|
||||
font-size: x-large;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
min-height: 100px;
|
||||
min-width: 100px;
|
||||
|
||||
max-width: 100px;
|
||||
max-height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
import Header from '../../pieces/Header.svelte';
|
||||
import MatchListElem from "../../pieces/MatchListElem.svelte";
|
||||
import { fade, fly } from 'svelte/transition';
|
||||
|
||||
import Header from '../../pieces/Header.svelte';
|
||||
import MatchListElem from "../../pieces/MatchListElem.svelte";
|
||||
import type { Match } from "../../pieces/Match";
|
||||
import { fetchAvatar } from "../../pieces/utils";
|
||||
|
||||
import * as pongSpectator from "./client/pongSpectator";
|
||||
import { gameState } from "./client/ws";
|
||||
@@ -13,14 +15,17 @@
|
||||
let user;
|
||||
let allUsers;
|
||||
|
||||
//Game's stuff client side only
|
||||
let playerOneAvatar;
|
||||
let playerTwoAvatar;
|
||||
|
||||
//Game's stuff
|
||||
const gameAreaId = "game_area";
|
||||
let sound = "off";
|
||||
let matchList = [];
|
||||
|
||||
//html boolean for pages
|
||||
let hiddenGame = true;
|
||||
|
||||
let matchList: Match[] = [];
|
||||
let watchGameStateInterval;
|
||||
const watchGameStateIntervalRate = 142;
|
||||
|
||||
@@ -39,22 +44,27 @@
|
||||
pongSpectator.destroy();
|
||||
})
|
||||
|
||||
async function initGameSpectator(gameSessionId: string, matchOptions: pongSpectator.MatchOptions)
|
||||
async function initGameSpectator(match: Match)
|
||||
{
|
||||
watchGameStateInterval = setInterval(watchGameState, watchGameStateIntervalRate);
|
||||
pongSpectator.init(matchOptions, sound, gameAreaId, gameSessionId);
|
||||
pongSpectator.init(match.gameOptions, sound, gameAreaId, match.gameServerIdOfTheMatch);
|
||||
|
||||
// Users avatar
|
||||
gameState.playerOneUsername = match.playerOneUsername;
|
||||
gameState.playerTwoUsername = match.playerTwoUsername;
|
||||
playerOneAvatar = await fetchAvatar(gameState.playerOneUsername);
|
||||
playerTwoAvatar = await fetchAvatar(gameState.playerTwoUsername);
|
||||
|
||||
hiddenGame = false;
|
||||
};
|
||||
|
||||
const watchGameState = () => {
|
||||
console.log("watchGameState")
|
||||
if (gameState) { // trigger Svelte reactivity
|
||||
gameState.matchStarted = gameState.matchStarted;
|
||||
gameState.matchEnded = gameState.matchEnded;
|
||||
gameState.matchAborted = gameState.matchAborted;
|
||||
}
|
||||
// gameState.matchStarted = gameState.matchStarted; // trigger Svelte reactivity
|
||||
if (gameState.matchAborted || gameState.matchEnded)
|
||||
{
|
||||
gameState.matchEnded = gameState.matchEnded; // trigger Svelte reactivity
|
||||
gameState.matchAborted = gameState.matchAborted; // trigger Svelte reactivity
|
||||
clearInterval(watchGameStateInterval);
|
||||
console.log("watchGameState, end")
|
||||
setTimeout(() => {
|
||||
@@ -80,7 +90,6 @@
|
||||
.then( x => x.json() );
|
||||
};
|
||||
|
||||
|
||||
</script>
|
||||
<!-- -->
|
||||
|
||||
@@ -102,6 +111,12 @@
|
||||
</div>
|
||||
|
||||
{#if !hiddenGame}
|
||||
<div class="div_game">
|
||||
<img class="avatar" src="{playerOneAvatar}" alt="player one avatar">
|
||||
'{gameState.playerOneUsername}' VS '{gameState.playerTwoUsername}'
|
||||
<img class="avatar" src="{playerTwoAvatar}" alt="player two avatar">
|
||||
</div>
|
||||
|
||||
{#if !gameState.matchEnded}
|
||||
<div class="div_game">
|
||||
<button class="pong_button" on:click={leaveMatch}>leave</button>
|
||||
@@ -127,7 +142,7 @@
|
||||
{#if matchList.length !== 0}
|
||||
<menu id="match_list">
|
||||
{#each matchList as match}
|
||||
<MatchListElem match={match} on:click={(e) => initGameSpectator(match.gameServerIdOfTheMatch, match.gameOptions)} />
|
||||
<MatchListElem match={match} on:click={(e) => initGameSpectator(match)} />
|
||||
{/each}
|
||||
</menu>
|
||||
{:else}
|
||||
@@ -195,10 +210,15 @@ canvas {
|
||||
font-size: x-large;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#match_list {
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
min-height: 100px;
|
||||
min-width: 100px;
|
||||
|
||||
max-width: 100px;
|
||||
max-height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as c from "./constants.js"
|
||||
import * as en from "../shared_js/enums.js"
|
||||
import { GameArea } from "./class/GameArea.js";
|
||||
import { GameComponentsClient } from "./class/GameComponentsClient.js";
|
||||
import { socket, resetGameState } from "./ws.js";
|
||||
import { socket, gameState } from "./ws.js";
|
||||
import { initAudio } from "./audio.js";
|
||||
import type { InitOptions } from "./class/InitOptions.js";
|
||||
|
||||
@@ -57,5 +57,5 @@ export function destroyBase()
|
||||
}
|
||||
setGc(null);
|
||||
setMatchOptions(null);
|
||||
resetGameState();
|
||||
gameState.resetGameState();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import { initBase, destroyBase, computeMatchOptions } from "./init.js";
|
||||
export { computeMatchOptions } from "./init.js";
|
||||
export { MatchOptions } from "../shared_js/enums.js"
|
||||
|
||||
/* TODO: A way to delay the init of variables, but still use "const" not "let" ? */
|
||||
import { pong, gc } from "./global.js"
|
||||
import { setStartFunction } from "./global.js"
|
||||
|
||||
|
||||
@@ -10,16 +10,22 @@ import { muteFlag, soundRoblox } from "./audio.js"
|
||||
import { sleep } from "./utils.js";
|
||||
import { Vector, VectorInteger } from "../shared_js/class/Vector.js";
|
||||
|
||||
export const gameState = {
|
||||
matchStarted: false,
|
||||
matchEnded: false,
|
||||
matchAborted: false
|
||||
}
|
||||
|
||||
export function resetGameState() {
|
||||
gameState.matchStarted = false;
|
||||
gameState.matchEnded = false;
|
||||
gameState.matchAborted = false;
|
||||
class GameState {
|
||||
matchStarted: boolean;
|
||||
matchEnded: boolean;
|
||||
matchAborted: boolean;
|
||||
playerOneUsername: string;
|
||||
playerTwoUsername: string;
|
||||
constructor() {
|
||||
this.resetGameState();
|
||||
}
|
||||
resetGameState() {
|
||||
this.matchStarted = false;
|
||||
this.matchEnded = false;
|
||||
this.matchAborted = false;
|
||||
this.playerOneUsername = "";
|
||||
this.playerTwoUsername = "";
|
||||
}
|
||||
}
|
||||
|
||||
class ClientInfo {
|
||||
@@ -39,6 +45,7 @@ class ClientInfoSpectator {
|
||||
|
||||
const wsUrl = "ws://" + process.env.WEBSITE_HOST + ":" + process.env.WEBSITE_PORT + "/pong";
|
||||
export let socket: WebSocket;
|
||||
export const gameState = new GameState();
|
||||
export const clientInfo = new ClientInfo();
|
||||
export const clientInfoSpectator = new ClientInfoSpectator(); // WIP, could refactor this
|
||||
|
||||
@@ -85,6 +92,8 @@ function preMatchListener(this: WebSocket, event: MessageEvent)
|
||||
break;
|
||||
case en.EventTypes.matchmakingComplete:
|
||||
clientInfo.side = (<ev.EventMatchmakingComplete>data).side;
|
||||
gameState.playerOneUsername = (<ev.EventMatchmakingComplete>data).playerOneUsername;
|
||||
gameState.playerTwoUsername = (<ev.EventMatchmakingComplete>data).playerTwoUsername;
|
||||
if (clientInfo.side === en.PlayerSide.left)
|
||||
{
|
||||
clientInfo.racket = gc.playerLeft;
|
||||
|
||||
@@ -18,10 +18,13 @@ export class EventAssignId extends ServerEvent {
|
||||
}
|
||||
|
||||
export class EventMatchmakingComplete extends ServerEvent {
|
||||
side: en.PlayerSide;
|
||||
constructor(side: en.PlayerSide) {
|
||||
side: en.PlayerSide = en.PlayerSide.noSide;
|
||||
playerOneUsername: string;
|
||||
playerTwoUsername: string;
|
||||
constructor(playerOneUsername: string, playerTwoUsername: string) {
|
||||
super(en.EventTypes.matchmakingComplete);
|
||||
this.side = side;
|
||||
this.playerOneUsername = playerOneUsername;
|
||||
this.playerTwoUsername = playerTwoUsername;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
<div class="outer">
|
||||
{#if user !== undefined}
|
||||
<GenerateUserDisplay user={user} primary={true}/>
|
||||
<GenerateUserDisplay user={user}/>
|
||||
<button on:click={() => (push('/profile/settings'))}>Profile Settings</button>
|
||||
{:else}
|
||||
<h2>Sorry</h2>
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
import Card from '../../pieces/Card.svelte';
|
||||
import {onMount} from 'svelte';
|
||||
import { push } from 'svelte-spa-router';
|
||||
|
||||
|
||||
import Button from '../../pieces/Button.svelte';
|
||||
import { fetchAvatar } from "../../pieces/utils";
|
||||
|
||||
let user;
|
||||
let avatar, newAvatar;
|
||||
@@ -16,40 +17,21 @@
|
||||
const errors = { username: '', checkbox: '', avatar: ''};
|
||||
let success = {username: '', avatar: '' };
|
||||
|
||||
onMount( async() => {
|
||||
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
|
||||
.then( (x) => x.json() );
|
||||
// do a .catch?
|
||||
onMount( async() => {
|
||||
user = await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user`)
|
||||
.then( (x) => x.json() );
|
||||
// do a .catch?
|
||||
|
||||
if (user === undefined) {
|
||||
console.log('User did not load, something more official should prolly happen')
|
||||
}
|
||||
// i don't unerstand why this is necessary but it really doesn't like it otherwise
|
||||
nameTmp = user.username;
|
||||
console.log(user.username)
|
||||
if (user === undefined) {
|
||||
console.log('User did not load, something more official should prolly happen')
|
||||
}
|
||||
// i don't unerstand why this is necessary but it really doesn't like it otherwise
|
||||
nameTmp = user.username;
|
||||
|
||||
set.tfa = user.isEnabledTwoFactorAuth;
|
||||
set.tfa = user.isEnabledTwoFactorAuth;
|
||||
|
||||
// tmp
|
||||
// console.log('this is what is in the avatar before fetch')
|
||||
// console.log(avatar)
|
||||
|
||||
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`, {method: "GET"})
|
||||
.then(response => {return response.blob()})
|
||||
.then(data => {
|
||||
const url = URL.createObjectURL(data);
|
||||
avatar = url;
|
||||
})
|
||||
.catch(() => errors.avatar = 'Sorry your avatar could not be loaded' );
|
||||
|
||||
// .then(() => errors.avatar = '' ) // unnecessary i think cuz in on mount...
|
||||
|
||||
// tmp
|
||||
// console.log('this is what is in the avatar')
|
||||
// console.log(avatar)
|
||||
// console.log('this is what is in the NEW Avatar')
|
||||
// console.log(newAvatar)
|
||||
})
|
||||
avatar = await fetchAvatar(user.username);
|
||||
})
|
||||
|
||||
const settingsHandler = async() => {
|
||||
// I don't really care which i use at this point...
|
||||
@@ -91,39 +73,33 @@
|
||||
// .then(() => console.log('successful sub of new settings'))
|
||||
};
|
||||
|
||||
const uploadAvatar = async() => {
|
||||
errors.avatar = '';
|
||||
if (newAvatar === undefined) {
|
||||
errors.avatar = 'You need to pick a file.'
|
||||
return;
|
||||
}
|
||||
const data = new FormData();
|
||||
data.append("file", newAvatar[0]);
|
||||
const uploadAvatar = async() => {
|
||||
errors.avatar = '';
|
||||
if (newAvatar === undefined) {
|
||||
errors.avatar = 'You need to pick a file.'
|
||||
return;
|
||||
}
|
||||
const data = new FormData();
|
||||
data.append("file", newAvatar[0]);
|
||||
|
||||
// tmp
|
||||
console.log(data);
|
||||
// tmp
|
||||
console.log(data);
|
||||
|
||||
const responseWhenChangeAvatar = fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`,
|
||||
{
|
||||
method : 'POST',
|
||||
body : data,
|
||||
})
|
||||
const responseFromServer = await responseWhenChangeAvatar;
|
||||
if (responseFromServer.ok === true) {
|
||||
uploadAvatarSuccess = true;
|
||||
success.avatar = 'Your avatar has been updated';
|
||||
}
|
||||
else {
|
||||
errors.avatar = responseFromServer.statusText;
|
||||
}
|
||||
|
||||
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`, {method: "GET"})
|
||||
.then(response => {return response.blob()})
|
||||
.then(data => {
|
||||
const url = URL.createObjectURL(data);
|
||||
avatar = url;
|
||||
const responseWhenChangeAvatar = fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`,
|
||||
{
|
||||
method : 'POST',
|
||||
body : data,
|
||||
})
|
||||
.catch(() => errors.avatar = 'Sorry your avatar could not be loaded' );
|
||||
const responseFromServer = await responseWhenChangeAvatar;
|
||||
if (responseFromServer.ok === true) {
|
||||
uploadAvatarSuccess = true;
|
||||
success.avatar = 'Your avatar has been updated';
|
||||
}
|
||||
else {
|
||||
errors.avatar = responseFromServer.statusText;
|
||||
}
|
||||
|
||||
avatar = await fetchAvatar(user.username);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -39,8 +39,7 @@
|
||||
|
||||
|
||||
{#if user !== undefined}
|
||||
<GenerateUserDisplay user={user} primary={false}/>
|
||||
<!-- <GenerateUserDisplay user={user} primary={true}/> -->
|
||||
<GenerateUserDisplay user={user}/>
|
||||
{:else}
|
||||
<h2>Sorry</h2>
|
||||
<div>Failed to load user {aUsername}</div>
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import { fetchAvatar } from "./utils";
|
||||
|
||||
export let user;
|
||||
export let primary; // kinda useless, not sure what i was going for... Might be userful after all
|
||||
let rank = '';
|
||||
let avatar;
|
||||
// avatar needs to be updated!!!
|
||||
@@ -12,28 +12,10 @@
|
||||
// add errors
|
||||
let errors = {avatar: ''};
|
||||
|
||||
onMount( async() => {
|
||||
// console.log('Generate User Display, on mount ' + user.username)
|
||||
if (primary) {
|
||||
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar`, {method: "GET"})
|
||||
.then(response => {return response.blob()})
|
||||
.then(data => {
|
||||
const url = URL.createObjectURL(data);
|
||||
avatar = url;
|
||||
})
|
||||
.catch(() => errors.avatar = 'Sorry your avatar could not be loaded' );
|
||||
// console.log('avatar: ')
|
||||
// console.log(avatar)
|
||||
} else {
|
||||
await fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar?username=${user.username}`, {method: "GET"})
|
||||
.then(response => {return response.blob()})
|
||||
.then(data => {
|
||||
const url = URL.createObjectURL(data);
|
||||
avatar = url;
|
||||
})
|
||||
.catch(() => errors.avatar = 'Sorry your avatar could not be loaded' );
|
||||
}
|
||||
})
|
||||
onMount( async() => {
|
||||
// console.log('Generate User Display, on mount ' + user.username)
|
||||
avatar = await fetchAvatar(user.username);
|
||||
})
|
||||
|
||||
|
||||
/**** THIS IS BASICALLY ALL THE RANK LOGIC ERIC HAS MADE ****/
|
||||
|
||||
10
srcs/requirements/svelte/api_front/src/pieces/Match.ts
Normal file
10
srcs/requirements/svelte/api_front/src/pieces/Match.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
import type { MatchOptions } from "../pages/game/client/pongSpectator";
|
||||
export { MatchOptions } from "../pages/game/client/pongSpectator";
|
||||
|
||||
export class Match {
|
||||
gameServerIdOfTheMatch: string;
|
||||
gameOptions: MatchOptions;
|
||||
playerOneUsername: string;
|
||||
playerTwoUsername: string;
|
||||
}
|
||||
@@ -1,14 +1,9 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from "svelte";
|
||||
import { MatchOptions } from "../pages/game/client/pongSpectator";
|
||||
import { Match, MatchOptions} from "./Match";
|
||||
|
||||
export let match: {
|
||||
gameServerIdOfTheMatch: string,
|
||||
gameOptions: MatchOptions,
|
||||
playerOneUsername: string,
|
||||
playerTwoUsername: string
|
||||
};
|
||||
export let match: Match;
|
||||
|
||||
let matchOptionsString = "";
|
||||
|
||||
@@ -32,7 +27,7 @@
|
||||
|
||||
<li>
|
||||
<button on:click>
|
||||
"{match.playerOneUsername}" VS "{match.playerTwoUsername}"
|
||||
'{match.playerOneUsername}' VS '{match.playerTwoUsername}'
|
||||
<br/> [{matchOptionsString}]
|
||||
</button>
|
||||
</li>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
export interface Room
|
||||
{
|
||||
name: string;
|
||||
type: "public" | "protected" | "private" | "direct" | "user";
|
||||
users?: string[];
|
||||
}
|
||||
@@ -1,12 +1,23 @@
|
||||
<script lang="ts">
|
||||
|
||||
import { msgs, layout } from './Store_chat';
|
||||
import { msgs, layout, allowed_chars } from './Store_chat';
|
||||
import { change_room, create_room } from './Request_rooms';
|
||||
import { onMount } from 'svelte';
|
||||
import Button from './Element_button.svelte';
|
||||
import Warning from './Element_warning.svelte';
|
||||
|
||||
export let back = "";
|
||||
|
||||
let allowed_chars = 'loading...';
|
||||
//let regex;
|
||||
onMount(async() => {
|
||||
let response = await fetch('/api/v2/chat/allowedchars');
|
||||
let data = await response.json();
|
||||
console.log("data:", data);
|
||||
allowed_chars = data.chars;
|
||||
//regex = new RegExp(`^[a-zA-Z0-9\\s${allowed_chars}]+$`);
|
||||
});
|
||||
|
||||
let room_name: string;
|
||||
let room_type: string;
|
||||
let room_password: string;
|
||||
@@ -22,12 +33,16 @@
|
||||
if (!formIsValid)
|
||||
return;
|
||||
|
||||
let room = {
|
||||
name: room_name,
|
||||
type: room_type,
|
||||
};
|
||||
// send the new room
|
||||
response = await create_room(room_name, room_type);
|
||||
response = await create_room(room);
|
||||
|
||||
// go to room
|
||||
if (response.status === 200)
|
||||
await change_room(room_name);
|
||||
await change_room(response.room);
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -57,7 +72,10 @@
|
||||
{/if}
|
||||
<!-- name: -->
|
||||
<label for="chat_name"><p>new room name :</p></label>
|
||||
<input id="chat_name" bind:value={room_name} name="room_name" required>
|
||||
<!--
|
||||
<input id="chat_name" bind:value={room_name} name="room_name" placeholder="allowed special characters: {allowed_chars}" pattern={regex} required>
|
||||
-->
|
||||
<input id="chat_name" bind:value={room_name} name="room_name" placeholder="allowed special characters: {allowed_chars}" required>
|
||||
<!-- [ ] pubic -->
|
||||
<label for="chat_public" class="_radio">
|
||||
<p>public</p>
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
<script>
|
||||
|
||||
import { layout, msgs, user } from './Store_chat';
|
||||
import { change_room, get_room_messages, get_all_rooms } from './Request_rooms';
|
||||
import { change_room, get_room_messages, get_my_rooms } from './Request_rooms';
|
||||
import { onMount } from 'svelte';
|
||||
import Button from './Element_button.svelte';
|
||||
|
||||
let rooms = get_all_rooms();
|
||||
let rooms = get_my_rooms();
|
||||
|
||||
// go to clicked room
|
||||
async function go_to_room(evt)
|
||||
async function go_to_room(room)
|
||||
{
|
||||
console.log("inside go_to_room");
|
||||
await change_room(evt.target.innerText);
|
||||
|
||||
console.log("room:", room);
|
||||
await change_room(room);
|
||||
await get_room_messages();
|
||||
}
|
||||
|
||||
@@ -42,11 +44,10 @@
|
||||
<p class="__center">/ you have no chat room yet /</p>
|
||||
</div>
|
||||
{#await rooms}
|
||||
<!-- promise is pending -->
|
||||
<p>rooms are loaded...</p>
|
||||
<p>rooms are loading...</p>
|
||||
{:then rooms}
|
||||
{#each rooms as room}
|
||||
<Button my_class="list" on_click={go_to_room}>
|
||||
<Button my_class="list" on_click={function() {go_to_room(room)}}>
|
||||
{room.name}
|
||||
</Button>
|
||||
{/each}
|
||||
|
||||
@@ -1,32 +1,22 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
|
||||
import { layout, msgs, user, socket } from './Store_chat';
|
||||
import { join_room, change_room, get_room_messages } from './Request_rooms';
|
||||
import { join_room, change_room, get_room_messages, get_all_rooms } from './Request_rooms';
|
||||
import Button from './Element_button.svelte';
|
||||
|
||||
export let back = "";
|
||||
|
||||
let rooms = [];
|
||||
|
||||
// ask api for the rooms
|
||||
const get_rooms = fetch('/api/v2/chat/allrooms')
|
||||
.then(resp => resp.json())
|
||||
.then(data =>
|
||||
{
|
||||
console.log("data.rooms:", data.rooms);
|
||||
for (let room of data.rooms)
|
||||
console.log(room.name);
|
||||
rooms = data.rooms;
|
||||
});
|
||||
let rooms = get_all_rooms();
|
||||
|
||||
// join the room
|
||||
async function join_rooms(evt)
|
||||
async function join_rooms(room)
|
||||
{
|
||||
console.log("inside join_room");
|
||||
let room_name = evt.target.innerText;
|
||||
|
||||
await join_room(room_name);
|
||||
await change_room(room_name);
|
||||
console.log("room:", room);
|
||||
const updated_room = await join_room(room);
|
||||
console.log("updated room:", updated_room);
|
||||
await change_room(updated_room);
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -58,12 +48,11 @@
|
||||
<div class="__show_if_only_child">
|
||||
<p class="__center">/ there are no public rooms yet /</p>
|
||||
</div>
|
||||
{#await get_rooms}
|
||||
<!-- promise is pending -->
|
||||
<p>rooms are loaded...</p>
|
||||
{:then}
|
||||
{#await rooms}
|
||||
<p>rooms are loading...</p>
|
||||
{:then rooms}
|
||||
{#each rooms as room}
|
||||
<Button my_class="list" on_click={join_rooms}>
|
||||
<Button my_class="list" on_click={function() {join_rooms(room)}}>
|
||||
{room.name}
|
||||
</Button>
|
||||
{/each}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script>
|
||||
|
||||
import { layout, socket, msgs, add_msg, room_name } from './Store_chat';
|
||||
import { layout, socket, msgs, add_msg, current_room_name } from './Store_chat';
|
||||
import Button from './Element_button.svelte';
|
||||
import Msg from './Element_msg.svelte';
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
<!-- room_name -->
|
||||
<Button new_layout="room_set" my_class="room_name transparent">
|
||||
{$room_name}
|
||||
{$current_room_name}
|
||||
</Button>
|
||||
|
||||
<!-- close -->
|
||||
|
||||
@@ -1,10 +1,25 @@
|
||||
<script>
|
||||
|
||||
import { layout } from './Store_chat';
|
||||
import { layout, current_room_name } from './Store_chat';
|
||||
import { get_room_users, user_leave_room } from './Request_rooms';
|
||||
import Button from './Element_button.svelte';
|
||||
|
||||
export let back = "";
|
||||
|
||||
let users = get_room_users();
|
||||
|
||||
function user_profile()
|
||||
{
|
||||
console/log("in user_profile");
|
||||
}
|
||||
|
||||
function leave_room()
|
||||
{
|
||||
console.log("in leave_room");
|
||||
user_leave_room();
|
||||
layout.set("home");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="grid_box">
|
||||
@@ -16,7 +31,7 @@
|
||||
|
||||
<!-- room_name -->
|
||||
<Button my_class="room_name deactivate">
|
||||
<room_name>
|
||||
{$current_room_name}
|
||||
</Button>
|
||||
|
||||
<!-- close -->
|
||||
@@ -26,7 +41,7 @@
|
||||
|
||||
<!-- panel_room_set -->
|
||||
<div class="panel panel_room_set __border_top">
|
||||
<Button new_layout="create" my_class="create">
|
||||
<Button on_click={leave_room}>
|
||||
leave
|
||||
</Button>
|
||||
<p>room users :</p>
|
||||
@@ -34,21 +49,15 @@
|
||||
<div class="__show_if_only_child">
|
||||
<p class="__center">/ there are no public rooms yet /</p>
|
||||
</div>
|
||||
<!-- placeholders
|
||||
------------- -->
|
||||
<Button new_layout="user" my_class="list">
|
||||
user 1
|
||||
</Button>
|
||||
<Button new_layout="user" my_class="list blocked">
|
||||
user 2
|
||||
</Button>
|
||||
<Button new_layout="user" my_class="list">
|
||||
user 3
|
||||
</Button>
|
||||
<Button new_layout="user" my_class="list">
|
||||
user 4
|
||||
</Button>
|
||||
<!-- END placeholders -->
|
||||
{#await users}
|
||||
<p>list of users is loading...</p>
|
||||
{:then users}
|
||||
{#each users as user}
|
||||
<Button new_layout="user" my_class="list" on_click={user_profile}>
|
||||
{user}
|
||||
</Button>
|
||||
{/each}
|
||||
{/await}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { msgs, user, layout, socket, room_name } from './Store_chat';
|
||||
import { msgs, user, layout, socket, current_room_name } from './Store_chat';
|
||||
import type { Room } from './Interface_chat';
|
||||
|
||||
export async function get_room_messages()
|
||||
{
|
||||
@@ -7,6 +8,9 @@ export async function get_room_messages()
|
||||
const data = await response.json();
|
||||
const messages = data.messages;
|
||||
|
||||
if (messages === null)
|
||||
return;
|
||||
|
||||
messages.forEach(function(item) {
|
||||
if (item.name === user.username) {
|
||||
item.name = "me";
|
||||
@@ -16,88 +20,106 @@ export async function get_room_messages()
|
||||
msgs.set(messages);
|
||||
}
|
||||
|
||||
export async function create_room(room_name, room_type)
|
||||
export async function create_room(room: Room)
|
||||
{
|
||||
console.log("in create_room");
|
||||
|
||||
let form_data = {
|
||||
room_name: room_name,
|
||||
room_type: room_type,
|
||||
};
|
||||
|
||||
// send the new room
|
||||
const response = await fetch('/api/v2/chat/create', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(form_data),
|
||||
body: JSON.stringify(room),
|
||||
});
|
||||
|
||||
// get response status and message
|
||||
let response_status = response.status;
|
||||
let data = await response.json();
|
||||
let response_message = "";
|
||||
if (data.message)
|
||||
response_message = data.message;
|
||||
|
||||
return {
|
||||
status: response_status,
|
||||
message: response_message
|
||||
message: data.message,
|
||||
room: data.room,
|
||||
};
|
||||
}
|
||||
|
||||
export async function join_room(room_name)
|
||||
export async function join_room(room: Room)
|
||||
{
|
||||
console.log("in join_room");
|
||||
|
||||
let name = {
|
||||
room_name: room_name,
|
||||
}
|
||||
const response = await fetch('/api/v2/chat/join', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(name),
|
||||
body: JSON.stringify(room),
|
||||
});
|
||||
let data = await response.json();
|
||||
console.log(data.message);
|
||||
|
||||
socket.emit('join', room_name);
|
||||
return data.room;
|
||||
}
|
||||
|
||||
export async function change_room(name)
|
||||
export async function change_room(room: Room)
|
||||
{
|
||||
console.log("in change_room");
|
||||
|
||||
let r_name = {
|
||||
room_name: name,
|
||||
}
|
||||
console.log("room:", room);
|
||||
const response = await fetch('/api/v2/chat/change', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(r_name),
|
||||
body: JSON.stringify(room),
|
||||
});
|
||||
let data = await response.json();
|
||||
console.log(data.message);
|
||||
|
||||
await get_room_messages();
|
||||
socket.emit('join', name);
|
||||
|
||||
room_name.set(name);
|
||||
let room_name = data.room.name;
|
||||
if (room.type === 'direct')
|
||||
{
|
||||
room_name === room.users[0];
|
||||
if (room_name === user.username)
|
||||
room_name === room.users[1];
|
||||
}
|
||||
current_room_name.set(room_name);
|
||||
layout.set("room");
|
||||
}
|
||||
|
||||
export async function get_my_rooms()
|
||||
{
|
||||
console.log("in get_my_rooms");
|
||||
|
||||
const response = await fetch('/api/v2/chat/myrooms');
|
||||
const data = await response.json();
|
||||
console.log("data.rooms:", data.rooms);
|
||||
|
||||
return data.rooms;
|
||||
}
|
||||
|
||||
export async function get_all_rooms()
|
||||
{
|
||||
console.log("in get_all_rooms");
|
||||
|
||||
// ask api for the rooms
|
||||
const response = await fetch('/api/v2/chat/myrooms');
|
||||
const response = await fetch('/api/v2/chat/allrooms');
|
||||
const data = await response.json();
|
||||
|
||||
console.log("data.rooms:", data.rooms);
|
||||
for (let room of data.rooms)
|
||||
console.log(room.name);
|
||||
let rooms = data.rooms;
|
||||
|
||||
return rooms;
|
||||
return data.rooms;
|
||||
}
|
||||
|
||||
export async function get_room_users()
|
||||
{
|
||||
console.log("in get_room_users");
|
||||
|
||||
const response = await fetch('/api/v2/chat/roomusers');
|
||||
const data = await response.json();
|
||||
|
||||
return data.users;
|
||||
}
|
||||
|
||||
export async function user_leave_room()
|
||||
{
|
||||
console.log("in leave_room");
|
||||
|
||||
const response = await fetch('/api/v2/chat/removeuser', {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { writable } from 'svelte/store';
|
||||
|
||||
export let msgs = writable([]);
|
||||
export let layout = writable("close");
|
||||
export let room_name = writable("");
|
||||
export let current_room_name = writable("");
|
||||
|
||||
export let user;
|
||||
export let socket;
|
||||
@@ -14,3 +14,4 @@ export function add_msg(name: string, message: string)
|
||||
{
|
||||
msgs.update(msgs => [...msgs, { name: "me", message: message }]);
|
||||
}
|
||||
|
||||
|
||||
17
srcs/requirements/svelte/api_front/src/pieces/utils.ts
Normal file
17
srcs/requirements/svelte/api_front/src/pieces/utils.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
export async function fetchAvatar(username: string)
|
||||
{
|
||||
return fetch(`http://${process.env.WEBSITE_HOST}:${process.env.WEBSITE_PORT}/api/v2/user/avatar?username=${username}`)
|
||||
.then((response) => {
|
||||
if (!response.ok) {
|
||||
throw new Error("Avatar not retrieved");
|
||||
}
|
||||
return response.blob();
|
||||
})
|
||||
.then((blob) => {
|
||||
return URL.createObjectURL(blob);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log("catch fetchAvatar: ", error);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user