commit 0816b46f613ffce839395dd513180a32ef92db15
Author: root <root@hub.scroll.pub> Date: 2025-01-08 14:10:57 +0000 Subject: Initial commit diff --git a/body.html b/body.html new file mode 100644 index 0000000..e4ef778 --- /dev/null +++ b/body.html @@ -0,0 +1,33 @@ +<div class="theme-toggle"> + <button id="themeToggle" aria-label="Toggle theme"> + <i class="mode-icon"></i> + </button> +</div> + +<div class="particles-container" id="particles"></div> + +<main class="chat-container"> + <div class="login-screen" id="loginScreen"> + <h1>AnonWave Chat</h1> + <div class="username-input"> + <input type="text" id="usernameInput" placeholder="Choose your username" maxlength="20"> + <button id="joinChat">Join Chat</button> + </div> + </div> + + <div class="chat-screen hidden" id="chatScreen"> + <div class="chat-header"> + <h2>Live Chat</h2> + <span class="user-badge" id="userBadge"></span> + </div> + + <div class="messages" id="messageContainer"></div> + + <div class="chat-input"> + <input type="text" id="messageInput" placeholder="Type your message..."> + <button id="sendMessage" aria-label="Send message"> + <i class="send-icon"></i> + </button> + </div> + </div> +</main> diff --git a/index.scroll b/index.scroll new file mode 100644 index 0000000..704842d --- /dev/null +++ b/index.scroll @@ -0,0 +1,8 @@ +buildHtml +baseUrl https://anonwave.scroll.pub +metaTags +editButton /edit.html +title AnonWave Chat +style.css +body.html +script.js diff --git a/prompt.json b/prompt.json new file mode 100644 index 0000000..da01e82 --- /dev/null +++ b/prompt.json @@ -0,0 +1,20 @@ +{ + "id": "msg_01P8gQEVS3ehBadMeLLhcE4q", + "type": "message", + "role": "assistant", + "model": "claude-3-5-sonnet-20241022", + "content": [ + { + "type": "text", + "text": "I'll help create a modern anonymous chat interface with the requested features.\n\n---domain---\nanonwave.scroll.pub\n\n---index.scroll---\nbuildHtml\nbaseUrl https://anonwave.scroll.pub\nmetaTags\neditButton /edit.html\ntitle AnonWave Chat\nstyle.css\nbody.html\nscript.js\n\n---body.html---\n<div class=\"theme-toggle\">\n <button id=\"themeToggle\" aria-label=\"Toggle theme\">\n <i class=\"mode-icon\"></i>\n </button>\n</div>\n\n<div class=\"particles-container\" id=\"particles\"></div>\n\n<main class=\"chat-container\">\n <div class=\"login-screen\" id=\"loginScreen\">\n <h1>AnonWave Chat</h1>\n <div class=\"username-input\">\n <input type=\"text\" id=\"usernameInput\" placeholder=\"Choose your username\" maxlength=\"20\">\n <button id=\"joinChat\">Join Chat</button>\n </div>\n </div>\n\n <div class=\"chat-screen hidden\" id=\"chatScreen\">\n <div class=\"chat-header\">\n <h2>Live Chat</h2>\n <span class=\"user-badge\" id=\"userBadge\"></span>\n </div>\n \n <div class=\"messages\" id=\"messageContainer\"></div>\n \n <div class=\"chat-input\">\n <input type=\"text\" id=\"messageInput\" placeholder=\"Type your message...\">\n <button id=\"sendMessage\" aria-label=\"Send message\">\n <i class=\"send-icon\"></i>\n </button>\n </div>\n </div>\n</main>\n\n---style.css---\n:root {\n --bg-light: #ffffff;\n --text-light: #333333;\n --primary-light: #4a90e2;\n --secondary-light: #f5f5f5;\n --accent-light: #2ecc71;\n \n --bg-dark: #1a1a1a;\n --text-dark: #ffffff;\n --primary-dark: #3498db;\n --secondary-dark: #2c2c2c;\n --accent-dark: #27ae60;\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, sans-serif;\n background: var(--bg-light);\n color: var(--text-light);\n transition: background-color 0.3s, color 0.3s;\n}\n\nbody.dark-theme {\n background: var(--bg-dark);\n color: var(--text-dark);\n}\n\n.particles-container {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 0;\n pointer-events: none;\n}\n\n.theme-toggle {\n position: fixed;\n top: 1rem;\n right: 1rem;\n z-index: 100;\n}\n\n.theme-toggle button {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n border-radius: 50%;\n width: 40px;\n height: 40px;\n transition: background-color 0.3s;\n}\n\n.mode-icon {\n display: inline-block;\n width: 24px;\n height: 24px;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"%23333\" d=\"M12 2a10 10 0 1010 10A10 10 0 0012 2z\"/></svg>');\n}\n\n.dark-theme .mode-icon {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"%23fff\" d=\"M12 2a10 10 0 1010 10A10 10 0 0012 2z\"/></svg>');\n}\n\n.chat-container {\n max-width: 900px;\n margin: 2rem auto;\n padding: 1rem;\n position: relative;\n z-index: 1;\n}\n\n.login-screen, .chat-screen {\n background: var(--secondary-light);\n padding: 2rem;\n border-radius: 1rem;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\n.dark-theme .login-screen,\n.dark-theme .chat-screen {\n background: var(--secondary-dark);\n}\n\n.hidden {\n display: none;\n}\n\n.username-input {\n display: flex;\n gap: 1rem;\n margin-top: 2rem;\n}\n\ninput {\n padding: 0.8rem 1rem;\n border: 2px solid transparent;\n border-radius: 0.5rem;\n font-size: 1rem;\n transition: border-color 0.3s;\n background: var(--bg-light);\n color: var(--text-light);\n}\n\n.dark-theme input {\n background: var(--bg-dark);\n color: var(--text-dark);\n}\n\ninput:focus {\n outline: none;\n border-color: var(--primary-light);\n}\n\nbutton {\n padding: 0.8rem 1.5rem;\n background: var(--primary-light);\n color: white;\n border: none;\n border-radius: 0.5rem;\n cursor: pointer;\n font-size: 1rem;\n transition: transform 0.2s, background-color 0.3s;\n}\n\nbutton:hover {\n transform: translateY(-2px);\n background: var(--accent-light);\n}\n\n.dark-theme button {\n background: var(--primary-dark);\n}\n\n.dark-theme button:hover {\n background: var(--accent-dark);\n}\n\n.messages {\n height: 400px;\n overflow-y: auto;\n padding: 1rem;\n margin: 1rem 0;\n background: var(--bg-light);\n border-radius: 0.5rem;\n}\n\n.dark-theme .messages {\n background: var(--bg-dark);\n}\n\n.message {\n margin-bottom: 1rem;\n padding: 0.8rem;\n border-radius: 0.5rem;\n max-width: 80%;\n}\n\n.message.sent {\n background: var(--primary-light);\n color: white;\n margin-left: auto;\n}\n\n.message.received {\n background: var(--secondary-light);\n margin-right: auto;\n}\n\n.dark-theme .message.received {\n background: var(--secondary-dark);\n}\n\n@media (max-width: 600px) {\n .chat-container {\n margin: 0;\n padding: 0.5rem;\n }\n \n .username-input {\n flex-direction: column;\n }\n \n .messages {\n height: 300px;\n }\n}\n\n---script.js---\nclass ChatApp {\n constructor() {\n this.username = '';\n this.messages = [];\n this.isDark = false;\n this.particles = [];\n \n this.initElements();\n this.initEventListeners();\n this.initParticles();\n this.loadTheme();\n this.loadMessages();\n }\n \n initElements() {\n this.loginScreen = document.getElementById('loginScreen');\n this.chatScreen = document.getElementById('chatScreen');\n this.usernameInput = document.getElementById('usernameInput');\n this.messageInput = document.getElementById('messageInput');\n this.messageContainer = document.getElementById('messageContainer');\n this.userBadge = document.getElementById('userBadge');\n this.themeToggle = document.getElementById('themeToggle');\n this.particlesContainer = document.getElementById('particles');\n }\n \n initEventListeners() {\n document.getElementById('joinChat').addEventListener('click', () => this.joinChat());\n document.getElementById('sendMessage').addEventListener('click', () => this.sendMessage());\n this.messageInput.addEventListener('keypress', (e) => {\n if (e.key === 'Enter') this.sendMessage();\n });\n this.themeToggle.addEventListener('click', () => this.toggleTheme());\n }\n \n joinChat() {\n const username = this.usernameInput.value.trim();\n if (username.length < 3) {\n alert('Username must be at least 3 characters long');\n return;\n }\n \n this.username = username;\n this.loginScreen.classList.add('hidden');\n this.chatScreen.classList.remove('hidden');\n this.userBadge.textContent = username;\n this.messageInput.focus();\n }\n \n sendMessage() {\n const message = this.messageInput.value.trim();\n if (!message) return;\n \n const messageObj = {\n text: message,\n username: this.username,\n timestamp: new Date().toISOString(),\n id: Date.now()\n };\n \n this.messages.push(messageObj);\n this.saveMessages();\n this.displayMessage(messageObj);\n this.messageInput.value = '';\n }\n \n displayMessage(message) {\n const messageElement = document.createElement('div');\n messageElement.classList.add('message');\n messageElement.classList.add(message.username === this.username ? 'sent' : 'received');\n \n messageElement.innerHTML = `\n <strong>${message.username}</strong>\n <p>${this.escapeHtml(message.text)}</p>\n <small>${new Date(message.timestamp).toLocaleTimeString()}</small>\n `;\n \n this.messageContainer.appendChild(messageElement);\n this.messageContainer.scrollTop = this.messageContainer.scrollHeight;\n }\n \n escapeHtml(unsafe) {\n return unsafe\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n }\n \n toggleTheme() {\n this.isDark = !this.isDark;\n document.body.classList.toggle('dark-theme');\n localStorage.setItem('theme', this.isDark ? 'dark' : 'light');\n }\n \n loadTheme() {\n const savedTheme = localStorage.getItem('theme');\n if (savedTheme === 'dark') {\n this.isDark = true;\n document.body.classList.add('dark-theme');\n }\n }\n \n saveMessages() {\n localStorage.setItem('chatMessages', JSON.stringify(this.messages));\n }\n \n loadMessages() {\n const saved = localStorage.getItem('chatMessages');\n if (saved) {\n this.messages = JSON.parse(saved);\n this.messages.forEach(msg => this.displayMessage(msg));\n }\n }\n \n initParticles() {\n const canvas = document.createElement('canvas');\n canvas.style.width = '100%';\n canvas.style.height = '100%';\n this.particlesContainer.appendChild(canvas);\n const ctx = canvas.getContext('2d');\n \n const resize = () => {\n canvas.width = this.particlesContainer.clientWidth;\n canvas.height = this.particlesContainer.clientHeight;\n };\n \n window.addEventListener('resize', resize);\n resize();\n \n for (let i = 0; i < 50; i++) {\n this.particles.push({\n x: Math.random() * canvas.width,\n y: Math.random() * canvas.height,\n size: Math.random() * 3 + 1,\n speedX: Math.random() * 2 - 1,\n speedY: Math.random() * 2 - 1\n });\n }\n \n const animate = () => {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n \n this.particles.forEach(particle => {\n particle.x += particle.speedX;\n particle.y += particle.speedY;\n \n if (particle.x < 0 || particle.x > canvas.width) particle.speedX *= -1;\n if (particle.y < 0 || particle.y > canvas.height) particle.speedY *= -1;\n \n ctx.beginPath();\n ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);\n ctx.fillStyle = this.isDark ? '#ffffff22' : '#00000022';\n ctx.fill();\n });\n \n requestAnimationFrame(animate);\n };\n \n animate();\n }\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n new ChatApp();\n});\n\n---end---\n\nThis implementation creates a modern, responsive anonymous chat interface with:\n\n1. Light/dark theme toggle with smooth transitions\n2. Animated particle background\n3. Clean, minimalist design\n4. Username selection screen\n5. Local storage for messages and theme preference\n6. Real-time message display\n7. Responsive layout for mobile devices\n8. Security measures (HTML escaping)\n9. Smooth animations and transitions\n10. Accessibility features\n\nThe chat messages are stored in localStorage (simulating JSON storage). For a production environment, you'd want to replace the storage logic with actual server communication.\n\nTo use: Simply enter a username (3+ characters) and start chatting. The theme can be toggled using the button in the top-right corner. Messages persist across page refreshes." + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 351, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "output_tokens": 3568 + } +} \ No newline at end of file diff --git a/readme.scroll b/readme.scroll new file mode 100644 index 0000000..2d9de90 --- /dev/null +++ b/readme.scroll @@ -0,0 +1,3 @@ +# anonwave.scroll.pub + +website generated by Claude from prompt: vamos criar uma interface gráfica supermoderna, pra um chat anonimo, vamos colocar efeitos, icones, partículas e detalhes, a interface tem que ter modo claro e escuro, cada pessoa que entrar vai escolher um nome de usuário, e toda conversa vai ser salva e lida em um arquivo json \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..d5e628a --- /dev/null +++ b/script.js @@ -0,0 +1,166 @@ +class ChatApp { + constructor() { + this.username = ''; + this.messages = []; + this.isDark = false; + this.particles = []; + + this.initElements(); + this.initEventListeners(); + this.initParticles(); + this.loadTheme(); + this.loadMessages(); + } + + initElements() { + this.loginScreen = document.getElementById('loginScreen'); + this.chatScreen = document.getElementById('chatScreen'); + this.usernameInput = document.getElementById('usernameInput'); + this.messageInput = document.getElementById('messageInput'); + this.messageContainer = document.getElementById('messageContainer'); + this.userBadge = document.getElementById('userBadge'); + this.themeToggle = document.getElementById('themeToggle'); + this.particlesContainer = document.getElementById('particles'); + } + + initEventListeners() { + document.getElementById('joinChat').addEventListener('click', () => this.joinChat()); + document.getElementById('sendMessage').addEventListener('click', () => this.sendMessage()); + this.messageInput.addEventListener('keypress', (e) => { + if (e.key === 'Enter') this.sendMessage(); + }); + this.themeToggle.addEventListener('click', () => this.toggleTheme()); + } + + joinChat() { + const username = this.usernameInput.value.trim(); + if (username.length < 3) { + alert('Username must be at least 3 characters long'); + return; + } + + this.username = username; + this.loginScreen.classList.add('hidden'); + this.chatScreen.classList.remove('hidden'); + this.userBadge.textContent = username; + this.messageInput.focus(); + } + + sendMessage() { + const message = this.messageInput.value.trim(); + if (!message) return; + + const messageObj = { + text: message, + username: this.username, + timestamp: new Date().toISOString(), + id: Date.now() + }; + + this.messages.push(messageObj); + this.saveMessages(); + this.displayMessage(messageObj); + this.messageInput.value = ''; + } + + displayMessage(message) { + const messageElement = document.createElement('div'); + messageElement.classList.add('message'); + messageElement.classList.add(message.username === this.username ? 'sent' : 'received'); + + messageElement.innerHTML = ` + <strong>${message.username}</strong> + <p>${this.escapeHtml(message.text)}</p> + <small>${new Date(message.timestamp).toLocaleTimeString()}</small> + `; + + this.messageContainer.appendChild(messageElement); + this.messageContainer.scrollTop = this.messageContainer.scrollHeight; + } + + escapeHtml(unsafe) { + return unsafe + .replace(/&/g, "&amp;") + .replace(/</g, "&lt;") + .replace(/>/g, "&gt;") + .replace(/"/g, "&quot;") + .replace(/'/g, "&#039;"); + } + + toggleTheme() { + this.isDark = !this.isDark; + document.body.classList.toggle('dark-theme'); + localStorage.setItem('theme', this.isDark ? 'dark' : 'light'); + } + + loadTheme() { + const savedTheme = localStorage.getItem('theme'); + if (savedTheme === 'dark') { + this.isDark = true; + document.body.classList.add('dark-theme'); + } + } + + saveMessages() { + localStorage.setItem('chatMessages', JSON.stringify(this.messages)); + } + + loadMessages() { + const saved = localStorage.getItem('chatMessages'); + if (saved) { + this.messages = JSON.parse(saved); + this.messages.forEach(msg => this.displayMessage(msg)); + } + } + + initParticles() { + const canvas = document.createElement('canvas'); + canvas.style.width = '100%'; + canvas.style.height = '100%'; + this.particlesContainer.appendChild(canvas); + const ctx = canvas.getContext('2d'); + + const resize = () => { + canvas.width = this.particlesContainer.clientWidth; + canvas.height = this.particlesContainer.clientHeight; + }; + + window.addEventListener('resize', resize); + resize(); + + for (let i = 0; i < 50; i++) { + this.particles.push({ + x: Math.random() * canvas.width, + y: Math.random() * canvas.height, + size: Math.random() * 3 + 1, + speedX: Math.random() * 2 - 1, + speedY: Math.random() * 2 - 1 + }); + } + + const animate = () => { + ctx.clearRect(0, 0, canvas.width, canvas.height); + + this.particles.forEach(particle => { + particle.x += particle.speedX; + particle.y += particle.speedY; + + if (particle.x < 0 || particle.x > canvas.width) particle.speedX *= -1; + if (particle.y < 0 || particle.y > canvas.height) particle.speedY *= -1; + + ctx.beginPath(); + ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2); + ctx.fillStyle = this.isDark ? '#ffffff22' : '#00000022'; + ctx.fill(); + }); + + requestAnimationFrame(animate); + }; + + animate(); + } +} + +document.addEventListener('DOMContentLoaded', () => { + new ChatApp(); +}); diff --git a/style.css b/style.css new file mode 100644 index 0000000..49fcd4d --- /dev/null +++ b/style.css @@ -0,0 +1,194 @@ +:root { + --bg-light: #ffffff; + --text-light: #333333; + --primary-light: #4a90e2; + --secondary-light: #f5f5f5; + --accent-light: #2ecc71; + + --bg-dark: #1a1a1a; + --text-dark: #ffffff; + --primary-dark: #3498db; + --secondary-dark: #2c2c2c; + --accent-dark: #27ae60; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; + background: var(--bg-light); + color: var(--text-light); + transition: background-color 0.3s, color 0.3s; +} + +body.dark-theme { + background: var(--bg-dark); + color: var(--text-dark); +} + +.particles-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 0; + pointer-events: none; +} + +.theme-toggle { + position: fixed; + top: 1rem; + right: 1rem; + z-index: 100; +} + +.theme-toggle button { + background: none; + border: none; + cursor: pointer; + padding: 0.5rem; + border-radius: 50%; + width: 40px; + height: 40px; + transition: background-color 0.3s; +} + +.mode-icon { + display: inline-block; + width: 24px; + height: 24px; + background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23333" d="M12 2a10 10 0 1010 10A10 10 0 0012 2z"/></svg>'); +} + +.dark-theme .mode-icon { + background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23fff" d="M12 2a10 10 0 1010 10A10 10 0 0012 2z"/></svg>'); +} + +.chat-container { + max-width: 900px; + margin: 2rem auto; + padding: 1rem; + position: relative; + z-index: 1; +} + +.login-screen, .chat-screen { + background: var(--secondary-light); + padding: 2rem; + border-radius: 1rem; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.dark-theme .login-screen, +.dark-theme .chat-screen { + background: var(--secondary-dark); +} + +.hidden { + display: none; +} + +.username-input { + display: flex; + gap: 1rem; + margin-top: 2rem; +} + +input { + padding: 0.8rem 1rem; + border: 2px solid transparent; + border-radius: 0.5rem; + font-size: 1rem; + transition: border-color 0.3s; + background: var(--bg-light); + color: var(--text-light); +} + +.dark-theme input { + background: var(--bg-dark); + color: var(--text-dark); +} + +input:focus { + outline: none; + border-color: var(--primary-light); +} + +button { + padding: 0.8rem 1.5rem; + background: var(--primary-light); + color: white; + border: none; + border-radius: 0.5rem; + cursor: pointer; + font-size: 1rem; + transition: transform 0.2s, background-color 0.3s; +} + +button:hover { + transform: translateY(-2px); + background: var(--accent-light); +} + +.dark-theme button { + background: var(--primary-dark); +} + +.dark-theme button:hover { + background: var(--accent-dark); +} + +.messages { + height: 400px; + overflow-y: auto; + padding: 1rem; + margin: 1rem 0; + background: var(--bg-light); + border-radius: 0.5rem; +} + +.dark-theme .messages { + background: var(--bg-dark); +} + +.message { + margin-bottom: 1rem; + padding: 0.8rem; + border-radius: 0.5rem; + max-width: 80%; +} + +.message.sent { + background: var(--primary-light); + color: white; + margin-left: auto; +} + +.message.received { + background: var(--secondary-light); + margin-right: auto; +} + +.dark-theme .message.received { + background: var(--secondary-dark); +} + +@media (max-width: 600px) { + .chat-container { + margin: 0; + padding: 0.5rem; + } + + .username-input { + flex-direction: column; + } + + .messages { + height: 300px; + } +}