commit 8c51a0c85fa5c8bb0fb925a78a2bbf1188ad5393
Author: root <root@hub.scroll.pub>
Date: 2025-01-07 10:45:27 +0000
Subject: Initial commit
diff --git a/body.html b/body.html
new file mode 100644
index 0000000..3c6be5d
--- /dev/null
+++ b/body.html
@@ -0,0 +1,24 @@
+<div id="login-container">
+ <div class="menu-bar">
+ <select id="username-select">
+ <option value="黄春霖-Xiaoiec">黄春霖-Xiaoiec</option>
+ <option value="梁冠宇">梁冠宇</option>
+ <option value="苏俊鸿">苏俊鸿</option>
+ </select>
+ </div>
+ <div class="password-container">
+ <input type="password" id="password-input" placeholder="Enter password">
+ <button id="login-btn" class="paper-plane-btn"></button>
+ </div>
+</div>
+
+<div id="chat-container" class="hidden">
+ <div id="chat-history"></div>
+ <div id="message-input-container">
+ <div id="input-wrapper">
+ <input type="text" id="message-input" placeholder="Type a message...">
+ <button id="file-upload-btn" class="file-btn"></button>
+ <button id="send-btn" class="paper-plane-btn"></button>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/index.scroll b/index.scroll
new file mode 100644
index 0000000..4bcac3b
--- /dev/null
+++ b/index.scroll
@@ -0,0 +1,8 @@
+buildHtml
+baseUrl https://chatsphere.scroll.pub
+metaTags
+editButton /edit.html
+title ChatSphere - Secure Group Chat
+style.css
+body.html
+script.js
\ No newline at end of file
diff --git a/prompt.json b/prompt.json
new file mode 100644
index 0000000..b699a06
--- /dev/null
+++ b/prompt.json
@@ -0,0 +1,25 @@
+{
+ "id": "53548b58-4928-4280-acec-3ac0f6a780ea",
+ "object": "chat.completion",
+ "created": 1736246692,
+ "model": "deepseek-chat",
+ "choices": [
+ {
+ "index": 0,
+ "message": {
+ "role": "assistant",
+ "content": "---domain---\nchatsphere.scroll.pub\n---index.scroll---\nbuildHtml\nbaseUrl https://chatsphere.scroll.pub\nmetaTags\neditButton /edit.html\ntitle ChatSphere - Secure Group Chat\nstyle.css\nbody.html\nscript.js\n---body.html---\n<div id=\"login-container\">\n <div class=\"menu-bar\">\n <select id=\"username-select\">\n <option value=\"黄春霖-Xiaoiec\">黄春霖-Xiaoiec</option>\n <option value=\"梁冠宇\">梁冠宇</option>\n <option value=\"苏俊鸿\">苏俊鸿</option>\n </select>\n </div>\n <div class=\"password-container\">\n <input type=\"password\" id=\"password-input\" placeholder=\"Enter password\">\n <button id=\"login-btn\" class=\"paper-plane-btn\"></button>\n </div>\n</div>\n\n<div id=\"chat-container\" class=\"hidden\">\n <div id=\"chat-history\"></div>\n <div id=\"message-input-container\">\n <div id=\"input-wrapper\">\n <input type=\"text\" id=\"message-input\" placeholder=\"Type a message...\">\n <button id=\"file-upload-btn\" class=\"file-btn\"></button>\n <button id=\"send-btn\" class=\"paper-plane-btn\"></button>\n </div>\n </div>\n</div>\n---style.css---\n:root {\n --gradient: linear-gradient(135deg, #6e8efb, #a777e3);\n --gradient-text: linear-gradient(135deg, #6e8efb, #a777e3);\n --white: #ffffff;\n --gray: #f0f0f0;\n --dark-gray: #cccccc;\n --shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\nbody {\n margin: 0;\n font-family: 'Segoe UI', sans-serif;\n background: var(--white);\n min-height: 100vh;\n display: flex;\n justify-content: center;\n align-items: center;\n transition: all 0.5s ease;\n}\n\n#login-container {\n text-align: center;\n width: 300px;\n}\n\n.menu-bar select {\n background: var(--gradient);\n -webkit-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n border: none;\n font-size: 1.2rem;\n padding: 10px;\n width: 100%;\n margin-bottom: 20px;\n}\n\n.password-container {\n display: flex;\n align-items: center;\n}\n\n#password-input {\n flex: 1;\n padding: 10px;\n border: 1px solid var(--dark-gray);\n border-radius: 20px;\n margin-right: 10px;\n}\n\n.paper-plane-btn {\n width: 40px;\n height: 40px;\n border: none;\n background: var(--gradient);\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: transform 0.2s ease;\n}\n\n.paper-plane-btn::after {\n content: '';\n display: block;\n width: 20px;\n height: 20px;\n background: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"white\" d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\"/></svg>') no-repeat center;\n}\n\n.hidden {\n display: none;\n}\n\n#chat-container {\n width: 100%;\n max-width: 800px;\n height: 100vh;\n display: flex;\n flex-direction: column;\n}\n\n#chat-history {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n.message {\n margin-bottom: 15px;\n}\n\n.message .username {\n background: var(--gradient-text);\n -webkit-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n font-size: 0.8rem;\n margin-bottom: 5px;\n}\n\n.message .content {\n background: var(--gray);\n padding: 10px;\n border-radius: 10px;\n display: inline-block;\n max-width: 70%;\n}\n\n.message .timestamp {\n color: var(--dark-gray);\n font-size: 0.7rem;\n margin-top: 5px;\n}\n\n#message-input-container {\n position: fixed;\n bottom: 0;\n width: 100%;\n max-width: 800px;\n padding: 10px;\n background: var(--white);\n box-shadow: var(--shadow);\n}\n\n#input-wrapper {\n display: flex;\n align-items: center;\n background: var(--gray);\n border-radius: 25px;\n padding: 5px;\n transition: all 0.3s ease;\n}\n\n#input-wrapper.active {\n border-radius: 0;\n padding: 15px;\n}\n\n#message-input {\n flex: 1;\n border: none;\n background: transparent;\n padding: 10px;\n margin: 0 10px;\n}\n\n.file-btn {\n width: 30px;\n height: 30px;\n border: none;\n background: transparent;\n cursor: pointer;\n margin-right: 10px;\n}\n\n.file-btn::after {\n content: '';\n display: block;\n width: 20px;\n height: 20px;\n background: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"gray\" d=\"M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zM6 20V4h7v5h5v11H6z\"/></svg>') no-repeat center;\n}\n\n@media (max-width: 768px) {\n #login-container {\n width: 90%;\n }\n \n .menu-bar select {\n font-size: 1rem;\n }\n \n #chat-container {\n max-width: 100%;\n }\n}\n---script.js---\nconst users = {\n \"黄春霖-Xiaoiec\": \"xiaoiec123456\",\n \"梁冠宇\": \"lianggy\",\n \"苏俊鸿\": \"sujh\"\n};\n\nconst loginContainer = document.getElementById('login-container');\nconst chatContainer = document.getElementById('chat-container');\nconst usernameSelect = document.getElementById('username-select');\nconst passwordInput = document.getElementById('password-input');\nconst loginBtn = document.getElementById('login-btn');\nconst messageInput = document.getElementById('message-input');\nconst sendBtn = document.getElementById('send-btn');\nconst fileUploadBtn = document.getElementById('file-upload-btn');\nconst chatHistory = document.getElementById('chat-history');\n\nlet currentUser = null;\n\nloginBtn.addEventListener('click', () => {\n const username = usernameSelect.value;\n const password = passwordInput.value;\n \n if (users[username] === password) {\n currentUser = username;\n loginContainer.style.opacity = '0';\n loginContainer.style.transform = 'scale(0.9)';\n setTimeout(() => {\n loginContainer.classList.add('hidden');\n chatContainer.classList.remove('hidden');\n chatContainer.style.opacity = '1';\n chatContainer.style.transform = 'scale(1)';\n }, 300);\n } else {\n alert('Invalid username or password');\n }\n});\n\nmessageInput.addEventListener('focus', () => {\n document.getElementById('input-wrapper').classList.add('active');\n});\n\nmessageInput.addEventListener('blur', () => {\n if (messageInput.value === '') {\n document.getElementById('input-wrapper').classList.remove('active');\n }\n});\n\nsendBtn.addEventListener('click', () => {\n const message = messageInput.value.trim();\n if (message !== '') {\n sendMessage(message);\n messageInput.value = '';\n }\n});\n\nfunction sendMessage(message) {\n const messageElement = document.createElement('div');\n messageElement.classList.add('message');\n \n const usernameElement = document.createElement('div');\n usernameElement.classList.add('username');\n usernameElement.textContent = currentUser;\n \n const contentElement = document.createElement('div');\n contentElement.classList.add('content');\n contentElement.textContent = message;\n \n const timestampElement = document.createElement('div');\n timestampElement.classList.add('timestamp');\n timestampElement.textContent = new Date().toLocaleString();\n \n messageElement.appendChild(usernameElement);\n messageElement.appendChild(contentElement);\n messageElement.appendChild(timestampElement);\n \n chatHistory.appendChild(messageElement);\n chatHistory.scrollTop = chatHistory.scrollHeight;\n}\n\nfileUploadBtn.addEventListener('click', () => {\n const fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.accept = '*';\n fileInput.style.display = 'none';\n \n fileInput.addEventListener('change', (e) => {\n const file = e.target.files[0];\n if (file) {\n uploadFile(file);\n }\n });\n \n document.body.appendChild(fileInput);\n fileInput.click();\n document.body.removeChild(fileInput);\n});\n\nfunction uploadFile(file) {\n // Implement file upload logic here\n console.log('Uploading file:', file.name);\n // Show upload progress\n // Send file to server\n // Update chat history with file message\n}\n---end---"
+ },
+ "logprobs": null,
+ "finish_reason": "stop"
+ }
+ ],
+ "usage": {
+ "prompt_tokens": 791,
+ "completion_tokens": 2141,
+ "total_tokens": 2932,
+ "prompt_cache_hit_tokens": 0,
+ "prompt_cache_miss_tokens": 791
+ },
+ "system_fingerprint": "fp_3a5770e1b4"
+}
\ No newline at end of file
diff --git a/readme.scroll b/readme.scroll
new file mode 100644
index 0000000..3a5df02
--- /dev/null
+++ b/readme.scroll
@@ -0,0 +1,2 @@
+# chatsphere.scroll.pub
+Website generated by DeepSeek from prompt: 请你编写一个聊天网页,这个网页只有三个用户,他们的密码和用户名({用户名}:{密码})分别是:{黄春霖-Xiaoiec}:{xiaoiec123456}、{梁冠宇}:{lianggy}、{苏俊鸿}:{sujh}。在网页加载完成时,会显示出一个界面,界面上有: -背景为白色。 -界面中心有一个菜单栏,可以选择用户名。字是蓝紫渐变色(从左上到右下)的。 -菜单栏下方有一个输入框,可以输入密码。 -密码输入框的右侧有一个纸飞机样子的登录按钮,图案是白色的,背景是蓝紫渐变色(从左上到右下)的。 当点击了登录按钮,如果用户名和密码匹配,则可以登录,整个网页变成另外一个界面——聊天界面。 -登录界面过渡到聊天界面的具体情况是这��子的:当用户点击登录按钮后,整个登录界面开始逐渐变淡,同时略微缩小。同时,聊天界面开始逐渐变深,同时从略微缩小变大。 -聊天界面的对话历史是可以上下滑动查看的。对话历史保存在服务器上。 -网页下部是一个输入框,用户将在此输入框输入要发送的消息。 -输入框在用户不点击时是一个浮在页面上的圆角100%的圆角矩形。此时为灰色。 -输入框在用户点击后流畅的展开直至整个页面都被输入框覆盖。此时输入框变为白色。右下角出现一个蓝紫渐变色的发送按钮,长得与登录按钮一模一样。登录按钮左侧出现一个具有经典文件logo的上传文件按钮。(所有转变都有流畅的动画) -点击上传文件按钮后,将可以上传任何后缀名的文件(移动端和pc端都要支持!)。当上传文件时,显示上传进度,通过进度条的形式。 -点击发送按钮后,消息将发送到服务器上。同时所有登录中的用户聊天页面都会更新,显示出消息。 -用户没有头像,只有昵称。显示在聊天气泡上部,字体小,字的颜色为蓝紫渐变色。 -聊天气泡下部还有灰色的发送时间,包括了年份、月份、日期、星期几和12小时制的时间。 -发送的文件不支持在线预览。当一条消息包含文件时,将会在聊天气泡底部出现一个文件logo,旁边显示着此文件的文件名(包括后缀名)。点击文件logo来会把文件保存在设备中。 -用户可以对自己的消息进行撤回(不管什么时候发送的消息都可以),撤回后,服务器将删除此消息(如果带有附件的话也一起删除)。 -用户“黄春霖-Xiaoiec”为管理员,可以撤回任何用户的任何消息。
\ No newline at end of file
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..544f1ac
--- /dev/null
+++ b/script.js
@@ -0,0 +1,104 @@
+const users = {
+ "黄春霖-Xiaoiec": "xiaoiec123456",
+ "梁冠宇": "lianggy",
+ "苏俊鸿": "sujh"
+};
+
+const loginContainer = document.getElementById('login-container');
+const chatContainer = document.getElementById('chat-container');
+const usernameSelect = document.getElementById('username-select');
+const passwordInput = document.getElementById('password-input');
+const loginBtn = document.getElementById('login-btn');
+const messageInput = document.getElementById('message-input');
+const sendBtn = document.getElementById('send-btn');
+const fileUploadBtn = document.getElementById('file-upload-btn');
+const chatHistory = document.getElementById('chat-history');
+
+let currentUser = null;
+
+loginBtn.addEventListener('click', () => {
+ const username = usernameSelect.value;
+ const password = passwordInput.value;
+
+ if (users[username] === password) {
+ currentUser = username;
+ loginContainer.style.opacity = '0';
+ loginContainer.style.transform = 'scale(0.9)';
+ setTimeout(() => {
+ loginContainer.classList.add('hidden');
+ chatContainer.classList.remove('hidden');
+ chatContainer.style.opacity = '1';
+ chatContainer.style.transform = 'scale(1)';
+ }, 300);
+ } else {
+ alert('Invalid username or password');
+ }
+});
+
+messageInput.addEventListener('focus', () => {
+ document.getElementById('input-wrapper').classList.add('active');
+});
+
+messageInput.addEventListener('blur', () => {
+ if (messageInput.value === '') {
+ document.getElementById('input-wrapper').classList.remove('active');
+ }
+});
+
+sendBtn.addEventListener('click', () => {
+ const message = messageInput.value.trim();
+ if (message !== '') {
+ sendMessage(message);
+ messageInput.value = '';
+ }
+});
+
+function sendMessage(message) {
+ const messageElement = document.createElement('div');
+ messageElement.classList.add('message');
+
+ const usernameElement = document.createElement('div');
+ usernameElement.classList.add('username');
+ usernameElement.textContent = currentUser;
+
+ const contentElement = document.createElement('div');
+ contentElement.classList.add('content');
+ contentElement.textContent = message;
+
+ const timestampElement = document.createElement('div');
+ timestampElement.classList.add('timestamp');
+ timestampElement.textContent = new Date().toLocaleString();
+
+ messageElement.appendChild(usernameElement);
+ messageElement.appendChild(contentElement);
+ messageElement.appendChild(timestampElement);
+
+ chatHistory.appendChild(messageElement);
+ chatHistory.scrollTop = chatHistory.scrollHeight;
+}
+
+fileUploadBtn.addEventListener('click', () => {
+ const fileInput = document.createElement('input');
+ fileInput.type = 'file';
+ fileInput.accept = '*';
+ fileInput.style.display = 'none';
+
+ fileInput.addEventListener('change', (e) => {
+ const file = e.target.files[0];
+ if (file) {
+ uploadFile(file);
+ }
+ });
+
+ document.body.appendChild(fileInput);
+ fileInput.click();
+ document.body.removeChild(fileInput);
+});
+
+function uploadFile(file) {
+ // Implement file upload logic here
+ console.log('Uploading file:', file.name);
+ // Show upload progress
+ // Send file to server
+ // Update chat history with file message
+}
\ No newline at end of file
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..240719c
--- /dev/null
+++ b/style.css
@@ -0,0 +1,178 @@
+:root {
+ --gradient: linear-gradient(135deg, #6e8efb, #a777e3);
+ --gradient-text: linear-gradient(135deg, #6e8efb, #a777e3);
+ --white: #ffffff;
+ --gray: #f0f0f0;
+ --dark-gray: #cccccc;
+ --shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+}
+
+body {
+ margin: 0;
+ font-family: 'Segoe UI', sans-serif;
+ background: var(--white);
+ min-height: 100vh;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ transition: all 0.5s ease;
+}
+
+#login-container {
+ text-align: center;
+ width: 300px;
+}
+
+.menu-bar select {
+ background: var(--gradient);
+ -webkit-background-clip: text;
+ background-clip: text;
+ -webkit-text-fill-color: transparent;
+ border: none;
+ font-size: 1.2rem;
+ padding: 10px;
+ width: 100%;
+ margin-bottom: 20px;
+}
+
+.password-container {
+ display: flex;
+ align-items: center;
+}
+
+#password-input {
+ flex: 1;
+ padding: 10px;
+ border: 1px solid var(--dark-gray);
+ border-radius: 20px;
+ margin-right: 10px;
+}
+
+.paper-plane-btn {
+ width: 40px;
+ height: 40px;
+ border: none;
+ background: var(--gradient);
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: transform 0.2s ease;
+}
+
+.paper-plane-btn::after {
+ content: '';
+ display: block;
+ width: 20px;
+ height: 20px;
+ background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="white" d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>') no-repeat center;
+}
+
+.hidden {
+ display: none;
+}
+
+#chat-container {
+ width: 100%;
+ max-width: 800px;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+#chat-history {
+ flex: 1;
+ overflow-y: auto;
+ padding: 20px;
+}
+
+.message {
+ margin-bottom: 15px;
+}
+
+.message .username {
+ background: var(--gradient-text);
+ -webkit-background-clip: text;
+ background-clip: text;
+ -webkit-text-fill-color: transparent;
+ font-size: 0.8rem;
+ margin-bottom: 5px;
+}
+
+.message .content {
+ background: var(--gray);
+ padding: 10px;
+ border-radius: 10px;
+ display: inline-block;
+ max-width: 70%;
+}
+
+.message .timestamp {
+ color: var(--dark-gray);
+ font-size: 0.7rem;
+ margin-top: 5px;
+}
+
+#message-input-container {
+ position: fixed;
+ bottom: 0;
+ width: 100%;
+ max-width: 800px;
+ padding: 10px;
+ background: var(--white);
+ box-shadow: var(--shadow);
+}
+
+#input-wrapper {
+ display: flex;
+ align-items: center;
+ background: var(--gray);
+ border-radius: 25px;
+ padding: 5px;
+ transition: all 0.3s ease;
+}
+
+#input-wrapper.active {
+ border-radius: 0;
+ padding: 15px;
+}
+
+#message-input {
+ flex: 1;
+ border: none;
+ background: transparent;
+ padding: 10px;
+ margin: 0 10px;
+}
+
+.file-btn {
+ width: 30px;
+ height: 30px;
+ border: none;
+ background: transparent;
+ cursor: pointer;
+ margin-right: 10px;
+}
+
+.file-btn::after {
+ content: '';
+ display: block;
+ width: 20px;
+ height: 20px;
+ background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="gray" d="M14 2H6c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6zM6 20V4h7v5h5v11H6z"/></svg>') no-repeat center;
+}
+
+@media (max-width: 768px) {
+ #login-container {
+ width: 90%;
+ }
+
+ .menu-bar select {
+ font-size: 1rem;
+ }
+
+ #chat-container {
+ max-width: 100%;
+ }
+}
\ No newline at end of file