abdoul / index.html
Comh58's picture
Add 3 files
c3d8f79 verified
Raw
History Blame Contribute Delete
18.2 kB
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Talkie-Walkie Offline</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.recording-animation {
animation: pulse 1s infinite;
}
#visualizer {
height: 80px;
background: linear-gradient(to right, #3b82f6, #8b5cf6);
border-radius: 10px;
overflow: hidden;
}
.bar {
background-color: white;
width: 4px;
height: 20px;
margin: 0 2px;
display: inline-block;
border-radius: 2px;
}
</style>
</head>
<body class="bg-gray-900 text-white min-h-screen">
<div class="container mx-auto px-4 py-6">
<!-- En-tête -->
<header class="flex flex-col items-center mb-8">
<div class="flex items-center justify-center mb-2">
<i class="fas fa-walkie-talkie text-4xl text-blue-500 mr-3"></i>
<h1 class="text-3xl md:text-4xl font-bold text-center bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-purple-500">
Talkie-Walkie Offline
</h1>
</div>
<p class="text-lg text-gray-400">Communication sans Internet via Wi-Fi/Bluetooth</p>
</header>
<!-- Contenu principal -->
<main class="flex flex-col items-center">
<!-- État de la connexion -->
<div class="w-full max-w-md bg-gray-800 rounded-xl p-4 mb-6 shadow-lg border border-gray-700">
<div class="flex justify-between items-center">
<div>
<h2 class="text-lg font-semibold">État de la connexion</h2>
<p id="connectionStatus" class="text-sm text-gray-400">Non connecté</p>
</div>
<div id="connectionType" class="flex items-center">
<i class="fas fa-wifi text-gray-500 mr-2"></i>
<span class="text-sm">Wi-Fi</span>
</div>
</div>
<div class="mt-4 flex flex-col space-y-3">
<button id="discoverBtn" class="w-full py-2 bg-blue-600 hover:bg-blue-700 rounded-lg font-medium flex items-center justify-center gap-2">
<i class="fas fa-search"></i> Découvrir des appareils
</button>
<button id="hostBtn" class="w-full py-2 bg-purple-600 hover:bg-purple-700 rounded-lg font-medium flex items-center justify-center gap-2">
<i class="fas fa-broadcast-tower"></i> Héberger un réseau
</button>
</div>
</div>
<!-- Liste des appareils disponibles -->
<div id="devicesContainer" class="w-full max-w-md bg-gray-800 rounded-xl p-4 mb-6 shadow-lg border border-gray-700 hidden">
<h2 class="text-lg font-semibold mb-3 flex items-center gap-2">
<i class="fas fa-list"></i> Appareils disponibles
</h2>
<div id="devicesList" class="space-y-2">
<!-- Les appareils seront ajoutés dynamiquement ici -->
</div>
</div>
<!-- Contrôles audio -->
<div class="w-full max-w-md bg-gray-800 rounded-xl p-4 shadow-lg border border-gray-700">
<h2 class="text-lg font-semibold mb-4 flex items-center gap-2">
<i class="fas fa-microphone"></i> Contrôles
</h2>
<!-- Visualiseur audio -->
<div id="visualizer" class="mb-4 flex items-end justify-center">
<!-- Les barres du visualiseur seront ajoutées dynamiquement -->
</div>
<!-- Boutons de contrôle -->
<div class="flex justify-center space-x-4">
<button id="talkBtn" class="w-16 h-16 rounded-full bg-red-600 hover:bg-red-700 flex items-center justify-center shadow-lg transform hover:scale-105 transition-transform disabled:opacity-50" disabled>
<i class="fas fa-microphone text-2xl"></i>
</button>
<button id="settingsBtn" class="w-16 h-16 rounded-full bg-gray-700 hover:bg-gray-600 flex items-center justify-center shadow-lg transform hover:scale-105 transition-transform">
<i class="fas fa-cog text-2xl"></i>
</button>
</div>
<!-- Indicateur d'état -->
<div id="statusIndicator" class="mt-4 text-center text-sm text-gray-400">
Appuyez et maintenez pour parler
</div>
</div>
</main>
<!-- Paramètres (modal) -->
<div id="settingsModal" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center p-4 z-50 hidden">
<div class="bg-gray-800 rounded-xl p-6 w-full max-w-md shadow-2xl border border-gray-700">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-semibold">Paramètres</h3>
<button id="closeSettingsBtn" class="text-gray-400 hover:text-white">
<i class="fas fa-times text-2xl"></i>
</button>
</div>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium mb-1">Mode de connexion</label>
<select id="connectionMode" class="w-full bg-gray-700 border border-gray-600 rounded-lg p-2">
<option value="wifi">Wi-Fi Direct</option>
<option value="bluetooth">Bluetooth</option>
</select>
</div>
<div>
<label class="block text-sm font-medium mb-1">Qualité audio</label>
<select id="audioQuality" class="w-full bg-gray-700 border border-gray-600 rounded-lg p-2">
<option value="low">Faible (8kHz)</option>
<option value="medium" selected>Moyenne (16kHz)</option>
<option value="high">Haute (44.1kHz)</option>
</select>
</div>
<div>
<label class="block text-sm font-medium mb-1">Portée estimée</label>
<div class="flex items-center gap-2">
<i class="fas fa-signal text-blue-500"></i>
<span id="rangeEstimate" class="font-medium">~100 mètres (Wi-Fi)</span>
</div>
</div>
<div class="pt-2">
<button id="saveSettingsBtn" class="w-full py-2 bg-blue-600 hover:bg-blue-700 rounded-lg font-medium">
Enregistrer les paramètres
</button>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Éléments DOM
const discoverBtn = document.getElementById('discoverBtn');
const hostBtn = document.getElementById('hostBtn');
const talkBtn = document.getElementById('talkBtn');
const settingsBtn = document.getElementById('settingsBtn');
const closeSettingsBtn = document.getElementById('closeSettingsBtn');
const saveSettingsBtn = document.getElementById('saveSettingsBtn');
const settingsModal = document.getElementById('settingsModal');
const connectionStatus = document.getElementById('connectionStatus');
const connectionType = document.getElementById('connectionType');
const devicesContainer = document.getElementById('devicesContainer');
const devicesList = document.getElementById('devicesList');
const statusIndicator = document.getElementById('statusIndicator');
const visualizer = document.getElementById('visualizer');
const connectionMode = document.getElementById('connectionMode');
const audioQuality = document.getElementById('audioQuality');
const rangeEstimate = document.getElementById('rangeEstimate');
// Variables d'état
let isRecording = false;
let isConnected = false;
let currentConnectionMode = 'wifi';
// Créer le visualiseur audio
function createAudioVisualizer() {
visualizer.innerHTML = '';
for (let i = 0; i < 30; i++) {
const bar = document.createElement('div');
bar.className = 'bar';
bar.style.height = `${Math.random() * 60 + 20}px`;
visualizer.appendChild(bar);
}
}
// Mettre à jour le visualiseur
function updateVisualizer() {
if (!isRecording) return;
const bars = visualizer.querySelectorAll('.bar');
bars.forEach(bar => {
bar.style.height = `${Math.random() * 60 + 20}px`;
});
requestAnimationFrame(updateVisualizer);
}
// Simuler la découverte d'appareils
function discoverDevices() {
devicesList.innerHTML = '';
connectionStatus.textContent = 'Recherche en cours...';
// Simuler un délai de recherche
setTimeout(() => {
const deviceNames = [
'Talkie-1 (Proche)',
'Talkie-2',
'Talkie-3',
'Talkie-4 (Faible signal)'
];
deviceNames.forEach((name, index) => {
const device = document.createElement('div');
device.className = 'flex justify-between items-center p-3 bg-gray-700 rounded-lg hover:bg-gray-600 cursor-pointer';
device.innerHTML = `
<div class="flex items-center gap-3">
<i class="fas fa-mobile-alt text-blue-400"></i>
<span>${name}</span>
</div>
<div class="flex items-center gap-1">
<i class="fas fa-signal ${index === 3 ? 'text-yellow-500' : 'text-green-500'}"></i>
<span class="text-xs">${index === 0 ? 'Fort' : index === 3 ? 'Faible' : 'Moyen'}</span>
</div>
`;
device.addEventListener('click', () => connectToDevice(name));
devicesList.appendChild(device);
});
devicesContainer.classList.remove('hidden');
connectionStatus.textContent = 'Appareils trouvés';
}, 2000);
}
// Simuler la connexion à un appareil
function connectToDevice(deviceName) {
connectionStatus.textContent = `Connexion à ${deviceName}...`;
statusIndicator.textContent = `Connexion à ${deviceName}...`;
setTimeout(() => {
isConnected = true;
connectionStatus.textContent = `Connecté à ${deviceName}`;
statusIndicator.textContent = 'Prêt à communiquer';
talkBtn.disabled = false;
devicesContainer.classList.add('hidden');
// Mettre à jour l'interface pour la connexion
const wifiIcon = connectionType.querySelector('i');
wifiIcon.className = currentConnectionMode === 'wifi' ? 'fas fa-wifi text-green-500 mr-2' : 'fas fa-bluetooth-b text-green-500 mr-2';
connectionType.querySelector('span').textContent = currentConnectionMode === 'wifi' ? 'Wi-Fi Direct' : 'Bluetooth';
}, 1500);
}
// Simuler l'hébergement d'un réseau
function hostNetwork() {
connectionStatus.textContent = 'Création du réseau...';
setTimeout(() => {
connectionStatus.textContent = 'Réseau hébergé - En attente de connexion';
statusIndicator.textContent = 'En attente de connexion...';
// Simuler une connexion après un délai
setTimeout(() => {
isConnected = true;
connectionStatus.textContent = 'Connecté à Talkie-5';
statusIndicator.textContent = 'Prêt à communiquer';
talkBtn.disabled = false;
const wifiIcon = connectionType.querySelector('i');
wifiIcon.className = currentConnectionMode === 'wifi' ? 'fas fa-wifi text-green-500 mr-2' : 'fas fa-bluetooth-b text-green-500 mr-2';
connectionType.querySelector('span').textContent = currentConnectionMode === 'wifi' ? 'Wi-Fi Direct' : 'Bluetooth';
}, 3000);
}, 2000);
}
// Gérer l'enregistrement audio
function toggleRecording() {
if (!isRecording) {
// Commencer l'enregistrement
isRecording = true;
talkBtn.classList.add('recording-animation');
statusIndicator.textContent = 'Enregistrement en cours...';
createAudioVisualizer();
updateVisualizer();
} else {
// Arrêter l'enregistrement
isRecording = false;
talkBtn.classList.remove('recording-animation');
statusIndicator.textContent = 'Message envoyé';
setTimeout(() => {
statusIndicator.textContent = 'Prêt à communiquer';
}, 2000);
}
}
// Gérer les paramètres
function showSettings() {
settingsModal.classList.remove('hidden');
}
function hideSettings() {
settingsModal.classList.add('hidden');
}
function saveSettings() {
currentConnectionMode = connectionMode.value;
// Mettre à jour l'estimation de portée
if (currentConnectionMode === 'wifi') {
rangeEstimate.textContent = '~100 mètres (Wi-Fi)';
} else {
rangeEstimate.textContent = '~10 mètres (Bluetooth)';
}
hideSettings();
}
// Événements
discoverBtn.addEventListener('click', discoverDevices);
hostBtn.addEventListener('click', hostNetwork);
talkBtn.addEventListener('mousedown', toggleRecording);
talkBtn.addEventListener('mouseup', toggleRecording);
talkBtn.addEventListener('mouseleave', function() {
if (isRecording) toggleRecording();
});
settingsBtn.addEventListener('click', showSettings);
closeSettingsBtn.addEventListener('click', hideSettings);
saveSettingsBtn.addEventListener('click', saveSettings);
// Empêcher le menu contextuel sur le bouton talk
talkBtn.addEventListener('contextmenu', (e) => e.preventDefault());
// Initialiser le visualiseur
createAudioVisualizer();
// Mettre à jour l'interface en fonction du mode de connexion
connectionMode.addEventListener('change', function() {
const icon = connectionType.querySelector('i');
if (this.value === 'wifi') {
icon.className = 'fas fa-wifi text-gray-500 mr-2';
connectionType.querySelector('span').textContent = 'Wi-Fi';
} else {
icon.className = 'fas fa-bluetooth-b text-gray-500 mr-2';
connectionType.querySelector('span').textContent = 'Bluetooth';
}
});
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Comh58/abdoul" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>