shell-mirror 1.5.75 → 1.5.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/public/app/terminal.html +205 -99
- package/public/app/terminal.js +94 -24
package/package.json
CHANGED
package/public/app/terminal.html
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
4
6
|
<title>Terminal Mirror</title>
|
|
5
7
|
|
|
6
8
|
<!-- Google Analytics 4 -->
|
|
@@ -74,7 +76,7 @@
|
|
|
74
76
|
flex-direction: column;
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
/* Session Header */
|
|
79
|
+
/* Session Header - Unified Design */
|
|
78
80
|
.session-header {
|
|
79
81
|
background: #2a2a2a;
|
|
80
82
|
color: #ccc;
|
|
@@ -85,64 +87,157 @@
|
|
|
85
87
|
justify-content: space-between;
|
|
86
88
|
font-size: 0.9em;
|
|
87
89
|
z-index: 100;
|
|
90
|
+
height: 40px;
|
|
88
91
|
}
|
|
89
|
-
|
|
90
|
-
.
|
|
92
|
+
|
|
93
|
+
.header-left {
|
|
91
94
|
display: flex;
|
|
92
95
|
align-items: center;
|
|
93
|
-
gap:
|
|
96
|
+
gap: 10px;
|
|
97
|
+
position: relative;
|
|
94
98
|
}
|
|
95
|
-
|
|
96
|
-
.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
|
|
100
|
+
.header-center {
|
|
101
|
+
flex: 1;
|
|
102
|
+
display: flex;
|
|
103
|
+
justify-content: center;
|
|
99
104
|
}
|
|
100
|
-
|
|
101
|
-
.
|
|
105
|
+
|
|
106
|
+
.header-right {
|
|
102
107
|
display: flex;
|
|
103
108
|
align-items: center;
|
|
104
109
|
gap: 8px;
|
|
105
110
|
}
|
|
106
|
-
|
|
111
|
+
|
|
112
|
+
/* Session Info Button */
|
|
113
|
+
.session-info-btn {
|
|
114
|
+
background: transparent;
|
|
115
|
+
border: 1px solid #444;
|
|
116
|
+
color: #ccc;
|
|
117
|
+
padding: 4px 12px;
|
|
118
|
+
border-radius: 4px;
|
|
119
|
+
cursor: pointer;
|
|
120
|
+
display: flex;
|
|
121
|
+
align-items: center;
|
|
122
|
+
gap: 8px;
|
|
123
|
+
font-size: 0.9em;
|
|
124
|
+
transition: all 0.2s ease;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.session-info-btn:hover {
|
|
128
|
+
background: #3a3a3a;
|
|
129
|
+
border-color: #667eea;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.session-name {
|
|
133
|
+
font-weight: bold;
|
|
134
|
+
color: #fff;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.session-id {
|
|
138
|
+
color: #999;
|
|
139
|
+
font-size: 0.85em;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.dropdown-arrow {
|
|
143
|
+
color: #888;
|
|
144
|
+
font-size: 0.7em;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* Session Info Dropdown */
|
|
148
|
+
.session-info-dropdown {
|
|
149
|
+
display: none;
|
|
150
|
+
position: absolute;
|
|
151
|
+
top: 100%;
|
|
152
|
+
left: 0;
|
|
153
|
+
margin-top: 8px;
|
|
154
|
+
background: #2a2a2a;
|
|
155
|
+
border: 1px solid #555;
|
|
156
|
+
border-radius: 4px;
|
|
157
|
+
min-width: 280px;
|
|
158
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.5);
|
|
159
|
+
z-index: 1000;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.session-info-dropdown.show {
|
|
163
|
+
display: block;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.dropdown-section {
|
|
167
|
+
padding: 12px 16px;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.dropdown-divider {
|
|
171
|
+
height: 1px;
|
|
172
|
+
background: #444;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.session-detail-name {
|
|
176
|
+
font-weight: bold;
|
|
177
|
+
color: #fff;
|
|
178
|
+
margin-bottom: 4px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.session-detail-id {
|
|
182
|
+
color: #999;
|
|
183
|
+
font-size: 0.85em;
|
|
184
|
+
font-family: monospace;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.connection-detail {
|
|
188
|
+
color: #ccc;
|
|
189
|
+
font-size: 0.9em;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.version-info {
|
|
193
|
+
color: #888;
|
|
194
|
+
font-size: 0.85em;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* Sessions Dropdown */
|
|
107
198
|
.session-dropdown {
|
|
108
199
|
position: relative;
|
|
109
200
|
display: inline-block;
|
|
110
201
|
}
|
|
111
|
-
|
|
202
|
+
|
|
112
203
|
.session-dropdown-btn {
|
|
113
|
-
background:
|
|
204
|
+
background: transparent;
|
|
114
205
|
color: #ccc;
|
|
115
|
-
border: 1px solid #
|
|
116
|
-
padding: 4px
|
|
206
|
+
border: 1px solid #444;
|
|
207
|
+
padding: 4px 12px;
|
|
117
208
|
border-radius: 4px;
|
|
118
209
|
cursor: pointer;
|
|
119
|
-
font-size: 0.
|
|
210
|
+
font-size: 0.9em;
|
|
120
211
|
display: flex;
|
|
121
212
|
align-items: center;
|
|
122
213
|
gap: 4px;
|
|
214
|
+
transition: all 0.2s ease;
|
|
123
215
|
}
|
|
124
|
-
|
|
216
|
+
|
|
125
217
|
.session-dropdown-btn:hover {
|
|
126
|
-
background: #
|
|
218
|
+
background: #3a3a3a;
|
|
219
|
+
border-color: #667eea;
|
|
127
220
|
}
|
|
128
|
-
|
|
221
|
+
|
|
129
222
|
.session-dropdown-content {
|
|
130
223
|
display: none;
|
|
131
224
|
position: absolute;
|
|
132
225
|
background: #2a2a2a;
|
|
133
226
|
border: 1px solid #555;
|
|
134
227
|
border-radius: 4px;
|
|
135
|
-
|
|
228
|
+
left: 50%;
|
|
229
|
+
transform: translateX(-50%);
|
|
136
230
|
top: 100%;
|
|
231
|
+
margin-top: 8px;
|
|
137
232
|
min-width: 200px;
|
|
138
233
|
z-index: 1000;
|
|
139
234
|
box-shadow: 0 4px 8px rgba(0,0,0,0.3);
|
|
140
235
|
}
|
|
141
|
-
|
|
236
|
+
|
|
142
237
|
.session-dropdown-content.show {
|
|
143
238
|
display: block;
|
|
144
239
|
}
|
|
145
|
-
|
|
240
|
+
|
|
146
241
|
.session-dropdown-item {
|
|
147
242
|
padding: 8px 12px;
|
|
148
243
|
cursor: pointer;
|
|
@@ -151,82 +246,79 @@
|
|
|
151
246
|
justify-content: space-between;
|
|
152
247
|
align-items: center;
|
|
153
248
|
}
|
|
154
|
-
|
|
249
|
+
|
|
155
250
|
.session-dropdown-item:last-child {
|
|
156
251
|
border-bottom: none;
|
|
157
252
|
}
|
|
158
|
-
|
|
253
|
+
|
|
159
254
|
.session-dropdown-item:hover {
|
|
160
255
|
background: #3a3a3a;
|
|
161
256
|
}
|
|
162
|
-
|
|
257
|
+
|
|
163
258
|
.session-dropdown-item.current {
|
|
164
259
|
background: #4285f4;
|
|
165
260
|
color: white;
|
|
166
261
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
background
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
#connect-container { padding: 2em; text-align: center; }
|
|
176
|
-
#agent-id-input { font-size: 1.2em; padding: 8px; width: 400px; margin-bottom: 1em; }
|
|
177
|
-
#connect-btn { font-size: 1.2em; padding: 10px 20px; }
|
|
178
|
-
|
|
179
|
-
/* How to Use Button */
|
|
180
|
-
.how-to-use-btn {
|
|
181
|
-
position: fixed;
|
|
182
|
-
top: 20px;
|
|
183
|
-
left: 170px;
|
|
184
|
-
background: rgba(102, 126, 234, 0.9);
|
|
185
|
-
color: white;
|
|
186
|
-
border: none;
|
|
187
|
-
border-radius: 8px;
|
|
188
|
-
padding: 10px 16px;
|
|
262
|
+
|
|
263
|
+
/* Header Buttons */
|
|
264
|
+
.header-btn {
|
|
265
|
+
background: transparent;
|
|
266
|
+
border: 1px solid #444;
|
|
267
|
+
color: #ccc;
|
|
268
|
+
padding: 6px 12px;
|
|
269
|
+
border-radius: 4px;
|
|
189
270
|
cursor: pointer;
|
|
190
|
-
font-size: 0.9em;
|
|
191
|
-
font-weight: 500;
|
|
192
271
|
display: flex;
|
|
193
272
|
align-items: center;
|
|
194
273
|
gap: 6px;
|
|
195
|
-
|
|
196
|
-
|
|
274
|
+
font-size: 0.9em;
|
|
275
|
+
text-decoration: none;
|
|
197
276
|
transition: all 0.2s ease;
|
|
198
277
|
}
|
|
199
278
|
|
|
200
|
-
.
|
|
201
|
-
background:
|
|
202
|
-
|
|
279
|
+
.header-btn:hover {
|
|
280
|
+
background: #3a3a3a;
|
|
281
|
+
border-color: #667eea;
|
|
203
282
|
}
|
|
204
283
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
position: fixed;
|
|
208
|
-
top: 20px;
|
|
209
|
-
right: 20px;
|
|
210
|
-
background: rgba(66, 133, 244, 0.9);
|
|
211
|
-
color: white;
|
|
212
|
-
border: none;
|
|
213
|
-
padding: 12px 20px;
|
|
214
|
-
border-radius: 8px;
|
|
215
|
-
font-weight: 500;
|
|
216
|
-
cursor: pointer;
|
|
217
|
-
z-index: 1000;
|
|
218
|
-
transition: all 0.2s ease;
|
|
219
|
-
display: flex;
|
|
220
|
-
align-items: center;
|
|
221
|
-
gap: 8px;
|
|
222
|
-
text-decoration: none;
|
|
284
|
+
.help-btn .btn-text {
|
|
285
|
+
display: none;
|
|
223
286
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
287
|
+
|
|
288
|
+
@media (min-width: 768px) {
|
|
289
|
+
.help-btn .btn-text {
|
|
290
|
+
display: inline;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/* Dashboard button with status dot */
|
|
295
|
+
.dashboard-btn {
|
|
296
|
+
position: relative;
|
|
228
297
|
}
|
|
229
298
|
|
|
299
|
+
.dashboard-btn::before {
|
|
300
|
+
content: '';
|
|
301
|
+
position: absolute;
|
|
302
|
+
top: 4px;
|
|
303
|
+
right: 4px;
|
|
304
|
+
width: 8px;
|
|
305
|
+
height: 8px;
|
|
306
|
+
border-radius: 50%;
|
|
307
|
+
background: #44ff44;
|
|
308
|
+
box-shadow: 0 0 8px rgba(68, 255, 68, 0.5);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
#terminal {
|
|
312
|
+
padding: 8px; /* Mac Terminal.app padding */
|
|
313
|
+
background-color: #000000;
|
|
314
|
+
height: calc(100% - 16px - 40px); /* Subtract session header height */
|
|
315
|
+
width: calc(100% - 16px);
|
|
316
|
+
flex: 1;
|
|
317
|
+
}
|
|
318
|
+
#connect-container { padding: 2em; text-align: center; }
|
|
319
|
+
#agent-id-input { font-size: 1.2em; padding: 8px; width: 400px; margin-bottom: 1em; }
|
|
320
|
+
#connect-btn { font-size: 1.2em; padding: 10px 20px; }
|
|
321
|
+
|
|
230
322
|
/* Connection Status Indicator */
|
|
231
323
|
.connection-status {
|
|
232
324
|
width: 8px;
|
|
@@ -254,29 +346,40 @@
|
|
|
254
346
|
</style>
|
|
255
347
|
</head>
|
|
256
348
|
<body>
|
|
257
|
-
<!-- Back to Dashboard Button -->
|
|
258
|
-
<a href="/app/dashboard.html" class="back-to-dashboard" id="dashboard-btn">
|
|
259
|
-
<div class="connection-status" id="connection-status"></div>
|
|
260
|
-
<span>←</span>
|
|
261
|
-
<span>Dashboard</span>
|
|
262
|
-
</a>
|
|
263
|
-
|
|
264
|
-
<!-- How to Use Button -->
|
|
265
|
-
<button class="how-to-use-btn" id="how-to-use-btn" onclick="showHelpModal()">
|
|
266
|
-
📖 How to Use
|
|
267
|
-
</button>
|
|
268
|
-
|
|
269
349
|
<div id="connect-container">
|
|
270
350
|
<h2>Terminal Mirror</h2>
|
|
271
351
|
<p>Connecting to terminal...</p>
|
|
272
352
|
</div>
|
|
273
353
|
<div id="terminal-container">
|
|
274
354
|
<div class="session-header" id="session-header" style="display: none;">
|
|
275
|
-
<div class="
|
|
276
|
-
<
|
|
277
|
-
<
|
|
355
|
+
<div class="header-left">
|
|
356
|
+
<div class="connection-status" id="connection-status"></div>
|
|
357
|
+
<button class="session-info-btn" id="session-info-btn">
|
|
358
|
+
<span class="session-name" id="session-name">Terminal Session</span>
|
|
359
|
+
<span class="session-id" id="session-id"></span>
|
|
360
|
+
<span class="dropdown-arrow">▼</span>
|
|
361
|
+
</button>
|
|
362
|
+
|
|
363
|
+
<!-- Session Info Dropdown -->
|
|
364
|
+
<div class="session-info-dropdown" id="session-info-dropdown">
|
|
365
|
+
<div class="dropdown-section">
|
|
366
|
+
<div class="session-detail-name" id="detail-name">Session 1</div>
|
|
367
|
+
<div class="session-detail-id" id="detail-id">ses_1764...</div>
|
|
368
|
+
</div>
|
|
369
|
+
<div class="dropdown-divider"></div>
|
|
370
|
+
<div class="dropdown-section">
|
|
371
|
+
<div class="connection-detail" id="connection-detail">
|
|
372
|
+
🟢 Connected via WebRTC
|
|
373
|
+
</div>
|
|
374
|
+
</div>
|
|
375
|
+
<div class="dropdown-divider"></div>
|
|
376
|
+
<div class="dropdown-section version-info">
|
|
377
|
+
<div id="version-info-dropdown">v1.5.76 • Built Nov 26, 2025</div>
|
|
378
|
+
</div>
|
|
379
|
+
</div>
|
|
278
380
|
</div>
|
|
279
|
-
|
|
381
|
+
|
|
382
|
+
<div class="header-center">
|
|
280
383
|
<div class="session-dropdown">
|
|
281
384
|
<button class="session-dropdown-btn" id="session-dropdown-btn">
|
|
282
385
|
<span>Sessions</span>
|
|
@@ -289,6 +392,16 @@
|
|
|
289
392
|
</div>
|
|
290
393
|
</div>
|
|
291
394
|
</div>
|
|
395
|
+
|
|
396
|
+
<div class="header-right">
|
|
397
|
+
<button class="header-btn help-btn" onclick="showHelpModal()">
|
|
398
|
+
<span>📖</span>
|
|
399
|
+
<span class="btn-text">Help</span>
|
|
400
|
+
</button>
|
|
401
|
+
<a href="/app/dashboard.html" class="header-btn dashboard-btn">
|
|
402
|
+
<span>📊</span>
|
|
403
|
+
</a>
|
|
404
|
+
</div>
|
|
292
405
|
</div>
|
|
293
406
|
<div id="terminal"></div>
|
|
294
407
|
</div>
|
|
@@ -338,13 +451,6 @@
|
|
|
338
451
|
</div>
|
|
339
452
|
</div>
|
|
340
453
|
|
|
341
|
-
<!-- Version Footer -->
|
|
342
|
-
<footer style="background: #ff6b35; color: white; text-align: center; padding: 10px 0; font-size: 0.8rem; position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000;">
|
|
343
|
-
<div style="max-width: 1200px; margin: 0 auto;">
|
|
344
|
-
<p id="terminal-version-info">Terminal Mirror • Loading version...</p>
|
|
345
|
-
</div>
|
|
346
|
-
</footer>
|
|
347
|
-
|
|
348
454
|
<script>
|
|
349
455
|
// Help Modal Functions
|
|
350
456
|
function showHelpModal() {
|
package/public/app/terminal.js
CHANGED
|
@@ -155,7 +155,7 @@ const chunkAssembler = {
|
|
|
155
155
|
function updateConnectionStatus(status) {
|
|
156
156
|
const statusElement = document.getElementById('connection-status');
|
|
157
157
|
if (!statusElement) return;
|
|
158
|
-
|
|
158
|
+
|
|
159
159
|
statusElement.className = 'connection-status';
|
|
160
160
|
switch(status) {
|
|
161
161
|
case 'connecting':
|
|
@@ -169,6 +169,9 @@ function updateConnectionStatus(status) {
|
|
|
169
169
|
// Default red styling already applied
|
|
170
170
|
break;
|
|
171
171
|
}
|
|
172
|
+
|
|
173
|
+
// Update connection detail in dropdown
|
|
174
|
+
updateConnectionDetail(status);
|
|
172
175
|
}
|
|
173
176
|
|
|
174
177
|
// Cleanup timer for chunk assembler
|
|
@@ -217,27 +220,63 @@ window.addEventListener('load', () => {
|
|
|
217
220
|
}
|
|
218
221
|
});
|
|
219
222
|
|
|
220
|
-
// Load version info
|
|
223
|
+
// Load version info into dropdown
|
|
221
224
|
async function loadVersionInfo() {
|
|
222
225
|
try {
|
|
223
226
|
const response = await fetch('/build-info.json');
|
|
224
227
|
const buildInfo = await response.json();
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
228
|
+
|
|
229
|
+
if (buildInfo) {
|
|
230
|
+
const buildDateTime = new Date(buildInfo.buildTime).toLocaleString('en-US', {
|
|
231
|
+
month: 'short',
|
|
232
|
+
day: 'numeric',
|
|
233
|
+
year: 'numeric',
|
|
234
|
+
hour: '2-digit',
|
|
235
|
+
minute: '2-digit'
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
const versionElement = document.getElementById('version-info-dropdown');
|
|
239
|
+
if (versionElement) {
|
|
240
|
+
versionElement.textContent = `v${buildInfo.version} • Built ${buildDateTime}`;
|
|
236
241
|
}
|
|
237
242
|
}
|
|
238
243
|
} catch (error) {
|
|
239
244
|
console.log('Could not load build info for terminal:', error);
|
|
240
|
-
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Update connection detail in dropdown
|
|
249
|
+
function updateConnectionDetail(status, method = 'WebRTC') {
|
|
250
|
+
const detail = document.getElementById('connection-detail');
|
|
251
|
+
if (!detail) return;
|
|
252
|
+
|
|
253
|
+
const statusIcons = {
|
|
254
|
+
connected: '🟢',
|
|
255
|
+
connecting: '🟡',
|
|
256
|
+
disconnected: '🔴'
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const statusTexts = {
|
|
260
|
+
connected: 'Connected',
|
|
261
|
+
connecting: 'Connecting',
|
|
262
|
+
disconnected: 'Disconnected'
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
detail.textContent = `${statusIcons[status] || '⚪'} ${statusTexts[status] || 'Unknown'} via ${method}`;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Update session details in dropdown
|
|
269
|
+
function updateSessionDetails() {
|
|
270
|
+
if (currentSession) {
|
|
271
|
+
const detailName = document.getElementById('detail-name');
|
|
272
|
+
const detailId = document.getElementById('detail-id');
|
|
273
|
+
|
|
274
|
+
if (detailName) {
|
|
275
|
+
detailName.textContent = currentSession.name || 'Terminal Session';
|
|
276
|
+
}
|
|
277
|
+
if (detailId) {
|
|
278
|
+
detailId.textContent = `ID: ${currentSession.id}`;
|
|
279
|
+
}
|
|
241
280
|
}
|
|
242
281
|
}
|
|
243
282
|
|
|
@@ -262,6 +301,7 @@ function startConnection() {
|
|
|
262
301
|
// Delay fit to ensure proper dimensions after CSS transitions
|
|
263
302
|
setTimeout(() => {
|
|
264
303
|
fitAddon.fit();
|
|
304
|
+
term.focus(); // Ensure cursor is visible even before connection
|
|
265
305
|
}, 100);
|
|
266
306
|
initialize();
|
|
267
307
|
}
|
|
@@ -919,15 +959,18 @@ function updateSessionDisplay() {
|
|
|
919
959
|
const sessionHeader = document.getElementById('session-header');
|
|
920
960
|
const sessionName = document.getElementById('session-name');
|
|
921
961
|
const sessionId = document.getElementById('session-id');
|
|
922
|
-
|
|
962
|
+
|
|
923
963
|
if (currentSession) {
|
|
924
964
|
sessionHeader.style.display = 'flex';
|
|
925
965
|
sessionName.textContent = currentSession.name;
|
|
926
966
|
sessionId.textContent = `(${currentSession.id.substring(0, 8)}...)`;
|
|
927
|
-
|
|
967
|
+
|
|
928
968
|
// Update available sessions dropdown
|
|
929
969
|
updateSessionDropdown();
|
|
930
|
-
|
|
970
|
+
|
|
971
|
+
// Update session details in dropdown
|
|
972
|
+
updateSessionDetails();
|
|
973
|
+
|
|
931
974
|
console.log('[CLIENT] 📋 Session display updated:', currentSession);
|
|
932
975
|
}
|
|
933
976
|
}
|
|
@@ -997,22 +1040,49 @@ function createNewSession() {
|
|
|
997
1040
|
window.location.href = url.toString();
|
|
998
1041
|
}
|
|
999
1042
|
|
|
1000
|
-
// Setup dropdown
|
|
1043
|
+
// Setup dropdown toggles
|
|
1001
1044
|
document.addEventListener('DOMContentLoaded', () => {
|
|
1045
|
+
// Session info dropdown
|
|
1046
|
+
const sessionInfoBtn = document.getElementById('session-info-btn');
|
|
1047
|
+
const sessionInfoDropdown = document.getElementById('session-info-dropdown');
|
|
1048
|
+
|
|
1049
|
+
// Sessions menu dropdown
|
|
1002
1050
|
const dropdownBtn = document.getElementById('session-dropdown-btn');
|
|
1003
1051
|
const dropdownContent = document.getElementById('session-dropdown-content');
|
|
1004
|
-
|
|
1052
|
+
|
|
1053
|
+
// Session info dropdown toggle
|
|
1054
|
+
if (sessionInfoBtn && sessionInfoDropdown) {
|
|
1055
|
+
sessionInfoBtn.onclick = (e) => {
|
|
1056
|
+
e.stopPropagation();
|
|
1057
|
+
sessionInfoDropdown.classList.toggle('show');
|
|
1058
|
+
// Close sessions dropdown if open
|
|
1059
|
+
if (dropdownContent) {
|
|
1060
|
+
dropdownContent.classList.remove('show');
|
|
1061
|
+
}
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
// Sessions menu dropdown toggle
|
|
1005
1066
|
if (dropdownBtn && dropdownContent) {
|
|
1006
1067
|
dropdownBtn.onclick = (e) => {
|
|
1007
1068
|
e.stopPropagation();
|
|
1008
1069
|
dropdownContent.classList.toggle('show');
|
|
1070
|
+
// Close session info dropdown if open
|
|
1071
|
+
if (sessionInfoDropdown) {
|
|
1072
|
+
sessionInfoDropdown.classList.remove('show');
|
|
1073
|
+
}
|
|
1009
1074
|
};
|
|
1010
|
-
|
|
1011
|
-
// Close dropdown when clicking outside
|
|
1012
|
-
document.addEventListener('click', () => {
|
|
1013
|
-
dropdownContent.classList.remove('show');
|
|
1014
|
-
});
|
|
1015
1075
|
}
|
|
1076
|
+
|
|
1077
|
+
// Close both dropdowns when clicking outside
|
|
1078
|
+
document.addEventListener('click', () => {
|
|
1079
|
+
if (dropdownContent) {
|
|
1080
|
+
dropdownContent.classList.remove('show');
|
|
1081
|
+
}
|
|
1082
|
+
if (sessionInfoDropdown) {
|
|
1083
|
+
sessionInfoDropdown.classList.remove('show');
|
|
1084
|
+
}
|
|
1085
|
+
});
|
|
1016
1086
|
});
|
|
1017
1087
|
|
|
1018
1088
|
// Handle session-related data channel messages
|