commit bb78b6d1a8c30e66a59c344786b4e5faba7c64ea
Author: root <root@hub.scroll.pub>
Date: 2025-01-16 06:34:27 +0000
Subject: Initial commit
diff --git a/index.scroll b/index.scroll
new file mode 100644
index 0000000..f1ef957
--- /dev/null
+++ b/index.scroll
@@ -0,0 +1,58 @@
+buildHtml
+baseUrl https://chatter.scroll.pub
+metaTags
+editButton /edit.html
+title Chatter - Modern WebSocket Chat
+style.css
+header
+ class header-main
+ div
+ class logo
+ h1 Chatter
+ nav
+ class nav-links
+ a Online
+ href #online-users
+ a Rooms
+ href #chat-rooms
+ a Settings
+ href #settings
+main
+ class chat-container
+ aside
+ class user-list
+ h2 Online Users
+ ul
+ id online-users
+ section
+ class chat-main
+ div
+ class messages
+ id message-container
+ form
+ class message-form
+ id chat-form
+ input
+ type text
+ id message-input
+ placeholder Type your message...
+ required
+ button Send
+ type submit
+ class send-button
+aside
+ class room-list
+ h2 Chat Rooms
+ ul
+ id chat-rooms
+footer
+ class footer-main
+ p Built with WebSocket
+ nav
+ a Terms
+ href /terms
+ a Privacy
+ href /privacy
+ a Support
+ href /support
+script.js
diff --git a/prompt.json b/prompt.json
new file mode 100644
index 0000000..888fa9c
--- /dev/null
+++ b/prompt.json
@@ -0,0 +1,20 @@
+{
+ "id": "msg_01DEwNNkHq68E62sJ68WpCQW",
+ "type": "message",
+ "role": "assistant",
+ "model": "claude-3-5-sonnet-20241022",
+ "content": [
+ {
+ "type": "text",
+ "text": "I'll create a modern WebSocket-based chat website. For the domain, I suggest:\n\n---domain---\nchatter.scroll.pub\n\n---index.scroll---\nbuildHtml\nbaseUrl https://chatter.scroll.pub\nmetaTags\neditButton /edit.html\ntitle Chatter - Modern WebSocket Chat\nstyle.css\nheader\n class header-main\n div\n class logo\n h1 Chatter\n nav\n class nav-links\n a Online\n href #online-users\n a Rooms\n href #chat-rooms\n a Settings\n href #settings\nmain\n class chat-container\n aside\n class user-list\n h2 Online Users\n ul\n id online-users\n section\n class chat-main\n div\n class messages\n id message-container\n form\n class message-form\n id chat-form\n input\n type text\n id message-input\n placeholder Type your message...\n required\n button Send\n type submit\n class send-button\naside\n class room-list\n h2 Chat Rooms\n ul\n id chat-rooms\nfooter\n class footer-main\n p Built with WebSocket\n nav\n a Terms\n href /terms\n a Privacy\n href /privacy\n a Support\n href /support\nscript.js\n\n---style.css---\n:root {\n --primary-color: #2d3436;\n --secondary-color: #00b894;\n --bg-color: #f5f6fa;\n --text-color: #2d3436;\n --border-radius: 12px;\n --transition: all 0.3s ease;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n line-height: 1.6;\n color: var(--text-color);\n background: var(--bg-color);\n}\n\n.header-main {\n background: var(--primary-color);\n color: white;\n padding: 1rem 2rem;\n display: flex;\n justify-content: space-between;\n align-items: center;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n.nav-links a {\n color: white;\n text-decoration: none;\n margin-left: 2rem;\n transition: var(--transition);\n}\n\n.nav-links a:hover {\n color: var(--secondary-color);\n}\n\n.chat-container {\n display: grid;\n grid-template-columns: 250px 1fr 250px;\n height: calc(100vh - 140px);\n gap: 1rem;\n padding: 1rem;\n}\n\n.user-list, .room-list {\n background: white;\n border-radius: var(--border-radius);\n padding: 1rem;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n.chat-main {\n display: flex;\n flex-direction: column;\n background: white;\n border-radius: var(--border-radius);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n.messages {\n flex-grow: 1;\n padding: 1rem;\n overflow-y: auto;\n}\n\n.message-form {\n display: flex;\n padding: 1rem;\n gap: 1rem;\n border-top: 1px solid #eee;\n}\n\n#message-input {\n flex-grow: 1;\n padding: 0.8rem;\n border: 2px solid #eee;\n border-radius: var(--border-radius);\n transition: var(--transition);\n}\n\n#message-input:focus {\n outline: none;\n border-color: var(--secondary-color);\n}\n\n.send-button {\n background: var(--secondary-color);\n color: white;\n border: none;\n padding: 0.8rem 1.5rem;\n border-radius: var(--border-radius);\n cursor: pointer;\n transition: var(--transition);\n}\n\n.send-button:hover {\n transform: translateY(-2px);\n box-shadow: 0 2px 8px rgba(0,184,148,0.4);\n}\n\n.footer-main {\n background: var(--primary-color);\n color: white;\n padding: 1rem 2rem;\n text-align: center;\n}\n\n.footer-main nav {\n margin-top: 0.5rem;\n}\n\n.footer-main a {\n color: white;\n text-decoration: none;\n margin: 0 1rem;\n transition: var(--transition);\n}\n\n.footer-main a:hover {\n color: var(--secondary-color);\n}\n\n@media (max-width: 768px) {\n .chat-container {\n grid-template-columns: 1fr;\n }\n \n .user-list, .room-list {\n display: none;\n }\n}\n\n---script.js---\ndocument.addEventListener('DOMContentLoaded', () => {\n const messageContainer = document.getElementById('message-container');\n const messageForm = document.getElementById('chat-form');\n const messageInput = document.getElementById('message-input');\n const onlineUsers = document.getElementById('online-users');\n const chatRooms = document.getElementById('chat-rooms');\n\n let ws;\n \n function connectWebSocket() {\n ws = new WebSocket(`wss://${window.location.host}/ws`);\n \n ws.onopen = () => {\n console.log('Connected to WebSocket server');\n addSystemMessage('Connected to chat server');\n };\n \n ws.onmessage = (event) => {\n const message = JSON.parse(event.data);\n displayMessage(message);\n };\n \n ws.onclose = () => {\n console.log('Disconnected from WebSocket server');\n addSystemMessage('Disconnected from chat server. Reconnecting...');\n setTimeout(connectWebSocket, 3000);\n };\n \n ws.onerror = (error) => {\n console.error('WebSocket error:', error);\n addSystemMessage('Error connecting to chat server');\n };\n }\n\n function displayMessage(message) {\n const messageElement = document.createElement('div');\n messageElement.classList.add('message');\n \n const timestamp = new Date().toLocaleTimeString();\n messageElement.innerHTML = `\n <span class=\"timestamp\">${timestamp}</span>\n <span class=\"username\">${message.username}</span>\n <span class=\"content\">${escapeHtml(message.content)}</span>\n `;\n \n messageContainer.appendChild(messageElement);\n messageContainer.scrollTop = messageContainer.scrollHeight;\n }\n\n function addSystemMessage(text) {\n const messageElement = document.createElement('div');\n messageElement.classList.add('system-message');\n messageElement.textContent = text;\n messageContainer.appendChild(messageElement);\n messageContainer.scrollTop = messageContainer.scrollHeight;\n }\n\n function escapeHtml(unsafe) {\n return unsafe\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n }\n\n messageForm.addEventListener('submit', (e) => {\n e.preventDefault();\n \n const message = messageInput.value.trim();\n if (message && ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify({\n type: 'message',\n content: message\n }));\n messageInput.value = '';\n }\n });\n\n // Initialize demo chat rooms\n const demoRooms = ['General', 'Tech', 'Random'];\n demoRooms.forEach(room => {\n const li = document.createElement('li');\n li.textContent = room;\n chatRooms.appendChild(li);\n });\n\n // Initialize demo online users\n const demoUsers = ['Alice', 'Bob', 'Charlie'];\n demoUsers.forEach(user => {\n const li = document.createElement('li');\n li.textContent = user;\n onlineUsers.appendChild(li);\n });\n\n // Start WebSocket connection\n connectWebSocket();\n});\n\n---end---\n\nThis creates a modern, responsive chat website with WebSocket functionality. The design features a clean three-column layout with online users list, main chat area, and chat rooms list. The color scheme is professional and the UI includes smooth transitions and hover effects.\n\nKey features:\n- Real-time WebSocket communication\n- Responsive design that adapts to mobile devices\n- Clean, accessible semantic HTML\n- Modern CSS with CSS Grid and Flexbox\n- Auto-reconnect functionality\n- Message escape/sanitization\n- System messages for connection status\n- Demo users and rooms for immediate visual feedback\n\nThe CSS includes modern features like CSS variables, smooth transitions, and subtle shadows for depth. The JavaScript handles all WebSocket communication, message display, and form submission with proper error handling and reconnection logic."
+ }
+ ],
+ "stop_reason": "end_turn",
+ "stop_sequence": null,
+ "usage": {
+ "input_tokens": 834,
+ "cache_creation_input_tokens": 0,
+ "cache_read_input_tokens": 0,
+ "output_tokens": 2362
+ }
+}
\ No newline at end of file
diff --git a/readme.scroll b/readme.scroll
new file mode 100644
index 0000000..78a4845
--- /dev/null
+++ b/readme.scroll
@@ -0,0 +1,3 @@
+# chatter.scroll.pub
+
+website generated by Claude from prompt: 一个现代化的在线聊天网站,使用websocket
\ No newline at end of file
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..89ca363
--- /dev/null
+++ b/script.js
@@ -0,0 +1,98 @@
+document.addEventListener('DOMContentLoaded', () => {
+ const messageContainer = document.getElementById('message-container');
+ const messageForm = document.getElementById('chat-form');
+ const messageInput = document.getElementById('message-input');
+ const onlineUsers = document.getElementById('online-users');
+ const chatRooms = document.getElementById('chat-rooms');
+
+ let ws;
+
+ function connectWebSocket() {
+ ws = new WebSocket(`wss://${window.location.host}/ws`);
+
+ ws.onopen = () => {
+ console.log('Connected to WebSocket server');
+ addSystemMessage('Connected to chat server');
+ };
+
+ ws.onmessage = (event) => {
+ const message = JSON.parse(event.data);
+ displayMessage(message);
+ };
+
+ ws.onclose = () => {
+ console.log('Disconnected from WebSocket server');
+ addSystemMessage('Disconnected from chat server. Reconnecting...');
+ setTimeout(connectWebSocket, 3000);
+ };
+
+ ws.onerror = (error) => {
+ console.error('WebSocket error:', error);
+ addSystemMessage('Error connecting to chat server');
+ };
+ }
+
+ function displayMessage(message) {
+ const messageElement = document.createElement('div');
+ messageElement.classList.add('message');
+
+ const timestamp = new Date().toLocaleTimeString();
+ messageElement.innerHTML = `
+ <span class="timestamp">${timestamp}</span>
+ <span class="username">${message.username}</span>
+ <span class="content">${escapeHtml(message.content)}</span>
+ `;
+
+ messageContainer.appendChild(messageElement);
+ messageContainer.scrollTop = messageContainer.scrollHeight;
+ }
+
+ function addSystemMessage(text) {
+ const messageElement = document.createElement('div');
+ messageElement.classList.add('system-message');
+ messageElement.textContent = text;
+ messageContainer.appendChild(messageElement);
+ messageContainer.scrollTop = messageContainer.scrollHeight;
+ }
+
+ function escapeHtml(unsafe) {
+ return unsafe
+ .replace(/&/g, "&")
+ .replace(/</g, "<")
+ .replace(/>/g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+ }
+
+ messageForm.addEventListener('submit', (e) => {
+ e.preventDefault();
+
+ const message = messageInput.value.trim();
+ if (message && ws.readyState === WebSocket.OPEN) {
+ ws.send(JSON.stringify({
+ type: 'message',
+ content: message
+ }));
+ messageInput.value = '';
+ }
+ });
+
+ // Initialize demo chat rooms
+ const demoRooms = ['General', 'Tech', 'Random'];
+ demoRooms.forEach(room => {
+ const li = document.createElement('li');
+ li.textContent = room;
+ chatRooms.appendChild(li);
+ });
+
+ // Initialize demo online users
+ const demoUsers = ['Alice', 'Bob', 'Charlie'];
+ demoUsers.forEach(user => {
+ const li = document.createElement('li');
+ li.textContent = user;
+ onlineUsers.appendChild(li);
+ });
+
+ // Start WebSocket connection
+ connectWebSocket();
+});
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..c8b0897
--- /dev/null
+++ b/style.css
@@ -0,0 +1,138 @@
+:root {
+ --primary-color: #2d3436;
+ --secondary-color: #00b894;
+ --bg-color: #f5f6fa;
+ --text-color: #2d3436;
+ --border-radius: 12px;
+ --transition: all 0.3s ease;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
+ line-height: 1.6;
+ color: var(--text-color);
+ background: var(--bg-color);
+}
+
+.header-main {
+ background: var(--primary-color);
+ color: white;
+ padding: 1rem 2rem;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+}
+
+.nav-links a {
+ color: white;
+ text-decoration: none;
+ margin-left: 2rem;
+ transition: var(--transition);
+}
+
+.nav-links a:hover {
+ color: var(--secondary-color);
+}
+
+.chat-container {
+ display: grid;
+ grid-template-columns: 250px 1fr 250px;
+ height: calc(100vh - 140px);
+ gap: 1rem;
+ padding: 1rem;
+}
+
+.user-list, .room-list {
+ background: white;
+ border-radius: var(--border-radius);
+ padding: 1rem;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+}
+
+.chat-main {
+ display: flex;
+ flex-direction: column;
+ background: white;
+ border-radius: var(--border-radius);
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+}
+
+.messages {
+ flex-grow: 1;
+ padding: 1rem;
+ overflow-y: auto;
+}
+
+.message-form {
+ display: flex;
+ padding: 1rem;
+ gap: 1rem;
+ border-top: 1px solid #eee;
+}
+
+#message-input {
+ flex-grow: 1;
+ padding: 0.8rem;
+ border: 2px solid #eee;
+ border-radius: var(--border-radius);
+ transition: var(--transition);
+}
+
+#message-input:focus {
+ outline: none;
+ border-color: var(--secondary-color);
+}
+
+.send-button {
+ background: var(--secondary-color);
+ color: white;
+ border: none;
+ padding: 0.8rem 1.5rem;
+ border-radius: var(--border-radius);
+ cursor: pointer;
+ transition: var(--transition);
+}
+
+.send-button:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 2px 8px rgba(0,184,148,0.4);
+}
+
+.footer-main {
+ background: var(--primary-color);
+ color: white;
+ padding: 1rem 2rem;
+ text-align: center;
+}
+
+.footer-main nav {
+ margin-top: 0.5rem;
+}
+
+.footer-main a {
+ color: white;
+ text-decoration: none;
+ margin: 0 1rem;
+ transition: var(--transition);
+}
+
+.footer-main a:hover {
+ color: var(--secondary-color);
+}
+
+@media (max-width: 768px) {
+ .chat-container {
+ grid-template-columns: 1fr;
+ }
+
+ .user-list, .room-list {
+ display: none;
+ }
+}