sugakrit6 commited on
Commit
256e024
·
verified ·
1 Parent(s): 4e28ec5

Update online.html

Browse files
Files changed (1) hide show
  1. online.html +218 -161
online.html CHANGED
@@ -2,261 +2,318 @@
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>AeroCore OS - Community Hub</title>
7
  <link href="https://fonts.cdnfonts.com/css/gamestart" rel="stylesheet">
8
  <style>
9
  :root {
10
- --aero-blue: #0080ff;
11
- --aero-green: #40ffaa;
12
- --mosaic-bg: rgba(255, 255, 255, 0.85);
13
- --gloss-top: rgba(255, 255, 255, 0.5);
14
  }
15
 
16
  body {
17
- background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%),
18
- url('https://www.transparenttextures.com/patterns/cubes.png');
 
19
  font-family: 'GameStart', sans-serif;
20
- color: #003366;
21
  margin: 0;
22
  display: flex;
23
  justify-content: center;
24
  align-items: center;
25
  height: 100vh;
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  }
27
 
28
  .window {
29
- width: 700px;
30
  height: 550px;
31
- background: var(--mosaic-bg);
32
- border: 5px solid #fff;
33
- box-shadow: 10px 10px 0px rgba(0, 0, 0, 0.15);
 
 
34
  display: flex;
35
  flex-direction: column;
36
- position: relative;
37
  }
38
 
39
- /* Screen Management */
40
- .screen { display: none; padding: 20px; flex-direction: column; height: 100%; box-sizing: border-box; }
41
  .active { display: flex; }
42
 
43
- h1, h2 { text-shadow: 2px 2px #fff; margin-top: 0; }
44
-
45
- /* Frutiger Buttons */
46
  button {
47
  font-family: 'GameStart', sans-serif;
48
- padding: 8px 12px;
49
- margin: 5px;
50
- background: linear-gradient(to bottom, #ffffff 0%, #aadaff 50%, #4facfe 100%);
51
  border: 2px solid #fff;
52
- border-radius: 4px;
 
53
  cursor: pointer;
54
- color: #003366;
55
- font-size: 0.8rem;
56
- box-shadow: 2px 2px 0px #0055aa;
57
  }
58
 
59
- button:active { transform: translate(2px, 2px); box-shadow: 0px 0px; }
60
-
61
- /* Chat Display */
62
- #chat-display {
63
- background: rgba(255,255,255,0.5);
64
  border: 3px inset #fff;
 
 
 
 
 
 
 
65
  flex-grow: 1;
66
  overflow-y: auto;
67
- padding: 10px;
68
  margin-bottom: 10px;
69
  }
70
 
71
- .message {
72
- background: rgba(255,255,255,0.8);
73
- border-left: 4px solid var(--aero-blue);
74
- padding: 8px;
75
- margin-bottom: 8px;
76
- font-size: 0.7rem;
77
  position: relative;
78
  }
79
 
80
- .msg-meta { font-size: 0.5rem; color: #666; margin-bottom: 4px; }
81
- .msg-tools { margin-top: 5px; display: flex; gap: 5px; }
82
-
83
- .btn-del { background: linear-gradient(#ff8888, #aa0000); color: white; font-size: 0.5rem; }
84
 
85
- input {
86
- font-family: 'GameStart', sans-serif;
87
- padding: 8px;
88
- border: 2px solid var(--aero-blue);
 
 
 
 
 
 
 
89
  }
90
 
91
- .media-btn-row { display: flex; gap: 5px; margin-bottom: 5px; }
92
-
93
- /* Hidden Inputs */
94
- input[type="file"] { display: none; }
95
  </style>
96
  </head>
97
  <body>
98
 
 
 
99
  <div class="window">
100
- <div id="screen-home" class="screen active">
101
- <h1>AEROCORE v2.0</h1>
102
- <p>SYSTEM STATUS: ONLINE</p>
103
- <button onclick="nav('screen-chat')">ENTER COMMUNITY HUB</button>
104
- <button onclick="nav('screen-settings')">FILTERS & DATA</button>
 
 
105
  </div>
106
 
107
- <div id="screen-chat" class="screen">
 
 
 
 
 
 
 
 
 
108
  <h2>COMMUNITY HUB</h2>
109
- <div id="lobby-ui">
110
- <button onclick="initChat('Public')">JOIN PUBLIC SERVER</button>
111
- <hr>
112
- <button onclick="createPrivate()">HOST PRIVATE ROOM</button>
113
- <div id="private-code-box" style="margin: 10px 0; color: var(--aero-blue);"></div>
114
- <input type="text" id="join-code" placeholder="ENTER ROOM CODE">
115
- <button onclick="initChat('Private')">JOIN PRIVATE</button>
116
- </div>
 
117
 
118
- <div id="chat-ui" style="display:none; flex-direction:column; flex-grow:1; height:80%;">
119
- <div id="chat-display"></div>
120
-
121
- <div class="media-btn-row">
122
- <button onclick="triggerFile('img')">IMG</button>
123
- <button onclick="triggerFile('aud')">AUD</button>
124
- <button onclick="triggerFile('vid')">VID</button>
125
- </div>
126
-
127
- <input type="file" id="fileInput" onchange="handleFileUpload()">
128
- <input type="text" id="chatInput" placeholder="TYPE MESSAGE...">
129
-
130
- <div style="display:flex; margin-top:10px;">
131
- <button onclick="sendMessage()" style="flex:2">SEND</button>
132
- <button onclick="exitChat()" style="flex:1; background: linear-gradient(#40ffaa, #008844);">DONE</button>
 
 
133
  </div>
134
  </div>
135
- <button onclick="nav('screen-home')" id="back-home">BACK</button>
136
  </div>
 
137
 
138
- <div id="screen-settings" class="screen">
139
- <h2>SYSTEM CONFIG</h2>
140
- <label>CENSORSHIP:</label>
141
- <select id="censor-toggle">
142
- <option value="on">ENABLED (STRICT)</option>
143
- <option value="off">DISABLED</option>
144
- </select>
145
- <br><br>
146
- <button onclick="clearData()" style="background: red; color: white;">WIPE DATA</button>
147
- <button onclick="nav('screen-home')">SAVE & EXIT</button>
148
- </div>
149
  </div>
150
 
151
  <script>
152
- // --- DATABASE & STATE ---
153
- let db = JSON.parse(localStorage.getItem('aero_db')) || { messages: [], filter: 'on' };
154
- let currentRoom = "Public";
155
- let pendingFileType = '';
 
 
 
156
 
 
 
 
157
  function nav(id) {
158
  document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
159
  document.getElementById(id).classList.add('active');
 
 
160
  }
161
 
162
- // --- CHAT LOGIC ---
163
- function createPrivate() {
164
- const code = Math.floor(1000 + Math.random() * 9000);
165
- document.getElementById('private-code-box').innerText = "GENERATED CODE: " + code;
 
 
 
 
 
 
 
166
  }
167
 
168
- function initChat(mode) {
169
- if(mode === 'Private' && !document.getElementById('join-code').value) return alert("Code Required");
170
- currentRoom = mode;
171
- document.getElementById('lobby-ui').style.display = 'none';
172
- document.getElementById('back-home').style.display = 'none';
173
- document.getElementById('chat-ui').style.display = 'flex';
174
- renderMessages();
175
  }
176
 
177
- function exitChat() {
178
- document.getElementById('lobby-ui').style.display = 'block';
179
- document.getElementById('back-home').style.display = 'block';
180
- document.getElementById('chat-ui').style.display = 'none';
181
- }
182
 
183
- function triggerFile(type) {
184
- pendingFileType = type;
185
- document.getElementById('fileInput').click();
 
 
 
186
  }
187
 
188
- function handleFileUpload() {
189
- const file = document.getElementById('fileInput').files[0];
190
- if (file) {
191
- const reader = new FileReader();
192
- reader.onload = (e) => addMessage(e.target.result, pendingFileType);
193
- reader.readAsDataURL(file);
 
 
 
 
 
 
 
 
 
 
 
 
194
  }
195
  }
196
 
197
- function sendMessage() {
198
- const txt = document.getElementById('chatInput').value;
199
- if(txt) {
200
- addMessage(txt, 'text');
201
- document.getElementById('chatInput').value = '';
202
- }
 
 
203
  }
204
 
205
- function addMessage(content, type) {
206
- const isCensor = document.getElementById('censor-toggle').value === 'on';
207
- let safeContent = content;
208
-
209
- if(type === 'text' && isCensor) {
210
- const badWords = ["bad", "rude"];
211
- badWords.forEach(w => safeContent = safeContent.replace(new RegExp(w, 'gi'), '***'));
212
- }
 
 
 
213
 
214
- const msgObj = {
215
  id: Date.now(),
216
- room: currentRoom,
217
- body: safeContent,
 
218
  type: type,
219
- date: new Date().toLocaleString()
220
  };
221
 
222
- db.messages.push(msgObj);
223
  save();
 
224
  renderMessages();
225
  }
226
 
227
  function renderMessages() {
228
- const container = document.getElementById('chat-display');
229
- const roomMsgs = db.messages.filter(m => m.room === currentRoom);
230
-
231
- container.innerHTML = roomMsgs.map(m => `
232
- <div class="message" id="msg-${m.id}">
233
- <div class="msg-meta">${m.date} | Room: ${m.room}</div>
234
- <div class="msg-body">
235
- ${renderBody(m)}
236
- </div>
237
- <div class="msg-tools">
238
- <button class="btn-del" onclick="deleteMsg(${m.id})">DELETE FOR ME</button>
239
  </div>
240
  </div>
241
  `).join('');
242
- container.scrollTop = container.scrollHeight;
243
  }
244
 
245
- function renderBody(m) {
246
- if(m.type === 'img') return `<img src="${m.body}" style="max-width:100px;">`;
247
- if(m.type === 'aud') return `<audio src="${m.body}" controls style="width:150px;"></audio>`;
248
- if(m.type === 'vid') return `<video src="${m.body}" controls style="width:150px;"></video>`;
249
- return m.body;
250
  }
251
 
252
- function deleteMsg(id) {
253
- db.messages = db.messages.filter(m => m.id !== id);
 
 
 
 
 
 
 
254
  save();
255
  renderMessages();
256
  }
257
-
258
- function save() { localStorage.setItem('aero_db', JSON.stringify(db)); }
259
- function clearData() { localStorage.removeItem('aero_db'); location.reload(); }
260
  </script>
261
 
262
  </body>
 
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <title>AeroCore OS - Community v2.0</title>
 
6
  <link href="https://fonts.cdnfonts.com/css/gamestart" rel="stylesheet">
7
  <style>
8
  :root {
9
+ --aero-blue: #00d2ff;
10
+ --aero-green: #3affaa;
11
+ --mosaic-glass: rgba(255, 255, 255, 0.8);
 
12
  }
13
 
14
  body {
15
+ background: linear-gradient(45deg, #3a7bd5, #00d2ff, #3affaa);
16
+ background-size: 400% 400%;
17
+ animation: gradientBG 15s ease infinite;
18
  font-family: 'GameStart', sans-serif;
 
19
  margin: 0;
20
  display: flex;
21
  justify-content: center;
22
  align-items: center;
23
  height: 100vh;
24
+ overflow: hidden;
25
+ }
26
+
27
+ @keyframes gradientBG { 0% {background-position: 0% 50%;} 50% {background-position: 100% 50%;} 100% {background-position: 0% 50%;} }
28
+
29
+ /* Mosaic Texture Overlay */
30
+ .mosaic-overlay {
31
+ position: fixed;
32
+ top: 0; left: 0; width: 100%; height: 100%;
33
+ background-image: radial-gradient(rgba(255,255,255,0.2) 1px, transparent 1px);
34
+ background-size: 4px 4px;
35
+ pointer-events: none;
36
+ z-index: 10;
37
  }
38
 
39
  .window {
40
+ width: 750px;
41
  height: 550px;
42
+ background: var(--mosaic-glass);
43
+ border: 6px solid #fff;
44
+ box-shadow: 12px 12px 0px rgba(0,0,0,0.2);
45
+ position: relative;
46
+ z-index: 20;
47
  display: flex;
48
  flex-direction: column;
 
49
  }
50
 
51
+ .screen { display: none; padding: 30px; flex-direction: column; height: 100%; box-sizing: border-box; overflow-y: auto; }
 
52
  .active { display: flex; }
53
 
54
+ /* Aero Buttons */
 
 
55
  button {
56
  font-family: 'GameStart', sans-serif;
57
+ padding: 10px;
58
+ margin: 5px 0;
59
+ background: linear-gradient(to bottom, #fff, #aadaff, #0080ff);
60
  border: 2px solid #fff;
61
+ color: white;
62
+ text-shadow: 1px 1px 2px #000;
63
  cursor: pointer;
64
+ box-shadow: 3px 3px 0px #0055aa;
 
 
65
  }
66
 
67
+ input {
68
+ font-family: 'GameStart', sans-serif;
69
+ padding: 10px;
70
+ margin-bottom: 10px;
 
71
  border: 3px inset #fff;
72
+ background: rgba(255,255,255,0.9);
73
+ }
74
+
75
+ /* Chat Styles */
76
+ #chat-box {
77
+ background: white;
78
+ border: 3px inset #ccc;
79
  flex-grow: 1;
80
  overflow-y: auto;
81
+ padding: 15px;
82
  margin-bottom: 10px;
83
  }
84
 
85
+ .msg {
86
+ background: #f0faff;
87
+ border-left: 5px solid var(--aero-blue);
88
+ padding: 10px;
89
+ margin-bottom: 10px;
 
90
  position: relative;
91
  }
92
 
93
+ .msg-info { font-size: 0.6rem; color: #555; margin-bottom: 5px; }
94
+ .del-btn { font-size: 0.5rem; background: #ff4d4d; margin-right: 5px; }
 
 
95
 
96
+ /* Version Popup */
97
+ #version-popup {
98
+ position: absolute;
99
+ top: 50%; left: 50%;
100
+ transform: translate(-50%, -50%);
101
+ background: white;
102
+ border: 4px solid var(--aero-green);
103
+ padding: 20px;
104
+ text-align: center;
105
+ z-index: 100;
106
+ box-shadow: 0 0 50px rgba(0,0,0,0.5);
107
  }
108
 
109
+ .hidden { display: none !important; }
 
 
 
110
  </style>
111
  </head>
112
  <body>
113
 
114
+ <div class="mosaic-overlay"></div>
115
+
116
  <div class="window">
117
+ <div id="screen-auth" class="screen active">
118
+ <h2>AEROCORE ACCESS</h2>
119
+ <form id="auth-form" onsubmit="handleAuth(event)">
120
+ <input type="text" id="username" name="username" placeholder="USERNAME" required autocomplete="username">
121
+ <input type="password" id="password" name="password" placeholder="PASSWORD" required autocomplete="current-password" style="-webkit-text-security: none;">
122
+ <button type="submit" id="auth-btn">SIGN UP / LOG IN</button>
123
+ </form>
124
  </div>
125
 
126
+ <div id="screen-tutorial" class="screen">
127
+ <h2>SYSTEM TUTORIAL</h2>
128
+ <p>1. <b>Rooms:</b> Public is open. Private requires a Code.</p>
129
+ <p>2. <b>Media:</b> You can send text, images, and audio links.</p>
130
+ <p>3. <b>Control:</b> Hosts must approve you in Private rooms.</p>
131
+ <p>4. <b>Safety:</b> Use the 'Delete' options to manage your history.</p>
132
+ <button onclick="nav('screen-lobby')">UNDERSTOOD</button>
133
+ </div>
134
+
135
+ <div id="screen-lobby" class="screen">
136
  <h2>COMMUNITY HUB</h2>
137
+ <p id="welcome-msg"></p>
138
+ <button onclick="joinRoom('Public')">JOIN PUBLIC CHAT</button>
139
+ <hr>
140
+ <button onclick="createPrivate()">HOST PRIVATE ROOM</button>
141
+ <div id="host-code-display"></div>
142
+ <br>
143
+ <input type="text" id="join-code-input" placeholder="ENTER 4-DIGIT CODE">
144
+ <button onclick="joinRoom('Private')">REQUEST ENTRY</button>
145
+ </div>
146
 
147
+ <div id="screen-approval" class="screen">
148
+ <h2>HOST CONTROL PANEL</h2>
149
+ <p>Waiting Requests:</p>
150
+ <div id="approval-list"></div>
151
+ <button onclick="nav('screen-chat')">ENTER CHAT</button>
152
+ </div>
153
+
154
+ <div id="screen-chat" class="screen">
155
+ <h2 id="room-header">CHAT</h2>
156
+ <div id="chat-box"></div>
157
+ <div id="chat-inputs">
158
+ <input type="text" id="msg-input" placeholder="Message or URL...">
159
+ <div style="display:flex; gap: 5px;">
160
+ <button onclick="sendMsg('text')">SEND</button>
161
+ <button onclick="sendMsg('img')" style="background:var(--aero-blue)">IMG</button>
162
+ <button onclick="sendMsg('aud')" style="background:var(--aero-green)">AUD</button>
163
+ <button onclick="nav('screen-lobby')" style="background:#888">EXIT</button>
164
  </div>
165
  </div>
 
166
  </div>
167
+ </div>
168
 
169
+ <div id="version-popup" class="hidden">
170
+ <h3>AeroCore v2.0</h3>
171
+ <p>Released: 20th February 2026</p>
172
+ <button onclick="closePopup()">EXIT & START</button>
 
 
 
 
 
 
 
173
  </div>
174
 
175
  <script>
176
+ // --- DATA STATE ---
177
+ let db = JSON.parse(localStorage.getItem('aero_core_db')) || {
178
+ users: [],
179
+ messages: [],
180
+ rooms: {}, // code: {host, members, pending}
181
+ currentUser: null
182
+ };
183
 
184
+ function save() { localStorage.setItem('aero_core_db', JSON.stringify(db)); }
185
+
186
+ // --- NAVIGATION ---
187
  function nav(id) {
188
  document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
189
  document.getElementById(id).classList.add('active');
190
+ if(id === 'screen-chat') renderMessages();
191
+ if(id === 'screen-approval') renderApprovalList();
192
  }
193
 
194
+ // --- AUTH ---
195
+ function handleAuth(e) {
196
+ e.preventDefault();
197
+ const user = document.getElementById('username').value;
198
+ const pass = document.getElementById('password').value;
199
+
200
+ db.currentUser = { name: user, pass: pass };
201
+ document.getElementById('welcome-msg').innerText = "Hello, " + user;
202
+
203
+ // Show Version Popup on first login
204
+ document.getElementById('version-popup').classList.remove('hidden');
205
  }
206
 
207
+ function closePopup() {
208
+ document.getElementById('version-popup').classList.add('hidden');
209
+ nav('screen-tutorial');
 
 
 
 
210
  }
211
 
212
+ // --- ROOM LOGIC ---
213
+ let activeRoomCode = 'Public';
 
 
 
214
 
215
+ function createPrivate() {
216
+ const code = Math.floor(1000 + Math.random() * 9000).toString();
217
+ db.rooms[code] = { host: db.currentUser.name, members: [db.currentUser.name], pending: [] };
218
+ document.getElementById('host-code-display').innerHTML = `<b>YOUR ROOM CODE: ${code}</b><br><button onclick="nav('screen-approval')">MANAGE MEMBERS</button>`;
219
+ activeRoomCode = code;
220
+ save();
221
  }
222
 
223
+ function joinRoom(type) {
224
+ if(type === 'Public') {
225
+ activeRoomCode = 'Public';
226
+ nav('screen-chat');
227
+ } else {
228
+ const code = document.getElementById('join-code-input').value;
229
+ if(!db.rooms[code]) return alert("Room not found");
230
+
231
+ activeRoomCode = code;
232
+ if(db.rooms[code].members.includes(db.currentUser.name)) {
233
+ nav('screen-chat');
234
+ } else {
235
+ if(!db.rooms[code].pending.includes(db.currentUser.name)) {
236
+ db.rooms[code].pending.push(db.currentUser.name);
237
+ save();
238
+ }
239
+ alert("Request sent to host. Wait for approval.");
240
+ }
241
  }
242
  }
243
 
244
+ function renderApprovalList() {
245
+ const list = document.getElementById('approval-list');
246
+ const room = db.rooms[activeRoomCode];
247
+ list.innerHTML = room.pending.map(u => `
248
+ <div style="margin-bottom:10px;">
249
+ ${u} <button onclick="approveUser('${u}')">APPROVE</button>
250
+ </div>
251
+ `).join('') || "No pending requests.";
252
  }
253
 
254
+ function approveUser(user) {
255
+ db.rooms[activeRoomCode].members.push(user);
256
+ db.rooms[activeRoomCode].pending = db.rooms[activeRoomCode].pending.filter(u => u !== user);
257
+ save();
258
+ renderApprovalList();
259
+ }
260
+
261
+ // --- MESSAGING ---
262
+ function sendMsg(type) {
263
+ const input = document.getElementById('msg-input');
264
+ if(!input.value) return;
265
 
266
+ const msg = {
267
  id: Date.now(),
268
+ code: activeRoomCode,
269
+ sender: db.currentUser.name,
270
+ content: input.value,
271
  type: type,
272
+ date: new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})
273
  };
274
 
275
+ db.messages.push(msg);
276
  save();
277
+ input.value = '';
278
  renderMessages();
279
  }
280
 
281
  function renderMessages() {
282
+ const box = document.getElementById('chat-box');
283
+ const msgs = db.messages.filter(m => m.code === activeRoomCode);
284
+ document.getElementById('room-header').innerText = `ROOM: ${activeRoomCode}`;
285
+
286
+ box.innerHTML = msgs.map(m => `
287
+ <div class="msg">
288
+ <div class="msg-info">${m.sender} - ${m.date}</div>
289
+ <div>${renderContent(m)}</div>
290
+ <div style="margin-top:5px;">
291
+ <button class="del-btn" onclick="deleteMsg(${m.id}, 'me')">DEL FOR ME</button>
292
+ ${m.sender === db.currentUser.name ? `<button class="del-btn" onclick="deleteMsg(${m.id}, 'everyone')">DEL FOR EVERYONE</button>` : ''}
293
  </div>
294
  </div>
295
  `).join('');
296
+ box.scrollTop = box.scrollHeight;
297
  }
298
 
299
+ function renderContent(m) {
300
+ if(m.type === 'img') return `<img src="${m.content}" style="max-width:150px; border:2px solid #fff;">`;
301
+ if(m.type === 'aud') return `<audio src="${m.content}" controls style="width:180px;"></audio>`;
302
+ return m.content;
 
303
  }
304
 
305
+ function deleteMsg(id, type) {
306
+ if(type === 'everyone') {
307
+ db.messages = db.messages.filter(m => m.id !== id);
308
+ } else {
309
+ // "Delete for me" locally filters it out for this session
310
+ const el = document.getElementById(`msg-container-${id}`);
311
+ // In a simple local DB, we just filter it out of the current view
312
+ db.messages = db.messages.filter(m => m.id !== id);
313
+ }
314
  save();
315
  renderMessages();
316
  }
 
 
 
317
  </script>
318
 
319
  </body>