Merge branch 'master' into hugo

This commit is contained in:
simplonco
2023-01-01 17:30:55 +01:00
154 changed files with 97 additions and 49299 deletions

View File

@@ -19,10 +19,10 @@ down:
docker compose -f ${DOCKERCOMPOSEPATH} -v down
destroy:
docker compose -f ${DOCKERCOMPOSEPATH} down -v --rmi all --remove-orphans
docker ps -aq | xargs --no-run-if-empty docker rm -f
docker images -aq | xargs --no-run-if-empty docker rmi -f
docker volume ls -q | xargs --no-run-if-empty docker volume rm
- docker compose -f ${DOCKERCOMPOSEPATH} down -v --rmi all --remove-orphans
- docker ps -aq | xargs --no-run-if-empty docker rm -f
- docker images -aq | xargs --no-run-if-empty docker rmi -f
- docker volume ls -q | xargs --no-run-if-empty docker volume rm
stop:
docker compose -f ${DOCKERCOMPOSEPATH} stop

View File

@@ -1,11 +1,24 @@
#! /usr/bin/env bash
# Function to generate passwords
#
function generate_password
{
# base64 alphabet is alphanumeric characters and "+", "/", "="
# https://en.wikipedia.org/wiki/Base64#Base64_table_from_RFC_4648
# we could delete them 'tr -d "+/="', but that would randomly shorten the string
echo $(openssl rand -base64 32 | tr "/" "_" );
}
# This script is used to create a new environment for the project.
#
ENV_FILE_DOCKER=./srcs/.env
ENV_FILE_NESTJS=./srcs/requirements/nestjs/api_back/.env
# Check for existing .env
# Check for existing .env
if [ -f "$ENV_FILE_DOCKER" ] && [ -f "$ENV_FILE_NESTJS" ]; then
echo "The file $ENV_FILE_DOCKER and $ENV_FILE_NESTJS already exists. Do you want to overwrite them ? (y/n)"
OVERWRITE=""
@@ -23,11 +36,12 @@
fi
# Create a new environment for docker
#
echo "Creating a new environment for docker"
NODE_ENV=""
# Ask if dev or prod environment
# Ask if dev or prod environment
while [ "$NODE_ENV" != "1" ] && [ "$NODE_ENV" != "2" ]; do
read -p "Enter the env configuration for nestjs : \"1\" for development OR \"2\" for production : " NODE_ENV
done
@@ -36,20 +50,20 @@
else
echo "NODE_ENV=production" > "$ENV_FILE_DOCKER"
fi
# Env variables
# Env variables
read -p "Enter the name of the host like \"localhost\" : " PROJECT_HOST
echo "WEBSITE_HOST=$PROJECT_HOST" >> "$ENV_FILE_DOCKER"
echo "WEBSITE_PORT=8080" >> "$ENV_FILE_DOCKER"
echo "POSTGRES_USER=postgres" >> "$ENV_FILE_DOCKER"
echo "#if change postgres pswd, do make destroy" >> "$ENV_FILE_DOCKER"
POSTGRES_PASSWORD=$(openssl rand -base64 32)
echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> "$ENV_FILE_DOCKER"
echo "POSTGRES_PASSWORD=$(generate_password)" >> "$ENV_FILE_DOCKER"
echo "POSTGRES_DB=transcendance_db" >> "$ENV_FILE_DOCKER"
echo "POSTGRES_HOST=postgresql" >> "$ENV_FILE_DOCKER"
echo "POSTGRES_PORT=5432" >> "$ENV_FILE_DOCKER"
echo "REDIS_HOST=redis" >> "$ENV_FILE_DOCKER"
echo "REDIS_PORT=6379" >> "$ENV_FILE_DOCKER"
echo "REDIS_PASSWORD=$(openssl rand -base64 32)" >> "$ENV_FILE_DOCKER"
echo "REDIS_PASSWORD=$(generate_password)" >> "$ENV_FILE_DOCKER"
# Create a new environment for nestjs
@@ -63,7 +77,7 @@
echo "POSTGRES_DB=\$POSTGRES_DB" >> "$ENV_FILE_NESTJS"
echo "POSTGRES_HOST=\$POSTGRES_HOST" >> "$ENV_FILE_NESTJS"
echo "POSTGRES_PORT=\$POSTGRES_PORT" >> "$ENV_FILE_NESTJS"
# Connection to 42
# Connection to 42
echo "In the next steps, we'll need to enter the client secret and client id of the 42 api"
read -p "Enter the client id of the 42 api : " CLIENT_ID
echo "FORTYTWO_CLIENT_ID=$CLIENT_ID" >> "$ENV_FILE_NESTJS"
@@ -71,13 +85,11 @@
echo "FORTYTWO_CLIENT_SECRET=$CLIENT_SECRET" >> "$ENV_FILE_NESTJS"
FT_CALLBACK="http://\$WEBSITE_HOST:\$WEBSITE_PORT/api/v2/auth/redirect"
echo "FORTYTWO_CALLBACK_URL=$FT_CALLBACK" >> "$ENV_FILE_NESTJS"
# Other configs
echo "COOKIE_SECRET=$(openssl rand -base64 32)" >> "$ENV_FILE_NESTJS"
# Other configs
echo "COOKIE_SECRET=$(generate_password)" >> "$ENV_FILE_NESTJS"
echo "PORT=3000" >> "$ENV_FILE_NESTJS"
AUTH="Transcendance"
echo "TWO_FACTOR_AUTHENTICATION_APP_NAME=$AUTH" >> "$ENV_FILE_NESTJS"
GAME_SECRET=$(openssl rand -base64 32)
echo "TICKET_FOR_PLAYING_GAME_SECRET=$GAME_SECRET" >> "$ENV_FILE_NESTJS"
echo "TWO_FACTOR_AUTHENTICATION_APP_NAME=Transcendance" >> "$ENV_FILE_NESTJS"
echo "TICKET_FOR_PLAYING_GAME_SECRET=$(generate_password)" >> "$ENV_FILE_NESTJS"
# it's finished !

View File

@@ -3,10 +3,10 @@ WEBSITE_HOST=transcendance
WEBSITE_PORT=8080
POSTGRES_USER=postgres
#if change postgres pswd, do make destroy
POSTGRES_PASSWORD=Y4a81mFbS7QDn42wEKx4i8a+o1Zex4rcgNTALS5RFoQ=
POSTGRES_PASSWORD=m7V8CkL+wl+SU1GagenTWP3oyPJx8JJG+tHRiENxoZQ=
POSTGRES_DB=transcendance_db
POSTGRES_HOST=postgresql
POSTGRES_PORT=5432
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=BTNQcvEeH8h0Iry0vbbuujyKwpJP7aZ4q4i+juoDniE=
REDIS_PASSWORD=JKDf9vhE4bb5+JW0CvRXVJ2rcV33Bs1MGcQmCxdL+Qs=

View File

@@ -14,14 +14,32 @@ ARG POSTGRES_PORT
COPY ./api_back ./
COPY ./api_back/src/uploads/avatars/default.png ./uploads/avatars/default.png
COPY ./api_back/.env ./.env
RUN sed -i "s/\$NODE_ENV/${NODE_ENV}/g" ./.env && \
sed -i "s/\$WEBSITE_HOST/${WEBSITE_HOST}/g" ./.env && \
sed -i "s/\$WEBSITE_PORT/${WEBSITE_PORT}/g" ./.env && \
sed -i "s/\$POSTGRES_USER/${POSTGRES_USER}/g" ./.env && \
sed -i "s/\$POSTGRES_PASSWORD/${POSTGRES_PASSWORD}/g" ./.env && \
sed -i "s/\$POSTGRES_DB/${POSTGRES_DB}/g" ./.env && \
sed -i "s/\$POSTGRES_HOST/${POSTGRES_HOST}/g" ./.env && \
sed -i "s/\$POSTGRES_PORT/${POSTGRES_PORT}/g" ./.env
#RUN sed -i "s/\$NODE_ENV/${NODE_ENV}/g" ./.env && \
# sed -i "s/\$WEBSITE_HOST/${WEBSITE_HOST}/g" ./.env && \
# sed -i "s/\$WEBSITE_PORT/${WEBSITE_PORT}/g" ./.env && \
# sed -i "s/\$POSTGRES_USER/${POSTGRES_USER}/g" ./.env && \
# sed -i "s/\$POSTGRES_PASSWORD/${POSTGRES_PASSWORD}/g" ./.env && \
# sed -i "s/\$POSTGRES_DB/${POSTGRES_DB}/g" ./.env && \
# sed -i "s/\$POSTGRES_HOST/${POSTGRES_HOST}/g" ./.env && \
# sed -i "s/\$POSTGRES_PORT/${POSTGRES_PORT}/g" ./.env
RUN sed -i "s/\$NODE_ENV/${NODE_ENV}/g" ./.env
RUN sed -i "s/\$WEBSITE_HOST/${WEBSITE_HOST}/g" ./.env
RUN sed -i "s/\$WEBSITE_PORT/${WEBSITE_PORT}/g" ./.env
RUN sed -i "s/\$POSTGRES_USER/${POSTGRES_USER}/g" ./.env
RUN echo ["$POSTGRESS_PASSWORD"] && \
echo ["$POSTGRESS_PASSWORD"] && \
echo ["$POSTGRESS_PASSWORD"] && \
echo ["$POSTGRESS_PASSWORD"] && \
echo ["$POSTGRESS_PASSWORD"] && \
echo ["$POSTGRESS_PASSWORD"] && \
echo ["$POSTGRESS_PASSWORD"] && \
sed -i "s/\$POSTGRES_PASSWORD/'${POSTGRESS_PASSWORD}'/g" ./.env
RUN sed -i "s/\$POSTGRES_DB/${POSTGRES_DB}/g" ./.env
RUN sed -i "s/\$POSTGRES_HOST/${POSTGRES_HOST}/g" ./.env
RUN sed -i "s/\$POSTGRES_PORT/${POSTGRES_PORT}/g" ./.env
RUN npm install
RUN npm ci

View File

@@ -9,7 +9,7 @@ POSTGRES_PORT=$POSTGRES_PORT
FORTYTWO_CLIENT_ID=u-s4t2ud-49dc7b539bcfe1acb48b928b2b281671c99fc5bfab1faca57a536ab7e0075500
FORTYTWO_CLIENT_SECRET=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
FORTYTWO_CALLBACK_URL=http://$WEBSITE_HOST:$WEBSITE_PORT/api/v2/auth/redirect
COOKIE_SECRET=FgqjKDff1NBior+t1R3xPgr4Qop2mzE6BOaDb2i1azI=
COOKIE_SECRET=wABcR5SytbN4kiPa_4Y8IhhdLDb4Yn0EvVvOPZRQf4Q=
PORT=3000
TWO_FACTOR_AUTHENTICATION_APP_NAME=Transcendance
TICKET_FOR_PLAYING_GAME_SECRET=PhszotanbBviW3nHNklQ5IizKU3fmv3KJhrJqRT8Zag=
TICKET_FOR_PLAYING_GAME_SECRET=hvt8PQo3o+BHimS0RO5viln65yF9zMIuZFEmhxQGdik=

View File

@@ -1,33 +1,33 @@
div.wrapper.svelte-1q8uute{display:flexbox;align-items:center}div.wrapper.svelte-1q8uute{display:flexbox;align-items:center}main.svelte-1cznfcz.svelte-1cznfcz{text-align:center;padding-top:40px;padding-bottom:40px}form.svelte-1cznfcz.svelte-1cznfcz{padding-top:15px}form.svelte-1cznfcz input.svelte-1cznfcz{max-width:330px}.error.svelte-1cznfcz.svelte-1cznfcz{font-weight:bold;font-size:0.8em;color:red}header.svelte-7t4byu.svelte-7t4byu{overflow-y:hidden}.grid-container.svelte-7t4byu.svelte-7t4byu{position:absolute;left:0;top:0;box-sizing:border-box;width:100%;height:100%;white-space:nowrap;margin-bottom:0px;overflow:hidden;padding:20px 40px;margin:0px;display:grid;grid-template-columns:repeat(12, 1fr);grid-template-rows:1fr 1fr 1fr 1fr 1fr;align-items:center}header.svelte-7t4byu h1.svelte-7t4byu{grid-column:1 / 7;grid-row:1;padding:20px;border:1px solid bisque}header.svelte-7t4byu nav.svelte-7t4byu{grid-column:7 / 13;grid-row:1;justify-self:end;padding:20px;border:1px solid bisque}header.svelte-7t4byu h2.svelte-7t4byu{grid-row:3;grid-column:5 / span 4;justify-self:center;border:1px solid black;z-index:3}header.svelte-7t4byu h2 div.svelte-7t4byu{font-size:2em}nav.svelte-7t4byu div.svelte-7t4byu{display:inline;color:bisque;font-weight:bold}nav.svelte-7t4byu>div.svelte-7t4byu{padding-left:1em}nav.svelte-7t4byu div.svelte-7t4byu:hover{text-decoration:underline;cursor:pointer}@font-face{font-family:"Bit5x3";src:url("/fonts/Bit5x3.woff2") format("woff2"),
header.svelte-7t4byu.svelte-7t4byu{overflow-y:hidden}.grid-container.svelte-7t4byu.svelte-7t4byu{position:absolute;left:0;top:0;box-sizing:border-box;width:100%;height:100%;white-space:nowrap;margin-bottom:0px;overflow:hidden;padding:20px 40px;margin:0px;display:grid;grid-template-columns:repeat(12, 1fr);grid-template-rows:1fr 1fr 1fr 1fr 1fr;align-items:center}header.svelte-7t4byu h1.svelte-7t4byu{grid-column:1 / 7;grid-row:1;padding:20px;border:1px solid bisque}header.svelte-7t4byu nav.svelte-7t4byu{grid-column:7 / 13;grid-row:1;justify-self:end;padding:20px;border:1px solid bisque}header.svelte-7t4byu h2.svelte-7t4byu{grid-row:3;grid-column:5 / span 4;justify-self:center;border:1px solid black;z-index:3}header.svelte-7t4byu h2 div.svelte-7t4byu{font-size:2em}nav.svelte-7t4byu div.svelte-7t4byu{display:inline;color:bisque;font-weight:bold}nav.svelte-7t4byu>div.svelte-7t4byu{padding-left:1em}nav.svelte-7t4byu div.svelte-7t4byu:hover{text-decoration:underline;cursor:pointer}main.svelte-1cznfcz.svelte-1cznfcz{text-align:center;padding-top:40px;padding-bottom:40px}form.svelte-1cznfcz.svelte-1cznfcz{padding-top:15px}form.svelte-1cznfcz input.svelte-1cznfcz{max-width:330px}.error.svelte-1cznfcz.svelte-1cznfcz{font-weight:bold;font-size:0.8em;color:red}div.wrapper.svelte-1q8uute{display:flexbox;align-items:center}div.wrapper.svelte-1q8uute{display:flexbox;align-items:center}@font-face{font-family:"Bit5x3";src:url("/fonts/Bit5x3.woff2") format("woff2"),
local("Bit5x3"),
url("/fonts/Bit5x3.woff") format("woff");font-weight:normal;font-style:normal;font-display:swap}#game_page.svelte-y455cj.svelte-y455cj{margin:0;background-color:#222425;position:relative;width:100%;height:100%}#canvas_container.svelte-y455cj.svelte-y455cj{margin-top:20px;text-align:center}#users_name.svelte-y455cj.svelte-y455cj{text-align:center;font-family:"Bit5x3";color:rgb(245, 245, 245);font-size:x-large}#div_game.svelte-y455cj.svelte-y455cj{margin-top:20px;text-align:center;font-family:"Bit5x3";color:rgb(245, 245, 245);font-size:x-large}#error_notification.svelte-y455cj.svelte-y455cj{text-align:center;display:block;font-family:"Bit5x3";color:rgb(143, 19, 19);font-size:x-large}#div_game.svelte-y455cj fieldset.svelte-y455cj{max-width:50vw;width:auto;margin:0 auto}#div_game.svelte-y455cj fieldset div.svelte-y455cj{padding:10px}#pong_button.svelte-y455cj.svelte-y455cj{font-family:"Bit5x3";color:rgb(245, 245, 245);background-color:#333333;font-size:x-large;padding:10px}canvas.svelte-y455cj.svelte-y455cj{background-color:#333333;max-width:75vw;width:80%}@font-face{font-family:'Bondi';src:url('/fonts/Bondi.ttf.woff') format('woff'),
url("/fonts/Bit5x3.woff") format("woff");font-weight:normal;font-style:normal;font-display:swap}#game_page.svelte-y455cj.svelte-y455cj{margin:0;background-color:#222425;position:relative;width:100%;height:100%}#canvas_container.svelte-y455cj.svelte-y455cj{margin-top:20px;text-align:center}#users_name.svelte-y455cj.svelte-y455cj{text-align:center;font-family:"Bit5x3";color:rgb(245, 245, 245);font-size:x-large}#div_game.svelte-y455cj.svelte-y455cj{margin-top:20px;text-align:center;font-family:"Bit5x3";color:rgb(245, 245, 245);font-size:x-large}#error_notification.svelte-y455cj.svelte-y455cj{text-align:center;display:block;font-family:"Bit5x3";color:rgb(143, 19, 19);font-size:x-large}#div_game.svelte-y455cj fieldset.svelte-y455cj{max-width:50vw;width:auto;margin:0 auto}#div_game.svelte-y455cj fieldset div.svelte-y455cj{padding:10px}#pong_button.svelte-y455cj.svelte-y455cj{font-family:"Bit5x3";color:rgb(245, 245, 245);background-color:#333333;font-size:x-large;padding:10px}canvas.svelte-y455cj.svelte-y455cj{background-color:#333333;max-width:75vw;width:80%}canvas.svelte-1bstsd0{width:100%;height:100%;background-color:#666}@font-face{font-family:'Bondi';src:url('/fonts/Bondi.ttf.woff') format('woff'),
url('/fonts/Bondi.ttf.svg#Bondi') format('svg'),
url('/fonts/Bondi.ttf.eot'),
url('/fonts/Bondi.ttf.eot?#iefix') format('embedded-opentype');font-weight:normal;font-style:normal}header.svelte-1aisfio.svelte-1aisfio{background:#618174;margin:0}header.svelte-1aisfio.svelte-1aisfio{position:sticky;display:grid;grid-template-columns:1fr 1fr 1fr}h1.svelte-1aisfio.svelte-1aisfio{font-family:'Bondi'}h1.svelte-1aisfio.svelte-1aisfio{margin:0;text-align:left;display:flex;justify-self:center;align-self:center}img.svelte-1aisfio.svelte-1aisfio{cursor:pointer;max-width:40px;padding:7px 20px;justify-self:left}nav.svelte-1aisfio.svelte-1aisfio{display:flex;justify-content:right}nav.svelte-1aisfio button.svelte-1aisfio{margin:7px 20px;border-radius:4px}canvas.svelte-1bstsd0{width:100%;height:100%;background-color:#666}div.outer.svelte-1tyjf3q{max-width:960px;margin:40px auto}:root{--purple:rgb(123, 31, 162);--violet:rgb(103, 58, 183);--pink:rgb(244, 143, 177)}@keyframes svelte-1tyjf3q-background-pan{from{background-position:0% center}to{background-position:-200% center}}@keyframes svelte-1tyjf3q-scale{from,to{transform:scale(0)}50%{transform:scale(1)}}@keyframes svelte-1tyjf3q-rotate{from{transform:rotate(0deg)}to{transform:rotate(180deg)}}main.svelte-qtbld7{text-align:center}div.cards.svelte-qtbld7{display:grid;grid-template-columns:1fr 1fr;grid-gap:20px}img.svelte-qtbld7{width:60px}form.svelte-qtbld7{text-align:center}.form-field.svelte-qtbld7{padding:10px}.label.svelte-qtbld7{font-weight:bold}.inline-check.svelte-qtbld7{display:inline}.error.svelte-qtbld7{font-size:0.8em;font-weight:bold;color:red}.success.svelte-qtbld7{font-size:0.8em;font-weight:bold;color:green}div.top-grid.svelte-55f7si{display:grid;grid-template-columns:repeat(12, 1fr);height:85vh}div.all-users-sidebar.svelte-55f7si{grid-column:1 / span 2;background:white}div.a-user.svelte-55f7si{display:inline-block}div.status.svelte-55f7si{font-size:0.6em;font-weight:bold}div[class^="a-user"].svelte-55f7si:hover{text-decoration:underline;font-weight:bold;cursor:pointer}div.main-display.svelte-55f7si{grid-column:3 / span 10}.error.svelte-55f7si{font-size:0.8em;font-weight:bold;color:red}.card.svelte-8smyff{background:white;padding:20px;border-radius:6px;box-shadow:0px 2px 4px rgba(0,0,0,0.1)}button.svelte-1u0z9cq{border:0;cursor:pointer;border-radius:6px;padding:8px 12px;font-weight:bold;box-shadow:1px 2px 3px rgba(0,0,0,0.2)}.primary.svelte-1u0z9cq{background:#d91b42;color:white}.secondary.svelte-1u0z9cq{background:#45c496;color:white}.flat.svelte-1u0z9cq{box-shadow:none}.primary.inverse.svelte-1u0z9cq{color:#d91b42;background:white;border:2px solid #d91b42}.secondary.inverse.svelte-1u0z9cq{color:#45c496;background:white;border:2px solid #45c496}div.outer.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{max-width:960px;margin:40px auto}main.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{max-width:960px;margin:40px auto;text-align:center}.avatar.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{max-width:150px}section.main-stats.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{max-width:600px;margin:40px auto;text-align:center;display:grid;grid-template-columns:repeat(3, 1fr);grid-template-rows:repeat(3, 1fr)}section.main-stats.svelte-16aefqu h4.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{grid-column:1 / span 3}div.username.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{font-size:1.5em;font-weight:bold;padding-bottom:5px}div.rank.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{font-size:1.2em;font-weight:bold}:root{--purple:rgb(123, 31, 162);--violet:rgb(103, 58, 183);--pink:rgb(244, 143, 177)}@keyframes svelte-16aefqu-background-pan{from{background-position:0% center}to{background-position:-200% center}}@keyframes svelte-16aefqu-scale{from,to{transform:scale(0)}50%{transform:scale(1)}}@keyframes svelte-16aefqu-rotate{from{transform:rotate(0deg)}to{transform:rotate(180deg)}}div.svelte-16aefqu>.glitter.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{display:inline-block;position:relative}div.svelte-16aefqu>.glitter.svelte-16aefqu>.glitter-star.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{--size:clamp(20px, 1.5vw, 30px);animation:svelte-16aefqu-scale 700ms ease forwards;display:block;height:var(--size);left:var(--star-left);position:absolute;top:var(--star-top);width:var(--size)}div.svelte-16aefqu>.glitter.svelte-16aefqu>.glitter-star.svelte-16aefqu>svg.svelte-16aefqu.svelte-16aefqu{animation:svelte-16aefqu-rotate 1000ms linear infinite;display:block;opacity:0.7}div.svelte-16aefqu>.glitter.svelte-16aefqu>.glitter-star.svelte-16aefqu>svg.svelte-16aefqu>path.svelte-16aefqu{fill:var(--violet)}div.svelte-16aefqu>.glitter.svelte-16aefqu>.glitter-text.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{animation:svelte-16aefqu-background-pan 3s linear infinite;background:linear-gradient(
url('/fonts/Bondi.ttf.eot?#iefix') format('embedded-opentype');font-weight:normal;font-style:normal}header.svelte-1aisfio.svelte-1aisfio{background:#618174;margin:0}header.svelte-1aisfio.svelte-1aisfio{position:sticky;display:grid;grid-template-columns:1fr 1fr 1fr}h1.svelte-1aisfio.svelte-1aisfio{font-family:'Bondi'}h1.svelte-1aisfio.svelte-1aisfio{margin:0;text-align:left;display:flex;justify-self:center;align-self:center}img.svelte-1aisfio.svelte-1aisfio{cursor:pointer;max-width:40px;padding:7px 20px;justify-self:left}nav.svelte-1aisfio.svelte-1aisfio{display:flex;justify-content:right}nav.svelte-1aisfio button.svelte-1aisfio{margin:7px 20px;border-radius:4px}div.outer.svelte-1tyjf3q{max-width:960px;margin:40px auto}:root{--purple:rgb(123, 31, 162);--violet:rgb(103, 58, 183);--pink:rgb(244, 143, 177)}@keyframes svelte-1tyjf3q-background-pan{from{background-position:0% center}to{background-position:-200% center}}@keyframes svelte-1tyjf3q-scale{from,to{transform:scale(0)}50%{transform:scale(1)}}@keyframes svelte-1tyjf3q-rotate{from{transform:rotate(0deg)}to{transform:rotate(180deg)}}main.svelte-qtbld7{text-align:center}div.cards.svelte-qtbld7{display:grid;grid-template-columns:1fr 1fr;grid-gap:20px}img.svelte-qtbld7{width:60px}form.svelte-qtbld7{text-align:center}.form-field.svelte-qtbld7{padding:10px}.label.svelte-qtbld7{font-weight:bold}.inline-check.svelte-qtbld7{display:inline}.error.svelte-qtbld7{font-size:0.8em;font-weight:bold;color:red}.success.svelte-qtbld7{font-size:0.8em;font-weight:bold;color:green}div.top-grid.svelte-55f7si{display:grid;grid-template-columns:repeat(12, 1fr);height:85vh}div.all-users-sidebar.svelte-55f7si{grid-column:1 / span 2;background:white}div.a-user.svelte-55f7si{display:inline-block}div.status.svelte-55f7si{font-size:0.6em;font-weight:bold}div[class^="a-user"].svelte-55f7si:hover{text-decoration:underline;font-weight:bold;cursor:pointer}div.main-display.svelte-55f7si{grid-column:3 / span 10}.error.svelte-55f7si{font-size:0.8em;font-weight:bold;color:red}div.outer.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{max-width:960px;margin:40px auto}main.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{max-width:960px;margin:40px auto;text-align:center}.avatar.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{max-width:150px}section.main-stats.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{max-width:600px;margin:40px auto;text-align:center;display:grid;grid-template-columns:repeat(3, 1fr);grid-template-rows:repeat(3, 1fr)}section.main-stats.svelte-16aefqu h4.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{grid-column:1 / span 3}div.username.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{font-size:1.5em;font-weight:bold;padding-bottom:5px}div.rank.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{font-size:1.2em;font-weight:bold}:root{--purple:rgb(123, 31, 162);--violet:rgb(103, 58, 183);--pink:rgb(244, 143, 177)}@keyframes svelte-16aefqu-background-pan{from{background-position:0% center}to{background-position:-200% center}}@keyframes svelte-16aefqu-scale{from,to{transform:scale(0)}50%{transform:scale(1)}}@keyframes svelte-16aefqu-rotate{from{transform:rotate(0deg)}to{transform:rotate(180deg)}}div.svelte-16aefqu>.glitter.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{display:inline-block;position:relative}div.svelte-16aefqu>.glitter.svelte-16aefqu>.glitter-star.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{--size:clamp(20px, 1.5vw, 30px);animation:svelte-16aefqu-scale 700ms ease forwards;display:block;height:var(--size);left:var(--star-left);position:absolute;top:var(--star-top);width:var(--size)}div.svelte-16aefqu>.glitter.svelte-16aefqu>.glitter-star.svelte-16aefqu>svg.svelte-16aefqu.svelte-16aefqu{animation:svelte-16aefqu-rotate 1000ms linear infinite;display:block;opacity:0.7}div.svelte-16aefqu>.glitter.svelte-16aefqu>.glitter-star.svelte-16aefqu>svg.svelte-16aefqu>path.svelte-16aefqu{fill:var(--violet)}div.svelte-16aefqu>.glitter.svelte-16aefqu>.glitter-text.svelte-16aefqu.svelte-16aefqu.svelte-16aefqu{animation:svelte-16aefqu-background-pan 3s linear infinite;background:linear-gradient(
to right,
var(--purple),
var(--violet),
var(--pink),
var(--purple)
);background-size:200%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;color:transparent;white-space:nowrap}.chat_box.svelte-6ej1tr{display:flex;position:fixed;bottom:20px;right:20px;padding:0px;width:auto;height:auto;border:1px solid black;z-index:1}.chat_box.svelte-6ej1tr *{-ms-overflow-style:none;scrollbar-width:none}.chat_box.svelte-6ej1tr *::-webkit-scrollbar{display:none}.chat_box.svelte-6ej1tr .grid_box{display:grid;margin:5px;gap:5px;width:300px;height:400px}.chat_box.svelte-6ej1tr .grid_box *{display:flex;flex-direction:column;position:relative;box-sizing:border-box}.chat_box.svelte-6ej1tr .grid_box p{padding:10px;font-size:15px}.chat_box.svelte-6ej1tr .panel{overflow-y:scroll}.chat_box.svelte-6ej1tr .panel > *{margin-top:10px;margin-bottom:10px}.chat_box.svelte-6ej1tr .__show_if_only_child{display:none}.chat_box.svelte-6ej1tr .__show_if_only_child:only-child{display:flex;color:rgb(100, 100, 100)}.chat_box.svelte-6ej1tr .__center{margin-left:auto;margin-right:auto}.chat_box.svelte-6ej1tr .__border_top{border-top:1px solid black}.chat_box.svelte-6ej1tr .__check_change_next:checked ~ .__to_show{display:flex}.chat_box.svelte-6ej1tr .__check_change_next:checked ~ .__to_block,.chat_box.svelte-6ej1tr .__check_change_next:checked ~ .__to_block *{pointer-events:none;color:rgb(100, 100, 100)}.chat_box.svelte-6ej1tr .__to_show{display:none}.grid_box.svelte-1quyp80 .back {grid-area:back}.grid_box.svelte-1quyp80 .room_name {grid-area:room_name}.grid_box.svelte-1quyp80 .close {grid-area:close}.grid_box.svelte-1quyp80 .panel_msg {grid-area:panel_msg}.grid_box.svelte-1quyp80 .send {grid-area:send}.grid_box.svelte-1quyp80 .panel_write{grid-area:panel_write}.grid_box.svelte-1quyp80.svelte-1quyp80{grid:' back room_name room_name close ' auto
' panel_msg panel_msg panel_msg panel_msg ' 1fr
' panel_write panel_write send send ' auto
/ auto 1fr auto auto }.grid_box.svelte-1quyp80 .panel_write.svelte-1quyp80{border:none;overflow:visible}.grid_box.svelte-1quyp80 .text_area.svelte-1quyp80{display:block;position:absolute;bottom:0px;left:0px;width:100%;height:100%;overflow-x:hidden;overflow-y:scroll;background-color:white;border:1px solid black}.grid_box.svelte-1quyp80 .text_area.svelte-1quyp80:focus{height:auto;min-height:100%;max-height:300px}.grid_box.svelte-1quyp80 .panel_write .text_area.svelte-1quyp80 *{display:block ruby}.grid_box.svelte-1quyp80 .panel_msg.svelte-1quyp80{flex-direction:column-reverse;border:1px solid black}.grid_box.svelte-1quyp80 .msg_thread.svelte-1quyp80{width:100%;padding:0px 5px}.grid_box.svelte-fc4a40 .chat{grid-area:chat}.grid_box.svelte-fc4a40{gap:0px;grid:' chat ' auto
);background-size:200%;-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text;color:transparent;white-space:nowrap}.card.svelte-8smyff{background:white;padding:20px;border-radius:6px;box-shadow:0px 2px 4px rgba(0,0,0,0.1)}button.svelte-1u0z9cq{border:0;cursor:pointer;border-radius:6px;padding:8px 12px;font-weight:bold;box-shadow:1px 2px 3px rgba(0,0,0,0.2)}.primary.svelte-1u0z9cq{background:#d91b42;color:white}.secondary.svelte-1u0z9cq{background:#45c496;color:white}.flat.svelte-1u0z9cq{box-shadow:none}.primary.inverse.svelte-1u0z9cq{color:#d91b42;background:white;border:2px solid #d91b42}.secondary.inverse.svelte-1u0z9cq{color:#45c496;background:white;border:2px solid #45c496}.chat_box.svelte-6ej1tr{display:flex;position:fixed;bottom:20px;right:20px;padding:0px;width:auto;height:auto;border:1px solid black;z-index:1}.chat_box.svelte-6ej1tr *{-ms-overflow-style:none;scrollbar-width:none}.chat_box.svelte-6ej1tr *::-webkit-scrollbar{display:none}.chat_box.svelte-6ej1tr .grid_box{display:grid;margin:5px;gap:5px;width:300px;height:400px}.chat_box.svelte-6ej1tr .grid_box *{display:flex;flex-direction:column;position:relative;box-sizing:border-box}.chat_box.svelte-6ej1tr .grid_box p{padding:10px;font-size:15px}.chat_box.svelte-6ej1tr .panel{overflow-y:scroll}.chat_box.svelte-6ej1tr .panel > *{margin-top:10px;margin-bottom:10px}.chat_box.svelte-6ej1tr .__show_if_only_child{display:none}.chat_box.svelte-6ej1tr .__show_if_only_child:only-child{display:flex;color:rgb(100, 100, 100)}.chat_box.svelte-6ej1tr .__center{margin-left:auto;margin-right:auto}.chat_box.svelte-6ej1tr .__border_top{border-top:1px solid black}.chat_box.svelte-6ej1tr .__check_change_next:checked ~ .__to_show{display:flex}.chat_box.svelte-6ej1tr .__check_change_next:checked ~ .__to_block,.chat_box.svelte-6ej1tr .__check_change_next:checked ~ .__to_block *{pointer-events:none;color:rgb(100, 100, 100)}.chat_box.svelte-6ej1tr .__to_show{display:none}.grid_box.svelte-fc4a40 .chat{grid-area:chat}.grid_box.svelte-fc4a40{gap:0px;grid:' chat ' auto
/ auto }.chat_box.close .grid_box.svelte-fc4a40{margin:0px;width:auto;height:auto}.grid_box.svelte-1jygwt2 .settings {grid-area:settings}.grid_box.svelte-1jygwt2 .close {grid-area:close}.grid_box.svelte-1jygwt2 .new {grid-area:new}.grid_box.svelte-1jygwt2 .panel_home{grid-area:panel_home}.grid_box.svelte-1jygwt2.svelte-1jygwt2{grid:' settings new close ' auto
' panel_home panel_home panel_home ' 1fr
/ auto 1fr auto }.panel_home.svelte-1jygwt2 p.title.svelte-1jygwt2{margin:10px auto 0px auto}.grid_box.svelte-1b4c0qx .back {grid-area:back}.grid_box.svelte-1b4c0qx .new {grid-area:new}.grid_box.svelte-1b4c0qx .close {grid-area:close}.grid_box.svelte-1b4c0qx .panel_new{grid-area:panel_new}.grid_box.svelte-1b4c0qx{grid:' back new close ' auto
/ auto 1fr auto }.panel_home.svelte-1jygwt2 p.title.svelte-1jygwt2{margin:10px auto 0px auto}.grid_box.svelte-1quyp80 .back {grid-area:back}.grid_box.svelte-1quyp80 .room_name {grid-area:room_name}.grid_box.svelte-1quyp80 .close {grid-area:close}.grid_box.svelte-1quyp80 .panel_msg {grid-area:panel_msg}.grid_box.svelte-1quyp80 .send {grid-area:send}.grid_box.svelte-1quyp80 .panel_write{grid-area:panel_write}.grid_box.svelte-1quyp80.svelte-1quyp80{grid:' back room_name room_name close ' auto
' panel_msg panel_msg panel_msg panel_msg ' 1fr
' panel_write panel_write send send ' auto
/ auto 1fr auto auto }.grid_box.svelte-1quyp80 .panel_write.svelte-1quyp80{border:none;overflow:visible}.grid_box.svelte-1quyp80 .text_area.svelte-1quyp80{display:block;position:absolute;bottom:0px;left:0px;width:100%;height:100%;overflow-x:hidden;overflow-y:scroll;background-color:white;border:1px solid black}.grid_box.svelte-1quyp80 .text_area.svelte-1quyp80:focus{height:auto;min-height:100%;max-height:300px}.grid_box.svelte-1quyp80 .panel_write .text_area.svelte-1quyp80 *{display:block ruby}.grid_box.svelte-1quyp80 .panel_msg.svelte-1quyp80{flex-direction:column-reverse;border:1px solid black}.grid_box.svelte-1quyp80 .msg_thread.svelte-1quyp80{width:100%;padding:0px 5px}.grid_box.svelte-1b4c0qx .back {grid-area:back}.grid_box.svelte-1b4c0qx .new {grid-area:new}.grid_box.svelte-1b4c0qx .close {grid-area:close}.grid_box.svelte-1b4c0qx .panel_new{grid-area:panel_new}.grid_box.svelte-1b4c0qx{grid:' back new close ' auto
' panel_new panel_new panel_new ' 1fr
/ auto 1fr auto }.grid_box.svelte-1lfmc2m .back {grid-area:back}.grid_box.svelte-1lfmc2m .settings {grid-area:settings}.grid_box.svelte-1lfmc2m .close {grid-area:close}.grid_box.svelte-1lfmc2m .panel_settings{grid-area:panel_settings}.grid_box.svelte-1lfmc2m{grid:' back settings close ' auto
' panel_settings panel_settings panel_settings ' 1fr
/ auto 1fr auto }.grid_box.svelte-1cmnkcw .back {grid-area:back}.grid_box.svelte-1cmnkcw .create {grid-area:create}.grid_box.svelte-1cmnkcw .close {grid-area:close}.grid_box.svelte-1cmnkcw .panel_create{grid-area:panel_create}.grid_box.svelte-1cmnkcw.svelte-1cmnkcw.svelte-1cmnkcw{grid:' back create close ' auto
' panel_create panel_create panel_create ' 1fr
/ auto 1fr auto }form.svelte-1cmnkcw input[type=radio].svelte-1cmnkcw.svelte-1cmnkcw{display:none}form.svelte-1cmnkcw label._radio.svelte-1cmnkcw.svelte-1cmnkcw{margin:0px 20px 0px auto;padding-right:10px;cursor:pointer}form.svelte-1cmnkcw label._radio p.svelte-1cmnkcw.svelte-1cmnkcw{margin-top:0px;margin-bottom:0px}form.svelte-1cmnkcw label._radio.svelte-1cmnkcw.svelte-1cmnkcw::after{content:"";position:absolute;top:calc(50% - 6px);right:0px;width:12px;height:12px;border-radius:6px;border:2px solid rgb(150, 150, 150);box-sizing:border-box;cursor:pointer}form.svelte-1cmnkcw input[type=radio].svelte-1cmnkcw:checked+label._radio.svelte-1cmnkcw::after{background-color:rgb(200, 200, 200)}form.svelte-1cmnkcw input[type=submit].svelte-1cmnkcw.svelte-1cmnkcw{margin-top:20px}.grid_box.svelte-2tekts .back {grid-area:back}.grid_box.svelte-2tekts .room_name {grid-area:room_name}.grid_box.svelte-2tekts .close {grid-area:close}.grid_box.svelte-2tekts .panel_protected{grid-area:panel_protected}.grid_box.svelte-2tekts.svelte-2tekts{grid:' back room_name close ' auto
/ auto 1fr auto }.grid_box.svelte-1sv7l8q .back {grid-area:back}.grid_box.svelte-1sv7l8q .room_name {grid-area:room_name}.grid_box.svelte-1sv7l8q .close {grid-area:close}.grid_box.svelte-1sv7l8q .panel_room_set{grid-area:panel_room_set}.grid_box.svelte-1sv7l8q{grid:' back room_name close ' auto
' panel_room_set panel_room_set panel_room_set ' 1fr
/ auto 1fr auto }.grid_box.svelte-2tekts .back {grid-area:back}.grid_box.svelte-2tekts .room_name {grid-area:room_name}.grid_box.svelte-2tekts .close {grid-area:close}.grid_box.svelte-2tekts .panel_protected{grid-area:panel_protected}.grid_box.svelte-2tekts.svelte-2tekts{grid:' back room_name close ' auto
' panel_protected panel_protected panel_protected ' 1fr
/ auto 1fr auto }form.svelte-2tekts input[type=submit].svelte-2tekts{margin-top:20px}.grid_box.svelte-yo0any .back {grid-area:back}.grid_box.svelte-yo0any .back {grid-area:back}.grid_box.svelte-yo0any .user {grid-area:user}.grid_box.svelte-yo0any .close {grid-area:close}.grid_box.svelte-yo0any .panel_mute{grid-area:panel_mute}.grid_box.svelte-yo0any.svelte-yo0any.svelte-yo0any{grid:' back user close ' auto
/ auto 1fr auto }form.svelte-2tekts input[type=submit].svelte-2tekts{margin-top:20px}.grid_box.svelte-1cmnkcw .back {grid-area:back}.grid_box.svelte-1cmnkcw .create {grid-area:create}.grid_box.svelte-1cmnkcw .close {grid-area:close}.grid_box.svelte-1cmnkcw .panel_create{grid-area:panel_create}.grid_box.svelte-1cmnkcw.svelte-1cmnkcw.svelte-1cmnkcw{grid:' back create close ' auto
' panel_create panel_create panel_create ' 1fr
/ auto 1fr auto }form.svelte-1cmnkcw input[type=radio].svelte-1cmnkcw.svelte-1cmnkcw{display:none}form.svelte-1cmnkcw label._radio.svelte-1cmnkcw.svelte-1cmnkcw{margin:0px 20px 0px auto;padding-right:10px;cursor:pointer}form.svelte-1cmnkcw label._radio p.svelte-1cmnkcw.svelte-1cmnkcw{margin-top:0px;margin-bottom:0px}form.svelte-1cmnkcw label._radio.svelte-1cmnkcw.svelte-1cmnkcw::after{content:"";position:absolute;top:calc(50% - 6px);right:0px;width:12px;height:12px;border-radius:6px;border:2px solid rgb(150, 150, 150);box-sizing:border-box;cursor:pointer}form.svelte-1cmnkcw input[type=radio].svelte-1cmnkcw:checked+label._radio.svelte-1cmnkcw::after{background-color:rgb(200, 200, 200)}form.svelte-1cmnkcw input[type=submit].svelte-1cmnkcw.svelte-1cmnkcw{margin-top:20px}.grid_box.svelte-yo0any .back {grid-area:back}.grid_box.svelte-yo0any .back {grid-area:back}.grid_box.svelte-yo0any .user {grid-area:user}.grid_box.svelte-yo0any .close {grid-area:close}.grid_box.svelte-yo0any .panel_mute{grid-area:panel_mute}.grid_box.svelte-yo0any.svelte-yo0any.svelte-yo0any{grid:' back user close ' auto
' panel_mute panel_mute panel_mute ' 1fr
/ auto 1fr auto }form.svelte-yo0any input[type=checkbox].svelte-yo0any.svelte-yo0any{display:none}form.svelte-yo0any label._checkbox.svelte-yo0any.svelte-yo0any{margin:0px auto 0px 10px;padding-left:10px;cursor:pointer}form.svelte-yo0any label._checkbox.svelte-yo0any.svelte-yo0any::after{content:"";position:absolute;top:calc(50% - 6px);left:0px;width:12px;height:12px;border:2px solid rgb(150, 150, 150);box-sizing:border-box;cursor:pointer}form.svelte-yo0any input[type=checkbox].svelte-yo0any:checked+label._checkbox.svelte-yo0any::after{background-color:rgb(200, 200, 200)}form.svelte-yo0any label._select.svelte-yo0any.svelte-yo0any{flex-direction:row}form.svelte-yo0any label._select p.svelte-yo0any.svelte-yo0any{margin:0px}form.svelte-yo0any select.svelte-yo0any.svelte-yo0any{margin:auto auto auto 10px;background-color:rgb(220, 220, 220);border:none;padding:5px;cursor:pointer}form.svelte-yo0any select.svelte-yo0any.svelte-yo0any:hover{background-color:rgb(200, 200, 200)}form.svelte-yo0any input[type=submit].svelte-yo0any.svelte-yo0any{margin-top:20px}.grid_box.svelte-1fj8iha .back {grid-area:back}.grid_box.svelte-1fj8iha .user {grid-area:user}.grid_box.svelte-1fj8iha .close {grid-area:close}.grid_box.svelte-1fj8iha .room_name {grid-area:room_name}.grid_box.svelte-1fj8iha .panel_user{grid-area:panel_user}.grid_box.svelte-1fj8iha{grid:' back user close ' auto
' room_name room_name room_name ' auto
' panel_user panel_user panel_user ' 1fr
/ auto 1fr auto }.panel_user.svelte-1fj8iha{margin-top:-5px}.grid_box.svelte-1sv7l8q .back {grid-area:back}.grid_box.svelte-1sv7l8q .room_name {grid-area:room_name}.grid_box.svelte-1sv7l8q .close {grid-area:close}.grid_box.svelte-1sv7l8q .panel_room_set{grid-area:panel_room_set}.grid_box.svelte-1sv7l8q{grid:' back room_name close ' auto
' panel_room_set panel_room_set panel_room_set ' 1fr
/ auto 1fr auto }button.svelte-b72wpv.svelte-b72wpv{padding:0px;margin:auto;width:100%;cursor:pointer;outline:none;border:none;background-color:rgb(220, 220, 220)}button.svelte-b72wpv p.svelte-b72wpv{width:100%;margin:auto;text-align:center}button.svelte-b72wpv.svelte-b72wpv:hover{background-color:rgb(200, 200, 200)}button.svelte-b72wpv.svelte-b72wpv:active{background-color:rgb(190, 190, 190)}.list.svelte-b72wpv.svelte-b72wpv:not(:hover){background-color:rgb(240, 240, 240)}.list.svelte-b72wpv p.svelte-b72wpv{text-align:left}.transparent.svelte-b72wpv.svelte-b72wpv:not(:hover){background-color:transparent}.deactivate.svelte-b72wpv.svelte-b72wpv{background-color:transparent;pointer-events:none}.icon.svelte-b72wpv p.svelte-b72wpv{display:none}.icon.svelte-b72wpv.svelte-b72wpv:not(:hover){background-color:transparent}.icon.svelte-b72wpv.svelte-b72wpv{width:30px;height:100%;padding:0px}.dots.svelte-b72wpv.svelte-b72wpv::after{content:'\2807';font-size:20px;position:absolute;top:50%;left:0px;width:100%;height:auto;text-align:center;transform:translateY(-50%);cursor:pointer}.close.svelte-b72wpv.svelte-b72wpv::before{content:"";position:absolute;top:calc(50% - 1px);left:5px;width:20px;height:2px;background-color:black}.back.svelte-b72wpv.svelte-b72wpv::before{content:"";position:absolute;top:calc(50% - 6px - 1px);left:6px;width:14px;height:14px;border-left:1px solid black;border-bottom:1px solid black;transform:rotate(45deg)}.blocked.svelte-b72wpv.svelte-b72wpv{padding-left:30px}.blocked.svelte-b72wpv.svelte-b72wpv::before{content:"";position:absolute;top:calc(50% - 2px);left:10px;cursor:pointer;width:13px;height:10px;border-radius:2px;background-color:rgb(110, 110, 110)}.blocked.svelte-b72wpv.svelte-b72wpv::after{content:"";position:absolute;top:calc(50% - 9px);left:12px;cursor:pointer;width:9px;height:13px;border-radius:5px;box-sizing:border-box;border:3px solid rgb(110, 110, 110)}.chat_msg.svelte-14xxpbz.svelte-14xxpbz{margin:5px auto;padding:5px;border-radius:5px}.chat_msg.svelte-14xxpbz.svelte-14xxpbz{margin-left:0px;background-color:rgb(210, 210, 210);max-width:80%}.chat_msg.svelte-14xxpbz p.svelte-14xxpbz{padding:0px}.chat_msg.svelte-14xxpbz p.name.svelte-14xxpbz{margin:0px;font-size:12px;color:rgb(100, 100, 100)}.chat_msg.svelte-14xxpbz p.msg.svelte-14xxpbz{margin:5px 0px}.chat_msg.svelte-14xxpbz p.msg.svelte-14xxpbz *{display:inline}.chat_msg.me.svelte-14xxpbz.svelte-14xxpbz{margin-right:0px;margin-left:auto;background-color:rgb(210, 110, 10)}.chat_msg.me.svelte-14xxpbz p.name.svelte-14xxpbz{display:none}.chat_msg.SERVER.svelte-14xxpbz.svelte-14xxpbz{margin-left:auto;background-color:transparent}.chat_msg.SERVER.svelte-14xxpbz p.name.svelte-14xxpbz{display:none}.chat_msg.SERVER.svelte-14xxpbz p.msg.svelte-14xxpbz{margin:0px auto;font-size:12px;color:rgb(100, 100, 100)}
/ auto 1fr auto }.panel_user.svelte-1fj8iha{margin-top:-5px}button.svelte-b72wpv.svelte-b72wpv{padding:0px;margin:auto;width:100%;cursor:pointer;outline:none;border:none;background-color:rgb(220, 220, 220)}button.svelte-b72wpv p.svelte-b72wpv{width:100%;margin:auto;text-align:center}button.svelte-b72wpv.svelte-b72wpv:hover{background-color:rgb(200, 200, 200)}button.svelte-b72wpv.svelte-b72wpv:active{background-color:rgb(190, 190, 190)}.list.svelte-b72wpv.svelte-b72wpv:not(:hover){background-color:rgb(240, 240, 240)}.list.svelte-b72wpv p.svelte-b72wpv{text-align:left}.transparent.svelte-b72wpv.svelte-b72wpv:not(:hover){background-color:transparent}.deactivate.svelte-b72wpv.svelte-b72wpv{background-color:transparent;pointer-events:none}.icon.svelte-b72wpv p.svelte-b72wpv{display:none}.icon.svelte-b72wpv.svelte-b72wpv:not(:hover){background-color:transparent}.icon.svelte-b72wpv.svelte-b72wpv{width:30px;height:100%;padding:0px}.dots.svelte-b72wpv.svelte-b72wpv::after{content:'\2807';font-size:20px;position:absolute;top:50%;left:0px;width:100%;height:auto;text-align:center;transform:translateY(-50%);cursor:pointer}.close.svelte-b72wpv.svelte-b72wpv::before{content:"";position:absolute;top:calc(50% - 1px);left:5px;width:20px;height:2px;background-color:black}.back.svelte-b72wpv.svelte-b72wpv::before{content:"";position:absolute;top:calc(50% - 6px - 1px);left:6px;width:14px;height:14px;border-left:1px solid black;border-bottom:1px solid black;transform:rotate(45deg)}.blocked.svelte-b72wpv.svelte-b72wpv{padding-left:30px}.blocked.svelte-b72wpv.svelte-b72wpv::before{content:"";position:absolute;top:calc(50% - 2px);left:10px;cursor:pointer;width:13px;height:10px;border-radius:2px;background-color:rgb(110, 110, 110)}.blocked.svelte-b72wpv.svelte-b72wpv::after{content:"";position:absolute;top:calc(50% - 9px);left:12px;cursor:pointer;width:9px;height:13px;border-radius:5px;box-sizing:border-box;border:3px solid rgb(110, 110, 110)}.chat_msg.svelte-14xxpbz.svelte-14xxpbz{margin:5px auto;padding:5px;border-radius:5px}.chat_msg.svelte-14xxpbz.svelte-14xxpbz{margin-left:0px;background-color:rgb(210, 210, 210);max-width:80%}.chat_msg.svelte-14xxpbz p.svelte-14xxpbz{padding:0px}.chat_msg.svelte-14xxpbz p.name.svelte-14xxpbz{margin:0px;font-size:12px;color:rgb(100, 100, 100)}.chat_msg.svelte-14xxpbz p.msg.svelte-14xxpbz{margin:5px 0px}.chat_msg.svelte-14xxpbz p.msg.svelte-14xxpbz *{display:inline}.chat_msg.me.svelte-14xxpbz.svelte-14xxpbz{margin-right:0px;margin-left:auto;background-color:rgb(210, 110, 10)}.chat_msg.me.svelte-14xxpbz p.name.svelte-14xxpbz{display:none}.chat_msg.SERVER.svelte-14xxpbz.svelte-14xxpbz{margin-left:auto;background-color:transparent}.chat_msg.SERVER.svelte-14xxpbz p.name.svelte-14xxpbz{display:none}.chat_msg.SERVER.svelte-14xxpbz p.msg.svelte-14xxpbz{margin:0px auto;font-size:12px;color:rgb(100, 100, 100)}

View File

@@ -1,85 +0,0 @@
```
fetch conversations
___________________
| _ |
| no conversation | if len == 0
| |
| [join public] |
| |
| [start new] |
| |
|...................|
| |
|___________________|
___________________
| convs _ |
|___________________| if len > 0
| |
| |
| |
| |
| |
|___________________|
| |send |
|_____________|_____|
___________________
| convs _ |
|_ ____________|
| .list |
| .of |
| .convs |
| |
| |
|___________________|
| |send |
|_____________|_____|
___________________
| [join public] _ |
| | if join_public
| .list | fetch public_conversations
| .of |
| .public |
| .convs |
| |
| |
| |
|___________________|
___________________
| [start new] _ |
| | if start_new
| .list | fetch friends
| .of |
| .friends |
| |
| |
| |
| |
|___________________|
___________________
| convs _ |
|___________________| if click_on_list_element
| .blablabla | fetch conversation(list_element)
| blablabla. |
| .bla | --server side--
| blabla. | if conversation_exist
| bla. | return text
|___________________| else if is_allowed
| |send | return "start conv"
|_____________|_____|
```
### goals :
- own messages are not sent to myself and directly printed
- i can create a room
- my messages are sent to other people in room
- i can choose in which room to send the messages
### routes :
- https://transcendance:8080/api/v2/chat/conversations
- returns list of objects, each object contains :
- id: unique conv identification
- title: name of the conversation (name of other guy if direct message)
-

View File

@@ -1,16 +0,0 @@
https://www.youtube.com/watch?v=7xpLYk4q0Sg
npm install (to install packages)
npm run start:dev
- [ ] can create chat-rooms (public/private, password protected)
- [ ] send direct messages
- [ ] block other users
- [ ] creators of chat-room are owners, untill they leave
- [ ] chat-room owner can set, change, remove password
- [ ] chat-room owner is administrator and can set other administrators
- [ ] administrators can ban or mute for a time other users
- [ ] send game invitation in chat
- [ ] view user profiles from chat

View File

@@ -1,57 +0,0 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="./style/chat.css" type="text/css" rel="stylesheet">
</head>
<body>
<input type="checkbox" id="chat_input" style="display: none;"/>
<div class="chat_box">
<div class="chat_item controls_area">
</div>
<label class="chat_item open_close button" for="chat_input">
<p>chat</p>
</label>
<div class="chat_item msg_thread">
<div class="msg_box" id="msg_thread">
</div>
</div>
<div class="chat_item msg_write">
<!--
<textarea class="text_area" id="msg_write">
</textarea>
-->
<div class="text_area" id="msg_write" contenteditable>
</div>
</div>
<button class="chat_item msg_send button" onclick="submit_new_message()">
<p>send</p>
</button>
</div>
<!-- https://socket.io/docs/v4/client-installation/ -->
<!-- https://socket.io/docs/v4/client-api/ -->
<script src="https://cdn.socket.io/4.5.3/socket.io.min.js" integrity="sha384-WPFUvHkB1aHA5TDSZi6xtDgkF0wXJcIIxXhC6h8OT8EH3fC5PWro5pWJ1THjcfEi" crossorigin="anonymous"></script>
<script>
const socket = io("http://localhost:3000");
socket.on("connect", () => {
console.log("client: connection");
});
</script>
<script src="./chat_submit_msg.js"></script>
<script src="./chat_receive_msg.js"></script>
</body>
</html>

View File

@@ -1,20 +0,0 @@
socket.on('message', ({ data }) => {
handle_new_message(data);
});
const handle_new_message = (message) => {
const div_thread = document.getElementById('msg_thread');
console.log("received message:");
console.log(`[${message}]`);
div_thread.appendChild(build_new_message(message));
}
const build_new_message = (message) => {
const p = document.createElement("p");
p.appendChild(document.createTextNode(message));
return p;
}

View File

@@ -1,17 +0,0 @@
const submit_new_message = () => {
const div_msg = document.getElementById('msg_write');
/*
const msg = div_msg.value;
const msg = div_msg.innerText;
*/
const msg = div_msg.innerText.trim();
console.log("msg:");
console.log(`[${msg}]`);
console.log(msg.length);
if (msg.length > 0)
socket.emit('message', { data: msg });
}

View File

@@ -1,103 +0,0 @@
@import 'msg_thread.css';
@import 'msg_write.css';
/**
* GRID
*/
/* global settings */
.chat_box * {
position: relative;
box-sizing: border-box;
}
.chat_box .chat_item.controls_area { grid-area: controls;}
.chat_box .chat_item.open_close { grid-area: open_close;}
.chat_box .chat_item.msg_thread { grid-area: msg_thread;}
.chat_box .chat_item.msg_write { grid-area: msg_write;}
.chat_box .chat_item.msg_send { grid-area: msg_send;}
.chat_box {
position: fixed;
bottom: 20px;
right: 20px;
display: grid;
grid:
' controls open_close ' auto
' msg_thread msg_thread ' 1fr
' msg_write msg_send ' auto
/ 1fr auto;
gap: 0px;
padding: 0px;
width: auto;
height: auto;
border: 1px solid green;
}
.chat_box .chat_item {
/*
border: 1px solid blue;
*/
}
/* buttons settings */
.chat_box .chat_item.button {
display: flex;
width: auto;
padding: 10px;
cursor: pointer;
outline: none;
border: none;
background-color: rgb(220, 220, 220);
}
.chat_box .chat_item.button p {
margin: auto;
}
.chat_box .chat_item.button:hover {
background-color: rgb(200, 200, 200);
}
.chat_box .chat_item.button:active {
background-color: rgb(220, 220, 220);
}
/* collapse settings */
.chat_box .chat_item:not(.open_close) {
display: none;
}
#chat_input:checked +
.chat_box {
gap: 5px;
padding: 5px;
width: 300px;
height: 400px;
}
#chat_input:checked +
.chat_box .chat_item {
display: flex;
}
#chat_input:checked +
.chat_box .chat_item.open_close p {
display: none;
}
#chat_input:checked +
.chat_box .chat_item.open_close {
/*
*/
width: 30px;
height: 20px;
padding: 0px;
justify-self: end;
background-color: transparent;
border: none;
}
#chat_input:checked +
.chat_box .chat_item.open_close::before {
--collapse_width: 20px;
content: "";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
height: 2px;
width: 15px;
background-color: black;
}

View File

@@ -1,4 +0,0 @@
.chat_box .chat_item .msg_box {
width: 100%;
border: 1px solid blue;
}

View File

@@ -1,16 +0,0 @@
.chat_box .text_area {
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
height: auto;
min-height: 100%;
max-height: 300px;
/*
resize: none;
*/
overflow-x: hidden;
overflow-y: scroll;
background-color: white;
border: 1px solid red;
}

View File

@@ -1,25 +0,0 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir : __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};

View File

@@ -1,4 +0,0 @@
{
"singleQuote": true,
"trailingComma": "all"
}

View File

@@ -1,73 +0,0 @@
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="200" alt="Nest Logo" /></a>
</p>
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
```
## Running the app
```bash
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
```
## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).

View File

@@ -1,3 +0,0 @@
export declare class AppController {
place_holder(): void;
}

View File

@@ -1,27 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppController = void 0;
const common_1 = require("@nestjs/common");
let AppController = class AppController {
place_holder() { }
};
__decorate([
(0, common_1.Get)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], AppController.prototype, "place_holder", null);
AppController = __decorate([
(0, common_1.Controller)()
], AppController);
exports.AppController = AppController;
//# sourceMappingURL=app.controller.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"app.controller.js","sourceRoot":"","sources":["../src/app.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiD;AAG1C,IAAM,aAAa,GAAnB,MAAM,aAAa;IAExB,YAAY,KAAI,CAAC;CAClB,CAAA;AAFC;IAAC,IAAA,YAAG,GAAE;;;;iDACW;AAFN,aAAa;IADzB,IAAA,mBAAU,GAAE;GACA,aAAa,CAGzB;AAHY,sCAAa"}

View File

@@ -1,2 +0,0 @@
export declare class AppModule {
}

View File

@@ -1,20 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppModule = void 0;
const common_1 = require("@nestjs/common");
const chat_gateway_1 = require("./chat.gateway");
let AppModule = class AppModule {
};
AppModule = __decorate([
(0, common_1.Module)({
providers: [chat_gateway_1.ChatGateway],
})
], AppModule);
exports.AppModule = AppModule;
//# sourceMappingURL=app.module.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,iDAA6C;AAKtC,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,SAAS;IAHrB,IAAA,eAAM,EAAC;QACN,SAAS,EAAE,CAAC,0BAAW,CAAC;KACzB,CAAC;GACW,SAAS,CAAG;AAAZ,8BAAS"}

View File

@@ -1,3 +0,0 @@
export declare class AppService {
getHello(): string;
}

View File

@@ -1,20 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppService = void 0;
const common_1 = require("@nestjs/common");
let AppService = class AppService {
getHello() {
return 'Hello World!';
}
};
AppService = __decorate([
(0, common_1.Injectable)()
], AppService);
exports.AppService = AppService;
//# sourceMappingURL=app.service.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"app.service.js","sourceRoot":"","sources":["../src/app.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAGrC,IAAM,UAAU,GAAhB,MAAM,UAAU;IACrB,QAAQ;QACN,OAAO,cAAc,CAAC;IACxB,CAAC;CACF,CAAA;AAJY,UAAU;IADtB,IAAA,mBAAU,GAAE;GACA,UAAU,CAItB;AAJY,gCAAU"}

View File

@@ -1,4 +0,0 @@
export declare class ChatGateway {
server: any;
handleMessage(message: string): void;
}

View File

@@ -1,43 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ChatGateway = void 0;
const websockets_1 = require("@nestjs/websockets");
let ChatGateway = class ChatGateway {
handleMessage(message) {
console.log("message received:");
console.log(`[${message}]`);
this.server.emit('message', message);
}
};
__decorate([
(0, websockets_1.WebSocketServer)(),
__metadata("design:type", Object)
], ChatGateway.prototype, "server", void 0);
__decorate([
(0, websockets_1.SubscribeMessage)('message'),
__param(0, (0, websockets_1.MessageBody)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [String]),
__metadata("design:returntype", void 0)
], ChatGateway.prototype, "handleMessage", null);
ChatGateway = __decorate([
(0, websockets_1.WebSocketGateway)({
cors: {
origin: '*',
},
})
], ChatGateway);
exports.ChatGateway = ChatGateway;
//# sourceMappingURL=chat.gateway.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"chat.gateway.js","sourceRoot":"","sources":["../src/chat.gateway.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,mDAK4B;AAOrB,IAAM,WAAW,GAAjB,MAAM,WAAW;IAKvB,aAAa,CAAgB,OAAe;QAC3C,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;CACD,CAAA;AATA;IAAC,IAAA,4BAAe,GAAE;;2CACX;AAEP;IAAC,IAAA,6BAAgB,EAAC,SAAS,CAAC;IACb,WAAA,IAAA,wBAAW,GAAE,CAAA;;;;gDAI3B;AATW,WAAW;IALvB,IAAA,6BAAgB,EAAC;QACjB,IAAI,EAAE;YACL,MAAM,EAAE,GAAG;SACX;KACD,CAAC;GACW,WAAW,CAUvB;AAVY,kCAAW"}

View File

@@ -1 +0,0 @@
export {};

View File

@@ -1,10 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@nestjs/core");
const app_module_1 = require("./app.module");
async function bootstrap() {
const app = await core_1.NestFactory.create(app_module_1.AppModule);
await app.listen(3000);
}
bootstrap();
//# sourceMappingURL=main.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,6CAAyC;AAEzC,KAAK,UAAU,SAAS;IACtB,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,CAAC,CAAC;IAChD,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AACD,SAAS,EAAE,CAAC"}

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +0,0 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src"
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,74 +0,0 @@
{
"name": "chat",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"@nestjs/platform-socket.io": "^9.2.0",
"@nestjs/websockets": "^9.2.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0",
"socket.io": "^4.5.3"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@types/express": "^4.17.13",
"@types/jest": "28.1.8",
"@types/node": "^16.0.0",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "28.1.3",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "28.0.8",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.1.0",
"typescript": "^4.7.4"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}

View File

@@ -1,7 +0,0 @@
import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
place_holder() {}
}

View File

@@ -1,7 +0,0 @@
import { Module } from '@nestjs/common';
import { ChatGateway } from './chat.gateway';
@Module({
providers: [ChatGateway],
})
export class AppModule {}

View File

@@ -1,24 +0,0 @@
import {
WebSocketGateway,
SubscribeMessage,
WebSocketServer,
MessageBody,
} from '@nestjs/websockets';
@WebSocketGateway({
cors: {
origin: '*',
},
})
export class ChatGateway {
@WebSocketServer()
server;
@SubscribeMessage('message')
handleMessage(@MessageBody() message: string): void {
console.log("message received:");
console.log(`[${message}]`);
this.server.emit('message', message);
}
}

View File

@@ -1,8 +0,0 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();

View File

@@ -1,24 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});

View File

@@ -1,9 +0,0 @@
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}

View File

@@ -1,4 +0,0 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}

View File

@@ -1,21 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
}
}

View File

@@ -1,22 +0,0 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir : __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};

View File

@@ -1,4 +0,0 @@
{
"singleQuote": true,
"trailingComma": "all"
}

View File

@@ -1,73 +0,0 @@
<p align="center">
<a href="http://nestjs.com/" target="blank"><img src="https://nestjs.com/img/logo-small.svg" width="200" alt="Nest Logo" /></a>
</p>
[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
[circleci-url]: https://circleci.com/gh/nestjs/nest
<p align="center">A progressive <a href="http://nodejs.org" target="_blank">Node.js</a> framework for building efficient and scalable server-side applications.</p>
<p align="center">
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/v/@nestjs/core.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/l/@nestjs/core.svg" alt="Package License" /></a>
<a href="https://www.npmjs.com/~nestjscore" target="_blank"><img src="https://img.shields.io/npm/dm/@nestjs/common.svg" alt="NPM Downloads" /></a>
<a href="https://circleci.com/gh/nestjs/nest" target="_blank"><img src="https://img.shields.io/circleci/build/github/nestjs/nest/master" alt="CircleCI" /></a>
<a href="https://coveralls.io/github/nestjs/nest?branch=master" target="_blank"><img src="https://coveralls.io/repos/github/nestjs/nest/badge.svg?branch=master#9" alt="Coverage" /></a>
<a href="https://discord.gg/G7Qnnhy" target="_blank"><img src="https://img.shields.io/badge/discord-online-brightgreen.svg" alt="Discord"/></a>
<a href="https://opencollective.com/nest#backer" target="_blank"><img src="https://opencollective.com/nest/backers/badge.svg" alt="Backers on Open Collective" /></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://opencollective.com/nest/sponsors/badge.svg" alt="Sponsors on Open Collective" /></a>
<a href="https://paypal.me/kamilmysliwiec" target="_blank"><img src="https://img.shields.io/badge/Donate-PayPal-ff3f59.svg"/></a>
<a href="https://opencollective.com/nest#sponsor" target="_blank"><img src="https://img.shields.io/badge/Support%20us-Open%20Collective-41B883.svg" alt="Support us"></a>
<a href="https://twitter.com/nestframework" target="_blank"><img src="https://img.shields.io/twitter/follow/nestframework.svg?style=social&label=Follow"></a>
</p>
<!--[![Backers on Open Collective](https://opencollective.com/nest/backers/badge.svg)](https://opencollective.com/nest#backer)
[![Sponsors on Open Collective](https://opencollective.com/nest/sponsors/badge.svg)](https://opencollective.com/nest#sponsor)-->
## Description
[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
## Installation
```bash
$ npm install
```
## Running the app
```bash
# development
$ npm run start
# watch mode
$ npm run start:dev
# production mode
$ npm run start:prod
```
## Test
```bash
# unit tests
$ npm run test
# e2e tests
$ npm run test:e2e
# test coverage
$ npm run test:cov
```
## Support
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
## Stay in touch
- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
- Website - [https://nestjs.com](https://nestjs.com/)
- Twitter - [@nestframework](https://twitter.com/nestframework)
## License
Nest is [MIT licensed](LICENSE).

View File

@@ -1,3 +0,0 @@
export declare class AppController {
getHello(): void;
}

View File

@@ -1,27 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppController = void 0;
const common_1 = require("@nestjs/common");
let AppController = class AppController {
getHello() { }
};
__decorate([
(0, common_1.Get)(),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", void 0)
], AppController.prototype, "getHello", null);
AppController = __decorate([
(0, common_1.Controller)()
], AppController);
exports.AppController = AppController;
//# sourceMappingURL=app.controller.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"app.controller.js","sourceRoot":"","sources":["../src/app.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiD;AAG1C,IAAM,aAAa,GAAnB,MAAM,aAAa;IAGxB,QAAQ,KAAI,CAAC;CACd,CAAA;AAFC;IAAC,IAAA,YAAG,GAAE;;;;6CACO;AAHF,aAAa;IADzB,IAAA,mBAAU,GAAE;GACA,aAAa,CAIzB;AAJY,sCAAa"}

View File

@@ -1,2 +0,0 @@
export declare class AppModule {
}

View File

@@ -1,22 +0,0 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppModule = void 0;
const common_1 = require("@nestjs/common");
const app_controller_1 = require("./app.controller");
let AppModule = class AppModule {
};
AppModule = __decorate([
(0, common_1.Module)({
imports: [],
controllers: [app_controller_1.AppController],
providers: [],
})
], AppModule);
exports.AppModule = AppModule;
//# sourceMappingURL=app.module.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,qDAAiD;AAO1C,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,SAAS;IALrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,EAAE;QACX,WAAW,EAAE,CAAC,8BAAa,CAAC;QAC5B,SAAS,EAAE,EAAE;KACd,CAAC;GACW,SAAS,CAAG;AAAZ,8BAAS"}

View File

@@ -1 +0,0 @@
export {};

View File

@@ -1,10 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@nestjs/core");
const app_module_1 = require("./app.module");
async function bootstrap() {
const app = await core_1.NestFactory.create(app_module_1.AppModule);
await app.listen(8000);
}
bootstrap();
//# sourceMappingURL=main.js.map

View File

@@ -1 +0,0 @@
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;AAAA,uCAA2C;AAC3C,6CAAyC;AAEzC,KAAK,UAAU,SAAS;IACtB,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,CAAC,CAAC;IAChD,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AACD,SAAS,EAAE,CAAC"}

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +0,0 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src"
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +0,0 @@
{
"name": "chat_nest_2",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"prebuild": "rimraf dist",
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@types/express": "^4.17.13",
"@types/jest": "28.1.8",
"@types/node": "^16.0.0",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "28.1.3",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "28.0.8",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.1.0",
"typescript": "^4.7.4"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}

View File

@@ -1,8 +0,0 @@
import { Controller, Get } from '@nestjs/common';
@Controller()
export class AppController {
@Get()
getHello() {}
}

View File

@@ -1,9 +0,0 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
@Module({
imports: [],
controllers: [AppController],
providers: [],
})
export class AppModule {}

View File

@@ -1,11 +0,0 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors(options:{
origin: ['http://localhost:3000']
});
await app.listen(8000);
}
bootstrap();

View File

@@ -1,24 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from './../src/app.module';
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
});

View File

@@ -1,9 +0,0 @@
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": ".",
"testEnvironment": "node",
"testRegex": ".e2e-spec.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}

View File

@@ -1,4 +0,0 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}

View File

@@ -1,21 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
}
}

View File

@@ -1,54 +0,0 @@
- [socket io multi room chat](http://psitsmike.com/2011/10/node-js-and-socket-io-multiroom-chat-tutorial/)
first time :
npm install --save express socket.io cors
sudo npm install -g nodemon
next time :
npm install
anytime :
nodemon server
- [ ] don't send message to oneself
- [ ] create a room
- [ ] automatically add someone to a room
- [ ] being able to accept or refuse to be added to a room
- [ ] what to do with message not received ?
```
-> create_public_conv( room_name );
-> create_private_conv( room_name );
-> create_protected_conv( room_name );
-> create_direct_conv( room_name );
-> change_conv( room_name );
-> get_conv_history( room_name );
-> get_last_conv();
-> get_my_convs_directs( );
-> get_my_convs_rooms( );
-> get_public_convs( );
[ list ][ create ][ join ]
"directs" . [direct] (public and protected)
"rooms" . [room]
. public
. private
. protected
on connection :
get_convs_directs();
get_convs_rooms();
last_conv = get_last_conv();
if (last_conv)
get_conv_history(last_conv);
```
## todo:
- check if drop down menu works also with buttons instead of <div tabindex=0>
- add window for option when select 'room'

View File

@@ -1,32 +0,0 @@
/*
*/
let test = document.createElement('form');
test.innerHTML = `
<button onclick="chat_layout(this.innerText)" type="reset">close</button>
<br><br><button onclick="chat_layout(this.innerText)" type="reset">home</button>
<br><br><button onclick="chat_layout(this.innerText)" type="reset">room</button>
<br><br><button onclick="chat_layout(this.innerText)" type="reset">new</button>
<br><br><button onclick="chat_layout(this.innerText)" type="reset">settings</button>
<br><br><button onclick="chat_layout(this.innerText)" type="reset">room_set</button>
<br><br><button onclick="chat_layout(this.innerText)" type="reset">protected</button>
<br><br><button onclick="chat_layout(this.innerText)" type="reset">create</button>
<br><br><button onclick="chat_layout(this.innerText)" type="reset">user</button>
<br><br><label><input onchange="chat_layout_toggle(this.nextElementSibling.innerText)" type="checkbox"><span>_blocked</span></label>
<br><br><label><input onchange="chat_layout_toggle(this.nextElementSibling.innerText)" type="checkbox"><span>_admin</span></label>
<br><br><label><input onchange="chat_layout_toggle(this.nextElementSibling.innerText)" type="checkbox"><span>_muted</span></label>
<br><br><label><input onchange="chat_layout_replace('_settings', '_room_set')" type="radio" name="form_from"><span>_room_set</span></label>
<br><br><label><input onchange="chat_layout_replace('_room_set', '_settings')" type="radio" name="form_from"><span>_settings</span></label>
<br><br><button onclick="chat_layout(this.innerText)" type="reset">mute</button>
`;
document.body.prepend(test);
function chat_layout_toggle(layout_class) {
document.getElementById('chat_box').classList.toggle(layout_class);
};
function chat_layout_replace(_old, _new) {
let chat = document.getElementById('chat_box');
chat.classList.remove(_old);
chat.classList.add(_new);
};

View File

@@ -1,444 +0,0 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="./style/chat.css" type="text/css" rel="stylesheet">
<script src="./_test_layouts.js" defer></script>
</head>
<body>
<div class="close" id="chat_box">
<!--
classes:
1. close -> layout close
2. home -> layout home
3. room -> layout room
4. new -> layout new
5. settings -> layout settings
6. room_set -> layout room_set
7. protected -> layout protected
8. create -> layout create
9. mute -> layout mute
10. user -> layout user
11. _blocked -> for user layout : user is blocked
12. _muted -> for user layout : user is muted
13. _admin -> for user layout : you are admin
14. _room_set -> for user layout : comes from room_set
15. _settings -> for user layout : comes from settings
classes for layout must replace the entire previous class
but classes starting with "_" must be added to existing class
-->
<button class="chat_item chat_chat btn" id="chat_chat" onclick="chat_layout('home')" ><p>chat</p></button>
<button class="chat_item chat_close btn" id="chat_close" onclick="chat_layout('close')" title="close" ></button>
<button class="chat_item chat_new btn" id="chat_new" onclick="chat_layout('new')" title="new" ><p>new</p></button>
<button class="chat_item chat_settings btn" id="chat_settings" onclick="chat_layout('settings')" title="settings"><p>settings</p></button>
<button class="chat_item chat_room_name btn" id="chat_room_name" onclick="chat_layout('room_set')" ><p>&lt;room_name&gt;</p></button>
<p class="chat_item chat_create" id="chat_create" >create</p>
<p class="chat_item chat_user" id="chat_user" >&lt;user_name&gt;</p>
<div class="chat_item chat_back" id="chat_back"></button>
<button class="btn back_room" onclick="chat_layout('room')" title="go back room"></button>
<button class="btn back_home" onclick="chat_layout('home')" title="go back home"></button>
<button class="btn back_new" onclick="chat_layout('new')" title="go back new"></button>
<button class="btn back_user" onclick="chat_layout('user')" title="go back user"></button>
<button class="btn back_settings" onclick="chat_layout('settings')" title="go back settings"></button>
<button class="btn back_room_set" onclick="chat_layout('room_set')" title="go back room settings"></button>
</div>
<!-- --------------------------------
PANELS
- HOME
- MSG
- NEW
- SETTINGS
- ROOM SET
- PROTECTED
- CREATE
- USER
- MUTE
- WRITE
--------------------------------- -->
<!-- HOME -->
<div class="chat_item chat_panel chat_panel_home" id="chat_panel_home">
<p class="__center">list of your rooms :</p>
<div id="chat_api_room_list" class="chat_api list_btn">
<div class="chat_room_name __show_if_only_child">
<p class="__center">/ you have no chat room yet /</p>
</div>
<!-- placeholders
------------- -->
<button class="chat_room_name btn" onclick="chat_layout('room')">
<p class="__left">a room</p>
</button>
<button class="chat_room_name btn" onclick="chat_layout('room')">
<p class="__left">another room</p>
</button>
<button class="chat_room_name btn" onclick="chat_layout('room')">
<p class="__left">placeholder</p>
</button>
<!-- END placeholders -->
</div>
</div>
<!-- NEW -->
<div class="chat_item chat_panel chat_panel_new" id="chat_panel_new">
<button class="chat_create_btn btn"><p>create</p></button>
<p>join room :</p>
<div id="chat_api_publics_rooms" class="chat_api chat_public_rooms list_btn">
<div class="__show_if_only_child">
<p class="__center">/ there are no public rooms yet /</p>
</div>
<!-- placeholders
------------- -->
<button class="chat_room_name btn" onclick="chat_layout('room')">
<p class="__left">join room</p>
</button>
<button class="chat_room_name btn" onclick="chat_layout('room')">
<p class="__left">one room</p>
</button>
<button class="chat_room_name btn" onclick="chat_layout('room')">
<p class="__left">another room</p>
</button>
<button class="chat_room_name btn" onclick="chat_layout('room')">
<p class="__left">one more room</p>
</button>
<!-- END placeholders -->
</div>
</div>
<!-- SETTINGS -->
<div class="chat_item chat_panel chat_panel_settings" id="chat_panel_settings">
<p>blocked users :</p>
<div id="chat_api_blocked_users" class="chat_api chat_blocked_users list_btn">
<!-- placeholders
------------- -->
<button class="chat_user btn" onclick="chat_layout('user _settings')">
<p class="__left blocked">user 1</p>
</button>
<button class="chat_user btn" onclick="chat_layout('user _settings')">
<p class="__left blocked">user 2</p>
</button>
<button class="chat_user btn" onclick="chat_layout('user _settings')">
<p class="__left blocked">user 3</p>
</button>
<button class="chat_user btn" onclick="chat_layout('user _settings')">
<p class="__left blocked">user 4</p>
</button>
<!-- END placeholders -->
</div>
</div>
<!-- ROOM SET -->
<div class="chat_item chat_panel chat_panel_room_set" id="chat_panel_room_set">
<button class="chat_leave_btn btn"><p>leave</p></button>
<p>room users :</p>
<div id="chat_api_room_users" class="chat_api chat_room_users list_btn">
<div class="chat_public_rooms __show_if_only_child">
<p class="__center">/ there are no public rooms yet /</p>
</div>
<!-- placeholders
------------- -->
<button class="chat_room_name btn" onclick="chat_layout('user _room_set')">
<p class="__left">user 1</p>
</button>
<button class="chat_room_name btn" onclick="chat_layout('user _room_set')">
<p class="__left blocked">user 2</p>
</button>
<button class="chat_room_name btn" onclick="chat_layout('user _room_set')">
<p class="__left">user 3</p>
</button>
<button class="chat_room_name btn" onclick="chat_layout('user _room_set')">
<p class="__left">user 4</p>
</button>
<!-- END placeholders -->
</div>
</div>
<!-- PROTECTED -->
<div class="chat_item chat_panel chat_panel_protected" id="chat_panel_protected">
<p class="__center" id="chat_protected_title">this room is protected</p>
<form>
<label for="chat_pswd"><p>password :</p></label>
<input id="chat_pswd" type="password" required>
<input type="submit" value="&#x2BA1">
</form>
</div>
<!-- CREATE -->
<div class="chat_item chat_panel chat_panel_create" id="chat_panel_create">
<form>
<!-- name: -->
<label for="chat_name"><p>name :</p></label>
<input id="chat_name" required>
<!-- [ ] pubic -->
<input id="chat_public" type="radio" name="chat_create_type" checked>
<label for="chat_public" class="_radio"><p>public</p></label>
<!-- [ ] private -->
<input id="chat_private" type="radio" name="chat_create_type">
<label for="chat_private" class="_radio"><p>private</p></label>
<!-- [ ] protected -->
<input id="chat_protected" class="_check_change_next" type="radio" name="chat_create_type">
<label for="chat_protected" class="_radio"><p>protected</p></label>
<!-- [x] protected -->
<div class="__content _is_hidden">
<label for="chat_pswd"><p>choose a password :</p></label>
<input id="chat_pswd" type="password" placeholder="minimum 8 characters" minlength="8">
<p>confirm password :</p>
<input type="password">
</div>
<input type="submit" value="&#x2BA1">
</form>
</div>
<!-- USER -->
<div class="chat_item chat_panel chat_panel_user" id="chat_panel_user">
<p class="__center">user options :</p>
<div class="chat_user_btn_wrapper">
<button class="chat_profile_btn btn"><p>view profile</p></button>
<button class="chat_game_btn btn"><p>game invitation</p></button>
<button class="chat_block_btn btn">
<p id="chat_user_block">block</p>
<p id="chat_user_unblock">unblock</p>
</button>
<div id="chat_user_admin">
<button class="chat_admin_btn btn"><p>make admin</p></button>
<button class="chat_mute_btn btn" id="chat_mute_btn">
<p id="chat_user_mute">mute</p>
<p id="chat_user_unmute">unmute</p>
</button>
</div>
</div>
</div>
<!-- MUTE -->
<div class="chat_item chat_panel chat_panel_mute" id="chat_panel_mute">
<p class="__center">mute this user for a time :</p>
<form>
<!-- forever -->
<input id="chat_mute_forever" type="checkbox" class="_check_change_next"></input>
<label for="chat_mute_forever" class="_checkbox"><p>forever</p></label>
<div class="__content _is_not_gray">
<!-- minutes -->
<label for="chat_mute_minutes" class="_select">
<p>minutes :</p>
<select id="chat_mute_minutes">
<option value="01">00</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="30">30</option>
<option value="31">31</option>
<option value="32">32</option>
<option value="33">33</option>
<option value="34">34</option>
<option value="35">35</option>
<option value="36">36</option>
<option value="37">37</option>
<option value="40">40</option>
<option value="41">41</option>
<option value="42">42</option>
<option value="43">43</option>
<option value="44">44</option>
<option value="45">45</option>
<option value="46">46</option>
<option value="47">47</option>
<option value="50">50</option>
<option value="51">51</option>
<option value="52">52</option>
<option value="53">53</option>
<option value="54">54</option>
<option value="55">55</option>
<option value="56">56</option>
<option value="57">57</option>
<option value="60">60</option>
</select>
</label>
<!-- hours -->
<label for="chat_mute_hours" class="_select">
<p>hours :</p>
<select id="chat_mute_hours">
<option value="01">00</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="30">30</option>
<option value="31">31</option>
<option value="32">32</option>
<option value="33">33</option>
<option value="34">34</option>
<option value="35">35</option>
<option value="36">36</option>
<option value="37">37</option>
<option value="40">40</option>
<option value="41">41</option>
<option value="42">42</option>
<option value="43">43</option>
<option value="44">44</option>
<option value="45">45</option>
<option value="46">46</option>
<option value="47">47</option>
<option value="50">50</option>
<option value="51">51</option>
<option value="52">52</option>
<option value="53">53</option>
<option value="54">54</option>
<option value="55">55</option>
<option value="56">56</option>
<option value="57">57</option>
<option value="60">60</option>
</select>
</label>
<!-- days -->
<label for="chat_mute_days" class="_select">
<p>days :</p>
<select id="chat_mute_days">
<option value="00">00</option>
<option value="01">01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
<option value="13">13</option>
<option value="14">14</option>
<option value="15">15</option>
<option value="16">16</option>
<option value="17">17</option>
<option value="20">20</option>
<option value="21">21</option>
<option value="22">22</option>
<option value="23">23</option>
<option value="24">24</option>
<option value="25">25</option>
<option value="26">26</option>
<option value="27">27</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
</label>
</div>
<input type="submit" value="&#x2BA1">
</form>
</div>
<!-- MSG -->
<div class="chat_item chat_panel chat_panel_msg" id="chat_panel_msg">
<div id="chat_api_msg_thread" class="chat_api">
<!-- placeholders
------------- -->
<div class="chat_msg bob">
<p class="name">bob</p>
<p class="msg">hello</p>
</div>
<div class="chat_msg me">
<p class="name">me</p>
<p class="msg">hello</p>
</div>
<!-- END placeholders -->
</div>
</div>
<!-- WRITE -->
<div class="chat_item chat_panel chat_panel_write" id="chat_panel_write">
<!--
<textarea class="text_area" id="chat_msg_write" onkeypress="send_msg_if(event)" placeholder="type here"></textarea>
-->
<div class="text_area" id="chat_msg_write" onkeypress="send_msg_if(event)" contenteditable="true" ></div>
</div>
<!-- send -->
<button class="chat_item chat_send btn" id="chat_send" onclick="send_msg()" title="send"><p>send</p></button>
<!-- --------------------------------
MODELS
<div class="chat_model" id="chat_model_myroom_name">
</div>
<div class="chat_model" id="chat_model_msg">
</div>
<div class="chat_model" id="chat_model_room_name">
</div>
<div class="chat_model" id="chat_model_blocked_user">
</div>
<div class="chat_model" id="chat_model_room_user">
</div>
--------------------------------- -->
</div>
<script>
function chat_layout(layout_class) {
document.getElementById('chat_box').className = layout_class;
};
</script>
<!-- https://socket.io/docs/v4/client-installation/ -->
<script src="https://cdn.socket.io/4.5.3/socket.io.min.js" integrity="sha384-WPFUvHkB1aHA5TDSZi6xtDgkF0wXJcIIxXhC6h8OT8EH3fC5PWro5pWJ1THjcfEi" crossorigin="anonymous"></script>
<script>
const socket = io("http://localhost:3000");
socket.on("connect", () => {
console.log("client: connection");
});
</script>
<script src="./chat_connection.js"></script>
<script src="./chat_send_msg.js"></script>
<script src="./chat_add_msg.js"></script>
<script src="./chat_create_room.js"></script>
<script src="./event_updatemsg.js"></script>
<script src="./event_updaterooms.js"></script>
</body>
</html>

View File

@@ -1,59 +0,0 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#chat_box * {
display: flex;
flex-direction: column;
position: relative;
box-sizing: border-box;
padding: 0px;
margin: auto;
}
#chat_box .chat_item {
display: none;
width: 100%;
height: 100%;
}
.chat_item#chat_chat {
grid-area: chat;
}
#chat_box {
display: grid;
position: fixed;
bottom: 20px;
right: 20px;
gap: 5px;
padding: 5px;
width: 300px;
height: 400px;
border: 1px solid black;
}
#chat_box.close {
gap: 0px;
padding: 0px;
width: auto;
height: auto;
grid:
' chat ' auto
/ auto ;
}
#chat_box.close .chat_item#chat_chat {
display: flex;
}
</style>
</head>
<body>
<div class="close" id="chat_box">
<button class="chat_item chat_chat btn" id="chat_chat"><p>chat</p></button>
</div>
</body>
</html>

View File

@@ -1,32 +0,0 @@
const add_message = (from, message ) => {
const div_thread = document.getElementById('chat_api_msg_thread');
div_thread.appendChild(build_new_message(from, message));
}
const build_new_message = (from, message) => {
const div = document.createElement("div");
const p_name = document.createElement("p");
const p_msg = document.createElement("p");
div.classList.add("chat_msg");
div.classList.add(from);
p_name.classList.add("name");
p_msg.classList.add("msg");
p_name.appendChild(document.createTextNode(from + " :"));
p_msg.appendChild(document.createTextNode(message));
div.appendChild(p_name);
div.appendChild(p_msg);
return div;
}
/*
<div class="chat_msg bob">
<p class="name">bob</p>
<p class="msg">hello</p>
</div>
*/

View File

@@ -1,3 +0,0 @@
//const add_room = (rooms, newroom) => {
//
//};

View File

@@ -1,5 +0,0 @@
socket.on('connect', () => {
//socket.emit('adduser', prompt("what's your name ?"));
socket.emit('adduser', "glurk");
//socket.emit('joinlastroom');
});

View File

@@ -1,5 +0,0 @@
let create_room = () => {
let room_name = prompt("room name ?");
socket.emit('createroom', room_name);
};

View File

@@ -1,32 +0,0 @@
function send_msg()
{
const div_msg = document.getElementById('chat_msg_write');
let msg = "";
if (div_msg.localName === "div")
{
msg = div_msg.innerText.trim();
div_msg.innerText = "";
}
else if (div_msg.localName === "textarea")
{
msg = div_msg.value.trim();
div_msg.value = "";
}
div_msg.focus();
console.log(msg);
if (msg.length > 0) {
socket.emit('sendmsg', msg);
add_message("me", msg);
}
}
function send_msg_if(evt)
{
if (evt.shiftKey && evt.key === "Enter")
{
evt.preventDefault();
send_msg();
}
}

View File

@@ -1,5 +0,0 @@
socket.on('updatemsg', (from, data) => {
console.log("data: " + data);
add_message(from, data);
});

View File

@@ -1,30 +0,0 @@
socket.on('updaterooms', (rooms) => {
let div_rooms = document.getElementById("rooms");
console.log("rooms: ");
console.log(rooms);
// let div_room_count = div_rooms.childElementCount;
// let div_room_list = document.getElementsByClassName("room_name");
// console.log(".div_room_list: ");
// console.log(div_room_list);
// for(let room of div_room_list) {
// console.log(room);
// console.log(room.innerHTML);
// }
div_rooms.innerHTML = "";
for (let room of rooms) {
//console.log(room.name);
const label = document.createElement("label");
const p = document.createElement("p");
const p_content = document.createTextNode(room.name);
label.setAttribute('for', "input_outside");
p.className = "room_name";
p.appendChild(p_content);
label.appendChild(p);
div_rooms.appendChild(label);
}
});

View File

@@ -1,82 +0,0 @@
/*
*/
@import 'chat__global.css';
@import 'layout_close.css';
@import 'layout_home.css';
@import 'layout_room.css';
@import 'layout_new.css';
@import 'layout_settings.css';
@import 'layout_room_set.css';
@import 'layout_protected.css';
@import 'layout_create.css';
@import 'layout_user.css';
@import 'layout_mute.css';
@import 'chat_panels.css';
@import 'chat_buttons.css';
@import 'chat_back.css';
@import 'chat_close.css';
@import 'chat_write.css';
@import 'chat_msg.css';
@import 'chat_blocked.css';
@import 'chat_form.css';
/*
GRID
*/
#chat_box * {
display: flex;
flex-direction: column;
position: relative;
box-sizing: border-box;
padding: 0px;
margin: auto;
}
#chat_box .chat_item {
display: none;
/*
border: 1px solid black;
*/
width: 100%;
height: 100%;
}
.chat_item#chat_chat { grid-area: chat;}
.chat_item#chat_close { grid-area: close;}
.chat_item#chat_new { grid-area: new;}
.chat_item#chat_settings { grid-area: settings;}
.chat_item#chat_room_name { grid-area: room_name;}
.chat_item#chat_send { grid-area: send;}
.chat_item#chat_create { grid-area: create;}
.chat_item#chat_user { grid-area: user;}
.chat_item#chat_back { grid-area: back;}
.chat_item#chat_panel_home { grid-area: panel_home;}
.chat_item#chat_panel_new { grid-area: panel_new;}
.chat_item#chat_panel_msg { grid-area: panel_msg;}
.chat_item#chat_panel_write { grid-area: panel_write;}
.chat_item#chat_panel_settings { grid-area: panel_settings;}
.chat_item#chat_panel_room_set { grid-area: panel_room_set;}
.chat_item#chat_panel_protected { grid-area: panel_protected;}
.chat_item#chat_panel_create { grid-area: panel_create;}
.chat_item#chat_panel_user { grid-area: panel_user;}
.chat_item#chat_panel_mute { grid-area: panel_mute;}
#chat_box {
display: grid;
position: fixed;
bottom: 20px;
right: 20px;
gap: 5px;
padding: 5px;
width: 300px;
height: 400px;
border: 1px solid black;
}

View File

@@ -1,67 +0,0 @@
/* Hide scrollbar
*/
#chat_box * {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
#chat_box *::-webkit-scrollbar {
display: none; /* Chrome, Safari and Opera */
}
/* p in chat_box
*/
#chat_box p {
padding: 10px;
font-size: 15px;
font-family: Cantarell;
}
/* show child only if it's alone
*/
#chat_box .__show_if_only_child {
display: none;
}
#chat_box .__show_if_only_child:only-child {
display: flex;
color: rgb(100, 100, 100);
}
/* separation line under controls
*/
#chat_box .chat_item.chat_panel {
border-top: 1px solid black;
}
/* text align
*/
#chat_box p.__center {
text-align: center;
}
#chat_box p.__left {
text-align: left;
}
#chat_box p.__right {
text-align: right;
}
/* default align items
*/
#chat_box .chat_item > * {
margin: 0px;
}
/* display content
*/
#chat_box .__content{
display: content;
}

View File

@@ -1,39 +0,0 @@
/*
https://www.fileformat.info/info/unicode/category/So/list.htm
U+1F512 LOCK 🔒
U+1F513 OPEN LOCK 🔓
*/
#chat_box .blocked {
padding-left: 30px;
}
#chat_box .blocked::before {
content: "";
position: absolute;
top: calc(50% - 2px);
left: 10px;
cursor: pointer;
width: 13px;
height: 10px;
border-radius: 2px;
/*
*/
background-color: rgb(110, 110, 110);
}
#chat_box .blocked::after {
content: "";
position: absolute;
top: calc(50% - 9px);
left: 12px;
cursor: pointer;
width: 9px;
height: 13px;
border-radius: 5px;
box-sizing: border-box;
/*
background-color: red;
*/
border: 3px solid rgb(110, 110, 110);
}

View File

@@ -1,55 +0,0 @@
#chat_box button {
display: flex;
width: auto;
cursor: pointer;
outline: none;
border: none;
background-color: rgb(220, 220, 220);
}
#chat_box button p {
width: 100%;
text-align: center;
}
#chat_box button.chat_item:hover,
#chat_box .chat_item button:hover {
background-color: rgb(200, 200, 200);
}
#chat_box button.chat_item:active,
#chat_box .chat_item button:active {
background-color: rgb(190, 190, 190);
}
/* BTN LIST
add or remove '.btn' to toggle the hover effect
*/
#chat_box .list_btn button {
margin: 0px;
background-color: transparent;
}
#chat_box .list_btn {
background-color: rgb(240, 240, 240);
}
/* BACK
*/
#chat_box .chat_item.chat_back button {
width: 30px;
height: 100%;
background-color: transparent;
display: none;
}
#chat_box .chat_item.chat_back button::before {
content: "";
position: absolute;
top: calc(50% - 6px - 1px);
left: 6px;
width: 14px;
height: 14px;
border-left: 1px solid black;
border-bottom: 1px solid black;
transform: rotate(45deg);
}

View File

@@ -1,20 +0,0 @@
#chat_box .chat_item#chat_close {
width: 30px;
}
/* add or remove '.chat_item' to toggle the hover effect */
#chat_box button.chat_item.chat_close {
width: 100%;
height: 100%;
padding: 0px;
background-color: transparent;
}
#chat_close::before {
content: "";
position: absolute;
top: calc(50% - 1px);
left: 5px;
width: 20px;
height: 2px;
background-color: black;
}

View File

@@ -1,120 +0,0 @@
/* default element take all space on each line
*/
#chat_box .chat_item form {
margin: 0px auto;
}
#chat_box .chat_item form * {
margin: 0px;
}
/* radio elements style check
*/
#chat_box .chat_item form input[type=radio] {
display: none;
}
#chat_box .chat_item form label._radio {
margin: 0px 0px 0px auto;
padding-right: 10px;
cursor: pointer;
}
#chat_box .chat_item form label._radio::after {
content: "";
position: absolute;
top: calc(50% - 6px);
right: 0px;
width: 12px;
height: 12px;
border-radius: 6px;
border: 2px solid rgb(150, 150, 150);
box-sizing: border-box;
cursor: pointer;
}
#chat_box .chat_item form input[type=radio]:checked
+ label._radio::after {
background-color: rgb(200, 200, 200);
}
/* change next element on check
*/
#chat_box form ._check_change_next:checked ~ ._is_hidden {
display: flex;
}
#chat_box form ._check_change_next:checked ~ ._is_not_gray {
pointer-events: none;
color: rgb(100, 100, 100);
}
#chat_box form ._is_hidden {
display: none;
}
/* submit button
https://www.fileformat.info/info/unicode/category/So/list.htm
U+21AA RIGHTWARDS ARROW WITH HOOK ↪
U+21B3 DOWNWARDS ARROW WITH TIP RIGHTWARDS ↳
U+2BA1 DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS ⮡
U+2BB1 RIBBON ARROW DOWN RIGHT ⮱
U+2BA9 BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW ⮩
*/
#chat_box .chat_item form input[type=submit] {
padding: 0px 10px;
border: none;
margin: 10px 0px 0px auto;
cursor: pointer;
background-color: rgb(220, 220, 220);
}
#chat_box .chat_item form input[type=submit]:hover {
background-color: rgb(200, 200, 200);
}
/* select
*/
#chat_box .chat_item form label._select {
flex-direction: row;
margin-left: auto;
}
#chat_box .chat_item form select {
margin: auto 0px;
background-color: rgb(220, 220, 220);
border: none;
padding: 5px;
cursor: pointer;
}
#chat_box .chat_item form select:hover {
background-color: rgb(200, 200, 200);
}
/* checkbox
<input id="chat_mute_forever" type="checkbox" class="_checkbox"></input>
<label for="chat_mute_forever">forever</label>
*/
#chat_box .chat_item form input[type=checkbox] {
display: none;
}
#chat_box .chat_item form label._checkbox {
margin: 0px 0px 0px auto;
padding-right: 10px;
cursor: pointer;
}
#chat_box .chat_item form label._checkbox::after {
content: "";
position: absolute;
top: calc(50% - 6px);
right: 0px;
width: 12px;
height: 12px;
border: 2px solid rgb(150, 150, 150);
box-sizing: border-box;
cursor: pointer;
}
#chat_box .chat_item form input[type=checkbox]:checked
+ label._checkbox::after {
background-color: rgb(200, 200, 200);
}

View File

@@ -1,75 +0,0 @@
#chat_box #chat_panel_msg {
flex-direction: column-reverse;
overflow: scroll;
border: 1px solid black;
}
#chat_box #chat_panel_msg #chat_api_msg_thread {
flex-direction: column;
width: 100%;
padding: 0px 5px;
margin-bottom: 0px;
}
#chat_box #chat_panel_msg #chat_api_msg_thread .chat_msg {
white-space: pre-wrap;
margin: 5px auto;
padding: 5px;
border-radius: 5px;
}
/* * * * * * * * * * * * * *
ALL MSG
*/
#chat_box #chat_panel_msg #chat_api_msg_thread .chat_msg {
margin-left: 0px;
background-color: rgb(210, 210, 210);
max-width: 80%;
}
#chat_box #chat_panel_msg #chat_api_msg_thread .chat_msg p {
padding: 0px;
}
#chat_box #chat_panel_msg #chat_api_msg_thread .chat_msg p.name {
margin: 0px;
margin-bottom: 5px;
font-size: 12px;
color: rgb(100, 100, 100);
}
#chat_box #chat_panel_msg #chat_api_msg_thread .chat_msg p.msg {
/*
margin: 5px 0px;
line-height: 8px;
*/
}
/* * * * * * * * * * * * * *
MSG PERSO
*/
#chat_box #chat_panel_msg #chat_api_msg_thread .chat_msg.me {
margin-right: 0px;
margin-left: auto;
background-color: rgb(210, 110, 10);
}
#chat_box #chat_panel_msg #chat_api_msg_thread .chat_msg.me p.name {
display: none;
}
/* * * * * * * * * * * * * *
MSG SERVER
*/
#chat_box #chat_panel_msg #chat_api_msg_thread .chat_msg.SERVER {
margin-left: auto;
background-color: transparent;
}
#chat_box #chat_panel_msg #chat_api_msg_thread .chat_msg.SERVER p.name {
display: none;
}
#chat_box #chat_panel_msg #chat_api_msg_thread .chat_msg.SERVER p.msg {
margin: 0px auto;
font-size: 12px;
color: rgb(100, 100, 100);
}

View File

@@ -1,3 +0,0 @@
#chat_box .chat_panel {
overflow-y: scroll;
}

View File

@@ -1,36 +0,0 @@
#chat_box .chat_item#chat_panel_write {
border: none;
overflow: visible;
}
#chat_box .chat_item#chat_panel_write .text_area {
display: block;
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
overflow-x: hidden;
overflow-y: scroll;
background-color: white;
border: 1px solid black;
}
#chat_box .chat_item#chat_panel_write .text_area * {
display: block ruby;
}
/* if .text_area is a contenteditable div
*/
#chat_box .chat_item#chat_panel_write .text_area {
height: auto;
min-height: 100%;
max-height: 300px;
}
/* if .text_area is a textarea
*/
#chat_box .chat_item#chat_panel_write textarea.text_area {
resize: none;
height: 100px;
}
#chat_box .chat_item#chat_panel_write textarea.text_area:placeholder-shown {
height: 100%;
}

View File

@@ -1,58 +0,0 @@
#chat_box.close {
gap: 0px;
padding: 0px;
width: auto;
height: auto;
grid:
' chat ' auto
/ auto ;
}
#chat_box.close .chat_item#chat_chat {
display: flex;
}
/*
* COLLAPSE
.chat._item:not(.open_close) {
display: none;
}
#chat_input:checked ~
#chat_box {
gap: 5px;
padding: 5px;
width: 300px;
height: 400px;
}
#chat_input:checked ~
#chat_box .chat._item {
display: flex;
}
#chat_input:checked ~
#chat_box .chat._item.open_close p {
display: none;
}
#chat_input:checked ~
#chat_box .chat._item.open_close {
width: 30px;
height: 20px;
padding: 0px;
justify-self: end;
background-color: transparent;
border: none;
}
#chat_input:checked ~
#chat_box .chat._item.open_close::before {
content: "";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
height: 4px;
width: 15px;
background-color: black;
}
*/

View File

@@ -1,28 +0,0 @@
#chat_box.create {
grid:
' back create close ' auto
' panel_create panel_create panel_create ' 1fr
/ auto 1fr auto ;
}
#chat_box.create .chat_item#chat_back,
#chat_box.create .chat_item#chat_create,
#chat_box.create .chat_item#chat_close,
#chat_box.create .chat_item#chat_panel_create {
display: flex;
}
/* back btn
*/
#chat_box.create .chat_item.chat_back button.back_new {
display: flex;
}
/* title "create" appearance
*/
#chat_box.create .chat_item.chat_create {
text-align: center;
}

View File

@@ -1,54 +0,0 @@
#chat_box.home {
grid:
' settings new close ' auto
' panel_home panel_home panel_home ' 1fr
/ auto 1fr auto ;
}
#chat_box.home .chat_item#chat_settings,
#chat_box.home .chat_item#chat_new,
#chat_box.home .chat_item#chat_close,
#chat_box.home .chat_item#chat_panel_home {
display: flex;
}
/* button "new" appearance
*/
/* add or remove '.chat_item' to toggle the hover effect */
#chat_box.home button.chat_new {
width: auto;
background-color: transparent;
}
/* button "settings" as 3 dots
*/
#chat_box.home .chat_item#chat_settings p {
display: none;
}
#chat_box.home button.chat_item#chat_settings {
width: 30px;
height: 100%;
padding: 0px;
}
/* add or remove '.chat_item' to toggle the hover effect */
#chat_box.home button.chat_item#chat_settings {
background-color: transparent;
}
#chat_box.home .chat_item#chat_settings::after {
content: '\2807';
font-size: 20px;
position: absolute;
top: 50%;
left: 0px;
width: 100%;
height: auto;
text-align: center;
transform: translateY(-50%);
cursor: pointer;
/*
background-color: black;
*/
}

View File

@@ -1,30 +0,0 @@
#chat_box.mute {
grid:
' back user close ' auto
' panel_mute panel_mute panel_mute ' 1fr
/ auto 1fr auto ;
}
#chat_box.mute .chat_item#chat_back,
#chat_box.mute .chat_item#chat_user,
#chat_box.mute .chat_item#chat_close,
#chat_box.mute .chat_item#chat_panel_mute {
display: flex;
}
/* back btn
*/
#chat_box.mute .chat_item.chat_back button.back_user {
display: flex;
}
/* title "mute" appearance
*/
#chat_box.mute .chat_item.chat_user {
text-align: center;
}

View File

@@ -1,40 +0,0 @@
#chat_box.new {
grid:
' back new close ' auto
' panel_new panel_new panel_new ' 1fr
/ auto 1fr auto ;
}
#chat_box.new .chat_item#chat_back,
#chat_box.new .chat_item#chat_new,
#chat_box.new .chat_item#chat_close,
#chat_box.new .chat_item#chat_panel_new {
display: flex;
}
/* back btn
*/
#chat_box.new .chat_item.chat_back button.back_home {
display: flex;
}
/* button "new" appearance
*/
/* add or remove '.chat_item' to toggle the hover effect */
#chat_box.new button.chat_item.chat_new {
width: auto;
background-color: transparent;
pointer-events: none;
}
/* button "create" appearance
*/
#chat_box.new .chat_item button.chat_create_btn {
margin: 10px 0px;
}

View File

@@ -1,36 +0,0 @@
#chat_box.protected {
grid:
' back room_name close ' auto
' panel_protected panel_protected panel_protected ' 1fr
/ auto 1fr auto ;
}
#chat_box.protected .chat_item#chat_back,
#chat_box.protected .chat_item#chat_room_name,
#chat_box.protected .chat_item#chat_close,
#chat_box.protected .chat_item#chat_panel_protected {
display: flex;
}
/* back btn
*/
#chat_box.protected .chat_item.chat_back button.back_new {
display: flex;
}
/* button "<room_name>" appearance
add or remove '.chat_item' to toggle the hover effect
*/
#chat_box.protected button.chat_item.chat_room_name {
width: auto;
background-color: transparent;
pointer-events: none;
}
#chat_box #chat_protected_title {
margin-top: 30px;
}

View File

@@ -1,34 +0,0 @@
#chat_box.room {
grid:
' back room_name room_name close ' auto
' panel_msg panel_msg panel_msg panel_msg ' 1fr
' panel_write panel_write send send ' auto
/ auto 1fr auto auto ;
}
#chat_box.room .chat_item#chat_back,
#chat_box.room .chat_item#chat_room_name,
#chat_box.room .chat_item#chat_close,
#chat_box.room .chat_item#chat_panel_msg,
#chat_box.room .chat_item#chat_send,
#chat_box.room .chat_item#chat_panel_write {
display: flex;
}
/* back btn
*/
#chat_box.room .chat_item.chat_back button.back_home {
display: flex;
}
/* button "<room_name>" appearance
*/
/* add or remove '.chat_item' to toggle the hover effect */
#chat_box.room button.chat_room_name {
width: auto;
background-color: transparent;
}

View File

@@ -1,38 +0,0 @@
#chat_box.room_set {
grid:
' back room_name close ' auto
' panel_room_set panel_room_set panel_room_set ' 1fr
/ auto 1fr auto ;
}
#chat_box.room_set .chat_item#chat_back,
#chat_box.room_set .chat_item#chat_room_name,
#chat_box.room_set .chat_item#chat_close,
#chat_box.room_set .chat_item#chat_panel_room_set {
display: flex;
}
/* back btn
*/
#chat_box.room_set .chat_item.chat_back button.back_room {
display: flex;
}
/* button "<room_name>" appearance
*/
/* add or remove '.chat_item' to toggle the hover effect */
#chat_box.room_set button.chat_item.chat_room_name {
width: auto;
background-color: transparent;
pointer-events: none;
}
/* button "leave" appearance
*/
#chat_box.room_set .chat_item button.chat_leave_btn {
margin: 10px 0px;
}

View File

@@ -1,32 +0,0 @@
#chat_box.settings {
grid:
' back settings close ' auto
' panel_settings panel_settings panel_settings ' 1fr
/ auto 1fr auto ;
}
#chat_box.settings .chat_item#chat_back,
#chat_box.settings .chat_item#chat_settings,
#chat_box.settings .chat_item#chat_close,
#chat_box.settings .chat_item#chat_panel_settings {
display: flex;
}
/* back btn
*/
#chat_box.settings .chat_item.chat_back button.back_home {
display: flex;
}
/* button "settings" appearance
*/
/* add or remove '.chat_item' to toggle the hover effect */
#chat_box.settings button.chat_item.chat_settings {
width: auto;
background-color: transparent;
pointer-events: none;
}

View File

@@ -1,80 +0,0 @@
#chat_box.user {
grid:
' back user close ' auto
' room_name room_name room_name ' auto
' panel_user panel_user panel_user ' 1fr
/ auto 1fr auto ;
}
#chat_box.user .chat_item#chat_back,
#chat_box.user .chat_item#chat_user,
#chat_box.user .chat_item#chat_close,
#chat_box.user .chat_item#chat_panel_user {
display: flex;
}
/* title "user" appearance
*/
#chat_box.user .chat_item.chat_user {
text-align: center;
}
/* for line height
*/
#chat_box.user .chat_item.chat_panel_user {
margin-top: -5px;
}
/* room_name appearance
*/
#chat_box.user button.chat_item#chat_room_name {
background-color: transparent;
border-top: 1px solid black;
}
/* back btn
*/
#chat_box.user .chat_item.chat_back button.back_home {display: flex;}
/* from settings */
#chat_box._settings .chat_item.chat_back button.btn {display: none;}
#chat_box._settings .chat_item.chat_back button.back_settings {display: flex;}
/* from room settings */
#chat_box._room_set .chat_item.chat_back button.btn {display: none;}
#chat_box._room_set .chat_item.chat_back button.back_room_set {display: flex;}
/* buttons appearance
*/
#chat_box.user .chat_item.chat_panel_user .chat_user_btn_wrapper {
margin: 0px auto;
}
#chat_box.user .chat_item.chat_panel_user button {
margin: 10px;
}
#chat_box.user #chat_user_admin {
margin: 0px;
}
/* toggle buttons according to chat_box class
*/
/* block/unblock */
#chat_box.user #chat_user_unblock {display: none;}
#chat_box.user._blocked #chat_user_block {display: none;}
#chat_box.user._blocked #chat_user_unblock {display: flex;}
/* admin if from room */
#chat_box.user #chat_user_admin {display: none;}
#chat_box.user._room_set._admin #chat_user_admin {display: flex;}
/* room_name if from room */
#chat_box.user #chat_room_name {display: none;}
#chat_box.user._room_set #chat_room_name {display: flex;}
/* mute/unmute */
#chat_box.user #chat_user_unmute {display: none;}
#chat_box.user._muted #chat_user_mute {display: none;}
#chat_box.user._muted #chat_user_unmute {display: flex;}

View File

@@ -1,21 +0,0 @@
const add_user = (socket, username, usernames, rooms) => {
//console.log(`adduser: ${username}, ${usernames[username]}`);
// store the username in the socket session for this client
socket.username = username;
// store the room name in the socket session for this client
socket.room = 'room1';
// add the client's username to the global list
usernames[username] = username;
// send client to room 1
socket.join('room1');
// echo to client they've connected
socket.emit('updatemsg', 'SERVER', 'you have connected to room1');
// echo to room 1 that a person has connected to their room
socket.broadcast.to('room1').emit('updatemsg', 'SERVER', username + ' has connected to this room');
socket.emit('updaterooms', rooms);
};
module.exports = add_user;

View File

@@ -1,9 +0,0 @@
const create_room = (room_name) => {
//console.log('createroom');
let last_room = rooms[rooms.length - 1];
rooms.push({ name: room_name, id: last_room.id + 1 });
socket.emit('updaterooms', rooms);
};
module.exports = create_room;

View File

@@ -1,8 +0,0 @@
const send_msg = (socket, msg) => {
//console.log('message from: ' + socket.username);
//console.log('message received: ' + msg);
socket.to(socket.room).emit('updatemsg', socket.username, msg);
};
module.exports = send_msg;

Some files were not shown because too many files have changed in this diff Show More