temp / index.html
commit3r's picture
create a minimal site that uses webrtc (so serverless) to stream live raw text messages, it only works for clients who are online and connected to the site, make it a cool design, no dramatic font and scientific but retro inspirted from mac os 7 - Initial Deployment
2caf0dc verified
raw
history blame
13.1 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RetroText Stream</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/peerjs@1.4.7/dist/peerjs.min.js"></script>
<style>
@font-face {
font-family: 'Chicago';
src: url('https://cdn.jsdelivr.net/gh/eliheuer/chicago@master/chicago.woff2') format('woff2');
}
body {
background: #C0C7C8 url("data:image/svg+xml,%3Csvg width='6' height='6' viewBox='0 0 6 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='%23a0a7a8' fill-opacity='0.2' fill-rule='evenodd'%3E%3Cpath d='M5 5h1v1H5V5zM0 0h1v1H0V0zm3 3h1v1H3V3z'/%3E%3C/g%3E%3C/svg%3E");
font-family: 'Chicago', 'SF Mono', monospace;
color: #000;
}
.mac-window {
border: 2px solid;
border-top-color: #fff;
border-left-color: #fff;
border-right-color: #808080;
border-bottom-color: #808080;
box-shadow: 2px 2px 0 #000;
}
.title-bar {
background: linear-gradient(to right, #000080, #1084d0);
color: white;
letter-spacing: 0.5px;
}
.btn {
border: 2px solid;
border-top-color: #fff;
border-left-color: #fff;
border-right-color: #808080;
border-bottom-color: #808080;
background: #c0c0c0;
box-shadow: inset -1px -1px 0 #000;
}
.btn:active {
border-top-color: #808080;
border-left-color: #808080;
border-right-color: #fff;
border-bottom-color: #fff;
box-shadow: inset 1px 1px 0 #000;
}
.message-box {
background: #fff;
border: 2px solid;
border-top-color: #808080;
border-left-color: #808080;
border-right-color: #fff;
border-bottom-color: #fff;
}
.status-bar {
background: #c0c0c0;
border-top: 2px solid #808080;
}
.scrollbar::-webkit-scrollbar {
width: 12px;
}
.scrollbar::-webkit-scrollbar-track {
background: #c0c0c0;
border-left: 2px solid #808080;
}
.scrollbar::-webkit-scrollbar-thumb {
background: #808080;
border: 2px solid #c0c0c0;
border-top-color: #fff;
border-left-color: #fff;
border-right-color: #000;
border-bottom-color: #000;
}
.terminal-text {
font-family: 'Chicago', monospace;
font-size: 14px;
line-height: 1.4;
color: #000;
}
.blink {
animation: blink 1s infinite;
}
@keyframes blink {
50% { opacity: 0; }
}
.peer-id {
background: #fff;
border: 1px solid #808080;
padding: 2px 4px;
font-size: 12px;
letter-spacing: 0.5px;
}
.input-field {
background: #fff;
border: 2px solid;
border-top-color: #000;
border-left-color: #000;
border-right-color: #fff;
border-bottom-color: #fff;
font-family: 'Chicago', monospace;
}
.input-field:focus {
outline: none;
border: 2px solid #000080;
}
</style>
</head>
<body class="min-h-screen flex items-center justify-center p-4">
<div class="mac-window w-full max-w-2xl">
<!-- Title Bar -->
<div class="title-bar flex items-center justify-between px-3 py-1">
<div class="flex items-center">
<div class="w-3 h-3 rounded-full bg-[#ff6057] mr-2"></div>
<div class="w-3 h-3 rounded-full bg-[#ffbd2e] mr-2"></div>
<div class="w-3 h-3 rounded-full bg-[#28c940] mr-2"></div>
<h1 class="text-sm font-bold">RetroText Stream</h1>
</div>
<div class="text-xs">WebRTC Text Broadcast</div>
</div>
<!-- Main Content -->
<div class="bg-[#c0c0c0] p-4">
<!-- Connection Info -->
<div class="mb-4 flex items-center justify-between">
<div class="flex items-center">
<span class="mr-2">Status:</span>
<div id="status" class="bg-[#28c940] px-2 py-1 text-xs font-bold">CONNECTING...</div>
</div>
<div class="flex items-center">
<span class="mr-2">Peer ID:</span>
<div id="peer-id" class="peer-id">Generating...</div>
</div>
</div>
<!-- Message Display -->
<div class="message-box mb-4 h-64 overflow-hidden">
<div id="message-container" class="terminal-text p-3 h-full overflow-y-auto scrollbar">
<div>> Initializing WebRTC connection...</div>
<div>> Using public STUN servers</div>
<div>> Establishing peer connection...</div>
<div id="connection-status" class="blink">> Waiting for peers</div>
</div>
</div>
<!-- Input Area -->
<div class="flex">
<input
type="text"
id="message-input"
class="input-field flex-grow px-3 py-2 mr-2"
placeholder="Type message here..."
disabled
>
<button id="send-btn" class="btn px-4 py-2 font-bold" disabled>Send</button>
</div>
</div>
<!-- Status Bar -->
<div class="status-bar px-3 py-1 flex justify-between text-xs">
<div>Connected Peers: <span id="peer-count">0</span></div>
<div>RetroText Stream v1.0</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// DOM Elements
const messageContainer = document.getElementById('message-container');
const messageInput = document.getElementById('message-input');
const sendBtn = document.getElementById('send-btn');
const statusIndicator = document.getElementById('status');
const peerIdDisplay = document.getElementById('peer-id');
const connectionStatus = document.getElementById('connection-status');
const peerCountDisplay = document.getElementById('peer-count');
// State
let peer = null;
let connections = [];
let peerId = null;
// Initialize PeerJS
function initializePeer() {
// Generate a random peer ID
peerId = 'retro-' + Math.random().toString(36).substr(2, 8).toUpperCase();
peerIdDisplay.textContent = peerId;
// Create peer
peer = new Peer(peerId, {
host: '0.peerjs.com',
port: 443,
secure: true,
config: {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'stun:stun1.l.google.com:19302' }
]
}
});
// Peer event handlers
peer.on('open', (id) => {
statusIndicator.textContent = 'CONNECTED';
statusIndicator.className = 'bg-[#28c940] px-2 py-1 text-xs font-bold';
connectionStatus.innerHTML = `> Ready to connect! Share ID: <span class="font-bold">${id}</span>`;
messageInput.disabled = false;
sendBtn.disabled = false;
});
peer.on('connection', (conn) => {
setupConnection(conn);
updatePeerCount();
});
peer.on('error', (err) => {
console.error('Peer error:', err);
appendMessage(`> ERROR: ${err.type} - ${err.message}`);
statusIndicator.textContent = 'ERROR';
statusIndicator.className = 'bg-[#ff6057] px-2 py-1 text-xs font-bold';
});
peer.on('disconnected', () => {
statusIndicator.textContent = 'DISCONNECTED';
statusIndicator.className = 'bg-[#ffbd2e] px-2 py-1 text-xs font-bold';
appendMessage('> Disconnected from signaling server');
});
}
// Set up a connection
function setupConnection(conn) {
connections.push(conn);
updatePeerCount();
conn.on('open', () => {
appendMessage(`> Connected to peer: ${conn.peer.substr(0, 8)}`);
});
conn.on('data', (data) => {
appendMessage(`${conn.peer.substr(0, 8)}> ${data}`);
});
conn.on('close', () => {
connections = connections.filter(c => c.peer !== conn.peer);
appendMessage(`> Disconnected from peer: ${conn.peer.substr(0, 8)}`);
updatePeerCount();
});
conn.on('error', (err) => {
console.error('Connection error:', err);
appendMessage(`> ERROR with peer ${conn.peer.substr(0, 8)}: ${err.message}`);
});
}
// Connect to another peer
function connectToPeer(peerId) {
if (!peer) return;
const conn = peer.connect(peerId);
setupConnection(conn);
}
// Send message to all connected peers
function broadcastMessage(message) {
if (message.trim() === '') return;
connections.forEach(conn => {
if (conn.open) {
conn.send(message);
}
});
appendMessage(`YOU> ${message}`);
messageInput.value = '';
}
// Append message to display
function appendMessage(message) {
const messageElement = document.createElement('div');
messageElement.textContent = message;
messageContainer.appendChild(messageElement);
messageContainer.scrollTop = messageContainer.scrollHeight;
}
// Update peer count display
function updatePeerCount() {
peerCountDisplay.textContent = connections.length;
}
// Event listeners
sendBtn.addEventListener('click', () => {
broadcastMessage(messageInput.value);
});
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
broadcastMessage(messageInput.value);
}
});
// Initialize
initializePeer();
// Handle URL parameters for connecting to a peer
const urlParams = new URLSearchParams(window.location.search);
const connectTo = urlParams.get('connect');
if (connectTo) {
setTimeout(() => {
connectToPeer(connectTo);
appendMessage(`> Attempting connection to ${connectTo.substr(0, 8)}...`);
}, 2000);
}
});
</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=commit3r/temp" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>