Bootstrap
Bootstrap5
Telegram
Chat
Messagerie
Html
Template Bootstrap 5 de messagerie type Telegram Web avec liste de conversations et panneau de discussion.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="copyright" content="MEZGANI Said" />
<meta name="author" content="AngularForAll" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Template Telegrame Bootstrap 5 01 | AngularForAll</title>
<!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', sans-serif;
background: var(--tg-theme-bg-color, #17212b);
height: 100vh;
overflow: hidden;
}
/* Variables Telegram */
:root {
--tg-bg: #17212b;
--tg-sidebar: #17212b;
--tg-header: #242f3d;
--tg-chat-bg: #0e1621;
--tg-message-out: #2b5278;
--tg-message-in: #242f3d;
--tg-text-primary: #ffffff;
--tg-text-secondary: #7c8b9a;
--tg-accent: #2fa9e4;
--tg-accent-hover: #3fb9f4;
--tg-border: #1f2c38;
--tg-scrollbar: #3a4a5a;
--tg-avatar-gradient-1: linear-gradient(135deg, #6ab0f2, #3a82c4);
--tg-avatar-gradient-2: linear-gradient(135deg, #f29b6a, #c47a3a);
--tg-avatar-gradient-3: linear-gradient(135deg, #6af29b, #3ac47a);
--tg-avatar-gradient-4: linear-gradient(135deg, #f26a9b, #c43a6a);
--tg-avatar-gradient-5: linear-gradient(135deg, #c46af2, #8a3ac4);
}
/* Structure principale */
.app-container {
display: flex;
height: 100vh;
background: var(--tg-bg);
}
/* ===== SIDEBAR GAUCHE ===== */
.sidebar {
width: 320px;
background: var(--tg-sidebar);
border-right: 1px solid var(--tg-border);
display: flex;
flex-direction: column;
}
/* Header sidebar avec menu hamburger */
.sidebar-header {
background: var(--tg-header);
padding: 12px 16px;
display: flex;
align-items: center;
justify-content: space-between;
min-height: 60px;
}
.menu-btn {
color: var(--tg-text-secondary);
font-size: 1.4rem;
cursor: pointer;
transition: color 0.2s;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
.menu-btn:hover {
color: var(--tg-text-primary);
background: rgba(255, 255, 255, 0.05);
}
.sidebar-title {
color: var(--tg-text-primary);
font-weight: 600;
font-size: 1.2rem;
margin: 0;
}
.search-container {
padding: 8px 12px;
background: var(--tg-sidebar);
}
.search-box {
background: var(--tg-header);
border-radius: 22px;
padding: 8px 16px;
display: flex;
align-items: center;
gap: 12px;
border: 1px solid transparent;
transition: border-color 0.2s, background 0.2s;
}
.search-box:focus-within {
border-color: var(--tg-accent);
background: var(--tg-chat-bg);
}
.search-box i {
color: var(--tg-text-secondary);
font-size: 1rem;
}
.search-box input {
background: transparent;
border: none;
color: var(--tg-text-primary);
outline: none;
width: 100%;
font-size: 0.95rem;
}
.search-box input::placeholder {
color: var(--tg-text-secondary);
}
/* Liste des conversations */
.chat-list {
flex: 1;
overflow-y: auto;
background: var(--tg-sidebar);
}
.chat-item {
display: flex;
align-items: center;
padding: 10px 12px;
cursor: pointer;
transition: background 0.15s;
border-radius: 10px;
margin: 2px 6px;
}
.chat-item:hover {
background: rgba(255, 255, 255, 0.05);
}
.chat-item.active {
background: var(--tg-accent);
}
.chat-item.active .chat-name,
.chat-item.active .last-message,
.chat-item.active .chat-time {
color: white;
}
.chat-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
margin-right: 12px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: 500;
font-size: 1.1rem;
text-transform: uppercase;
}
.chat-info {
flex: 1;
min-width: 0;
}
.chat-header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 4px;
}
.chat-name {
color: var(--tg-text-primary);
font-weight: 500;
font-size: 1rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.chat-time {
color: var(--tg-text-secondary);
font-size: 0.75rem;
}
.chat-last-message {
display: flex;
align-items: center;
gap: 4px;
}
.last-message {
color: var(--tg-text-secondary);
font-size: 0.85rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
}
.message-status {
color: var(--tg-accent);
font-size: 1rem;
}
.unread-badge {
background: var(--tg-accent);
color: white;
border-radius: 12px;
padding: 2px 8px;
font-size: 0.75rem;
font-weight: 600;
min-width: 20px;
text-align: center;
margin-left: 6px;
}
/* ===== ZONE PRINCIPALE (CHAT) ===== */
.chat-area {
flex: 1;
display: flex;
flex-direction: column;
background: var(--tg-chat-bg);
position: relative;
}
/* Fond Telegram avec motif */
.chat-background {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect width="100" height="100" fill="%230e1621"/><circle cx="20" cy="20" r="15" fill="%23111b26" opacity="0.5"/><circle cx="80" cy="80" r="15" fill="%23111b26" opacity="0.5"/></svg>');
background-size: 200px 200px;
opacity: 0.4;
z-index: 0;
}
/* Header du chat */
.chat-header-bar {
background: var(--tg-header);
padding: 10px 20px;
display: flex;
align-items: center;
justify-content: space-between;
min-height: 60px;
border-bottom: 1px solid var(--tg-border);
position: relative;
z-index: 1;
}
.chat-contact-info {
display: flex;
align-items: center;
gap: 15px;
}
.contact-avatar {
width: 42px;
height: 42px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: 500;
font-size: 1rem;
}
.contact-details h6 {
color: var(--tg-text-primary);
margin: 0;
font-size: 1rem;
font-weight: 600;
}
.contact-details small {
color: var(--tg-text-secondary);
font-size: 0.8rem;
}
.chat-actions {
display: flex;
gap: 16px;
}
.chat-actions i {
color: var(--tg-text-secondary);
font-size: 1.3rem;
cursor: pointer;
transition: color 0.2s;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
.chat-actions i:hover {
color: var(--tg-text-primary);
background: rgba(255, 255, 255, 0.05);
}
/* Zone des messages */
.messages-container {
flex: 1;
overflow-y: auto;
padding: 20px;
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
}
.message-group {
margin-bottom: 16px;
}
.message {
display: flex;
margin-bottom: 4px;
}
.message.sent {
justify-content: flex-end;
}
.message.received {
justify-content: flex-start;
}
.message-bubble-wrapper {
display: flex;
align-items: flex-end;
gap: 6px;
max-width: 70%;
}
.message.sent .message-bubble-wrapper {
flex-direction: row-reverse;
}
.message-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 0.8rem;
font-weight: 500;
flex-shrink: 0;
}
.message.received .message-avatar {
display: flex;
}
.message.sent .message-avatar {
display: none;
}
.message-bubble {
padding: 10px 14px;
border-radius: 18px;
position: relative;
word-wrap: break-word;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.message.sent .message-bubble {
background: var(--tg-message-out);
color: var(--tg-text-primary);
border-bottom-right-radius: 4px;
}
.message.received .message-bubble {
background: var(--tg-message-in);
color: var(--tg-text-primary);
border-bottom-left-radius: 4px;
}
.message-meta {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 4px;
margin-top: 4px;
font-size: 0.7rem;
color: var(--tg-text-secondary);
}
.message.sent .message-meta {
color: rgba(255, 255, 255, 0.6);
}
.message-status i {
font-size: 0.9rem;
color: var(--tg-accent);
}
/* Zone de saisie */
.message-input-container {
background: var(--tg-header);
padding: 12px 20px;
display: flex;
align-items: center;
gap: 12px;
position: relative;
z-index: 1;
border-top: 1px solid var(--tg-border);
}
.input-actions-left {
display: flex;
gap: 8px;
}
.input-actions-left i {
color: var(--tg-text-secondary);
font-size: 1.4rem;
cursor: pointer;
transition: color 0.2s;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
.input-actions-left i:hover {
color: var(--tg-text-primary);
background: rgba(255, 255, 255, 0.05);
}
.message-input {
flex: 1;
background: var(--tg-chat-bg);
border: none;
border-radius: 24px;
padding: 10px 18px;
color: var(--tg-text-primary);
outline: none;
font-size: 0.95rem;
border: 1px solid transparent;
transition: border-color 0.2s;
}
.message-input:focus {
border-color: var(--tg-accent);
}
.message-input::placeholder {
color: var(--tg-text-secondary);
}
.input-actions-right {
display: flex;
gap: 8px;
}
.input-actions-right i {
color: var(--tg-text-secondary);
font-size: 1.4rem;
cursor: pointer;
transition: all 0.2s;
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
.input-actions-right i:hover {
color: var(--tg-text-primary);
background: rgba(255, 255, 255, 0.05);
}
#sendMessageBtn {
color: var(--tg-accent);
}
#sendMessageBtn:hover {
background: rgba(47, 169, 228, 0.1);
}
/* Écran de bienvenue */
.welcome-screen {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
z-index: 1;
background: var(--tg-chat-bg);
}
.welcome-logo {
width: 160px;
height: 160px;
background: var(--tg-accent);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 30px;
box-shadow: 0 10px 30px rgba(47, 169, 228, 0.3);
}
.welcome-logo i {
font-size: 5rem;
color: white;
}
.welcome-screen h2 {
color: var(--tg-text-primary);
font-weight: 400;
margin-bottom: 15px;
}
.welcome-screen p {
color: var(--tg-text-secondary);
text-align: center;
max-width: 400px;
font-size: 0.95rem;
}
/* Scrollbar personnalisée style Telegram */
::-webkit-scrollbar {
width: 5px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: var(--tg-scrollbar);
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #4a5a6a;
}
/* Responsive */
@media (max-width: 768px) {
.sidebar {
width: 100%;
}
.chat-area {
display: none;
}
.chat-area.active {
display: flex;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
}
.back-btn-mobile {
display: block !important;
}
}
.back-btn-mobile {
display: none;
}
</style>
</head>
<body>
<div class="app-container">
<!-- ===== SIDEBAR (Liste des conversations) ===== -->
<div class="sidebar">
<!-- Header -->
<div class="sidebar-header">
<div class="menu-btn">
<i class="bi bi-list"></i>
</div>
<span class="sidebar-title">Telegram</span>
<div class="menu-btn">
<i class="bi bi-pencil-square"></i>
</div>
</div>
<!-- Barre de recherche -->
<div class="search-container">
<div class="search-box">
<i class="bi bi-search"></i>
<input type="text" placeholder="Rechercher" id="searchInput">
</div>
</div>
<!-- Liste des conversations -->
<div class="chat-list" id="chatList">
<!-- Les conversations seront injectées ici par JS -->
</div>
</div>
<!-- ===== ZONE PRINCIPALE (Chat) ===== -->
<div class="chat-area" id="chatArea">
<div class="chat-background"></div>
<!-- Écran de bienvenue (par défaut) -->
<div class="welcome-screen" id="welcomeScreen">
<div class="welcome-logo">
<i class="bi bi-send-fill"></i>
</div>
<h2>Telegram Web</h2>
<p>Sélectionnez une conversation pour commencer à discuter.<br>Vos messages sont synchronisés sur tous vos appareils.</p>
</div>
<!-- Zone de chat active (cachée par défaut) -->
<div id="activeChat" style="display: none; flex: 1; flex-direction: column;">
<!-- Header du chat -->
<div class="chat-header-bar">
<div class="chat-contact-info">
<i class="bi bi-arrow-left back-btn-mobile" style="color: var(--tg-text-secondary); font-size: 1.3rem; cursor: pointer; margin-right: 10px;" onclick="goBack()"></i>
<div class="contact-avatar" id="contactAvatar"></div>
<div class="contact-details">
<h6 id="contactName">Contact</h6>
<small id="contactStatus">en ligne</small>
</div>
</div>
<div class="chat-actions">
<i class="bi bi-search"></i>
<i class="bi bi-telephone"></i>
<i class="bi bi-three-dots-vertical"></i>
</div>
</div>
<!-- Messages -->
<div class="messages-container" id="messagesContainer">
<!-- Messages injectés ici -->
</div>
<!-- Zone de saisie -->
<div class="message-input-container">
<div class="input-actions-left">
<i class="bi bi-emoji-smile"></i>
<i class="bi bi-paperclip"></i>
</div>
<input type="text" class="message-input" id="messageInput" placeholder="Écrire un message...">
<div class="input-actions-right">
<i class="bi bi-mic"></i>
<i class="bi bi-send-fill" id="sendMessageBtn"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
// ===== DONNÉES DES CONVERSATIONS =====
const conversations = [
{
id: 1,
name: 'Marie Lambert',
avatar: 'ML',
avatarColor: '--tg-avatar-gradient-1',
lastMessage: 'On se voit demain pour le café ? ☕',
time: '12:45',
unread: 2,
status: 'en ligne',
messages: [
{ id: 1, text: 'Salut ! Comment vas-tu ?', sent: false, time: '12:30', status: 'read' },
{ id: 2, text: 'Très bien ! Et toi ? 😊', sent: true, time: '12:32', status: 'read' },
{ id: 3, text: 'Super ! Dis-moi, tu es libre demain ?', sent: false, time: '12:40', status: 'read' },
{ id: 4, text: 'Oui, pourquoi pas !', sent: true, time: '12:42', status: 'read' },
{ id: 5, text: 'On se voit demain pour le café ? ☕', sent: false, time: '12:45', status: 'read' }
]
},
{
id: 2,
name: 'Thomas Martin',
avatar: 'TM',
avatarColor: '--tg-avatar-gradient-2',
lastMessage: 'Le rapport est prêt, je te l\'envoie',
time: '11:20',
unread: 0,
status: 'en ligne',
messages: [
{ id: 1, text: 'Tu as avancé sur le projet ?', sent: true, time: '10:00', status: 'read' },
{ id: 2, text: 'Oui, presque terminé !', sent: false, time: '10:15', status: 'read' },
{ id: 3, text: 'Parfait, tu peux me l\'envoyer ?', sent: true, time: '11:10', status: 'read' },
{ id: 4, text: 'Le rapport est prêt, je te l\'envoie', sent: false, time: '11:20', status: 'read' }
]
},
{
id: 3,
name: 'Sophie Dubois',
avatar: 'SD',
avatarColor: '--tg-avatar-gradient-3',
lastMessage: 'Merci beaucoup ! 🙏',
time: 'Hier',
unread: 1,
status: 'vu à 18:30',
messages: [
{ id: 1, text: 'Coucou ! Tu as une minute ?', sent: false, time: '17:00', status: 'read' },
{ id: 2, text: 'Bien sûr, qu\'est-ce qu\'il y a ?', sent: true, time: '17:05', status: 'read' },
{ id: 3, text: 'Je voulais te remercier pour ton aide hier', sent: false, time: '17:10', status: 'read' },
{ id: 4, text: 'Avec plaisir ! N\'hésite pas si besoin', sent: true, time: '17:15', status: 'read' },
{ id: 5, text: 'Merci beaucoup ! 🙏', sent: false, time: '18:30', status: 'read' }
]
},
{
id: 4,
name: 'Lucas Bernard',
avatar: 'LB',
avatarColor: '--tg-avatar-gradient-4',
lastMessage: 'On se rejoint où exactement ?',
time: 'Hier',
unread: 0,
status: 'hors ligne',
messages: [
{ id: 1, text: 'Salut Lucas ! Dispo ce soir ?', sent: true, time: '19:00', status: 'read' },
{ id: 2, text: 'Oui, vers 20h ça te va ?', sent: false, time: '19:10', status: 'read' },
{ id: 3, text: 'Parfait ! On se retrouve où ?', sent: true, time: '19:15', status: 'read' },
{ id: 4, text: 'On se rejoint où exactement ?', sent: false, time: '19:30', status: 'read' }
]
},
{
id: 5,
name: 'Emma Petit',
avatar: 'EP',
avatarColor: '--tg-avatar-gradient-5',
lastMessage: '📸 Photo',
time: 'Lun',
unread: 3,
status: 'en ligne',
messages: [
{ id: 1, text: 'Hello ! Regarde cette vue 😍', sent: false, time: '09:00', status: 'read' },
{ id: 2, text: 'Wow, c\'est magnifique !', sent: true, time: '09:05', status: 'read' },
{ id: 3, text: '📸 Photo', sent: false, time: '09:10', status: 'read' }
]
},
{
id: 6,
name: 'Groupe Projet',
avatar: 'GP',
avatarColor: '--tg-avatar-gradient-1',
lastMessage: 'Alex: La réunion est confirmée pour 14h',
time: '09:30',
unread: 5,
status: '5 membres, 3 en ligne',
isGroup: true,
messages: [
{ id: 1, text: 'Marie: Bonjour tout le monde !', sent: false, time: '09:00', status: 'read' },
{ id: 2, text: 'Thomas: Hello ! Des nouvelles pour la réunion ?', sent: false, time: '09:15', status: 'read' },
{ id: 3, text: 'Moi: Oui, je propose 14h', sent: true, time: '09:20', status: 'read' },
{ id: 4, text: 'Alex: La réunion est confirmée pour 14h', sent: false, time: '09:30', status: 'read' }
]
}
];
let currentChatId = null;
// ===== INITIALISATION =====
function init() {
renderChatList();
setupEventListeners();
}
// ===== RENDU DE LA LISTE DES CONVERSATIONS =====
function renderChatList() {
const chatList = document.getElementById('chatList');
chatList.innerHTML = '';
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
const filteredConversations = conversations.filter(conv =>
conv.name.toLowerCase().includes(searchTerm) ||
conv.lastMessage.toLowerCase().includes(searchTerm)
);
filteredConversations.forEach(conv => {
const chatItem = document.createElement('div');
chatItem.className = `chat-item ${currentChatId === conv.id ? 'active' : ''}`;
chatItem.setAttribute('data-id', conv.id);
const avatarStyle = `background: var(${conv.avatarColor})`;
const checkIcon = conv.messages.some(m => m.sent && m.status === 'read') ?
'<i class="bi bi-check-all message-status"></i>' :
'<i class="bi bi-check message-status"></i>';
chatItem.innerHTML = `
<div class="chat-avatar" style="${avatarStyle}">${conv.avatar}</div>
<div class="chat-info">
<div class="chat-header">
<span class="chat-name">${conv.isGroup ? '<i class="bi bi-people-fill"></i> ' : ''}${conv.name}</span>
<span class="chat-time">${conv.time}</span>
</div>
<div class="chat-last-message">
<span class="last-message">${conv.lastMessage}</span>
${conv.messages[conv.messages.length - 1]?.sent ? checkIcon : ''}
${conv.unread > 0 ? `<span class="unread-badge">${conv.unread}</span>` : ''}
</div>
</div>
`;
chatItem.addEventListener('click', () => openChat(conv.id));
chatList.appendChild(chatItem);
});
}
// ===== OUVERTURE D'UNE CONVERSATION =====
function openChat(chatId) {
currentChatId = chatId;
const conversation = conversations.find(c => c.id === chatId);
if (!conversation) return;
// Réinitialiser les messages non lus
conversation.unread = 0;
// Mise à jour de l'UI
document.getElementById('welcomeScreen').style.display = 'none';
document.getElementById('activeChat').style.display = 'flex';
// Mise à jour du header
document.getElementById('contactName').textContent = conversation.name;
document.getElementById('contactStatus').textContent = conversation.status;
document.getElementById('contactAvatar').textContent = conversation.avatar;
document.getElementById('contactAvatar').style.background = `var(${conversation.avatarColor})`;
// Rendu des messages
renderMessages(conversation.messages);
// Mise à jour de la liste (pour l'état actif)
renderChatList();
// Scroll en bas des messages
const messagesContainer = document.getElementById('messagesContainer');
setTimeout(() => {
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}, 100);
// Sur mobile, afficher la zone de chat
if (window.innerWidth <= 768) {
document.getElementById('chatArea').classList.add('active');
}
}
// ===== RENDU DES MESSAGES =====
function renderMessages(messages) {
const container = document.getElementById('messagesContainer');
container.innerHTML = '';
messages.forEach((msg, index) => {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${msg.sent ? 'sent' : 'received'}`;
const statusIcon = msg.sent ?
(msg.status === 'read' ? '<i class="bi bi-check-all"></i>' :
'<i class="bi bi-check"></i>') : '';
// Avatar pour les messages reçus
const avatarHtml = !msg.sent ?
`<div class="message-avatar" style="background: var(--tg-avatar-gradient-2);">${msg.senderInitial || '?'}</div>` : '';
messageDiv.innerHTML = `
<div class="message-bubble-wrapper">
${avatarHtml}
<div>
<div class="message-bubble">
${msg.text}
</div>
<div class="message-meta">
<span>${msg.time}</span>
<span class="message-status">${statusIcon}</span>
</div>
</div>
</div>
`;
container.appendChild(messageDiv);
});
}
// ===== ENVOI D'UN MESSAGE =====
function sendMessage() {
const input = document.getElementById('messageInput');
const text = input.value.trim();
if (!text || !currentChatId) return;
const conversation = conversations.find(c => c.id === currentChatId);
if (!conversation) return;
// Ajouter le message
const newMessage = {
id: Date.now(),
text: text,
sent: true,
time: new Date().toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }),
status: 'sent'
};
conversation.messages.push(newMessage);
conversation.lastMessage = text;
conversation.time = newMessage.time;
// Mise à jour de l'UI
renderMessages(conversation.messages);
renderChatList();
// Vider l'input
input.value = '';
// Scroll en bas
const messagesContainer = document.getElementById('messagesContainer');
setTimeout(() => {
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}, 100);
// Marquer comme lu après un délai
setTimeout(() => {
newMessage.status = 'read';
if (currentChatId === conversation.id) {
renderMessages(conversation.messages);
}
renderChatList();
}, 1500);
// Simuler une réponse après 1-3 secondes
setTimeout(() => {
simulateResponse(conversation);
}, Math.random() * 2000 + 1500);
}
// ===== SIMULATION DE RÉPONSE =====
function simulateResponse(conversation) {
const responses = [
"D'accord, je vois !",
"Super, merci pour l'info ! 👍",
"Tu as raison",
"Je te réponds plus tard",
"Parfait !",
"😂😂😂",
"Ok, à plus tard !",
"Bien reçu !",
"Je suis d'accord avec toi",
"On en parle demain ?"
];
const randomResponse = responses[Math.floor(Math.random() * responses.length)];
const responseMessage = {
id: Date.now(),
text: randomResponse,
sent: false,
time: new Date().toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' }),
status: 'read',
senderInitial: conversation.avatar
};
conversation.messages.push(responseMessage);
conversation.lastMessage = randomResponse;
conversation.time = responseMessage.time;
// Incrémenter les messages non lus si la conversation n'est pas active
if (currentChatId !== conversation.id) {
conversation.unread++;
}
// Mise à jour de l'UI
if (currentChatId === conversation.id) {
renderMessages(conversation.messages);
const messagesContainer = document.getElementById('messagesContainer');
setTimeout(() => {
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}, 100);
}
renderChatList();
}
// ===== RETOUR (mobile) =====
function goBack() {
document.getElementById('chatArea').classList.remove('active');
currentChatId = null;
renderChatList();
}
// ===== CONFIGURATION DES ÉCOUTEURS D'ÉVÉNEMENTS =====
function setupEventListeners() {
// Recherche
document.getElementById('searchInput').addEventListener('input', renderChatList);
// Envoi de message
document.getElementById('sendMessageBtn').addEventListener('click', sendMessage);
// Envoi avec Entrée
document.getElementById('messageInput').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendMessage();
}
});
}
// ===== DÉMARRAGE =====
init();
console.log('✅ Telegram Web Clone - Bootstrap 5 - Prêt !');
</script>
</body>
</html>
Ouvrir cet aperçu dans un nouvel onglet du navigateur
🔗 Ouvrir dans le navigateur