Merge pull request #50 from Maix0/nigel/privateMsg
This commit is contained in:
commit
ca30de7f84
6 changed files with 655 additions and 255 deletions
|
|
@ -1,8 +1,10 @@
|
||||||
@import "tailwindcss";
|
@import "tailwindcss";
|
||||||
@font-face {
|
/* @font-face {
|
||||||
font-family: "Nimbus Mono L";
|
font-family: "Nimbus Mono L";
|
||||||
src: url("/fonts/NimbusMonoL.woff2") format("woff2");
|
src: url("/fonts/NimbusMonoL.woff2") format("woff2");
|
||||||
}
|
} */
|
||||||
|
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
.btn-style {
|
.btn-style {
|
||||||
@apply
|
@apply
|
||||||
|
|
@ -159,8 +161,11 @@
|
||||||
div-buddies-list {
|
div-buddies-list {
|
||||||
@apply
|
@apply
|
||||||
text-black
|
text-black
|
||||||
whitespace-pre-wrap;
|
whitespace-pre-wrap
|
||||||
|
cursor-pointer
|
||||||
|
hover:text-blue-500
|
||||||
|
transition-colors
|
||||||
|
duration-150;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
|
|
@ -180,4 +185,44 @@ div-notlog {
|
||||||
text-red-800
|
text-red-800
|
||||||
text-3xl
|
text-3xl
|
||||||
text-center;
|
text-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div-private {
|
||||||
|
@apply
|
||||||
|
text-blue-800;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.popUpBox {
|
||||||
|
@apply
|
||||||
|
bg-white
|
||||||
|
p-6 rounded-xl
|
||||||
|
shadow-xl
|
||||||
|
w-[800px]
|
||||||
|
h-[350px]
|
||||||
|
p-[10px]
|
||||||
|
border-1
|
||||||
|
border-black
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.profilPopup {
|
||||||
|
@apply
|
||||||
|
fixed
|
||||||
|
inset-0
|
||||||
|
bg-black/50
|
||||||
|
flex
|
||||||
|
justify-center
|
||||||
|
items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-b-clear {
|
||||||
|
@apply
|
||||||
|
absolute
|
||||||
|
bottom-42
|
||||||
|
right-12
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden{
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +28,13 @@
|
||||||
<div id = "div-buddies">
|
<div id = "div-buddies">
|
||||||
<!-- <p>Alice</p>
|
<!-- <p>Alice</p>
|
||||||
<p>Bob</p>
|
<p>Bob</p>
|
||||||
<p>Charlie</p> -->
|
<p>Charlie</p> -->Marks
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="profile-modal" class="profilPopup hidden">
|
||||||
|
<div class="popUpBox">
|
||||||
|
<p class="" id="modal-name"></p>
|
||||||
|
<button id="close-modal" class="btn-style absolute bottom-32 right-12">Close</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import authHtml from './chat.html?raw';
|
||||||
import client from '@app/api'
|
import client from '@app/api'
|
||||||
import { getUser, updateUser } from "@app/auth";
|
import { getUser, updateUser } from "@app/auth";
|
||||||
import io, { Socket } from 'socket.io-client';
|
import io, { Socket } from 'socket.io-client';
|
||||||
// import type { ClientMessage } from "@app/@types/dom";
|
|
||||||
|
|
||||||
const color = {
|
const color = {
|
||||||
red: 'color: red;',
|
red: 'color: red;',
|
||||||
|
|
@ -15,6 +14,7 @@ const color = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ClientMessage = {
|
export type ClientMessage = {
|
||||||
|
command: string
|
||||||
destination: string;
|
destination: string;
|
||||||
user: string;
|
user: string;
|
||||||
text: string;
|
text: string;
|
||||||
|
|
@ -32,11 +32,11 @@ document.addEventListener('ft:pageChange', () => {
|
||||||
__socket.close();
|
__socket.close();
|
||||||
__socket = undefined;
|
__socket = undefined;
|
||||||
console.log("Page changed");
|
console.log("Page changed");
|
||||||
})
|
});
|
||||||
|
|
||||||
function getSocket(): Socket {
|
function getSocket(): Socket {
|
||||||
// let addressHost = `wss://${machineHostName}:8888`;
|
let addressHost = `wss://${machineHostName}:8888`;
|
||||||
let addressHost = `wss://localhost:8888`;
|
// let addressHost = `wss://localhost:8888`;
|
||||||
if (__socket === undefined)
|
if (__socket === undefined)
|
||||||
|
|
||||||
__socket = io(addressHost, {
|
__socket = io(addressHost, {
|
||||||
|
|
@ -45,12 +45,54 @@ function getSocket(): Socket {
|
||||||
transports: ["websocket"],
|
transports: ["websocket"],
|
||||||
});
|
});
|
||||||
return __socket;
|
return __socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
console.log(`Added new message: ${text}`)
|
||||||
|
return ;
|
||||||
|
};
|
||||||
|
|
||||||
|
function clearText() {
|
||||||
|
const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement;
|
||||||
|
if (!chatWindow) return;
|
||||||
|
chatWindow.innerHTML = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isLoggedIn() {
|
||||||
async function isLoggedIn() {
|
|
||||||
return getUser() || null;
|
return getUser() || null;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
function actionBtnPopUp() {
|
||||||
|
setTimeout(() => {
|
||||||
|
const clearTextBtn = document.querySelector("#popup-b-clear");
|
||||||
|
clearTextBtn?.addEventListener("click", () => {
|
||||||
|
clearText();
|
||||||
|
});
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getProfil get the profil of user
|
||||||
|
function getProfil(socket: Socket, user: string) {
|
||||||
|
if (!socket.connected) return;
|
||||||
|
const profil = {
|
||||||
|
command: '@profil',
|
||||||
|
destination: 'profilMessage',
|
||||||
|
type: "chat",
|
||||||
|
user: user,
|
||||||
|
token: document.cookie ?? "",
|
||||||
|
text: user,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
SenderWindowID: socket.id,
|
||||||
|
};
|
||||||
|
// addMessage(JSON.stringify(profil));
|
||||||
|
socket.emit('profilMessage', JSON.stringify(profil));
|
||||||
|
}
|
||||||
|
|
||||||
async function windowStateHidden() {
|
async function windowStateHidden() {
|
||||||
const socketId = __socket || undefined;
|
const socketId = __socket || undefined;
|
||||||
|
|
@ -64,18 +106,18 @@ async function windowStateHidden() {
|
||||||
socketId.emit('client_left', {
|
socketId.emit('client_left', {
|
||||||
user: userName?.name,
|
user: userName?.name,
|
||||||
why: 'tab window hidden - socket not dead',
|
why: 'tab window hidden - socket not dead',
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
async function windowStateVisable() {
|
||||||
async function windowStateVisable() {
|
|
||||||
|
const buddies = document.getElementById('div-buddies') as HTMLDivElement;
|
||||||
const socketId = __socket || undefined;
|
const socketId = __socket || undefined;
|
||||||
let oldName = localStorage.getItem("oldName") || undefined;
|
let oldName = localStorage.getItem("oldName") || undefined;
|
||||||
console.log("%c WINDOW VISIBLE - oldName :'" + oldName + "'", color.green);
|
console.log("%c WINDOW VISIBLE - oldName :'" + oldName + "'", color.green);
|
||||||
|
|
||||||
if (socketId === undefined || oldName === undefined) {console.log("%SOCKET ID", color.red); return;}
|
if (socketId === undefined || oldName === undefined) {console.log("%SOCKET ID", color.red); return;}
|
||||||
// const res = await client.guestLogin();
|
|
||||||
let user = await updateUser();
|
let user = await updateUser();
|
||||||
if(user === null) return;
|
if(user === null) return;
|
||||||
console.log("%cUserName :'" + user?.name + "'", color.green);
|
console.log("%cUserName :'" + user?.name + "'", color.green);
|
||||||
|
|
@ -83,33 +125,121 @@ async function windowStateVisable() {
|
||||||
userName: oldName,
|
userName: oldName,
|
||||||
user: user?.name,
|
user: user?.name,
|
||||||
});
|
});
|
||||||
|
buddies.innerHTML = '';
|
||||||
|
buddies.textContent = '';
|
||||||
|
//connected(socketId);
|
||||||
setTitle('Chat Page');
|
setTitle('Chat Page');
|
||||||
return;
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
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', '@who', '@cls'];
|
||||||
|
if (noArgCommands.includes(msgText)) {
|
||||||
|
command[0] = msgText;
|
||||||
|
command[1] = '';
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ArgCommands = ['@profil', '@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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function listBuddies(socket: Socket, buddies: HTMLDivElement, listBuddies: string) {
|
||||||
async function listBuddies(buddies: HTMLDivElement, listBuddies: string ) {
|
|
||||||
|
|
||||||
if (!buddies) return;
|
if (!buddies) return;
|
||||||
const messageElement = document.createElement("div-buddies-list");
|
const sendtextbox = document.getElementById('t-chat-window') as HTMLButtonElement;
|
||||||
messageElement.textContent = listBuddies + '\n';
|
const buddiesElement = document.createElement("div-buddies-list");
|
||||||
buddies.appendChild(messageElement);
|
buddiesElement.textContent = listBuddies + '\n';
|
||||||
buddies.scrollTop = buddies.scrollHeight;
|
const user = getUser()?.name ?? "";
|
||||||
console.log(`Added buddies: ${listBuddies}`)
|
|
||||||
return ;
|
|
||||||
|
|
||||||
|
buddiesElement.style.cursor = "pointer";
|
||||||
|
buddiesElement.addEventListener("click", () => {
|
||||||
|
navigator.clipboard.writeText(listBuddies);
|
||||||
|
if (listBuddies !== user && user !== "") {
|
||||||
|
sendtextbox.value = `@${listBuddies}: `;
|
||||||
|
console.log("Copied to clipboard:", listBuddies);
|
||||||
|
sendtextbox.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
buddiesElement.addEventListener("dblclick", () => {
|
||||||
|
console.log("Open profile:", listBuddies);
|
||||||
|
getProfil(socket, listBuddies);
|
||||||
|
// openProfilePopup(`${profile}`);
|
||||||
|
// setTimeout(() => {
|
||||||
|
// const clearTextBtn = document.querySelector("#popup-b-clear");
|
||||||
|
// clearTextBtn?.addEventListener("click", () => {
|
||||||
|
// clearText();
|
||||||
|
// });
|
||||||
|
// }, 0)
|
||||||
|
// actionBtnPopUp();
|
||||||
|
});
|
||||||
|
|
||||||
|
buddies.appendChild(buddiesElement);
|
||||||
|
buddies.scrollTop = buddies.scrollHeight;
|
||||||
|
console.log(`Added buddies: ${listBuddies}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function waitSocketConnected(socket: Socket): Promise<void> {
|
function waitSocketConnected(socket: Socket): Promise<void> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
if (socket.connected) return resolve(); // already connected
|
if (socket.connected) return resolve();
|
||||||
socket.on("connect", () => resolve());
|
socket.on("connect", () => resolve());
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
const bconnected = document.getElementById('b-help') as HTMLButtonElement;
|
|
||||||
if (bconnected) {
|
function quitChat (socket: Socket) {
|
||||||
bconnected.click();
|
|
||||||
}
|
try {
|
||||||
|
const systemWindow = document.getElementById('system-box') as HTMLDivElement;
|
||||||
|
const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement;
|
||||||
|
if (socket) {
|
||||||
|
logout(socket);
|
||||||
|
setTitle('Chat Page');
|
||||||
|
systemWindow.innerHTML = "";
|
||||||
|
chatWindow.textContent = "";
|
||||||
|
connected(socket);
|
||||||
|
} else {
|
||||||
|
getSocket();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Quit Chat error:", e);
|
||||||
|
showError('Failed to Quit Chat: Unknown error');
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// const bconnected = document.getElementById('b-help') as HTMLButtonElement;
|
||||||
|
// if (bconnected) {
|
||||||
|
// bconnected.click();
|
||||||
|
// }
|
||||||
|
|
||||||
function logout(socket: Socket) {
|
function logout(socket: Socket) {
|
||||||
socket.emit("logout"); // notify server
|
socket.emit("logout"); // notify server
|
||||||
|
|
@ -118,6 +248,94 @@ function logout(socket: Socket) {
|
||||||
if (__socket !== undefined)
|
if (__socket !== undefined)
|
||||||
__socket.close();
|
__socket.close();
|
||||||
// window.location.href = "/login";
|
// window.location.href = "/login";
|
||||||
|
};
|
||||||
|
|
||||||
|
function broadcastMsg (socket: Socket, msgCommand: string[]): void {
|
||||||
|
let msgText = msgCommand[1] ?? "";
|
||||||
|
console.log('%cmsgText:', color.red, msgText);
|
||||||
|
addMessage(msgText);
|
||||||
|
const user = getUser();
|
||||||
|
if (user && socket?.connected) {
|
||||||
|
const message = {
|
||||||
|
command: msgCommand,
|
||||||
|
destination: '',
|
||||||
|
type: "chat",
|
||||||
|
user: user.name,
|
||||||
|
token: document.cookie,
|
||||||
|
text: msgText,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
SenderWindowID: socket.id,
|
||||||
|
};
|
||||||
|
socket.emit('message', JSON.stringify(message));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
async function connected(socket: Socket): Promise<void> {
|
||||||
|
|
||||||
|
try {
|
||||||
|
const buddies = document.getElementById('div-buddies') as HTMLDivElement;
|
||||||
|
const loggedIn = await isLoggedIn();
|
||||||
|
console.log('%cloggedIn:',color.blue, loggedIn?.name);
|
||||||
|
let oldUser = localStorage.getItem("oldName") ?? "";
|
||||||
|
console.log('%coldUser:',color.yellow, oldUser);
|
||||||
|
if (loggedIn?.name === undefined) {console.log('');return ;}
|
||||||
|
oldUser = loggedIn.name ?? "";
|
||||||
|
// const res = await client.guestLogin();
|
||||||
|
let user = await updateUser();
|
||||||
|
console.log('%cUser?name:',color.yellow, user?.name);
|
||||||
|
localStorage.setItem("oldName", oldUser);
|
||||||
|
buddies.textContent = "";
|
||||||
|
socket.emit('list', {
|
||||||
|
oldUser: oldUser,
|
||||||
|
user: user?.name,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Login error:", e);
|
||||||
|
showError('Failed to login: Unknown error');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function whoami(socket: Socket) {
|
||||||
|
try {
|
||||||
|
const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement;
|
||||||
|
const loggedIn = isLoggedIn();
|
||||||
|
|
||||||
|
const res = await client.guestLogin();
|
||||||
|
switch (res.kind) {
|
||||||
|
case 'success': {
|
||||||
|
let user = await updateUser();
|
||||||
|
if (chatWindow) {
|
||||||
|
socket.emit('updateClientName', {
|
||||||
|
oldUser: '',
|
||||||
|
user: user?.name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (user === null)
|
||||||
|
return showError('Failed to get user: no user ?');
|
||||||
|
setTitle(`Welcome ${user.guest ? '[GUEST] ' : ''}${user.name}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'failed': {
|
||||||
|
showError(`Failed to login: ${res.msg}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Login error:", e);
|
||||||
|
showError('Failed to login: Unknown error');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async function openProfilePopup(profil: string) {
|
||||||
|
|
||||||
|
|
||||||
|
const modalname = document.getElementById("modal-name") ?? null;
|
||||||
|
if (modalname)
|
||||||
|
modalname.innerHTML = `${profil}`;
|
||||||
|
const profilList = document.getElementById("profile-modal") ?? null;
|
||||||
|
if (profilList)
|
||||||
|
profilList.classList.remove("hidden");
|
||||||
|
// The popup now exists → attach the event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -130,13 +348,16 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
||||||
|
|
||||||
// Listen for the 'connect' event
|
// Listen for the 'connect' event
|
||||||
socket.on("connect", async () => {
|
socket.on("connect", async () => {
|
||||||
|
|
||||||
|
const systemWindow = document.getElementById('system-box') as HTMLDivElement;
|
||||||
await waitSocketConnected(socket);
|
await waitSocketConnected(socket);
|
||||||
console.log("I AM Connected to the server:", socket.id);
|
console.log("I AM Connected to the server:", socket.id);
|
||||||
const user = getUser()?.name;
|
const user = getUser()?.name;
|
||||||
// Ensure we have a user AND socket is connected
|
// Ensure we have a user AND socket is connected
|
||||||
if (!user || !socket.connected) return;
|
if (!user || !socket.connected) return;
|
||||||
const message = {
|
const message = {
|
||||||
|
command: "",
|
||||||
|
destination: 'system-info',
|
||||||
type: "chat",
|
type: "chat",
|
||||||
user,
|
user,
|
||||||
token: document.cookie ?? "",
|
token: document.cookie ?? "",
|
||||||
|
|
@ -145,19 +366,24 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
||||||
SenderWindowID: socket.id,
|
SenderWindowID: socket.id,
|
||||||
};
|
};
|
||||||
socket.emit('message', JSON.stringify(message));
|
socket.emit('message', JSON.stringify(message));
|
||||||
|
const messageElement = document.createElement("div");
|
||||||
|
messageElement.textContent = `${user}: is connected au server`;
|
||||||
|
systemWindow.appendChild(messageElement);
|
||||||
|
systemWindow.scrollTop = systemWindow.scrollHeight;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Listen for messages from the server "MsgObjectServer"
|
// Listen for messages from the server "MsgObjectServer"
|
||||||
socket.on("MsgObjectServer", (data: { message: ClientMessage}) => {
|
socket.on("MsgObjectServer", (data: { message: ClientMessage}) => {
|
||||||
console.log("Message Obj Recieved:", data);
|
console.log("%cDEBUG LOGS - Message Obj Recieved:", color.green, data);
|
||||||
console.log("%cRecieved data.message.text: ", color.blue, data.message.text);
|
console.log("%cDEBUG LOGS - Recieved data.message.text: ", color.green, data.message.text);
|
||||||
console.log("%cRecieved data.message.user: ", color.blue, data.message.user);
|
console.log("%cDEBUG LOGS - Recieved data.message.user: ", color.green, data.message.user);
|
||||||
// Display the message in the chat window
|
// Display the message in the chat window
|
||||||
const systemWindow = document.getElementById('system-box') as HTMLDivElement;
|
const systemWindow = document.getElementById('system-box') as HTMLDivElement;
|
||||||
const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement;
|
const chatWindow = document.getElementById("t-chatbox") as HTMLDivElement;
|
||||||
const bconnected = document.getElementById('b-help') as HTMLButtonElement;
|
const bconnected = document.getElementById('b-help') as HTMLButtonElement;
|
||||||
|
|
||||||
if (bconnected) {
|
if (bconnected) {
|
||||||
bconnected.click();
|
connected(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chatWindow && data.message.destination === "") {
|
if (chatWindow && data.message.destination === "") {
|
||||||
|
|
@ -166,6 +392,14 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
||||||
chatWindow.appendChild(messageElement);
|
chatWindow.appendChild(messageElement);
|
||||||
chatWindow.scrollTop = chatWindow.scrollHeight;
|
chatWindow.scrollTop = chatWindow.scrollHeight;
|
||||||
}
|
}
|
||||||
|
if (chatWindow && data.message.destination === "privateMsg") {
|
||||||
|
const messageElement = document.createElement("div-private");
|
||||||
|
messageElement.textContent = `🔒${data.message.user}: ${data.message.text}`;
|
||||||
|
chatWindow.appendChild(messageElement);
|
||||||
|
chatWindow.scrollTop = chatWindow.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const MAX_SYSTEM_MESSAGES = 10;
|
const MAX_SYSTEM_MESSAGES = 10;
|
||||||
|
|
||||||
if (systemWindow && data.message.destination === "system-info") {
|
if (systemWindow && data.message.destination === "system-info") {
|
||||||
|
|
@ -177,23 +411,25 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
||||||
while (systemWindow.children.length > MAX_SYSTEM_MESSAGES) {
|
while (systemWindow.children.length > MAX_SYSTEM_MESSAGES) {
|
||||||
systemWindow.removeChild(systemWindow.firstChild!);
|
systemWindow.removeChild(systemWindow.firstChild!);
|
||||||
}
|
}
|
||||||
|
|
||||||
systemWindow.scrollTop = systemWindow.scrollHeight;
|
systemWindow.scrollTop = systemWindow.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Getuser():", getUser());
|
console.log("Getuser():", getUser());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('profilMessage', (profil) => {
|
||||||
|
openProfilePopup(profil);
|
||||||
|
actionBtnPopUp();
|
||||||
socket.on('logout', () => {
|
|
||||||
const bquit = document.getElementById('b-quit') as HTMLDivElement | null;
|
|
||||||
if (bquit instanceof HTMLDivElement) {
|
|
||||||
bquit.click();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
socket.on('logout', () => {
|
||||||
|
quitChat(socket);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('privMessageCopy', (message) => {
|
||||||
|
addMessage(message);
|
||||||
|
})
|
||||||
|
|
||||||
type Providers = {
|
type Providers = {
|
||||||
name: string,
|
name: string,
|
||||||
display_name: string,
|
display_name: string,
|
||||||
|
|
@ -201,25 +437,46 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
||||||
color?: { default: string, hover: string },
|
color?: { default: string, hover: string },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let toggle = false
|
||||||
let toggle = false
|
window.addEventListener("focus", () => {
|
||||||
window.addEventListener("focus", () => {
|
//nst bwhoami = document.getElementById('b-whoami') as HTMLButtonElement;
|
||||||
const bwhoami = document.getElementById('b-whoami') as HTMLButtonElement;
|
if (window.location.pathname === '/app/chat') {
|
||||||
if (window.location.pathname === '/app/chat') {
|
connected(socket);
|
||||||
console.log("%cWindow is focused on /chat:" + socket.id, color.green);
|
console.log("%cWindow is focused on /chat:" + socket.id, color.green);
|
||||||
if (socket.id)
|
if (socket.id) {
|
||||||
windowStateVisable();
|
windowStateVisable();
|
||||||
bwhoami.click();
|
|
||||||
toggle = true;
|
|
||||||
}
|
}
|
||||||
});
|
toggle = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("blur", () => {
|
||||||
|
console.log("%cWindow is not focused on /chat", color.red);
|
||||||
|
if (socket.id)
|
||||||
|
windowStateHidden();
|
||||||
|
toggle = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// setInterval(async () => {
|
||||||
|
// //connected(socket);
|
||||||
|
// },10000); // every 10 seco
|
||||||
|
socket.on('listBud', async (myBuddies: string) => {
|
||||||
|
const buddies = document.getElementById('div-buddies') as HTMLDivElement;
|
||||||
|
console.log('List buddies connected ', myBuddies);
|
||||||
|
listBuddies(socket, buddies, myBuddies);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.once('welcome', (data) => {
|
||||||
|
const buddies = document.getElementById('div-buddies') as HTMLDivElement;
|
||||||
|
const chatWindow = document.getElementById('t-chatbox') as HTMLDivElement;
|
||||||
|
chatWindow.innerHTML = '';
|
||||||
|
buddies.textContent = '';
|
||||||
|
buddies.innerHTML = '';
|
||||||
|
connected(socket);
|
||||||
|
addMessage (`${data.msg} ` + getUser()?.name);
|
||||||
|
});
|
||||||
|
|
||||||
window.addEventListener("blur", () => {
|
|
||||||
console.log("%cWindow is not focused on /chat", color.red);
|
|
||||||
if (socket.id)
|
|
||||||
windowStateHidden();
|
|
||||||
toggle = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
setTitle('Chat Page');
|
setTitle('Chat Page');
|
||||||
// Listen for the 'connect' event
|
// Listen for the 'connect' event
|
||||||
|
|
@ -235,6 +492,7 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
||||||
const username = document.getElementById('username') as HTMLDivElement;
|
const username = document.getElementById('username') as HTMLDivElement;
|
||||||
const buddies = document.getElementById('div-buddies') as HTMLDivElement;
|
const buddies = document.getElementById('div-buddies') as HTMLDivElement;
|
||||||
const bquit = document.getElementById('b-quit') as HTMLDivElement;
|
const bquit = document.getElementById('b-quit') as HTMLDivElement;
|
||||||
|
const systemWindow = document.getElementById('system-box') as HTMLDivElement;
|
||||||
|
|
||||||
chatWindow.textContent = '';
|
chatWindow.textContent = '';
|
||||||
chatWindow.innerHTML = '';
|
chatWindow.innerHTML = '';
|
||||||
|
|
@ -251,105 +509,90 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
||||||
console.log('unknown response: ', value);
|
console.log('unknown response: ', value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const addMessage = (text: string) => {
|
|
||||||
if (!chatWindow) return;
|
|
||||||
const messageElement = document.createElement("div-test");
|
|
||||||
messageElement.textContent = text;
|
|
||||||
chatWindow.appendChild(messageElement);
|
|
||||||
chatWindow.scrollTop = chatWindow.scrollHeight;
|
|
||||||
console.log(`Added new message: ${text}`)
|
|
||||||
return ;
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.once('welcome', (data) => {
|
|
||||||
chatWindow.textContent = '';
|
const buttonPro = document.getElementById("close-modal") ?? null;
|
||||||
chatWindow.innerHTML = '';
|
|
||||||
buddies.textContent = '';
|
if (buttonPro)
|
||||||
buddies.innerHTML = '';
|
buttonPro.addEventListener("click", () => {
|
||||||
bconnected.click();
|
const profilList = document.getElementById("profile-modal") ?? null;
|
||||||
addMessage (`${data.msg} ` + getUser()?.name);
|
if (profilList) profilList.classList.add("hidden");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send button
|
// Send button
|
||||||
sendButton?.addEventListener("click", () => {
|
sendButton?.addEventListener("click", () => {
|
||||||
if (sendtextbox && sendtextbox.value.trim()) {
|
if (sendtextbox && sendtextbox.value.trim()) {
|
||||||
const msgText = sendtextbox.value.trim();
|
let msgText: string = sendtextbox.value.trim();
|
||||||
bconnected.click();
|
const msgCommand = parseCmdMsg(msgText) ?? "";
|
||||||
addMessage(msgText);
|
connected(socket);
|
||||||
const user = getUser();
|
if (msgCommand !== "") {
|
||||||
if (user && socket?.connected) {
|
switch (msgCommand[0]) {
|
||||||
const message = {
|
case '@msg':
|
||||||
destination: "",
|
broadcastMsg(socket, msgCommand);
|
||||||
type: "chat",
|
break;
|
||||||
user: user.name,
|
case '@who':
|
||||||
token: document.cookie,
|
whoami(socket);
|
||||||
text: msgText,
|
break;
|
||||||
timestamp: Date.now(),
|
case '@profil':
|
||||||
SenderWindowID: socket.id,
|
getProfil(socket, msgCommand[1]);
|
||||||
};
|
// Ensure we have a user AND socket is connected
|
||||||
socket.emit('message', JSON.stringify(message));
|
// if (!socket.connected) return;
|
||||||
|
// const profil = {
|
||||||
|
// command: msgCommand[0],
|
||||||
|
// destination: 'profil',
|
||||||
|
// type: "chat",
|
||||||
|
// user: msgCommand[1],
|
||||||
|
// token: document.cookie ?? "",
|
||||||
|
// text: msgCommand[1],
|
||||||
|
// timestamp: Date.now(),
|
||||||
|
// SenderWindowID: socket.id,
|
||||||
|
// };
|
||||||
|
// //socket.emit('MsgObjectServer', message);
|
||||||
|
// addMessage(JSON.stringify(profil));
|
||||||
|
// socket.emit('profilMessage', JSON.stringify(profil));
|
||||||
|
break;
|
||||||
|
case '@cls':
|
||||||
|
chatWindow.innerHTML = '';
|
||||||
|
break;
|
||||||
|
case '@quit':
|
||||||
|
quitChat(socket);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const user = getUser()?.name;
|
||||||
|
// Ensure we have a user AND socket is connected
|
||||||
|
if (!user || !socket.connected) return;
|
||||||
|
const message = {
|
||||||
|
command: msgCommand[0],
|
||||||
|
destination: '',
|
||||||
|
type: "chat",
|
||||||
|
user: user,
|
||||||
|
token: document.cookie ?? "",
|
||||||
|
text: msgCommand[1],
|
||||||
|
timestamp: Date.now(),
|
||||||
|
SenderWindowID: socket.id,
|
||||||
|
};
|
||||||
|
//socket.emit('MsgObjectServer', message);
|
||||||
|
socket.emit('privMessage', JSON.stringify(message));
|
||||||
|
// addMessage(JSON.stringify(message));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Clear the input in all cases
|
||||||
|
sendtextbox.value = "";
|
||||||
}
|
}
|
||||||
sendtextbox.value = "";
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Clear Text button
|
// Clear Text button
|
||||||
clearText?.addEventListener("click", () => {
|
clearText?.addEventListener("click", () => {
|
||||||
|
|
||||||
if (chatWindow) {
|
if (chatWindow) {
|
||||||
bconnected.click();
|
|
||||||
chatWindow.innerHTML = '';
|
chatWindow.innerHTML = '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
bquit?.addEventListener('click', () => {
|
bquit?.addEventListener('click', () => {
|
||||||
if (socket) {
|
quitChat(socket);
|
||||||
logout(socket);
|
|
||||||
setTitle('Chat Page');
|
|
||||||
bconnected.click();
|
|
||||||
} else {
|
|
||||||
getSocket();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
setInterval(async () => {
|
|
||||||
//bconnected.click();
|
|
||||||
}, 10000); // every 10 second
|
|
||||||
|
|
||||||
// Help Text button
|
|
||||||
bconnected?.addEventListener("click", async () => {
|
|
||||||
|
|
||||||
const loggedIn = await isLoggedIn();
|
|
||||||
console.log('%cloggedIn:',color.blue, loggedIn?.name);
|
|
||||||
let oldUser = localStorage.getItem("oldName") ?? "";
|
|
||||||
console.log('%coldUser:',color.yellow, oldUser);
|
|
||||||
if (loggedIn?.name === undefined) {console.log('');return ;}
|
|
||||||
oldUser = loggedIn.name || "undefined";
|
|
||||||
const res = await client.guestLogin();
|
|
||||||
let user = await updateUser();
|
|
||||||
console.log('%cUser?name:',color.yellow, user?.name);
|
|
||||||
localStorage.setItem("oldName", oldUser);
|
|
||||||
buddies.textContent = "";
|
|
||||||
// if (chatWindow) {
|
|
||||||
// addMessage('@list - lists all connected users in the chat');
|
|
||||||
socket.emit('list', {
|
|
||||||
oldUser: oldUser,
|
|
||||||
user: user?.name,
|
|
||||||
});
|
|
||||||
// }
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.on('listBud', (myBuddies: string) => {
|
|
||||||
console.log('List buddies connected ', myBuddies);
|
|
||||||
listBuddies(buddies,myBuddies);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Enter key to send message
|
// Enter key to send message
|
||||||
sendtextbox!.addEventListener('keydown', (event) => {
|
sendtextbox!.addEventListener('keydown', (event) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
|
|
@ -357,34 +600,10 @@ function handleChat(_url: string, _args: RouteHandlerParams): RouteHandlerReturn
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Whoami button to display user name
|
// Whoami button to display user name addMessage(msgCommand[0]);
|
||||||
|
|
||||||
bwhoami?.addEventListener('click', async () => {
|
bwhoami?.addEventListener('click', async () => {
|
||||||
try {
|
whoami(socket);
|
||||||
const loggedIn = await isLoggedIn();
|
|
||||||
|
|
||||||
const res = await client.guestLogin();
|
|
||||||
switch (res.kind) {
|
|
||||||
case 'success': {
|
|
||||||
let user = await updateUser();
|
|
||||||
if (chatWindow) {
|
|
||||||
socket.emit('updateClientName', {
|
|
||||||
oldUser: '',
|
|
||||||
user: user?.name
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (user === null)
|
|
||||||
return showError('Failed to get user: no user ?');
|
|
||||||
setTitle(`Welcome ${user.guest ? '[GUEST] ' : ''}${user.name}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'failed': {
|
|
||||||
showError(`Failed to login: ${res.msg}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Login error:", e);
|
|
||||||
showError('Failed to login: Unknown error');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import * as auth from '@shared/auth';
|
||||||
import * as swagger from '@shared/swagger';
|
import * as swagger from '@shared/swagger';
|
||||||
import * as utils from '@shared/utils';
|
import * as utils from '@shared/utils';
|
||||||
import { Server, Socket } from 'socket.io';
|
import { Server, Socket } from 'socket.io';
|
||||||
|
import type { User } from '@shared/database/mixin/user';
|
||||||
|
|
||||||
// colors for console.log
|
// colors for console.log
|
||||||
export const color = {
|
export const color = {
|
||||||
|
|
@ -34,6 +35,7 @@ interface ClientInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ClientMessage = {
|
export type ClientMessage = {
|
||||||
|
command: string
|
||||||
destination: string;
|
destination: string;
|
||||||
user: string;
|
user: string;
|
||||||
text: string;
|
text: string;
|
||||||
|
|
@ -82,6 +84,9 @@ declare module 'fastify' {
|
||||||
io: Server<{
|
io: Server<{
|
||||||
hello: (message: string) => string;
|
hello: (message: string) => string;
|
||||||
MsgObjectServer: (data: { message: ClientMessage }) => void;
|
MsgObjectServer: (data: { message: ClientMessage }) => void;
|
||||||
|
privMessage: (data: string) => void;
|
||||||
|
profilMessage: (data: string) => void;
|
||||||
|
privMessageCopy: (msg: string) => void;
|
||||||
message: (msg: string) => void;
|
message: (msg: string) => void;
|
||||||
listBud: (msg: string) => void;
|
listBud: (msg: string) => void;
|
||||||
testend: (sock_id_client: string) => void;
|
testend: (sock_id_client: string) => void;
|
||||||
|
|
@ -129,55 +134,117 @@ async function onReady(fastify: FastifyInstance) {
|
||||||
seen.add(username.user);
|
seen.add(username.user);
|
||||||
count++;
|
count++;
|
||||||
// console.log(color.green,"count: ", count);
|
// console.log(color.green,"count: ", count);
|
||||||
console.log(color.yellow, 'Client:', color.reset, username.user);
|
// console.log(color.yellow, 'Client:', color.reset, username.user);
|
||||||
|
|
||||||
const targetSocketId = target;
|
const targetSocketId = target;
|
||||||
io.to(targetSocketId!).emit('listBud', username.user);
|
io.to(targetSocketId!).emit('listBud', username.user);
|
||||||
console.log(
|
// console.log(
|
||||||
color.yellow,
|
// color.yellow,
|
||||||
'Chat Socket ID:',
|
// 'Chat Socket ID:',
|
||||||
color.reset,
|
// color.reset,
|
||||||
socketId,
|
// socketId,
|
||||||
);
|
// );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no io provided, assume entries in the map are valid and count them.
|
// If no io provided, assume entries in the map are valid and count them.
|
||||||
count++;
|
count++;
|
||||||
console.log(
|
console.log(color.red, 'DEBUG LOG: - Client (unverified):', color.reset, username);
|
||||||
color.red,
|
console.log(color.red, 'DEBUG LOG: - Chat Socket ID (unverified):', color.reset, socketId);
|
||||||
'Client (unverified):',
|
|
||||||
color.reset,
|
|
||||||
username,
|
|
||||||
);
|
|
||||||
console.log(
|
|
||||||
color.red,
|
|
||||||
'Chat Socket ID (unverified):',
|
|
||||||
color.reset,
|
|
||||||
socketId,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
function broadcast(data: ClientMessage, sender?: string) {
|
function broadcast(data: ClientMessage, sender?: string) {
|
||||||
fastify.io.fetchSockets().then((sockets) => {
|
fastify.io.fetchSockets().then((sockets) => {
|
||||||
for (const s of sockets) {
|
for (const socket of sockets) {
|
||||||
// Skip sender's own socket
|
// Skip sender's own socket
|
||||||
if (s.id === sender) continue;
|
if (socket.id === sender) continue;
|
||||||
// Get client name from map
|
// Get client name from map
|
||||||
|
const clientInfo = clientChat.get(socket.id);
|
||||||
|
if (!clientInfo?.user) {
|
||||||
|
console.log(color.yellow, `Skipping socket ${socket.id} (no user found)`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Emit structured JSON object
|
||||||
|
socket.emit('MsgObjectServer', { message: data });
|
||||||
|
// Debug logs
|
||||||
|
console.log(color.green, `'Broadcast to:', ${data.command} message: ${data.text}`);
|
||||||
|
// console.log('DEBUG - Target socket ID:', s.id);
|
||||||
|
// console.log('DEBUG - Target rooms:', [...s.rooms]);
|
||||||
|
// console.log('DEBUG - Sender socket ID:', sender ?? 'none');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// function formatTimestamp(ms: number) {
|
||||||
|
// const d = new Date(ms);
|
||||||
|
// return d.toLocaleString('fr-FR', { timeZone: 'Europe/Paris' });
|
||||||
|
// }
|
||||||
|
|
||||||
|
function getUserByName(users: User[], name: string) {
|
||||||
|
return users.find(u => u.name === name) || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// this function returns html the profil pop up in CHAT of a user 'nickname unique' TODO ....
|
||||||
|
async function getProfil(user: string): Promise <string> {
|
||||||
|
let profilHtmlPopup = '404: Error: Profil not found';
|
||||||
|
const users: User[] = fastify.db.getAllUsers() ?? [];
|
||||||
|
const allUsers: User | null = getUserByName(users, user);
|
||||||
|
console.log(color.yellow, `'userFound is:'${allUsers?.name}`);
|
||||||
|
if (user === allUsers?.name) {
|
||||||
|
console.log(color.yellow, `'login Name: '${allUsers.login}' user: '${user}'`);
|
||||||
|
profilHtmlPopup = `<div class="profile-info">
|
||||||
|
<div-profil-name id="profilName"> Profil of ${allUsers.name} </div>
|
||||||
|
<div-login-name id="loginName"> Login Name: '${allUsers?.login ?? 'Guest'}' </div>
|
||||||
|
</br>
|
||||||
|
<button id="popup-b-clear" class="btn-style popup-b-clear">Clear Text</button>
|
||||||
|
<div id="profile-about">About: No description</div>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return profilHtmlPopup;
|
||||||
|
};
|
||||||
|
|
||||||
|
function sendProfil(data: ClientMessage, clientProfil?: string) {
|
||||||
|
|
||||||
|
fastify.io.fetchSockets().then((sockets) => {
|
||||||
|
const senderSocket = sockets.find(socket => socket.id === clientProfil);
|
||||||
|
for (const socket of sockets) {
|
||||||
|
const clientInfo = clientChat.get(socket.id);
|
||||||
|
if (clientInfo?.user === data.user) {
|
||||||
|
if (senderSocket) {
|
||||||
|
socket.emit('profilMessage', `${data.text}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendPrivMessage(data: ClientMessage, sender?: string) {
|
||||||
|
fastify.io.fetchSockets().then((sockets) => {
|
||||||
|
const senderSocket = sockets.find(s => s.id === sender);
|
||||||
|
for (const s of sockets) {
|
||||||
|
if (s.id === sender) continue;
|
||||||
const clientInfo = clientChat.get(s.id);
|
const clientInfo = clientChat.get(s.id);
|
||||||
if (!clientInfo?.user) {
|
if (!clientInfo?.user) {
|
||||||
console.log(color.yellow, `Skipping socket ${s.id} (no user found)`);
|
console.log(color.yellow, `Skipping socket ${s.id} (no user found)`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Emit structured JSON object
|
const user: string = clientChat.get(s.id)?.user ?? '';
|
||||||
s.emit('MsgObjectServer', { message: data });
|
const atUser = `@${user}`;
|
||||||
// Debug logs
|
if (atUser !== data.command || atUser === '') {
|
||||||
console.log(color.green, 'Broadcast to:', clientInfo.user);
|
console.log(color.yellow, `DEBUG LOG: User: '${atUser}' command NOT FOUND: '${data.command[0]}' `);
|
||||||
console.log(' Target socket ID:', s.id);
|
continue;
|
||||||
console.log(' Target rooms:', [...s.rooms]);
|
}
|
||||||
console.log(' Sender socket ID:', sender ?? 'none');
|
if (data.text !== '') {
|
||||||
|
s.emit('MsgObjectServer', { message: data });
|
||||||
|
console.log(color.yellow, `DEBUG LOG: User: '${atUser}' command FOUND: '${data.command}' `);
|
||||||
|
if (senderSocket) {
|
||||||
|
senderSocket.emit('privMessageCopy', `${data.command}: ${data.text}🔒`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(color.green, `DEBUG LOG: 'Priv to:', ${data.command} message: ${data.text}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -212,12 +279,7 @@ async function onReady(fastify: FastifyInstance) {
|
||||||
|
|
||||||
// Send object directly — DO NOT wrap it in a string
|
// Send object directly — DO NOT wrap it in a string
|
||||||
broadcast(obj, obj.SenderWindowID);
|
broadcast(obj, obj.SenderWindowID);
|
||||||
console.log(
|
console.log(color.red, 'DEBUG LOG: connected in the Chat :', connectedUser(fastify.io), color.reset);
|
||||||
color.red,
|
|
||||||
'connected in the Chat :',
|
|
||||||
connectedUser(fastify.io),
|
|
||||||
color.reset,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('testend', (sock_id_cl: string) => {
|
socket.on('testend', (sock_id_cl: string) => {
|
||||||
|
|
@ -256,8 +318,7 @@ async function onReady(fastify: FastifyInstance) {
|
||||||
// };
|
// };
|
||||||
if (client) {
|
if (client) {
|
||||||
client.user = userFromFrontend.user;
|
client.user = userFromFrontend.user;
|
||||||
console.log(color.green, 'client.user is: ', client.user);
|
console.log(color.green, `'DEBUG LOG: client.user is, '${client.user}'`);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -269,6 +330,7 @@ async function onReady(fastify: FastifyInstance) {
|
||||||
if (!clientName) return;
|
if (!clientName) return;
|
||||||
console.log(color.green, `Client logging out: ${clientName} (${socket.id})`);
|
console.log(color.green, `Client logging out: ${clientName} (${socket.id})`);
|
||||||
const obj = {
|
const obj = {
|
||||||
|
command: '',
|
||||||
destination: 'system-info',
|
destination: 'system-info',
|
||||||
type: 'chat' as const,
|
type: 'chat' as const,
|
||||||
user: clientName,
|
user: clientName,
|
||||||
|
|
@ -295,6 +357,7 @@ async function onReady(fastify: FastifyInstance) {
|
||||||
|
|
||||||
if (clientName !== null) {
|
if (clientName !== null) {
|
||||||
const obj = {
|
const obj = {
|
||||||
|
command: '',
|
||||||
destination: 'system-info',
|
destination: 'system-info',
|
||||||
type: 'chat',
|
type: 'chat',
|
||||||
user: clientName,
|
user: clientName,
|
||||||
|
|
@ -319,6 +382,7 @@ async function onReady(fastify: FastifyInstance) {
|
||||||
|
|
||||||
if (clientName !== null) {
|
if (clientName !== null) {
|
||||||
const obj = {
|
const obj = {
|
||||||
|
command: '',
|
||||||
destination: 'system-info',
|
destination: 'system-info',
|
||||||
type: 'chat',
|
type: 'chat',
|
||||||
user: clientName,
|
user: clientName,
|
||||||
|
|
@ -328,11 +392,69 @@ async function onReady(fastify: FastifyInstance) {
|
||||||
SenderWindowID: socket.id,
|
SenderWindowID: socket.id,
|
||||||
};
|
};
|
||||||
console.log(color.blue, 'BROADCASTS OUT :', obj.SenderWindowID);
|
console.log(color.blue, 'BROADCASTS OUT :', obj.SenderWindowID);
|
||||||
|
|
||||||
broadcast(obj, obj.SenderWindowID);
|
broadcast(obj, obj.SenderWindowID);
|
||||||
// clientChat.delete(obj.user);
|
// clientChat.delete(obj.user);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
socket.on('privMessage', (data) => {
|
||||||
|
const clientName: string = clientChat.get(socket.id)?.user || '';
|
||||||
|
const prvMessage: ClientMessage = JSON.parse(data) || '';
|
||||||
|
console.log(
|
||||||
|
color.blue,
|
||||||
|
`DEBUG LOG: ClientName: '${clientName}' id Socket: '${socket.id}' target Name:`,
|
||||||
|
prvMessage.command,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (clientName !== null) {
|
||||||
|
const obj = {
|
||||||
|
command: prvMessage.command,
|
||||||
|
destination: 'privateMsg',
|
||||||
|
type: 'chat',
|
||||||
|
user: clientName,
|
||||||
|
token: '',
|
||||||
|
text: prvMessage.text,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
SenderWindowID: socket.id,
|
||||||
|
};
|
||||||
|
console.log(color.blue, 'DEBUG LOG: PRIV MESSAGE OUT :', obj.SenderWindowID);
|
||||||
|
sendPrivMessage(obj, obj.SenderWindowID);
|
||||||
|
// clientChat.delete(obj.user);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('profilMessage', async (data) => {
|
||||||
|
const clientName: string = clientChat.get(socket.id)?.user || '';
|
||||||
|
const profilMessage: ClientMessage = JSON.parse(data) || '';
|
||||||
|
const users: User[] = fastify.db.getAllUsers() ?? [];
|
||||||
|
console.log(color.yellow, 'DEBUG LOG: ALL USERS EVER CONNECTED:', users);
|
||||||
|
console.log(
|
||||||
|
color.blue,
|
||||||
|
`DEBUG LOG: ClientName: '${clientName}' id Socket: '${socket.id}' target profil:`,
|
||||||
|
profilMessage.user,
|
||||||
|
);
|
||||||
|
const profileHtml: string = await getProfil(profilMessage.user);
|
||||||
|
if (clientName !== null) {
|
||||||
|
const testuser: User | null = getUserByName(users, profilMessage.user);
|
||||||
|
console.log(color.yellow, 'user:', testuser?.login ?? 'Guest');
|
||||||
|
const obj = {
|
||||||
|
command: profilMessage.command,
|
||||||
|
destination: 'profilMsg',
|
||||||
|
type: 'chat',
|
||||||
|
user: clientName,
|
||||||
|
token: '',
|
||||||
|
text: profileHtml,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
SenderWindowID: socket.id,
|
||||||
|
};
|
||||||
|
console.log(color.blue, 'DEBUG - profil message MESSAGE OUT :', obj.SenderWindowID);
|
||||||
|
sendProfil(obj, obj.SenderWindowID);
|
||||||
|
// clientChat.delete(obj.user);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
socket.on('client_entered', (data) => {
|
socket.on('client_entered', (data) => {
|
||||||
|
|
||||||
// data may be undefined (when frontend calls emit with no payload)
|
// data may be undefined (when frontend calls emit with no payload)
|
||||||
|
|
@ -364,6 +486,7 @@ async function onReady(fastify: FastifyInstance) {
|
||||||
);
|
);
|
||||||
if (clientName !== null) {
|
if (clientName !== null) {
|
||||||
const obj = {
|
const obj = {
|
||||||
|
command: '',
|
||||||
destination: 'system-info',
|
destination: 'system-info',
|
||||||
type: 'chat',
|
type: 'chat',
|
||||||
user: clientName,
|
user: clientName,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
"vite": "^7.2.6"
|
"vite": "^7.2.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@redocly/cli": "^2.12.1",
|
"@redocly/cli": "^2.12.3",
|
||||||
"bindings": "^1.5.0"
|
"bindings": "^1.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
101
src/pnpm-lock.yaml
generated
101
src/pnpm-lock.yaml
generated
|
|
@ -9,8 +9,8 @@ importers:
|
||||||
.:
|
.:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@redocly/cli':
|
'@redocly/cli':
|
||||||
specifier: ^2.12.1
|
specifier: ^2.12.3
|
||||||
version: 2.12.1(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0)
|
version: 2.12.3(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0)
|
||||||
bindings:
|
bindings:
|
||||||
specifier: ^1.5.0
|
specifier: ^1.5.0
|
||||||
version: 1.5.0
|
version: 1.5.0
|
||||||
|
|
@ -943,8 +943,8 @@ packages:
|
||||||
'@redocly/ajv@8.17.1':
|
'@redocly/ajv@8.17.1':
|
||||||
resolution: {integrity: sha512-EDtsGZS964mf9zAUXAl9Ew16eYbeyAFWhsPr0fX6oaJxgd8rApYlPBf0joyhnUHz88WxrigyFtTaqqzXNzPgqw==}
|
resolution: {integrity: sha512-EDtsGZS964mf9zAUXAl9Ew16eYbeyAFWhsPr0fX6oaJxgd8rApYlPBf0joyhnUHz88WxrigyFtTaqqzXNzPgqw==}
|
||||||
|
|
||||||
'@redocly/cli@2.12.1':
|
'@redocly/cli@2.12.3':
|
||||||
resolution: {integrity: sha512-XGD28QjjZEzN+J9WOROzw4fHNi+Fyw/gCyDZDgI4nX4j9gEBT1PcxN75wWpMoDGHKAUj8ghrhMHtfQoUuR90zg==}
|
resolution: {integrity: sha512-1SDW551scNdb4HmNpzyUf4gjsK89KkRUeXF91VVMRkQ5+lFEq1Nj259jN1M25uOd/cg1QjKE3kIbnN1dxPa3ng==}
|
||||||
engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
|
engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
|
@ -958,12 +958,12 @@ packages:
|
||||||
resolution: {integrity: sha512-0EbE8LRbkogtcCXU7liAyC00n9uNG9hJ+eMyHFdUsy9lB/WGqnEBgwjA9q2cyzAVcdTkQqTBBU1XePNnN3OijA==}
|
resolution: {integrity: sha512-0EbE8LRbkogtcCXU7liAyC00n9uNG9hJ+eMyHFdUsy9lB/WGqnEBgwjA9q2cyzAVcdTkQqTBBU1XePNnN3OijA==}
|
||||||
engines: {node: '>=18.17.0', npm: '>=9.5.0'}
|
engines: {node: '>=18.17.0', npm: '>=9.5.0'}
|
||||||
|
|
||||||
'@redocly/openapi-core@2.12.1':
|
'@redocly/openapi-core@2.12.3':
|
||||||
resolution: {integrity: sha512-xMlKf4dnZsxP3JYBNZFsMNBJqVxWlwLuyGLhGc36hXw50YOla1UjrVZ5psIyzLXgUPI3QJDA1XmGcJ8rcex/ow==}
|
resolution: {integrity: sha512-3gdSRftIeUbzXvwDi/tBjO0uj9PzR0XzbWjNwuu3HlVXJ1ElB+K31AnzQ2iA6mjIHq9uvmLRXAs9MsP/0Hbzug==}
|
||||||
engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
|
engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
|
||||||
|
|
||||||
'@redocly/respect-core@2.12.1':
|
'@redocly/respect-core@2.12.3':
|
||||||
resolution: {integrity: sha512-ADm+JMHWGYeOwzdGEQ8CYKjmMBLU0ycZTwJbCkQsUulXSNkNA7GzA8lrMM2+I8cPMRk25G5PmtfAR7U+a0o1ew==}
|
resolution: {integrity: sha512-ZYqrLBlRVVHwgPawOjo94sKmeuuien77xtkXluTa6+y/wkQ8c5oYY7OqWbasMv0IoxSPehwVMa0AL0OCQP3uCQ==}
|
||||||
engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
|
engines: {node: '>=22.12.0 || >=20.19.0 <21.0.0', npm: '>=10'}
|
||||||
|
|
||||||
'@rollup/rollup-android-arm-eabi@4.53.3':
|
'@rollup/rollup-android-arm-eabi@4.53.3':
|
||||||
|
|
@ -2613,10 +2613,10 @@ packages:
|
||||||
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
|
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
react-dom@19.2.0:
|
react-dom@19.2.1:
|
||||||
resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==}
|
resolution: {integrity: sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^19.2.0
|
react: ^19.2.1
|
||||||
|
|
||||||
react-is@16.13.1:
|
react-is@16.13.1:
|
||||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||||
|
|
@ -2626,8 +2626,8 @@ packages:
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
react: ^18.0.0 || ^19.0.0
|
react: ^18.0.0 || ^19.0.0
|
||||||
|
|
||||||
react@19.2.0:
|
react@19.2.1:
|
||||||
resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==}
|
resolution: {integrity: sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
readable-stream@3.6.2:
|
readable-stream@3.6.2:
|
||||||
|
|
@ -3054,6 +3054,10 @@ packages:
|
||||||
resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==}
|
resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
|
ulid@3.0.2:
|
||||||
|
resolution: {integrity: sha512-yu26mwteFYzBAot7KVMqFGCVpsF6g8wXfJzQUHvu1no3+rRRSFcSV2nKeYvNPLD2J4b08jYBDhHUjeH0ygIl9w==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
undici-types@6.21.0:
|
undici-types@6.21.0:
|
||||||
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
||||||
|
|
||||||
|
|
@ -3864,14 +3868,14 @@ snapshots:
|
||||||
json-schema-traverse: 1.0.0
|
json-schema-traverse: 1.0.0
|
||||||
require-from-string: 2.0.2
|
require-from-string: 2.0.2
|
||||||
|
|
||||||
'@redocly/cli@2.12.1(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0)':
|
'@redocly/cli@2.12.3(@opentelemetry/api@1.9.0)(ajv@8.17.1)(core-js@3.47.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@opentelemetry/exporter-trace-otlp-http': 0.202.0(@opentelemetry/api@1.9.0)
|
'@opentelemetry/exporter-trace-otlp-http': 0.202.0(@opentelemetry/api@1.9.0)
|
||||||
'@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0)
|
'@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0)
|
||||||
'@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0)
|
'@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0)
|
||||||
'@opentelemetry/semantic-conventions': 1.34.0
|
'@opentelemetry/semantic-conventions': 1.34.0
|
||||||
'@redocly/openapi-core': 2.12.1(ajv@8.17.1)
|
'@redocly/openapi-core': 2.12.3(ajv@8.17.1)
|
||||||
'@redocly/respect-core': 2.12.1(ajv@8.17.1)
|
'@redocly/respect-core': 2.12.3(ajv@8.17.1)
|
||||||
abort-controller: 3.0.0
|
abort-controller: 3.0.0
|
||||||
chokidar: 3.6.0
|
chokidar: 3.6.0
|
||||||
colorette: 1.4.0
|
colorette: 1.4.0
|
||||||
|
|
@ -3883,13 +3887,14 @@ snapshots:
|
||||||
https-proxy-agent: 7.0.6(supports-color@10.2.2)
|
https-proxy-agent: 7.0.6(supports-color@10.2.2)
|
||||||
mobx: 6.15.0
|
mobx: 6.15.0
|
||||||
pluralize: 8.0.0
|
pluralize: 8.0.0
|
||||||
react: 19.2.0
|
react: 19.2.1
|
||||||
react-dom: 19.2.0(react@19.2.0)
|
react-dom: 19.2.1(react@19.2.1)
|
||||||
redoc: 2.5.1(core-js@3.47.0)(mobx@6.15.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(styled-components@6.1.19(react-dom@19.2.0(react@19.2.0))(react@19.2.0))
|
redoc: 2.5.1(core-js@3.47.0)(mobx@6.15.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(styled-components@6.1.19(react-dom@19.2.1(react@19.2.1))(react@19.2.1))
|
||||||
semver: 7.7.3
|
semver: 7.7.3
|
||||||
set-cookie-parser: 2.7.2
|
set-cookie-parser: 2.7.2
|
||||||
simple-websocket: 9.1.0
|
simple-websocket: 9.1.0
|
||||||
styled-components: 6.1.19(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
styled-components: 6.1.19(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||||
|
ulid: 3.0.2
|
||||||
undici: 6.22.0
|
undici: 6.22.0
|
||||||
yargs: 17.0.1
|
yargs: 17.0.1
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
|
@ -3922,7 +3927,7 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@redocly/openapi-core@2.12.1(ajv@8.17.1)':
|
'@redocly/openapi-core@2.12.3(ajv@8.17.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@redocly/ajv': 8.17.1
|
'@redocly/ajv': 8.17.1
|
||||||
'@redocly/config': 0.40.0
|
'@redocly/config': 0.40.0
|
||||||
|
|
@ -3936,12 +3941,12 @@ snapshots:
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- ajv
|
- ajv
|
||||||
|
|
||||||
'@redocly/respect-core@2.12.1(ajv@8.17.1)':
|
'@redocly/respect-core@2.12.3(ajv@8.17.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@faker-js/faker': 7.6.0
|
'@faker-js/faker': 7.6.0
|
||||||
'@noble/hashes': 1.8.0
|
'@noble/hashes': 1.8.0
|
||||||
'@redocly/ajv': 8.17.1
|
'@redocly/ajv': 8.17.1
|
||||||
'@redocly/openapi-core': 2.12.1(ajv@8.17.1)
|
'@redocly/openapi-core': 2.12.3(ajv@8.17.1)
|
||||||
better-ajv-errors: 1.2.0(ajv@8.17.1)
|
better-ajv-errors: 1.2.0(ajv@8.17.1)
|
||||||
colorette: 2.0.20
|
colorette: 2.0.20
|
||||||
json-pointer: 0.6.2
|
json-pointer: 0.6.2
|
||||||
|
|
@ -5282,21 +5287,21 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
obliterator: 2.0.5
|
obliterator: 2.0.5
|
||||||
|
|
||||||
mobx-react-lite@4.1.1(mobx@6.15.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
mobx-react-lite@4.1.1(mobx@6.15.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
mobx: 6.15.0
|
mobx: 6.15.0
|
||||||
react: 19.2.0
|
react: 19.2.1
|
||||||
use-sync-external-store: 1.6.0(react@19.2.0)
|
use-sync-external-store: 1.6.0(react@19.2.1)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react-dom: 19.2.0(react@19.2.0)
|
react-dom: 19.2.1(react@19.2.1)
|
||||||
|
|
||||||
mobx-react@9.2.0(mobx@6.15.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
mobx-react@9.2.0(mobx@6.15.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
mobx: 6.15.0
|
mobx: 6.15.0
|
||||||
mobx-react-lite: 4.1.1(mobx@6.15.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
mobx-react-lite: 4.1.1(mobx@6.15.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||||
react: 19.2.0
|
react: 19.2.1
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
react-dom: 19.2.0(react@19.2.0)
|
react-dom: 19.2.1(react@19.2.1)
|
||||||
|
|
||||||
mobx@6.15.0: {}
|
mobx@6.15.0: {}
|
||||||
|
|
||||||
|
|
@ -5661,20 +5666,20 @@ snapshots:
|
||||||
minimist: 1.2.8
|
minimist: 1.2.8
|
||||||
strip-json-comments: 2.0.1
|
strip-json-comments: 2.0.1
|
||||||
|
|
||||||
react-dom@19.2.0(react@19.2.0):
|
react-dom@19.2.1(react@19.2.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.2.0
|
react: 19.2.1
|
||||||
scheduler: 0.27.0
|
scheduler: 0.27.0
|
||||||
|
|
||||||
react-is@16.13.1: {}
|
react-is@16.13.1: {}
|
||||||
|
|
||||||
react-tabs@6.1.0(react@19.2.0):
|
react-tabs@6.1.0(react@19.2.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
clsx: 2.1.1
|
clsx: 2.1.1
|
||||||
prop-types: 15.8.1
|
prop-types: 15.8.1
|
||||||
react: 19.2.0
|
react: 19.2.1
|
||||||
|
|
||||||
react@19.2.0: {}
|
react@19.2.1: {}
|
||||||
|
|
||||||
readable-stream@3.6.2:
|
readable-stream@3.6.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
@ -5690,7 +5695,7 @@ snapshots:
|
||||||
|
|
||||||
real-require@0.2.0: {}
|
real-require@0.2.0: {}
|
||||||
|
|
||||||
redoc@2.5.1(core-js@3.47.0)(mobx@6.15.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(styled-components@6.1.19(react-dom@19.2.0(react@19.2.0))(react@19.2.0)):
|
redoc@2.5.1(core-js@3.47.0)(mobx@6.15.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(styled-components@6.1.19(react-dom@19.2.1(react@19.2.1))(react@19.2.1)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@redocly/openapi-core': 1.34.5(supports-color@10.2.2)
|
'@redocly/openapi-core': 1.34.5(supports-color@10.2.2)
|
||||||
classnames: 2.5.1
|
classnames: 2.5.1
|
||||||
|
|
@ -5703,19 +5708,19 @@ snapshots:
|
||||||
mark.js: 8.11.1
|
mark.js: 8.11.1
|
||||||
marked: 4.3.0
|
marked: 4.3.0
|
||||||
mobx: 6.15.0
|
mobx: 6.15.0
|
||||||
mobx-react: 9.2.0(mobx@6.15.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
mobx-react: 9.2.0(mobx@6.15.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||||
openapi-sampler: 1.6.2
|
openapi-sampler: 1.6.2
|
||||||
path-browserify: 1.0.1
|
path-browserify: 1.0.1
|
||||||
perfect-scrollbar: 1.5.6
|
perfect-scrollbar: 1.5.6
|
||||||
polished: 4.3.1
|
polished: 4.3.1
|
||||||
prismjs: 1.30.0
|
prismjs: 1.30.0
|
||||||
prop-types: 15.8.1
|
prop-types: 15.8.1
|
||||||
react: 19.2.0
|
react: 19.2.1
|
||||||
react-dom: 19.2.0(react@19.2.0)
|
react-dom: 19.2.1(react@19.2.1)
|
||||||
react-tabs: 6.1.0(react@19.2.0)
|
react-tabs: 6.1.0(react@19.2.1)
|
||||||
slugify: 1.4.7
|
slugify: 1.4.7
|
||||||
stickyfill: 1.1.1
|
stickyfill: 1.1.1
|
||||||
styled-components: 6.1.19(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
styled-components: 6.1.19(react-dom@19.2.1(react@19.2.1))(react@19.2.1)
|
||||||
swagger2openapi: 7.0.8
|
swagger2openapi: 7.0.8
|
||||||
url-template: 2.0.8
|
url-template: 2.0.8
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
|
@ -6034,7 +6039,7 @@ snapshots:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tokenizer/token': 0.3.0
|
'@tokenizer/token': 0.3.0
|
||||||
|
|
||||||
styled-components@6.1.19(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
styled-components@6.1.19(react-dom@19.2.1(react@19.2.1))(react@19.2.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@emotion/is-prop-valid': 1.2.2
|
'@emotion/is-prop-valid': 1.2.2
|
||||||
'@emotion/unitless': 0.8.1
|
'@emotion/unitless': 0.8.1
|
||||||
|
|
@ -6042,8 +6047,8 @@ snapshots:
|
||||||
css-to-react-native: 3.2.0
|
css-to-react-native: 3.2.0
|
||||||
csstype: 3.1.3
|
csstype: 3.1.3
|
||||||
postcss: 8.4.49
|
postcss: 8.4.49
|
||||||
react: 19.2.0
|
react: 19.2.1
|
||||||
react-dom: 19.2.0(react@19.2.0)
|
react-dom: 19.2.1(react@19.2.1)
|
||||||
shallowequal: 1.1.0
|
shallowequal: 1.1.0
|
||||||
stylis: 4.3.2
|
stylis: 4.3.2
|
||||||
tslib: 2.6.2
|
tslib: 2.6.2
|
||||||
|
|
@ -6178,6 +6183,8 @@ snapshots:
|
||||||
|
|
||||||
uint8array-extras@1.5.0: {}
|
uint8array-extras@1.5.0: {}
|
||||||
|
|
||||||
|
ulid@3.0.2: {}
|
||||||
|
|
||||||
undici-types@6.21.0: {}
|
undici-types@6.21.0: {}
|
||||||
|
|
||||||
undici-types@7.16.0: {}
|
undici-types@7.16.0: {}
|
||||||
|
|
@ -6194,9 +6201,9 @@ snapshots:
|
||||||
|
|
||||||
url-template@2.0.8: {}
|
url-template@2.0.8: {}
|
||||||
|
|
||||||
use-sync-external-store@1.6.0(react@19.2.0):
|
use-sync-external-store@1.6.0(react@19.2.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.2.0
|
react: 19.2.1
|
||||||
|
|
||||||
util-deprecate@1.0.2: {}
|
util-deprecate@1.0.2: {}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue