sugakrit6 commited on
Commit
ec621ee
·
verified ·
1 Parent(s): 3a5051b

Update online.html

Browse files
Files changed (1) hide show
  1. online.html +112 -100
online.html CHANGED
@@ -2,185 +2,198 @@
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
- <title>AeroCore OS 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.85);
12
  }
13
 
14
  body {
15
  background: linear-gradient(135deg, #3a7bd5, #00d2ff, #3affaa);
 
 
16
  font-family: 'GameStart', sans-serif;
17
  margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden;
18
  }
19
 
20
- /* The Mosaic Filter */
21
- body::after {
22
- content: ""; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
23
- background-image: radial-gradient(rgba(255,255,255,0.15) 1px, transparent 1px);
24
- background-size: 5px 5px; pointer-events: none; z-index: 100;
 
 
25
  }
26
 
27
  .window {
28
  width: 750px; height: 550px; background: var(--mosaic-glass);
29
- border: 6px solid #fff; box-shadow: 12px 12px 0px rgba(0,0,0,0.2);
 
30
  position: relative; z-index: 20; display: flex; flex-direction: column;
31
  }
32
 
33
- .screen { display: none; padding: 30px; flex-direction: column; height: 100%; box-sizing: border-box; }
34
  .active { display: flex; }
35
 
36
- /* Aero Elements */
37
  button {
38
- font-family: 'GameStart', sans-serif; padding: 10px; margin: 5px 0;
39
- background: linear-gradient(to bottom, #fff, #aadaff, #0080ff);
40
  border: 2px solid #fff; color: white; text-shadow: 1px 1px 2px #000;
41
- cursor: pointer; box-shadow: 3px 3px 0px #0055aa;
42
  }
 
43
 
44
  input {
45
  font-family: 'GameStart', sans-serif; padding: 12px; margin-bottom: 10px;
46
- border: 3px inset #fff; background: rgba(255,255,255,0.9);
47
  }
48
 
49
- #chat-box { background: white; border: 3px inset #ccc; flex-grow: 1; overflow-y: auto; padding: 15px; margin-bottom: 10px; }
50
 
51
- .msg { background: #f0faff; border-left: 5px solid var(--aero-blue); padding: 10px; margin-bottom: 10px; }
52
- .del-btn { font-size: 0.5rem; background: #ff4d4d; border: 1px solid white; margin-top: 5px; cursor: pointer;}
53
-
54
- /* Version Popup */
55
- #version-popup {
56
- position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
57
- background: white; border: 4px solid var(--aero-green); padding: 20px;
58
- text-align: center; z-index: 1000; box-shadow: 0 0 50px rgba(0,0,0,0.5);
 
59
  }
 
 
 
 
 
 
 
 
60
  </style>
61
  </head>
62
  <body>
63
 
 
 
 
 
 
 
 
 
 
 
64
  <div class="window">
65
  <div id="screen-auth" class="screen active">
66
  <h2>AEROCORE ACCESS</h2>
67
- <form id="login-form">
68
  <input type="text" id="username" name="username" placeholder="USERNAME" required autocomplete="username">
69
  <input type="password" id="password" name="password" placeholder="PASSWORD" required autocomplete="current-password"
70
  style="-webkit-text-security: none !important;">
71
- <small style="font-size: 0.5rem; display: block; margin-bottom: 10px;">*Passwords are always visible for memory.</small>
72
-
73
- <button type="button" onclick="handleAuth('signup')">SIGN UP (Create Account)</button>
74
- <button type="button" onclick="handleAuth('login')" style="background: var(--aero-green);">LOG IN</button>
75
  </form>
76
  </div>
77
 
78
  <div id="screen-tutorial" class="screen">
79
  <h2>SYSTEM TUTORIAL</h2>
80
- <p>• <b>HOSTING:</b> Create a room and get a code to share.</p>
81
- <p><b>JOINING:</b> Enter a code and wait for Host approval.</p>
82
- <p><b>MESSAGING:</b> Send text or media URLs.</p>
83
- <p><b>DATA:</b> Your messages are saved to your local database.</p>
84
- <button onclick="nav('screen-lobby')">ENTER SYSTEM</button>
 
85
  </div>
86
 
87
  <div id="screen-lobby" class="screen">
88
  <h2>COMMUNITY HUB</h2>
89
- <p id="welcome-msg"></p>
90
  <button onclick="joinRoom('Public')">JOIN PUBLIC SERVER</button>
91
- <hr>
92
  <button onclick="createPrivate()">HOST PRIVATE ROOM</button>
93
- <div id="host-code-display" style="color: var(--aero-blue); margin: 5px;"></div>
94
  <br>
95
  <input type="text" id="join-code-input" placeholder="ENTER ROOM CODE">
96
  <button onclick="joinRoom('Private')">REQUEST ENTRY</button>
97
  </div>
98
 
99
  <div id="screen-chat" class="screen">
100
- <div style="display:flex; justify-content: space-between;">
101
- <h2 id="room-header">CHAT</h2>
102
- <button id="host-admin-btn" class="hidden" onclick="nav('screen-approval')" style="font-size: 0.5rem;">ADMIN PANEL</button>
103
  </div>
104
  <div id="chat-box"></div>
105
  <input type="text" id="msg-input" placeholder="Message or URL...">
106
  <div style="display:flex; gap: 5px;">
107
- <button onclick="sendMsg('text')">SEND</button>
108
  <button onclick="sendMsg('img')" style="background:var(--aero-blue)">IMG</button>
109
- <button onclick="nav('screen-lobby')" style="background:#888">EXIT</button>
110
  </div>
111
  </div>
112
 
113
  <div id="screen-approval" class="screen">
114
- <h2>HOST: PENDING REQUESTS</h2>
115
  <div id="approval-list"></div>
116
  <button onclick="nav('screen-chat')">BACK TO CHAT</button>
117
  </div>
118
  </div>
119
 
120
- <div id="version-popup" class="hidden">
121
- <h3>AeroCore v2.0</h3>
122
- <p>Build Date: 20th February 2026</p>
123
- <button onclick="closePopup()">EXIT & START</button>
124
- </div>
125
-
126
  <script>
127
- // --- DATABASE LOGIC ---
128
- let db = JSON.parse(localStorage.getItem('aero_db_v2')) || {
129
- users: [], // {user, pass}
130
- messages: [],
131
- rooms: {} // code: {host, members, pending}
132
  };
133
  let currentUser = null;
134
  let activeRoomCode = 'Public';
135
 
136
- function save() { localStorage.setItem('aero_db_v2', JSON.stringify(db)); }
 
 
 
 
 
 
 
 
137
 
138
- // --- AUTHENTICATION FIX ---
139
- function handleAuth(mode) {
 
140
  const u = document.getElementById('username').value;
141
  const p = document.getElementById('password').value;
142
- if(!u || !p) return alert("Fill all fields");
143
 
144
- const userExists = db.users.find(user => user.username === u);
 
 
145
 
146
  if(mode === 'signup') {
147
- if(userExists) return alert("User already exists! Try Login.");
148
- db.users.push({ username: u, password: p });
149
  save();
150
- alert("Account Created! Now click LOG IN.");
151
  } else {
152
- if(!userExists || userExists.password !== p) {
153
- alert("WRONG PASSWORD or User doesn't exist!");
154
- return;
155
- }
156
- // SUCCESSFUL LOGIN
157
  currentUser = u;
158
- document.getElementById('welcome-msg').innerText = "Welcome, " + u;
159
- document.getElementById('version-popup').classList.remove('hidden');
160
  }
161
  }
162
 
163
  function closePopup() {
164
- document.getElementById('version-popup').classList.add('hidden');
165
  nav('screen-tutorial');
166
  }
167
 
168
- // --- NAVIGATION ---
169
- function nav(id) {
170
- document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
171
- document.getElementById(id).classList.add('active');
172
- if(id === 'screen-chat') renderMessages();
173
- if(id === 'screen-approval') renderApprovalList();
174
- }
175
-
176
- // --- ROOM & HOSTING ---
177
  function createPrivate() {
178
  const code = Math.floor(1000 + Math.random() * 9000).toString();
179
  db.rooms[code] = { host: currentUser, members: [currentUser], pending: [] };
180
- document.getElementById('host-code-display').innerText = "YOUR ROOM CODE: " + code;
181
  activeRoomCode = code;
182
  save();
183
- alert("Room created! Share the code.");
184
  }
185
 
186
  function joinRoom(type) {
@@ -189,12 +202,10 @@
189
  nav('screen-chat');
190
  } else {
191
  const code = document.getElementById('join-code-input').value;
192
- if(!db.rooms[code]) {
193
- alert("ROOM NOT FOUND! (Check if you typed it right)");
194
- return;
195
- }
196
- activeRoomCode = code;
197
  const room = db.rooms[code];
 
 
 
198
  if(room.members.includes(currentUser)) {
199
  nav('screen-chat');
200
  } else {
@@ -202,7 +213,7 @@
202
  room.pending.push(currentUser);
203
  save();
204
  }
205
- alert("Request sent to Host (" + room.host + "). Wait for approval.");
206
  }
207
  }
208
  }
@@ -211,20 +222,20 @@
211
  const list = document.getElementById('approval-list');
212
  const room = db.rooms[activeRoomCode];
213
  list.innerHTML = room.pending.map(u => `
214
- <div style="background:white; padding:10px; border:2px solid var(--aero-blue); margin-bottom:5px;">
215
- USER: ${u} <button onclick="approveUser('${u}')">APPROVE</button>
216
  </div>
217
- `).join('') || "No pending users.";
218
  }
219
 
220
  function approveUser(u) {
221
  db.rooms[activeRoomCode].members.push(u);
222
- db.rooms[activeRoomCode].pending = db.rooms[activeRoomCode].pending.filter(user => user !== u);
223
  save();
224
  renderApprovalList();
225
  }
226
 
227
- // --- MESSAGING & DELETION ---
228
  function sendMsg(type) {
229
  const val = document.getElementById('msg-input').value;
230
  if(!val) return;
@@ -234,7 +245,7 @@
234
  sender: currentUser,
235
  content: val,
236
  type: type,
237
- time: new Date().toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'})
238
  });
239
  save();
240
  document.getElementById('msg-input').value = '';
@@ -243,19 +254,20 @@
243
 
244
  function renderMessages() {
245
  const box = document.getElementById('chat-box');
246
- const roomMsgs = db.messages.filter(m => m.room === activeRoomCode);
 
247
 
248
- // Show Admin button only if Host
249
  if(activeRoomCode !== 'Public' && db.rooms[activeRoomCode].host === currentUser) {
250
- document.getElementById('host-admin-btn').classList.remove('hidden');
251
  } else {
252
- document.getElementById('host-admin-btn').classList.add('hidden');
253
  }
254
 
255
- box.innerHTML = roomMsgs.map(m => `
256
  <div class="msg">
257
- <div style="font-size:0.5rem; color:#888;">${m.sender} • ${m.time}</div>
258
- <div>${m.type === 'img' ? `<img src="${m.content}" style="max-width:100%;">` : m.content}</div>
259
  <button class="del-btn" onclick="deleteMsg(${m.id}, 'me')">Delete for me</button>
260
  ${m.sender === currentUser ? `<button class="del-btn" style="background:orange" onclick="deleteMsg(${m.id}, 'everyone')">Delete for everyone</button>` : ''}
261
  </div>
@@ -267,7 +279,7 @@
267
  if(mode === 'everyone') {
268
  db.messages = db.messages.filter(m => m.id !== id);
269
  } else {
270
- // Locally remove it from view for this session
271
  db.messages = db.messages.filter(m => m.id !== id);
272
  }
273
  save();
 
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <title>AeroCore OS v2.2</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.9);
12
  }
13
 
14
  body {
15
  background: linear-gradient(135deg, #3a7bd5, #00d2ff, #3affaa);
16
+ background-size: 400% 400%;
17
+ animation: gradientBG 15s ease infinite;
18
  font-family: 'GameStart', sans-serif;
19
  margin: 0; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden;
20
  }
21
 
22
+ @keyframes gradientBG { 0% {background-position: 0% 50%;} 50% {background-position: 100% 50%;} 100% {background-position: 0% 50%;} }
23
+
24
+ /* The Mosaic Filter Overlay */
25
+ .mosaic-layer {
26
+ position: fixed; top: 0; left: 0; width: 100%; height: 100%;
27
+ background-image: radial-gradient(rgba(255,255,255,0.2) 1.5px, transparent 1.5px);
28
+ background-size: 6px 6px; pointer-events: none; z-index: 5;
29
  }
30
 
31
  .window {
32
  width: 750px; height: 550px; background: var(--mosaic-glass);
33
+ border: 6px solid #fff; border-radius: 4px;
34
+ box-shadow: 15px 15px 0px rgba(0,0,0,0.1);
35
  position: relative; z-index: 20; display: flex; flex-direction: column;
36
  }
37
 
38
+ .screen { display: none; padding: 25px; flex-direction: column; height: 100%; box-sizing: border-box; }
39
  .active { display: flex; }
40
 
41
+ /* Aero Buttons & Inputs */
42
  button {
43
+ font-family: 'GameStart', sans-serif; padding: 12px; margin: 5px 0;
44
+ background: linear-gradient(to bottom, #ffffff 0%, #aadaff 40%, #0080ff 100%);
45
  border: 2px solid #fff; color: white; text-shadow: 1px 1px 2px #000;
46
+ cursor: pointer; box-shadow: 3px 3px 0px #0055aa; transition: 0.1s;
47
  }
48
+ button:active { transform: translate(2px, 2px); box-shadow: 0px 0px; }
49
 
50
  input {
51
  font-family: 'GameStart', sans-serif; padding: 12px; margin-bottom: 10px;
52
+ border: 3px inset #fff; background: rgba(255,255,255,0.9); width: 100%; box-sizing: border-box;
53
  }
54
 
55
+ #chat-box { background: white; border: 4px inset #eee; flex-grow: 1; overflow-y: auto; padding: 15px; margin-bottom: 10px; }
56
 
57
+ .msg { background: #e6f7ff; border-left: 6px solid var(--aero-blue); padding: 10px; margin-bottom: 10px; position: relative; }
58
+ .msg-info { font-size: 0.5rem; color: #555; margin-bottom: 4px; }
59
+ .del-btn { font-size: 0.5rem; background: #ff4d4d; border: 1px solid white; cursor: pointer; padding: 4px; margin-top: 5px;}
60
+
61
+ /* Version Popup Modal */
62
+ #modal-overlay {
63
+ position: fixed; top: 0; left: 0; width: 100%; height: 100%;
64
+ background: rgba(0,0,0,0.4); z-index: 1000;
65
+ display: none; justify-content: center; align-items: center;
66
  }
67
+
68
+ .modal {
69
+ background: white; border: 5px solid var(--aero-green);
70
+ padding: 30px; text-align: center; width: 400px;
71
+ box-shadow: 0 0 40px rgba(0,0,0,0.3);
72
+ }
73
+
74
+ .hidden { display: none !important; }
75
  </style>
76
  </head>
77
  <body>
78
 
79
+ <div class="mosaic-layer"></div>
80
+
81
+ <div id="modal-overlay">
82
+ <div class="modal">
83
+ <h3>AeroCore v2.0</h3>
84
+ <p>Built: 20th February 2026</p>
85
+ <button onclick="closePopup()" style="background: var(--aero-green); width: 100%;">EXIT & START</button>
86
+ </div>
87
+ </div>
88
+
89
  <div class="window">
90
  <div id="screen-auth" class="screen active">
91
  <h2>AEROCORE ACCESS</h2>
92
+ <form id="login-form" onsubmit="handleAuth(event, 'login')">
93
  <input type="text" id="username" name="username" placeholder="USERNAME" required autocomplete="username">
94
  <input type="password" id="password" name="password" placeholder="PASSWORD" required autocomplete="current-password"
95
  style="-webkit-text-security: none !important;">
96
+ <button type="submit">LOG IN</button>
97
+ <button type="button" onclick="handleAuth(event, 'signup')" style="background: #888;">SIGN UP</button>
 
 
98
  </form>
99
  </div>
100
 
101
  <div id="screen-tutorial" class="screen">
102
  <h2>SYSTEM TUTORIAL</h2>
103
+ <ul style="font-size: 0.8rem; line-height: 1.6;">
104
+ <li><b>HOST:</b> Create a Room Share Code Approve Members.</li>
105
+ <li><b>CLIENT:</b> Enter Code Wait for Approval.</li>
106
+ <li><b>DELETE:</b> 'For Me' (Local) / 'Everyone' (Global).</li>
107
+ </ul>
108
+ <button onclick="nav('screen-lobby')">ENTER CHATROOMS</button>
109
  </div>
110
 
111
  <div id="screen-lobby" class="screen">
112
  <h2>COMMUNITY HUB</h2>
113
+ <p id="welcome-msg" style="color: var(--aero-blue);"></p>
114
  <button onclick="joinRoom('Public')">JOIN PUBLIC SERVER</button>
115
+ <hr style="border: 1px solid #fff; width: 100%;">
116
  <button onclick="createPrivate()">HOST PRIVATE ROOM</button>
117
+ <div id="host-code-display" style="color: #0055aa; font-weight: bold;"></div>
118
  <br>
119
  <input type="text" id="join-code-input" placeholder="ENTER ROOM CODE">
120
  <button onclick="joinRoom('Private')">REQUEST ENTRY</button>
121
  </div>
122
 
123
  <div id="screen-chat" class="screen">
124
+ <div style="display:flex; justify-content: space-between; align-items: center;">
125
+ <h2 id="room-header" style="font-size: 0.9rem;">CHAT</h2>
126
+ <button id="admin-btn" class="hidden" onclick="nav('screen-approval')" style="font-size: 0.6rem; padding: 5px;">ADMIN</button>
127
  </div>
128
  <div id="chat-box"></div>
129
  <input type="text" id="msg-input" placeholder="Message or URL...">
130
  <div style="display:flex; gap: 5px;">
131
+ <button onclick="sendMsg('text')" style="flex: 1;">SEND</button>
132
  <button onclick="sendMsg('img')" style="background:var(--aero-blue)">IMG</button>
133
+ <button onclick="nav('screen-lobby')" style="background:#cc0000">EXIT</button>
134
  </div>
135
  </div>
136
 
137
  <div id="screen-approval" class="screen">
138
+ <h2>PENDING MEMBERS</h2>
139
  <div id="approval-list"></div>
140
  <button onclick="nav('screen-chat')">BACK TO CHAT</button>
141
  </div>
142
  </div>
143
 
 
 
 
 
 
 
144
  <script>
145
+ // --- DATABASE ---
146
+ let db = JSON.parse(localStorage.getItem('aero_v2_data')) || {
147
+ users: [], messages: [], rooms: {}
 
 
148
  };
149
  let currentUser = null;
150
  let activeRoomCode = 'Public';
151
 
152
+ function save() { localStorage.setItem('aero_v2_data', JSON.stringify(db)); }
153
+
154
+ // --- NAVIGATION ---
155
+ function nav(id) {
156
+ document.querySelectorAll('.screen').forEach(s => s.classList.remove('active'));
157
+ document.getElementById(id).classList.add('active');
158
+ if(id === 'screen-chat') renderMessages();
159
+ if(id === 'screen-approval') renderApprovalList();
160
+ }
161
 
162
+ // --- AUTHENTICATION ---
163
+ function handleAuth(event, mode) {
164
+ event.preventDefault();
165
  const u = document.getElementById('username').value;
166
  const p = document.getElementById('password').value;
 
167
 
168
+ if(!u || !p) return;
169
+
170
+ const user = db.users.find(x => x.username === u);
171
 
172
  if(mode === 'signup') {
173
+ if(user) return alert("User exists! Try Login.");
174
+ db.users.push({username: u, password: p});
175
  save();
176
+ alert("Account created! Now Log In.");
177
  } else {
178
+ if(!user || user.password !== p) return alert("Incorrect Username or Password!");
 
 
 
 
179
  currentUser = u;
180
+ document.getElementById('welcome-msg').innerText = "Logged in as: " + u;
181
+ document.getElementById('modal-overlay').style.display = 'flex'; // Show Version Popup
182
  }
183
  }
184
 
185
  function closePopup() {
186
+ document.getElementById('modal-overlay').style.display = 'none';
187
  nav('screen-tutorial');
188
  }
189
 
190
+ // --- ROOMS ---
 
 
 
 
 
 
 
 
191
  function createPrivate() {
192
  const code = Math.floor(1000 + Math.random() * 9000).toString();
193
  db.rooms[code] = { host: currentUser, members: [currentUser], pending: [] };
194
+ document.getElementById('host-code-display').innerText = "ROOM CODE: " + code;
195
  activeRoomCode = code;
196
  save();
 
197
  }
198
 
199
  function joinRoom(type) {
 
202
  nav('screen-chat');
203
  } else {
204
  const code = document.getElementById('join-code-input').value;
 
 
 
 
 
205
  const room = db.rooms[code];
206
+ if(!room) return alert("Room Not Found! Use the code from the other phone.");
207
+
208
+ activeRoomCode = code;
209
  if(room.members.includes(currentUser)) {
210
  nav('screen-chat');
211
  } else {
 
213
  room.pending.push(currentUser);
214
  save();
215
  }
216
+ alert("Request sent. Tell the Host to approve you on their screen!");
217
  }
218
  }
219
  }
 
222
  const list = document.getElementById('approval-list');
223
  const room = db.rooms[activeRoomCode];
224
  list.innerHTML = room.pending.map(u => `
225
+ <div style="background:#fff; padding:10px; margin-bottom:5px; border:2px solid var(--aero-blue);">
226
+ ${u} <button onclick="approveUser('${u}')">APPROVE</button>
227
  </div>
228
+ `).join('') || "No requests.";
229
  }
230
 
231
  function approveUser(u) {
232
  db.rooms[activeRoomCode].members.push(u);
233
+ db.rooms[activeRoomCode].pending = db.rooms[activeRoomCode].pending.filter(x => x !== u);
234
  save();
235
  renderApprovalList();
236
  }
237
 
238
+ // --- CHAT & DELETE ---
239
  function sendMsg(type) {
240
  const val = document.getElementById('msg-input').value;
241
  if(!val) return;
 
245
  sender: currentUser,
246
  content: val,
247
  type: type,
248
+ time: new Date().toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'})
249
  });
250
  save();
251
  document.getElementById('msg-input').value = '';
 
254
 
255
  function renderMessages() {
256
  const box = document.getElementById('chat-box');
257
+ const msgs = db.messages.filter(m => m.room === activeRoomCode);
258
+ document.getElementById('room-header').innerText = `ROOM: ${activeRoomCode}`;
259
 
260
+ // Show Admin btn if Host
261
  if(activeRoomCode !== 'Public' && db.rooms[activeRoomCode].host === currentUser) {
262
+ document.getElementById('admin-btn').classList.remove('hidden');
263
  } else {
264
+ document.getElementById('admin-btn').classList.add('hidden');
265
  }
266
 
267
+ box.innerHTML = msgs.map(m => `
268
  <div class="msg">
269
+ <div class="msg-info">${m.sender} • ${m.time}</div>
270
+ <div>${m.type === 'img' ? `<img src="${m.content}" style="max-width:100px;">` : m.content}</div>
271
  <button class="del-btn" onclick="deleteMsg(${m.id}, 'me')">Delete for me</button>
272
  ${m.sender === currentUser ? `<button class="del-btn" style="background:orange" onclick="deleteMsg(${m.id}, 'everyone')">Delete for everyone</button>` : ''}
273
  </div>
 
279
  if(mode === 'everyone') {
280
  db.messages = db.messages.filter(m => m.id !== id);
281
  } else {
282
+ // Local-only delete (for demo purposes it filters from array)
283
  db.messages = db.messages.filter(m => m.id !== id);
284
  }
285
  save();