374 lines
12 KiB
TypeScript
Executable File
374 lines
12 KiB
TypeScript
Executable File
import { groupsMock } from '../../mocks/mock-signature/groupsMock.js';
|
|
import { messageStore } from '../../utils/messageMock.js';
|
|
|
|
let messagesMock = messageStore.getMessages();
|
|
|
|
let selectedMemberId: number | null = null;
|
|
|
|
// Load the list of groups
|
|
function loadGroupList() {
|
|
const groupList = document.getElementById('group-list');
|
|
if (!groupList) return;
|
|
|
|
groupsMock.forEach(group => {
|
|
const li = document.createElement('li');
|
|
li.textContent = group.name;
|
|
li.onclick = (event) => {
|
|
event.stopPropagation();
|
|
toggleRoles(group, li);
|
|
};
|
|
groupList.appendChild(li);
|
|
});
|
|
}
|
|
|
|
// Toggle the list of Roles
|
|
function toggleRoles(group: { roles: { name: string; members: any[] }[] }, groupElement: HTMLElement) {
|
|
let roleList = groupElement.querySelector('.role-list') as HTMLElement;
|
|
if (roleList) {
|
|
roleList.style.display = roleList.style.display === 'none' ? 'block' : 'none';
|
|
return;
|
|
}
|
|
|
|
roleList = document.createElement('ul');
|
|
roleList.className = 'role-list';
|
|
|
|
group.roles.forEach(role => {
|
|
const roleItem = document.createElement('li');
|
|
roleItem.textContent = role.name;
|
|
|
|
roleItem.onclick = (event) => {
|
|
event.stopPropagation();
|
|
toggleMembers(role, roleItem);
|
|
};
|
|
|
|
roleList.appendChild(roleItem);
|
|
});
|
|
|
|
groupElement.appendChild(roleList);
|
|
}
|
|
|
|
// Toggle the list of membres
|
|
function toggleMembers(role: { members: { id: number; name: string; }[] }, roleElement: HTMLElement) {
|
|
let memberList = roleElement.querySelector('.member-list') as HTMLElement;
|
|
if (memberList) {
|
|
memberList.style.display = memberList.style.display === 'none' ? 'block' : 'none';
|
|
return;
|
|
}
|
|
|
|
memberList = document.createElement('ul');
|
|
memberList.className = 'member-list';
|
|
|
|
role.members.forEach(member => {
|
|
const memberItem = document.createElement('li');
|
|
memberItem.textContent = member.name;
|
|
|
|
memberItem.onclick = (event) => {
|
|
event.stopPropagation();
|
|
loadMemberChat(member.id);
|
|
};
|
|
|
|
memberList.appendChild(memberItem);
|
|
});
|
|
|
|
roleElement.appendChild(memberList);
|
|
}
|
|
|
|
// Load the list of members
|
|
function loadMemberChat(memberId: string | number) {
|
|
selectedMemberId = Number(memberId);
|
|
const memberMessages = messagesMock.find(m => String(m.memberId) === String(memberId));
|
|
|
|
// Trouver le processus et le rôle du membre
|
|
let memberInfo = { processName: '', roleName: '', memberName: '' };
|
|
groupsMock.forEach(process => {
|
|
process.roles.forEach(role => {
|
|
const member = role.members.find(m => String(m.id) === String(memberId));
|
|
if (member) {
|
|
memberInfo = {
|
|
processName: process.name,
|
|
roleName: role.name,
|
|
memberName: member.name
|
|
};
|
|
}
|
|
});
|
|
});
|
|
|
|
const chatHeader = document.getElementById('chat-header');
|
|
const messagesContainer = document.getElementById('messages');
|
|
|
|
if (!chatHeader || !messagesContainer) return;
|
|
|
|
chatHeader.textContent = `Chat with ${memberInfo.roleName} ${memberInfo.memberName} from ${memberInfo.processName}`;
|
|
messagesContainer.innerHTML = '';
|
|
|
|
if (memberMessages) {
|
|
memberMessages.messages.forEach((message: {
|
|
type: string;
|
|
fileData?: string;
|
|
fileName?: string;
|
|
sender: string;
|
|
text?: string;
|
|
time: string;
|
|
}) => {
|
|
const messageElement = document.createElement('div');
|
|
messageElement.className = 'message-container';
|
|
|
|
const messageContent = document.createElement('div');
|
|
messageContent.className = 'message';
|
|
if (message.type === 'file') {
|
|
messageContent.innerHTML = `<a href="${message.fileData}" download="${message.fileName}" target="_blank">${message.fileName}</a>`;
|
|
messageContent.classList.add('user');
|
|
} else {
|
|
messageContent.innerHTML = `<strong>${message.sender}</strong>: ${message.text} <span style="float: right;">${message.time}</span>`;
|
|
if (message.sender === "4NK") {
|
|
messageContent.classList.add('user');
|
|
}
|
|
}
|
|
|
|
messageElement.appendChild(messageContent);
|
|
messagesContainer.appendChild(messageElement);
|
|
});
|
|
}
|
|
|
|
|
|
scrollToBottom(messagesContainer);
|
|
}
|
|
|
|
// Scroll down the conversation after loading messages
|
|
function scrollToBottom(container: HTMLElement) {
|
|
container.scrollTop = container.scrollHeight;
|
|
}
|
|
|
|
// Generate an automatic response
|
|
function generateAutoReply(senderName: string) {
|
|
return {
|
|
id: Date.now(),
|
|
sender: senderName,
|
|
text: "OK...",
|
|
time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
|
|
type: 'text'
|
|
};
|
|
}
|
|
|
|
// Send a messsage
|
|
function sendMessage() {
|
|
const messageInput = document.getElementById('message-input') as HTMLInputElement;
|
|
if (!messageInput) return;
|
|
const messageText = messageInput.value.trim();
|
|
|
|
if (messageText === '' || selectedMemberId === null) {
|
|
return;
|
|
}
|
|
|
|
const newMessage = {
|
|
id: Date.now(),
|
|
sender: "4NK",
|
|
text: messageText,
|
|
time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
|
|
type: 'text'
|
|
};
|
|
|
|
// Ajouter et afficher le message immédiatement
|
|
messageStore.addMessage(selectedMemberId, newMessage);
|
|
messagesMock = messageStore.getMessages();
|
|
loadMemberChat(selectedMemberId);
|
|
|
|
// Réinitialiser l'input
|
|
messageInput.value = '';
|
|
|
|
// Réponse automatique après 2 secondes
|
|
setTimeout(() => {
|
|
if (selectedMemberId === null) return;
|
|
|
|
const autoReply = generateAutoReply(`Member ${selectedMemberId}`);
|
|
messageStore.addMessage(selectedMemberId, autoReply);
|
|
messagesMock = messageStore.getMessages();
|
|
loadMemberChat(selectedMemberId);
|
|
addNotification(selectedMemberId, autoReply);
|
|
}, 2000);
|
|
}
|
|
|
|
// Add an event for the submit button
|
|
const sendBtn = document.getElementById('send-button');
|
|
const messageInput = document.getElementById('message-input');
|
|
|
|
if (sendBtn) sendBtn.onclick = sendMessage;
|
|
if (messageInput) {
|
|
messageInput.addEventListener('keydown', function (event) {
|
|
if (event.key === 'Enter') {
|
|
event.preventDefault();
|
|
sendMessage();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Send a file
|
|
function sendFile(file: File) {
|
|
const reader = new FileReader();
|
|
reader.onloadend = function () {
|
|
const fileData = reader.result;
|
|
const fileName = file.name;
|
|
|
|
const newFileMessage = {
|
|
id: Date.now(),
|
|
sender: "4NK",
|
|
fileName: fileName,
|
|
fileData: fileData,
|
|
time: new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
|
|
type: 'file'
|
|
};
|
|
|
|
if (selectedMemberId === null) return;
|
|
messageStore.addMessage(selectedMemberId, newFileMessage);
|
|
|
|
messagesMock = messageStore.getMessages();
|
|
|
|
if (selectedMemberId !== null) {
|
|
loadMemberChat(selectedMemberId);
|
|
}
|
|
};
|
|
|
|
reader.readAsDataURL(file);
|
|
}
|
|
|
|
// Managing the sent file
|
|
document.getElementById('file-input')?.addEventListener('change', function (event: Event) {
|
|
const file = (event.target as HTMLInputElement).files?.[0];
|
|
if (file) {
|
|
sendFile(file);
|
|
}
|
|
});
|
|
|
|
|
|
///////////////////// Notification module /////////////////////
|
|
const notificationBadge = document.querySelector('.notification-badge') as HTMLElement;
|
|
const notificationBoard = document.getElementById('notification-board');
|
|
const notificationBell = document.getElementById('notification-bell');
|
|
|
|
interface Notification {
|
|
memberId: number;
|
|
text: string;
|
|
time: string;
|
|
}
|
|
|
|
let notifications: Notification[] = [];
|
|
let unreadCount = 0;
|
|
// Update notification badge
|
|
function updateNotificationBadge() {
|
|
if (!notificationBadge) return;
|
|
const count = notifications.length;
|
|
notificationBadge.textContent = count > 99 ? '+99' : count.toString();
|
|
notificationBadge.style.display = count > 0 ? 'block' : 'none';
|
|
}
|
|
|
|
// Add notification
|
|
function addNotification(memberId: number, message: { text: string; time: string }) {
|
|
// Creating a new notification
|
|
const notification = {
|
|
memberId,
|
|
text: `New message from Member ${memberId}: ${message.text}`,
|
|
time: message.time
|
|
};
|
|
|
|
// Added notification to list and interface
|
|
notifications.push(notification);
|
|
renderNotifications();
|
|
updateNotificationBadge();
|
|
}
|
|
|
|
// Show notifications
|
|
function renderNotifications() {
|
|
if (!notificationBoard) return;
|
|
|
|
// Reset the interface
|
|
notificationBoard.innerHTML = '';
|
|
|
|
// Displays "No notifications available" if there are no notifications
|
|
if (notifications.length === 0) {
|
|
notificationBoard.innerHTML = '<div class="no-notification">No notifications available</div>';
|
|
return;
|
|
}
|
|
|
|
// Add each notification to the list
|
|
notifications.forEach((notif, index) => {
|
|
const notifElement = document.createElement('div');
|
|
notifElement.className = 'notification-item';
|
|
notifElement.textContent = `${notif.text} at ${notif.time}`;
|
|
notifElement.onclick = () => {
|
|
loadMemberChat(notif.memberId);
|
|
removeNotification(index);
|
|
};
|
|
notificationBoard.appendChild(notifElement);
|
|
});
|
|
}
|
|
|
|
// Delete a notification
|
|
function removeNotification(index: number) {
|
|
notifications.splice(index, 1);
|
|
renderNotifications();
|
|
updateNotificationBadge();
|
|
}
|
|
|
|
// Adds an event for deploying the notification list
|
|
if (notificationBell && notificationBoard) {
|
|
notificationBell.onclick = () => {
|
|
notificationBoard.style.display = notificationBoard.style.display === 'block' ? 'none' : 'block';
|
|
};
|
|
}
|
|
|
|
// Close the notification board when clicking outside of it
|
|
document.addEventListener('click', (event) => {
|
|
if (notificationBoard && notificationBell &&
|
|
notificationBoard.style.display === 'block' &&
|
|
!notificationBoard.contains(event.target as Node) &&
|
|
!notificationBell.contains(event.target as Node)) {
|
|
notificationBoard.style.display = 'none';
|
|
}
|
|
});
|
|
|
|
// Loads group list at startup
|
|
//loadGroupList();
|
|
|
|
export function initChat(): void {
|
|
loadGroupList();
|
|
|
|
// Re-initialize event listeners
|
|
const sendBtn = document.getElementById('send-button');
|
|
const messageInput = document.getElementById('message-input');
|
|
const fileInput = document.getElementById('file-input');
|
|
|
|
if (sendBtn) sendBtn.onclick = sendMessage;
|
|
if (messageInput) {
|
|
messageInput.addEventListener('keydown', function (event) {
|
|
if (event.key === 'Enter') {
|
|
event.preventDefault();
|
|
sendMessage();
|
|
}
|
|
});
|
|
}
|
|
|
|
if (fileInput) {
|
|
fileInput.addEventListener('change', function (event: Event) {
|
|
const file = (event.target as HTMLInputElement).files?.[0];
|
|
if (file) {
|
|
sendFile(file);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Initialize notification listeners
|
|
const notificationBell = document.getElementById('notification-bell');
|
|
const notificationBoard = document.getElementById('notification-board');
|
|
|
|
if (notificationBell && notificationBoard) {
|
|
notificationBell.onclick = () => {
|
|
notificationBoard.style.display = notificationBoard.style.display === 'block' ? 'none' : 'block';
|
|
};
|
|
}
|
|
}
|
|
|
|
function saveMessagesToLocalStorage(messages: any[]) {
|
|
messageStore.setMessages(messages);
|
|
messagesMock = messageStore.getMessages();
|
|
}
|