Chat moved up to top level now in all services frontend
This commit is contained in:
parent
814c389e38
commit
b4af6e08ca
32 changed files with 687 additions and 42 deletions
|
|
@ -1,290 +0,0 @@
|
|||
@import "tailwindcss";
|
||||
@font-face {
|
||||
font-family: "DejaVu Sans Mono";
|
||||
src: url("/fonts/DejaVuSansMono.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@tailwind utilities;
|
||||
|
||||
.recessed {
|
||||
@apply
|
||||
inline-block
|
||||
bg-gray-100
|
||||
text-gray-800
|
||||
p-2
|
||||
rounded-md
|
||||
shadow-inner
|
||||
border
|
||||
border-gray-300;
|
||||
}
|
||||
|
||||
.btn-style {
|
||||
@apply
|
||||
w-25
|
||||
h-8
|
||||
border
|
||||
border-gray-500
|
||||
rounded-3xl
|
||||
bg-gray-500
|
||||
text-white
|
||||
cursor-pointer
|
||||
shadow-[0_2px_0_0_black]
|
||||
transition-all
|
||||
hover:bg-blue-200
|
||||
active:bg-gray-400
|
||||
active:translate-y-px
|
||||
active:shadow-[0_2px_0_0_black];
|
||||
}
|
||||
|
||||
.send-btn-style {
|
||||
@apply
|
||||
w-12.5
|
||||
h-12.5
|
||||
border
|
||||
border-gray-500
|
||||
rounded-3xl
|
||||
hover:bg-blue-200
|
||||
bg-red-100
|
||||
text-red-700
|
||||
cursor-pointer
|
||||
shadow-[0_2px_0_0_black]
|
||||
transition-all
|
||||
active:bg-gray-400
|
||||
active:translate-y-px
|
||||
active:shadow-[0_2px_0_0_black];;
|
||||
}
|
||||
|
||||
.chatbox-style {
|
||||
@apply
|
||||
w-162.5
|
||||
h-75 /* increase height if needed */
|
||||
p-2
|
||||
border
|
||||
border-black
|
||||
shadow-2xl
|
||||
text-left
|
||||
text-gray-700
|
||||
bg-white
|
||||
rounded-3xl
|
||||
overflow-y-auto
|
||||
whitespace-pre-line
|
||||
flex
|
||||
flex-col
|
||||
mx-auto;
|
||||
}
|
||||
|
||||
.system-info {
|
||||
@apply
|
||||
h-10
|
||||
bg-gray-200
|
||||
text-gray-700
|
||||
p-3
|
||||
rounded-3xl
|
||||
mb-2 border
|
||||
border-gray-200
|
||||
text-center
|
||||
shadow
|
||||
overflow-y-auto
|
||||
justify-end /* 👈 forces text to bottom */
|
||||
relative; /* needed for overlay */
|
||||
}
|
||||
|
||||
.modal-messages {
|
||||
@apply
|
||||
h-20
|
||||
bg-white
|
||||
text-gray-700
|
||||
p-3
|
||||
rounded-3xl
|
||||
mb-2 border
|
||||
border-gray-200
|
||||
text-center
|
||||
shadow
|
||||
overflow-y-auto
|
||||
justify-end /* 👈 forces text to bottom */
|
||||
relative; /* needed for overlay */
|
||||
}
|
||||
|
||||
|
||||
|
||||
.text-info {
|
||||
@apply
|
||||
text-blue-800
|
||||
|
||||
}
|
||||
|
||||
|
||||
.chat-window-style {
|
||||
@apply
|
||||
w-100
|
||||
h-12.5
|
||||
p-6
|
||||
border
|
||||
border-black
|
||||
shadow-sm
|
||||
flex-1
|
||||
rounded-3xl
|
||||
focus:bg-blue-300
|
||||
hover:bg-blue-200
|
||||
bg-white
|
||||
text-gray-800;
|
||||
}
|
||||
|
||||
.displaybox {
|
||||
@apply
|
||||
fixed
|
||||
inset-0
|
||||
flex
|
||||
items-center
|
||||
justify-center
|
||||
bg-[#43536b];
|
||||
|
||||
}
|
||||
|
||||
.mainboxDisplay {
|
||||
@apply
|
||||
fixed
|
||||
top-1/2
|
||||
left-1/2
|
||||
-translate-x-1/2
|
||||
-translate-y-1/2
|
||||
bg-gray-200 w-212.5
|
||||
p-6 rounded-xl
|
||||
shadow-2xl
|
||||
text-center z-50;
|
||||
}
|
||||
|
||||
.mainboxDisplay button {
|
||||
@apply
|
||||
cursor-pointer
|
||||
}
|
||||
|
||||
.title {
|
||||
@apply
|
||||
text-6xl
|
||||
font-bold
|
||||
text-gray-800
|
||||
}
|
||||
|
||||
.ping-box {
|
||||
@apply
|
||||
w-37.5
|
||||
ml-2 border
|
||||
border-gray-500
|
||||
bg-white
|
||||
rounded-2xl
|
||||
p-2
|
||||
shadow-md
|
||||
flex flex-col
|
||||
gap-1
|
||||
h-87.5;
|
||||
}
|
||||
|
||||
.ping-title {
|
||||
@apply
|
||||
text-sm
|
||||
font-semibold
|
||||
text-blue-800;
|
||||
}
|
||||
|
||||
div-buddies-list {
|
||||
@apply
|
||||
text-black
|
||||
whitespace-pre-wrap
|
||||
cursor-pointer
|
||||
hover:text-blue-500
|
||||
transition-colors
|
||||
duration-150;
|
||||
}
|
||||
|
||||
p {
|
||||
@apply
|
||||
text-black
|
||||
}
|
||||
|
||||
div-test {
|
||||
@apply
|
||||
text-red-800
|
||||
text-right;
|
||||
|
||||
}
|
||||
|
||||
div-notlog {
|
||||
@apply
|
||||
text-red-800
|
||||
text-3xl
|
||||
text-center;
|
||||
}
|
||||
|
||||
div-private {
|
||||
@apply
|
||||
text-blue-800;
|
||||
|
||||
}
|
||||
|
||||
.popUpBox {
|
||||
@apply
|
||||
bg-white
|
||||
rounded-xl
|
||||
shadow-xl
|
||||
w-200
|
||||
h-87.5
|
||||
p-6
|
||||
border
|
||||
border-black
|
||||
|
||||
}
|
||||
|
||||
.profilPopup {
|
||||
@apply
|
||||
fixed
|
||||
inset-0
|
||||
bg-black/50
|
||||
flex
|
||||
justify-center
|
||||
items-center;
|
||||
}
|
||||
|
||||
.popup-b-invite {
|
||||
@apply
|
||||
absolute
|
||||
bottom-42
|
||||
right-12
|
||||
}
|
||||
|
||||
.popup-b-block {
|
||||
@apply
|
||||
absolute
|
||||
bottom-52
|
||||
right-12
|
||||
}
|
||||
|
||||
.popUpMessage {
|
||||
@apply
|
||||
bg-white
|
||||
rounded-xl
|
||||
shadow-xl
|
||||
w-200
|
||||
h-33
|
||||
p-6
|
||||
border
|
||||
border-black
|
||||
|
||||
}
|
||||
|
||||
.gamePopup {
|
||||
@apply
|
||||
fixed
|
||||
inset-0
|
||||
bg-black/50
|
||||
flex
|
||||
justify-center
|
||||
items-center;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.hidden{
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import { Socket } from 'socket.io-client';
|
||||
import type { ClientProfil } from '../types_front';
|
||||
import { blockUser } from './blockUser';
|
||||
|
||||
export function actionBtnPopUpBlock(block: ClientProfil, senderSocket: Socket) {
|
||||
setTimeout(() => {
|
||||
const blockUserBtn = document.querySelector("#popup-b-block");
|
||||
blockUserBtn?.addEventListener("click", () => {
|
||||
block.text = '';
|
||||
blockUser(block, senderSocket);
|
||||
});
|
||||
}, 0)
|
||||
};
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
import type { ClientProfil } from "../types_front";
|
||||
import { Socket } from "socket.io-client";
|
||||
import { inviteToPlayPong } from "./inviteToPlayPong";
|
||||
|
||||
/**
|
||||
* function listens for a click on the U-Game button and activates a popup function
|
||||
* inviteToPlayPong
|
||||
* @param invite - Clients target profil
|
||||
* @param senderSocket - socket from the sender
|
||||
**/
|
||||
|
||||
export function actionBtnPopUpInvite(invite: ClientProfil, senderSocket: Socket) {
|
||||
setTimeout(() => {
|
||||
const InvitePongBtn = document.querySelector("#popup-b-invite");
|
||||
InvitePongBtn?.addEventListener("click", () => {
|
||||
inviteToPlayPong(invite, senderSocket);
|
||||
});
|
||||
}, 0)
|
||||
};
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
/**
|
||||
* function adds a message to the frontend chatWindow
|
||||
* @param text
|
||||
* @returns
|
||||
*/
|
||||
|
||||
export function addMessage(text: string) {
|
||||
const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement;
|
||||
if (!chatWindow) return;
|
||||
const messageElement = document.createElement("div-test");
|
||||
messageElement.textContent = text;
|
||||
chatWindow.appendChild(messageElement);
|
||||
chatWindow.scrollTop = chatWindow.scrollHeight;
|
||||
return ;
|
||||
};
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
import { Socket } from 'socket.io-client';
|
||||
import type { ClientProfil } from '../types_front';
|
||||
import { getUser } from "@app/auth";
|
||||
|
||||
export function blockUser(profil: ClientProfil, senderSocket: Socket) {
|
||||
profil.SenderName = getUser()?.name ?? '';
|
||||
if (profil.SenderName === profil.user) return;
|
||||
senderSocket.emit('blockUser', JSON.stringify(profil));
|
||||
};
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
import { addMessage } from "./addMessage";
|
||||
import { Socket } from 'socket.io-client';
|
||||
import { getUser } from "@app/auth";
|
||||
import type { ClientMessage } from "../types_front";
|
||||
import { noGuestFlag } from "../chat";
|
||||
/**
|
||||
* function sends socket.emit to the backend to active and broadcast a message to all sockets
|
||||
* echos the message with addMessage to the sender
|
||||
* @param socket
|
||||
* @param msgCommand
|
||||
*/
|
||||
export function broadcastMsg (socket: Socket, msgCommand: string[]): void {
|
||||
let msgText = msgCommand[1] ?? "";
|
||||
let dest = '';
|
||||
addMessage(msgText);
|
||||
const user = getUser();
|
||||
if (user && socket?.connected) {
|
||||
const message: ClientMessage = {
|
||||
command: msgCommand[0],
|
||||
destination: '',
|
||||
type: "chat",
|
||||
user: user.name,
|
||||
token: document.cookie,
|
||||
text: msgText,
|
||||
timestamp: Date.now(),
|
||||
SenderWindowID: socket.id ?? "",
|
||||
SenderUserName: user.name,
|
||||
SenderUserID: user.id,
|
||||
userID: '',
|
||||
frontendUserName: '',
|
||||
frontendUser: '',
|
||||
Sendertext: '',
|
||||
};
|
||||
socket.emit('message', JSON.stringify(message));
|
||||
}
|
||||
};
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import { Socket } from 'socket.io-client';
|
||||
|
||||
/**
|
||||
* function clears all messages in the chat window
|
||||
* @param senderSocket
|
||||
* @returns
|
||||
*/
|
||||
export function clearChatWindow(senderSocket: Socket) {
|
||||
const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement;
|
||||
if (!chatWindow) return;
|
||||
chatWindow.innerHTML = "";
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
import { addMessage } from "./addMessage";
|
||||
import { getUser } from "@app/auth";
|
||||
|
||||
export function cmdList() {
|
||||
|
||||
addMessage('*');
|
||||
addMessage('** ********** List of @cmds ********** **');
|
||||
addMessage('\'@cls\' - clear chat screen conversations');
|
||||
addMessage('\'@profile <name>\' - pulls ups user profile');
|
||||
addMessage('\'@block <name>\' - blocks / unblock user');
|
||||
const guestflag = getUser()?.guest;
|
||||
if(!guestflag) {
|
||||
addMessage('\'@guest\' - guest broadcast msgs on / off');
|
||||
}
|
||||
addMessage('\'@notify\' - toggles notifications on / off');
|
||||
addMessage('\'@quit\' - disconnect user from the chat');
|
||||
addMessage('** *********************************** **');
|
||||
addMessage('*');
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
import { Socket } from "socket.io-client";
|
||||
import { isLoggedIn } from "./isLoggedIn";
|
||||
import { showError } from "@app/toast";
|
||||
import { updateUser } from "@app/auth";
|
||||
|
||||
/**
|
||||
* function displays who is logged in the chat in the ping-Bubbies window
|
||||
* @param socket
|
||||
*/
|
||||
|
||||
export async function connected(socket: Socket): Promise<void> {
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
const buddies = document.getElementById('div-buddies') as HTMLDivElement;
|
||||
const loggedIn = isLoggedIn();
|
||||
if (!loggedIn) throw('Not Logged in');
|
||||
let oldUser = localStorage.getItem("oldName") ?? "";
|
||||
if (loggedIn?.name === undefined) {return ;};
|
||||
oldUser = loggedIn.name ?? "";
|
||||
let user = await updateUser();
|
||||
localStorage.setItem("oldName", oldUser);
|
||||
buddies.textContent = "";
|
||||
socket.emit('list', {
|
||||
oldUser: oldUser,
|
||||
user: user?.name,
|
||||
});
|
||||
} catch (e) {
|
||||
showError('Failed to login: Unknown error');
|
||||
}
|
||||
}, 16);
|
||||
};
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
import { Socket } from 'socket.io-client';
|
||||
import type { ClientProfil } from '../types_front';
|
||||
|
||||
/**
|
||||
* getProfil of a user
|
||||
* @param socket
|
||||
* @param user
|
||||
* @returns
|
||||
*/
|
||||
|
||||
export function getProfil(socket: Socket, user: string) {
|
||||
if (!socket.connected) return;
|
||||
const profil: ClientProfil = {
|
||||
command: '@profile',
|
||||
destination: 'profilMessage',
|
||||
type: "chat",
|
||||
user: user,
|
||||
token: document.cookie ?? "",
|
||||
text: user,
|
||||
userID: '',
|
||||
timestamp: Date.now(),
|
||||
SenderWindowID: socket.id,
|
||||
};
|
||||
socket.emit('profilMessage', JSON.stringify(profil));
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
|
||||
let count = 0;
|
||||
export function incrementCounter(): number {
|
||||
count += 1;
|
||||
return count;
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
import { Socket } from 'socket.io-client';
|
||||
import type { ClientProfil } from '../types_front';
|
||||
import { getUser } from '@app/auth';
|
||||
import { addMessage } from './addMessage';
|
||||
|
||||
/**
|
||||
* function displays an invite message to sender
|
||||
* it also sends a message to backend for a link and displays it in the target window
|
||||
* @param profil of the target
|
||||
* @param senderSocket
|
||||
*/
|
||||
|
||||
export function inviteToPlayPong(profil: ClientProfil, senderSocket: Socket) {
|
||||
profil.SenderName = getUser()?.name ?? '';
|
||||
if (profil.SenderName === profil.user) return;
|
||||
addMessage(`You invited to play: ${profil.user}🏓`)
|
||||
senderSocket.emit('inviteGame', JSON.stringify(profil));
|
||||
};
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
import { getUser } from "@app/auth";
|
||||
import type { User } from '@app/auth'
|
||||
/**
|
||||
* function checks if logged in
|
||||
* @returns either user | null
|
||||
*/
|
||||
export function isLoggedIn(): User | null {
|
||||
return getUser() || null;
|
||||
};
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
import { getUser } from "@app/auth";
|
||||
import { Socket } from 'socket.io-client';
|
||||
import { getProfil } from './getProfil';
|
||||
|
||||
/**
|
||||
* function adds a user to the ping Buddies window\
|
||||
* it also acts as click or double click\
|
||||
* activates two possible actions:\
|
||||
* click => private Mag\
|
||||
* dbl click => get Profil of the name\
|
||||
* collected in the clipBoard
|
||||
* @param socket
|
||||
* @param buddies
|
||||
* @param bud
|
||||
* @returns
|
||||
*/
|
||||
|
||||
export async function listBuddies(socket: Socket, buddies: HTMLDivElement, listBuddies: string[]) {
|
||||
|
||||
buddies.innerHTML = "";
|
||||
for (const bud of listBuddies)
|
||||
{
|
||||
if (!buddies) return;
|
||||
const sendtextbox = document.getElementById('t-chat-window') as HTMLButtonElement;
|
||||
const buddiesElement = document.createElement("div-buddies-list");
|
||||
buddiesElement.textContent = bud + '\n';
|
||||
const user = getUser()?.name ?? "";
|
||||
buddies.appendChild(buddiesElement);
|
||||
buddies.scrollTop = buddies.scrollHeight;
|
||||
|
||||
buddiesElement.style.cursor = "pointer";
|
||||
buddiesElement.addEventListener("click", () => {
|
||||
navigator.clipboard.writeText(bud);
|
||||
if (bud !== user && user !== "") {
|
||||
sendtextbox.value = `@${bud}: `;
|
||||
sendtextbox.focus();
|
||||
}
|
||||
});
|
||||
buddiesElement.addEventListener("dblclick", () => {
|
||||
getProfil(socket, bud);
|
||||
sendtextbox.value = "";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import { Socket } from "socket.io-client";
|
||||
import { __socket } from "../chat";
|
||||
|
||||
|
||||
export function logout(socket: Socket) {
|
||||
socket.emit("logout"); // notify server
|
||||
socket.disconnect(); // actually close the socket
|
||||
localStorage.clear();
|
||||
if (__socket !== undefined)
|
||||
__socket.close();
|
||||
};
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import { incrementCounter } from "./incrementCounter";
|
||||
// let count = 0;
|
||||
// function incrementCounter(): number {
|
||||
// count += 1;
|
||||
// return count;
|
||||
// }
|
||||
|
||||
export async function openMessagePopup(message: any) {
|
||||
|
||||
const modalmessage = document.getElementById("modal-message") ?? null;
|
||||
if(!message) return
|
||||
const obj = message;
|
||||
if (modalmessage) {
|
||||
const messageElement = document.createElement("div");
|
||||
messageElement.innerHTML = `
|
||||
<div id="profile-about">Next Game Message ${incrementCounter()}: ${obj.nextGame}</div>
|
||||
`;
|
||||
modalmessage.appendChild(messageElement);
|
||||
modalmessage.scrollTop = modalmessage.scrollHeight;
|
||||
|
||||
}
|
||||
const gameMessage = document.getElementById("game-modal") ?? null;
|
||||
if (gameMessage) {
|
||||
gameMessage.classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
import type { ClientProfil } from '../types_front';
|
||||
|
||||
export async function openProfilePopup(profil: ClientProfil) {
|
||||
const modalname = document.getElementById("modal-name") ?? null;
|
||||
if (modalname)
|
||||
modalname.innerHTML =
|
||||
`
|
||||
<div class="profile-info">
|
||||
<div-profil-name id="profilName" class="text-xl font-bold text-blue-500"> Profile of ${profil.user} </div>
|
||||
<div-login-name id="loginName"> Login status: <span class="recessed">${profil.loginName ?? 'Guest'}</span> </div>
|
||||
</br>
|
||||
<div-login-name id="loginName"> Login ID: <span class="recessed">${profil.userID ?? ''}</span> </div>
|
||||
</br>
|
||||
<button id="popup-b-invite" class="btn-style popup-b-invite">U Game ?</button>
|
||||
<button id="popup-b-block" class="btn-style popup-b-block">Block User</button>
|
||||
<div id="profile-about" class="text-2xl">About: <span class="recessed text-amber-500">${profil.text}</span> </div>
|
||||
</div>
|
||||
`;
|
||||
const profilList = document.getElementById("profile-modal") ?? null;
|
||||
if (profilList)
|
||||
profilList.classList.remove("hidden");
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
|
||||
/**
|
||||
* function takes the input line of the chat and checks the it's not a cmd
|
||||
* ex: @command "arg" or @command noarg
|
||||
* ex: command @help - displays commands availble
|
||||
* @param msgText : string from input line
|
||||
*
|
||||
*/
|
||||
|
||||
export function parseCmdMsg(msgText: string): string[] | undefined {
|
||||
|
||||
if (!msgText?.trim()) return;
|
||||
msgText = msgText.trim();
|
||||
const command: string[] = ['', ''];
|
||||
if (!msgText.startsWith('@')) {
|
||||
command[0] = '@msg';
|
||||
command[1] = msgText;
|
||||
return command;
|
||||
}
|
||||
const noArgCommands = ['@quit', '@help', '@cls'];
|
||||
if (noArgCommands.includes(msgText)) {
|
||||
command[0] = msgText;
|
||||
command[1] = '';
|
||||
return command;
|
||||
}
|
||||
|
||||
const ArgCommands = ['@profile', '@block'];
|
||||
const userName = msgText.indexOf(" ");
|
||||
const cmd2 = msgText.slice(0, userName).trim() ?? "";
|
||||
const user = msgText.slice(userName + 1).trim();
|
||||
if (ArgCommands.includes(cmd2)) {
|
||||
command[0] = cmd2;
|
||||
command[1] = user;
|
||||
return command;
|
||||
}
|
||||
const colonIndex = msgText.indexOf(":");
|
||||
if (colonIndex === -1) {
|
||||
command[0] = msgText;
|
||||
command[1] = '';
|
||||
return command;
|
||||
}
|
||||
const cmd = msgText.slice(0, colonIndex).trim();
|
||||
const rest = msgText.slice(colonIndex + 1).trim();
|
||||
command[0] = cmd;
|
||||
command[1] = rest;
|
||||
return command;
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import { Socket } from "socket.io-client";
|
||||
import { getSocket } from "../chat";
|
||||
import { logout } from "./logout";
|
||||
import { connected } from "./connected";
|
||||
import { showError } from "@app/toast";
|
||||
import { setTitle } from "@app/routing";
|
||||
|
||||
/**
|
||||
* function to quit the chat - leaves the ping-Buddies list
|
||||
* @param socket
|
||||
*/
|
||||
|
||||
export function quitChat (socket: Socket) {
|
||||
|
||||
try {
|
||||
const systemWindow = document.getElementById('system-box') as HTMLDivElement;
|
||||
const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement;
|
||||
if (socket) {
|
||||
logout(socket);
|
||||
setTitle('Chat Page');
|
||||
connected(socket);
|
||||
} else {
|
||||
getSocket();
|
||||
}
|
||||
} catch (e) {
|
||||
showError('Failed to Quit Chat: Unknown error');
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import { Socket } from 'socket.io-client';
|
||||
|
||||
/**
|
||||
* getProfil of a user
|
||||
* @param socket
|
||||
* @param user
|
||||
* @returns
|
||||
*/
|
||||
|
||||
export function setGuestInfo(socket: Socket, user: string, guest: boolean) {
|
||||
if (!socket.connected) return;
|
||||
const profilInfo = {
|
||||
command: '@guestInfo',
|
||||
destination: 'guestInfo',
|
||||
type: "chat",
|
||||
user: user,
|
||||
token: document.cookie ?? "",
|
||||
text: user,
|
||||
timestamp: Date.now(),
|
||||
SenderWindowID: socket.id,
|
||||
guest: guest,
|
||||
};
|
||||
socket.emit('guestInfo', JSON.stringify(profilInfo));
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
import { Socket } from "socket.io-client";
|
||||
|
||||
/**
|
||||
* function waits for the socket to be connected and when connected calls socket.on "connect"
|
||||
* @param socket
|
||||
* @returns
|
||||
*/
|
||||
|
||||
export function waitSocketConnected(socket: Socket): Promise<void> {
|
||||
return new Promise(resolve => {
|
||||
if (socket.connected) return resolve();
|
||||
socket.on("connect", () => resolve());
|
||||
});
|
||||
};
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
import { __socket } from '../chat';
|
||||
import { updateUser } from "@app/auth";
|
||||
|
||||
export async function windowStateHidden() {
|
||||
const socketId = __socket || undefined;
|
||||
// let oldName = localStorage.getItem("oldName") ?? undefined;
|
||||
let oldName: string;
|
||||
if (socketId === undefined) return;
|
||||
let userName = await updateUser();
|
||||
oldName = userName?.name ?? "";
|
||||
if (oldName === "") return;
|
||||
localStorage.setItem('oldName', oldName);
|
||||
socketId.emit('client_left', {
|
||||
user: userName?.name,
|
||||
why: 'tab window hidden - socket not dead',
|
||||
});
|
||||
return;
|
||||
};
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
import { __socket } from "../chat";
|
||||
import { setTitle } from "@app/routing";
|
||||
import { updateUser } from "@app/auth";
|
||||
|
||||
/**
|
||||
* function stores old name clears ping buddies list
|
||||
* and emit a client entered to backend
|
||||
* @returns
|
||||
*/
|
||||
|
||||
export async function windowStateVisable() {
|
||||
|
||||
const buddies = document.getElementById('div-buddies') as HTMLDivElement;
|
||||
const socketId = __socket || undefined;
|
||||
let oldName = localStorage.getItem("oldName") || undefined;
|
||||
|
||||
if (socketId === undefined || oldName === undefined) {return;};
|
||||
let user = await updateUser();
|
||||
if(user === null) return;
|
||||
socketId.emit('client_entered', {
|
||||
userName: oldName,
|
||||
user: user?.name,
|
||||
});
|
||||
buddies.innerHTML = '';
|
||||
buddies.textContent = '';
|
||||
setTitle('Chat Page');
|
||||
return;
|
||||
};
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
export type ClientMessage = {
|
||||
command: string
|
||||
destination: string;
|
||||
type: string,
|
||||
user: string;
|
||||
userID: string,
|
||||
token: string
|
||||
frontendUserName: string,
|
||||
frontendUser: string,
|
||||
text: string;
|
||||
SenderWindowID: string,
|
||||
SenderUserName: string,
|
||||
SenderUserID: string,
|
||||
timestamp: number,
|
||||
Sendertext: string,
|
||||
innerHtml?: string,
|
||||
};
|
||||
|
||||
|
||||
export type ClientProfil = ClientProfilPartial & {
|
||||
loginName?: string | '',
|
||||
SenderName?: string | '',
|
||||
Sendertext?: string | '',
|
||||
innerHtml?: string | '',
|
||||
};
|
||||
|
||||
|
||||
export type ClientProfilPartial = {
|
||||
command: string,
|
||||
type: string,
|
||||
destination: string,
|
||||
user?: string | '',
|
||||
userID?: string | '',
|
||||
timestamp: number,
|
||||
SenderWindowID?:string | '',
|
||||
SenderID?: string | '',
|
||||
text?: string | '',
|
||||
token?: string | '',
|
||||
guestmsg?: boolean,
|
||||
}
|
||||
|
||||
|
||||
|
||||
export type blockedUnBlocked =
|
||||
{
|
||||
userState: string,
|
||||
userTarget: string,
|
||||
by: string,
|
||||
};
|
||||
|
||||
export type obj =
|
||||
{
|
||||
command: string,
|
||||
destination: string,
|
||||
type: string,
|
||||
user: string,
|
||||
frontendUserName: string,
|
||||
frontendUser: string,
|
||||
token: string,
|
||||
text: string,
|
||||
timestamp: number,
|
||||
SenderWindowID: string,
|
||||
Sendertext: string,
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { setTitle, handleRoute } from '@app/routing';
|
||||
import './root/root.ts'
|
||||
import './chat/chat.ts'
|
||||
import '../chat/chat.ts'
|
||||
import './pong/pong.ts'
|
||||
import './login/login.ts'
|
||||
import './signin/signin.ts'
|
||||
|
|
|
|||
|
|
@ -6,38 +6,147 @@
|
|||
|
||||
@tailwind utilities;
|
||||
|
||||
@layer utilities {
|
||||
.gray-color {
|
||||
@apply border-gray-500 bg-gray-500
|
||||
}
|
||||
.white-color {
|
||||
@apply border-white bg-white
|
||||
}
|
||||
.fit-all {
|
||||
@apply
|
||||
w-fit h-fit
|
||||
}
|
||||
.blue-hover {
|
||||
@apply
|
||||
hover:bg-blue-200
|
||||
hover:border-blue-200
|
||||
}
|
||||
.rounded-elem {
|
||||
@apply
|
||||
border-6 rounded-3xl
|
||||
}
|
||||
.circle-8 {
|
||||
@apply w-8 h-8 rounded-full
|
||||
}
|
||||
.base-box {
|
||||
@apply
|
||||
flex items-center justify-center
|
||||
}
|
||||
.focus-elem {
|
||||
@apply
|
||||
z-50
|
||||
shadow-2xl
|
||||
text-center
|
||||
.btn-style {
|
||||
@apply
|
||||
w-25
|
||||
h-8
|
||||
border
|
||||
border-gray-500
|
||||
rounded-3xl
|
||||
bg-gray-500
|
||||
text-white
|
||||
cursor-pointer
|
||||
shadow-[0_2px_0_0_black]
|
||||
transition-all
|
||||
hover:bg-blue-200
|
||||
active:bg-gray-400
|
||||
active:translate-y-px
|
||||
active:shadow-[0_2px_0_0_black];
|
||||
}
|
||||
|
||||
.chatbox-style {
|
||||
@apply
|
||||
w-162.5
|
||||
h-75 /* increase height if needed */
|
||||
p-2
|
||||
border
|
||||
border-black
|
||||
shadow-2xl
|
||||
text-left
|
||||
text-gray-700
|
||||
bg-white
|
||||
rounded-3xl
|
||||
overflow-y-auto
|
||||
whitespace-pre-line
|
||||
flex
|
||||
flex-col
|
||||
mx-auto;
|
||||
}
|
||||
|
||||
.system-info {
|
||||
@apply
|
||||
h-10
|
||||
bg-gray-200
|
||||
text-gray-700
|
||||
p-3
|
||||
rounded-3xl
|
||||
mb-2 border
|
||||
border-gray-200
|
||||
text-center
|
||||
shadow
|
||||
overflow-y-auto
|
||||
justify-end /* 👈 forces text to bottom */
|
||||
relative; /* needed for overlay */
|
||||
}
|
||||
|
||||
.displaybox {
|
||||
@apply
|
||||
fixed
|
||||
inset-0
|
||||
flex
|
||||
items-center
|
||||
justify-center
|
||||
bg-[#43536b];
|
||||
|
||||
}
|
||||
|
||||
.mainboxDisplay {
|
||||
@apply
|
||||
fixed
|
||||
top-1/2
|
||||
left-1/2
|
||||
-translate-x-1/2
|
||||
-translate-y-1/2
|
||||
bg-gray-200 w-212.5
|
||||
p-6 rounded-xl
|
||||
shadow-2xl
|
||||
text-center
|
||||
z-50;
|
||||
}
|
||||
|
||||
.mainboxDisplay button {
|
||||
@apply
|
||||
cursor-pointer
|
||||
}
|
||||
|
||||
.pongbox-style {
|
||||
@apply
|
||||
h-112.5
|
||||
w-200
|
||||
bg-gray-400
|
||||
text-6xl
|
||||
flex
|
||||
items-center
|
||||
justify-center;
|
||||
}
|
||||
|
||||
.text-style {
|
||||
@apply
|
||||
text-black
|
||||
items-center
|
||||
justify-center
|
||||
min-w-[2rem] h-8 px-2
|
||||
rounded-md border border-gray-300
|
||||
bg-gray-100 text-gray-800
|
||||
font-mono text-sm font-medium
|
||||
shadow-sm
|
||||
select-none
|
||||
}
|
||||
|
||||
|
||||
.pong-field {
|
||||
@apply relative w-200 h-112.5 bg-black;
|
||||
}
|
||||
|
||||
.pong-bat {
|
||||
@apply absolute w-3 h-20 bg-white;
|
||||
}
|
||||
|
||||
.pong-batleft {
|
||||
@apply absolute left-4 w-3 h-20 top-0;
|
||||
}
|
||||
|
||||
.pong-batright {
|
||||
@apply absolute right-4 w-3 h-20 top-0;
|
||||
}
|
||||
|
||||
.pong-center-line {
|
||||
@apply
|
||||
absolute
|
||||
left-1/2
|
||||
top-0
|
||||
h-full
|
||||
w-1
|
||||
-translate-x-1/2
|
||||
bg-[linear-gradient(to_bottom,white_50%,transparent_50%)]
|
||||
bg-size-[4px_20px];
|
||||
}
|
||||
|
||||
.pong-end-screen {
|
||||
@apply
|
||||
rounded-2xl
|
||||
absolute
|
||||
justify-center
|
||||
text-black
|
||||
absolute
|
||||
text-xl
|
||||
|
|
@ -115,3 +224,36 @@
|
|||
absolute right-4 top-0;
|
||||
}
|
||||
}
|
||||
|
||||
.pong-protips-key {
|
||||
@apply
|
||||
inline-flex
|
||||
items-center
|
||||
justify-center
|
||||
min-w-[2rem] h-8 px-2
|
||||
rounded-md border border-gray-300
|
||||
bg-gray-100 text-gray-800
|
||||
font-mono text-sm font-medium
|
||||
shadow-sm
|
||||
select-none
|
||||
}
|
||||
|
||||
.pong-how-to-play {
|
||||
@apply
|
||||
inline-flex items-center justify-center
|
||||
rounded-full w-8 h-8 bg-blue-500
|
||||
border-10 border-blue-500
|
||||
}
|
||||
|
||||
.chatPopUp {
|
||||
@apply
|
||||
fixed
|
||||
inset-0
|
||||
flex
|
||||
justify-center
|
||||
items-center;
|
||||
}
|
||||
|
||||
.hidden{
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,6 +125,7 @@ function pongClient(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
|||
navigateTo("/app");
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
!batLeft ||
|
||||
!batRight ||
|
||||
|
|
@ -142,7 +143,8 @@ function pongClient(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
|||
!tour_infos
|
||||
)
|
||||
// sanity check
|
||||
return showError("fatal error");
|
||||
return showError("fatal error"); <a href="/chat" class="hover:bg-gray-700 rounded-md px-3 py-2">👤 Chat</a>
|
||||
|
||||
if (!how_to_play_btn || !protips) showError("missing protips"); // not a fatal error
|
||||
|
||||
tournamentBtn.addEventListener("click", () => {
|
||||
|
|
@ -179,6 +181,16 @@ function pongClient(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
|||
how_to_play_btn.innerText =
|
||||
how_to_play_btn.innerText === "?" ? "x" : "?";
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", (e) => {keys[e.key.toLowerCase()] = true;});
|
||||
document.addEventListener("keyup", (e) => {keys[e.key.toLowerCase()] = false;});
|
||||
|
||||
setInterval(() => { // key sender
|
||||
if (keys['escape'] === true && protips && how_to_play_btn) {
|
||||
protips.classList.add("hidden");
|
||||
how_to_play_btn.innerText = '?';
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", (e) => {
|
||||
keys[e.key.toLowerCase()] = true;
|
||||
|
|
@ -324,6 +336,7 @@ function pongClient(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
|||
queueBtn.innerText = QueueState.InQueu;
|
||||
socket.emit("enqueue");
|
||||
});
|
||||
|
||||
LocalGameBtn.addEventListener("click", () => {
|
||||
if (
|
||||
queueBtn.innerText !== QueueState.Iddle ||
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB |
|
|
@ -101,6 +101,7 @@
|
|||
<!-- CTA -->
|
||||
<section class="bg-yellow-500">
|
||||
<div class="max-w-7xl mx-auto px-6 py-16 text-center">
|
||||
|
||||
<h3 class="text-4xl font-extrabold mb-4">
|
||||
Embrace the Ball Lifestyle
|
||||
</h3>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue