pinokiod 3.250.0 → 3.252.0
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/kernel/peer.js +175 -22
- package/package.json +1 -1
- package/server/index.js +113 -50
- package/server/public/style.css +4 -0
- package/server/public/tab-link-popover.js +264 -28
- package/server/views/agents.ejs +2 -10
- package/server/views/app.ejs +3 -3
- package/server/views/connect.ejs +1 -9
- package/server/views/index.ejs +132 -32
- package/server/views/init/index.ejs +1 -9
- package/server/views/net.ejs +72 -11
- package/server/views/network.ejs +2 -10
- package/server/views/partials/peer_access_points.ejs +27 -0
- package/server/views/review.ejs +3 -3
- package/server/views/screenshots.ejs +1 -9
- package/server/views/settings.ejs +1 -9
- package/server/views/shell.ejs +3 -0
- package/server/views/terminal.ejs +3 -0
- package/server/views/tools.ejs +1 -9
package/server/views/index.ejs
CHANGED
|
@@ -162,16 +162,26 @@ body.dark .context-menu-wrapper {
|
|
|
162
162
|
color: white;
|
|
163
163
|
}
|
|
164
164
|
.context-menu-wrapper {
|
|
165
|
-
background:
|
|
165
|
+
background: whitesmoke !important;
|
|
166
|
+
border-radius: 10px;
|
|
167
|
+
overflow: hidden;
|
|
168
|
+
}
|
|
169
|
+
.menu-btns {
|
|
170
|
+
position: relative;
|
|
166
171
|
}
|
|
167
172
|
.context-menu {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
position: absolute;
|
|
174
|
+
right: auto;
|
|
175
|
+
margin: 0;
|
|
176
|
+
padding: 0;
|
|
177
|
+
z-index: 10;
|
|
178
|
+
border: none;
|
|
179
|
+
outline: none;
|
|
180
|
+
background: transparent;
|
|
181
|
+
}
|
|
182
|
+
.context-menu:popover-open {
|
|
183
|
+
border: none;
|
|
184
|
+
outline: none;
|
|
175
185
|
}
|
|
176
186
|
.context-menu .btn:hover {
|
|
177
187
|
color: cornflowerblue !important;
|
|
@@ -200,12 +210,6 @@ body.dark .btn {
|
|
|
200
210
|
body.dark .context-menu .btn {
|
|
201
211
|
color: white;
|
|
202
212
|
}
|
|
203
|
-
.context-menu.collapsed {
|
|
204
|
-
/*
|
|
205
|
-
max-height: 0;
|
|
206
|
-
*/
|
|
207
|
-
display: none;
|
|
208
|
-
}
|
|
209
213
|
body.dark .open-menu, body.dark .browse {
|
|
210
214
|
border: none !important;
|
|
211
215
|
/*
|
|
@@ -507,7 +511,7 @@ body.dark aside .current.selected {
|
|
|
507
511
|
-->
|
|
508
512
|
<% if (running.length > 0) { %>
|
|
509
513
|
<div class='running-apps'>
|
|
510
|
-
<% running.forEach((item) => { %>
|
|
514
|
+
<% running.forEach((item, index) => { %>
|
|
511
515
|
<a target="<%=item.target || '_self'%>" href="<%=item.browser_url%>" data-description="<%=item.description%>" data-index="<%=item.index%>" data-name="<%=item.name%>" data-title="<%=item.name%>" data-uri="<%=item.uri%>" data-icon="<%=item.icon%>" data-path="<%=item.path%>" data-iconpath="<%=item.iconpath ? item.iconpath : ''%>" class='line align-top'>
|
|
512
516
|
<h3>
|
|
513
517
|
<div class='item-icon'>
|
|
@@ -538,10 +542,10 @@ body.dark aside .current.selected {
|
|
|
538
542
|
<button class='btn browse' data-src="<%=item.view_url%>">
|
|
539
543
|
<i class="fa-regular fa-eye"></i> View
|
|
540
544
|
</button>
|
|
541
|
-
<button class='btn open-menu'>
|
|
545
|
+
<button class='btn open-menu' type='button' popovertarget="context-menu-running-<%=index%>" popovertargetaction="toggle" aria-haspopup="menu">
|
|
542
546
|
<i class="fa-solid fa-bars"></i><span> Menu</span>
|
|
543
547
|
</button>
|
|
544
|
-
<div class='context-menu
|
|
548
|
+
<div id='context-menu-running-<%=index%>' class='context-menu' popover>
|
|
545
549
|
<div class='context-menu-wrapper'>
|
|
546
550
|
<button class='btn' data-filepath="<%=item.filepath%>">
|
|
547
551
|
<i class="fa-solid fa-folder-open"></i> Open</button>
|
|
@@ -601,7 +605,7 @@ body.dark aside .current.selected {
|
|
|
601
605
|
<!--
|
|
602
606
|
<div class='header-label'>Not Running</div>
|
|
603
607
|
-->
|
|
604
|
-
<% notRunning.forEach((item) => { %>
|
|
608
|
+
<% notRunning.forEach((item, index) => { %>
|
|
605
609
|
<a target="<%=item.target || '_self'%>" href="<%=item.browser_url%>" data-description="<%=item.description%>" data-index="<%=item.index%>" data-name="<%=item.name%>" data-title="<%=item.name%>" data-uri="<%=item.uri%>" data-icon="<%=item.icon%>" data-path="<%=item.path%>" data-iconpath="<%=item.iconpath ? item.iconpath : ''%>" class='line align-top'>
|
|
606
610
|
<h3>
|
|
607
611
|
<div class='item-icon'>
|
|
@@ -632,10 +636,10 @@ body.dark aside .current.selected {
|
|
|
632
636
|
<button class='btn browse' data-src="<%=item.view_url%>">
|
|
633
637
|
<i class="fa-regular fa-eye"></i> View
|
|
634
638
|
</button>
|
|
635
|
-
<button class='btn open-menu'>
|
|
639
|
+
<button class='btn open-menu' type='button' popovertarget="context-menu-not-running-<%=index%>" popovertargetaction="toggle" aria-haspopup="menu">
|
|
636
640
|
<i class="fa-solid fa-bars"></i><span> Menu</span>
|
|
637
641
|
</button>
|
|
638
|
-
<div class='context-menu
|
|
642
|
+
<div id='context-menu-not-running-<%=index%>' class='context-menu' popover>
|
|
639
643
|
<div class='context-menu-wrapper'>
|
|
640
644
|
<button class='btn' data-filepath="<%=item.filepath%>">
|
|
641
645
|
<i class="fa-solid fa-folder-open"></i> Open</button>
|
|
@@ -740,15 +744,7 @@ body.dark aside .current.selected {
|
|
|
740
744
|
<a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
|
|
741
745
|
<a class='tab' href="/agents"><i class="fa-solid fa-robot"></i><div class='caption'>Agents</div></a>
|
|
742
746
|
<a class='tab' href="/home?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
|
|
743
|
-
|
|
744
|
-
<div class='qr' style='padding:12px 10px; text-align:center;'>
|
|
745
|
-
<a href="<%=peer_url%>" target="_blank" style="text-decoration:none; color:inherit; display:block;">
|
|
746
|
-
<img src="<%=peer_qr%>" alt="Open <%=peer_url%>" style="width:128px; height:128px; image-rendering: pixelated;"/>
|
|
747
|
-
<div class='caption'>Scan to open</div>
|
|
748
|
-
<div class='caption' style='font-size:10px; opacity:0.7;'><%=peer_url%></div>
|
|
749
|
-
</a>
|
|
750
|
-
</div>
|
|
751
|
-
<% } %>
|
|
747
|
+
<%- include('partials/peer_access_points', { peer_access_points, peer_url, peer_qr }) %>
|
|
752
748
|
</aside>
|
|
753
749
|
</main>
|
|
754
750
|
<script>
|
|
@@ -1101,6 +1097,47 @@ document.addEventListener("keydown", (e) => {
|
|
|
1101
1097
|
}
|
|
1102
1098
|
}
|
|
1103
1099
|
});
|
|
1100
|
+
const supportsNativePopovers = typeof document.createElement('div').showPopover === 'function'
|
|
1101
|
+
if (!supportsNativePopovers) {
|
|
1102
|
+
document.querySelectorAll('.context-menu[popover]').forEach((menu) => {
|
|
1103
|
+
menu.style.display = 'none'
|
|
1104
|
+
})
|
|
1105
|
+
}
|
|
1106
|
+
const getMenuDimensions = (menu) => {
|
|
1107
|
+
let width = parseFloat(menu.dataset.cachedWidth)
|
|
1108
|
+
let height = parseFloat(menu.dataset.cachedHeight)
|
|
1109
|
+
if (!width || !height) {
|
|
1110
|
+
const prev = {
|
|
1111
|
+
visibility: menu.style.visibility,
|
|
1112
|
+
display: menu.style.display,
|
|
1113
|
+
position: menu.style.position,
|
|
1114
|
+
top: menu.style.top,
|
|
1115
|
+
left: menu.style.left,
|
|
1116
|
+
}
|
|
1117
|
+
menu.style.visibility = 'hidden'
|
|
1118
|
+
menu.style.display = 'block'
|
|
1119
|
+
menu.style.position = 'fixed'
|
|
1120
|
+
menu.style.top = '0'
|
|
1121
|
+
menu.style.left = '0'
|
|
1122
|
+
width = menu.offsetWidth
|
|
1123
|
+
height = menu.offsetHeight
|
|
1124
|
+
if (width > 0) {
|
|
1125
|
+
menu.dataset.cachedWidth = width
|
|
1126
|
+
}
|
|
1127
|
+
if (height > 0) {
|
|
1128
|
+
menu.dataset.cachedHeight = height
|
|
1129
|
+
}
|
|
1130
|
+
menu.style.visibility = prev.visibility
|
|
1131
|
+
menu.style.display = prev.display
|
|
1132
|
+
menu.style.position = prev.position
|
|
1133
|
+
menu.style.top = prev.top
|
|
1134
|
+
menu.style.left = prev.left
|
|
1135
|
+
}
|
|
1136
|
+
return {
|
|
1137
|
+
width: width || 0,
|
|
1138
|
+
height: height || 0
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1104
1141
|
document.addEventListener("click", async (e) => {
|
|
1105
1142
|
if (e.target.classList.contains("shutdown")) {
|
|
1106
1143
|
target = e.target
|
|
@@ -1170,11 +1207,74 @@ document.addEventListener("click", async (e) => {
|
|
|
1170
1207
|
if (target) {
|
|
1171
1208
|
e.preventDefault()
|
|
1172
1209
|
e.stopPropagation()
|
|
1173
|
-
let
|
|
1174
|
-
|
|
1210
|
+
let popoverId = target.getAttribute('popovertarget')
|
|
1211
|
+
let contextMenu
|
|
1212
|
+
if (popoverId) {
|
|
1213
|
+
contextMenu = document.getElementById(popoverId)
|
|
1214
|
+
}
|
|
1215
|
+
if (!contextMenu) {
|
|
1216
|
+
contextMenu = target.closest(".col")?.querySelector(".context-menu")
|
|
1217
|
+
}
|
|
1218
|
+
if (contextMenu) {
|
|
1219
|
+
const hasNativePopover = supportsNativePopovers && typeof contextMenu.showPopover === 'function'
|
|
1220
|
+
const isOpen = hasNativePopover ? contextMenu.matches(':popover-open') : contextMenu.dataset.open === 'true'
|
|
1221
|
+
if (isOpen) {
|
|
1222
|
+
if (hasNativePopover) {
|
|
1223
|
+
contextMenu.hidePopover()
|
|
1224
|
+
} else {
|
|
1225
|
+
contextMenu.style.display = 'none'
|
|
1226
|
+
contextMenu.dataset.open = 'false'
|
|
1227
|
+
}
|
|
1228
|
+
return
|
|
1229
|
+
}
|
|
1230
|
+
if (hasNativePopover) {
|
|
1231
|
+
document.querySelectorAll('.context-menu[popover]').forEach((menuEl) => {
|
|
1232
|
+
if (menuEl !== contextMenu && menuEl.matches(':popover-open') && typeof menuEl.hidePopover === 'function') {
|
|
1233
|
+
menuEl.hidePopover()
|
|
1234
|
+
}
|
|
1235
|
+
})
|
|
1236
|
+
} else {
|
|
1237
|
+
document.querySelectorAll('.context-menu[data-open="true"]').forEach((menuEl) => {
|
|
1238
|
+
if (menuEl !== contextMenu) {
|
|
1239
|
+
menuEl.style.display = 'none'
|
|
1240
|
+
menuEl.dataset.open = 'false'
|
|
1241
|
+
}
|
|
1242
|
+
})
|
|
1243
|
+
}
|
|
1244
|
+
const buttonRect = target.getBoundingClientRect()
|
|
1245
|
+
const menuRect = getMenuDimensions(contextMenu)
|
|
1246
|
+
const viewportPadding = 12
|
|
1247
|
+
let left = Math.min(buttonRect.left, window.innerWidth - menuRect.width - viewportPadding)
|
|
1248
|
+
left = Math.max(viewportPadding, left)
|
|
1249
|
+
let top = buttonRect.bottom + 6
|
|
1250
|
+
if (top + menuRect.height + viewportPadding > window.innerHeight) {
|
|
1251
|
+
top = buttonRect.top - menuRect.height - 6
|
|
1252
|
+
}
|
|
1253
|
+
const maxTop = Math.max(viewportPadding, window.innerHeight - menuRect.height - viewportPadding)
|
|
1254
|
+
top = Math.min(Math.max(viewportPadding, top), maxTop)
|
|
1255
|
+
if (hasNativePopover) {
|
|
1256
|
+
contextMenu.style.position = 'fixed'
|
|
1257
|
+
contextMenu.style.left = left + 'px'
|
|
1258
|
+
contextMenu.style.top = top + 'px'
|
|
1259
|
+
contextMenu.style.right = 'auto'
|
|
1260
|
+
contextMenu.style.bottom = 'auto'
|
|
1261
|
+
contextMenu.togglePopover()
|
|
1262
|
+
} else {
|
|
1263
|
+
const btnContainer = target.closest('.menu-btns')
|
|
1264
|
+
if (!btnContainer) {
|
|
1265
|
+
return
|
|
1266
|
+
}
|
|
1267
|
+
const containerRect = btnContainer.getBoundingClientRect()
|
|
1268
|
+
contextMenu.style.left = Math.max(0, left - containerRect.left) + 'px'
|
|
1269
|
+
contextMenu.style.top = top - containerRect.top + 'px'
|
|
1270
|
+
contextMenu.style.right = 'auto'
|
|
1271
|
+
contextMenu.style.bottom = 'auto'
|
|
1272
|
+
contextMenu.style.display = 'block'
|
|
1273
|
+
contextMenu.dataset.open = 'true'
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1175
1276
|
return
|
|
1176
1277
|
}
|
|
1177
|
-
|
|
1178
1278
|
if (e.target.classList.contains("move-menu")) {
|
|
1179
1279
|
target = e.target
|
|
1180
1280
|
} else {
|
|
@@ -1954,15 +1954,7 @@ body.dark .ace-editor {
|
|
|
1954
1954
|
<a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
|
|
1955
1955
|
<a class='tab' href="/agents"><i class="fa-solid fa-robot"></i><div class='caption'>Agents</div></a>
|
|
1956
1956
|
<a class='tab' href="/home?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
|
|
1957
|
-
|
|
1958
|
-
<div class='qr' style='padding:12px 10px; text-align:center;'>
|
|
1959
|
-
<a href="<%=peer_url%>" target="_blank" style="text-decoration:none; color:inherit; display:block;">
|
|
1960
|
-
<img src="<%=peer_qr%>" alt="Open <%=peer_url%>" style="width:128px; height:128px; image-rendering: pixelated;"/>
|
|
1961
|
-
<div class='caption'>Scan to open</div>
|
|
1962
|
-
<div class='caption' style='font-size:10px; opacity:0.7;'><%=peer_url%></div>
|
|
1963
|
-
</a>
|
|
1964
|
-
</div>
|
|
1965
|
-
<% } %>
|
|
1957
|
+
<%- include('partials/peer_access_points', { peer_access_points, peer_url, peer_qr }) %>
|
|
1966
1958
|
</aside>
|
|
1967
1959
|
</main>
|
|
1968
1960
|
<div id='terminal-container' class='hidden'>
|
package/server/views/net.ejs
CHANGED
|
@@ -464,6 +464,37 @@ body.dark .net {
|
|
|
464
464
|
display: block;
|
|
465
465
|
background: none;
|
|
466
466
|
}
|
|
467
|
+
.access-point-list {
|
|
468
|
+
list-style: none;
|
|
469
|
+
padding: 0;
|
|
470
|
+
margin: 6px 0 0 0;
|
|
471
|
+
display: flex;
|
|
472
|
+
flex-direction: column;
|
|
473
|
+
gap: 4px;
|
|
474
|
+
}
|
|
475
|
+
.access-point-list li {
|
|
476
|
+
display: flex;
|
|
477
|
+
align-items: center;
|
|
478
|
+
gap: 6px;
|
|
479
|
+
font-size: 12px;
|
|
480
|
+
}
|
|
481
|
+
.access-point-list .badge {
|
|
482
|
+
display: inline-flex;
|
|
483
|
+
align-items: center;
|
|
484
|
+
justify-content: center;
|
|
485
|
+
padding: 0 6px;
|
|
486
|
+
font-size: 10px;
|
|
487
|
+
border-radius: 999px;
|
|
488
|
+
background: rgba(127, 91, 243, 0.12);
|
|
489
|
+
color: rgba(127, 91, 243, 0.9);
|
|
490
|
+
border: 1px solid rgba(127, 91, 243, 0.3);
|
|
491
|
+
text-transform: uppercase;
|
|
492
|
+
}
|
|
493
|
+
body.dark .access-point-list .badge {
|
|
494
|
+
background: rgba(127, 91, 243, 0.2);
|
|
495
|
+
color: #f0e9ff;
|
|
496
|
+
border-color: rgba(127, 91, 243, 0.4);
|
|
497
|
+
}
|
|
467
498
|
.net .mark {
|
|
468
499
|
background: rgba(0,0,0,0.9);
|
|
469
500
|
border-radius: 3px;
|
|
@@ -666,7 +697,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
666
697
|
<h2><i class="fa-solid fa-wifi"></i> Local network</h2><div>accessible from any machine on the local network</div>
|
|
667
698
|
</div>
|
|
668
699
|
<div class='section'>
|
|
669
|
-
<h2><i class="fa-solid fa-podcast"></i> Peer</h2><div>accessible from any pinokio peer on the local network
|
|
700
|
+
<h2><i class="fa-solid fa-podcast"></i> Peer</h2><div>accessible from any pinokio peer on the local network</a></div>
|
|
670
701
|
</div>
|
|
671
702
|
</div>
|
|
672
703
|
</div>
|
|
@@ -722,7 +753,45 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
722
753
|
<% } %>
|
|
723
754
|
</div>
|
|
724
755
|
<div class='section'>
|
|
725
|
-
<%
|
|
756
|
+
<%
|
|
757
|
+
const directHosts = []
|
|
758
|
+
if (Array.isArray(item.external_hosts)) {
|
|
759
|
+
const seenHosts = new Set()
|
|
760
|
+
item.external_hosts.forEach((hostEntry) => {
|
|
761
|
+
if (!hostEntry || !hostEntry.url) {
|
|
762
|
+
return
|
|
763
|
+
}
|
|
764
|
+
const key = hostEntry.url.toLowerCase()
|
|
765
|
+
if (seenHosts.has(key)) {
|
|
766
|
+
return
|
|
767
|
+
}
|
|
768
|
+
seenHosts.add(key)
|
|
769
|
+
const scope = (hostEntry.scope || '').toLowerCase()
|
|
770
|
+
let badge = ''
|
|
771
|
+
if (scope === 'lan') badge = 'LAN'
|
|
772
|
+
else if (scope === 'cgnat') badge = 'VPN'
|
|
773
|
+
else if (scope === 'public') badge = 'Public'
|
|
774
|
+
else if (scope === 'loopback') badge = 'Local'
|
|
775
|
+
else if (scope === 'linklocal') badge = 'Link-Local'
|
|
776
|
+
directHosts.push({
|
|
777
|
+
url: hostEntry.url,
|
|
778
|
+
badge
|
|
779
|
+
})
|
|
780
|
+
})
|
|
781
|
+
}
|
|
782
|
+
%>
|
|
783
|
+
<% if (directHosts.length > 0) { %>
|
|
784
|
+
<ul class="access-point-list">
|
|
785
|
+
<% directHosts.forEach((point) => { %>
|
|
786
|
+
<li>
|
|
787
|
+
<a class='net' target="_blank" href="<%= point.url %>"><%= point.url %></a>
|
|
788
|
+
<% if (point.badge) { %>
|
|
789
|
+
<span class="badge"><%= point.badge %></span>
|
|
790
|
+
<% } %>
|
|
791
|
+
</li>
|
|
792
|
+
<% }) %>
|
|
793
|
+
</ul>
|
|
794
|
+
<% } else if (item.external_ip) { %>
|
|
726
795
|
<a class='net' target="_blank" href="http://<%=item.external_ip%>">http://<%=item.external_ip%></a>
|
|
727
796
|
<% } %>
|
|
728
797
|
</div>
|
|
@@ -937,15 +1006,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
937
1006
|
<a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
|
|
938
1007
|
<a class='tab' href="/agents"><i class="fa-solid fa-robot"></i><div class='caption'>Agents</div></a>
|
|
939
1008
|
<a class='tab' href="/home?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
|
|
940
|
-
|
|
941
|
-
<div class='qr' style='padding:12px 10px; text-align:center;'>
|
|
942
|
-
<a href="<%=peer_url%>" target="_blank" style="text-decoration:none; color:inherit; display:block;">
|
|
943
|
-
<img src="<%=peer_qr%>" alt="Open <%=peer_url%>" style="width:128px; height:128px; image-rendering: pixelated;"/>
|
|
944
|
-
<div class='caption'>Scan to open</div>
|
|
945
|
-
<div class='caption' style='font-size:10px; opacity:0.7;'><%=peer_url%></div>
|
|
946
|
-
</a>
|
|
947
|
-
</div>
|
|
948
|
-
<% } %>
|
|
1009
|
+
<%- include('partials/peer_access_points', { peer_access_points, peer_url, peer_qr }) %>
|
|
949
1010
|
</aside>
|
|
950
1011
|
</main>
|
|
951
1012
|
<script>
|
package/server/views/network.ejs
CHANGED
|
@@ -1185,16 +1185,8 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
1185
1185
|
<a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
|
|
1186
1186
|
<a class='tab' href="/agents"><i class="fa-solid fa-robot"></i><div class='caption'>Agents</div></a>
|
|
1187
1187
|
<a class='tab' href="/home?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
<a href="<%=peer_url%>" target="_blank" style="text-decoration:none; color:inherit; display:block;">
|
|
1191
|
-
<img src="<%=peer_qr%>" alt="Open <%=peer_url%>" style="width:128px; height:128px; image-rendering: pixelated;"/>
|
|
1192
|
-
<div class='caption'>Scan to open</div>
|
|
1193
|
-
<div class='caption' style='font-size:10px; opacity:0.7;'><%=peer_url%></div>
|
|
1194
|
-
</a>
|
|
1195
|
-
</div>
|
|
1196
|
-
<% } %>
|
|
1197
|
-
</aside>
|
|
1188
|
+
<%- include('partials/peer_access_points', { peer_access_points, peer_url, peer_qr }) %>
|
|
1189
|
+
</aside>
|
|
1198
1190
|
</main>
|
|
1199
1191
|
<script>
|
|
1200
1192
|
let interval
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<%
|
|
2
|
+
const accessPoints = Array.isArray(peer_access_points) ? peer_access_points : []
|
|
3
|
+
const hasAccessPoints = accessPoints.length > 0
|
|
4
|
+
%>
|
|
5
|
+
<% if (hasAccessPoints) { %>
|
|
6
|
+
<% accessPoints.forEach((point) => { %>
|
|
7
|
+
<% if (!point || !point.url) { return } %>
|
|
8
|
+
<% const qrSrc = point.qr || (`/qr?data=${encodeURIComponent(point.url)}&s=4&m=0`) %>
|
|
9
|
+
<div class="qr">
|
|
10
|
+
<a href="<%= point.url %>" target="_blank" style="text-decoration:none; color:inherit; display:block;">
|
|
11
|
+
<img src="<%= qrSrc %>" alt="Open <%= point.url %>" style="width:128px; height:128px; image-rendering: pixelated;"/>
|
|
12
|
+
<div class='caption'>
|
|
13
|
+
Scan to open<% if (point.scope_label) { %> (<%= point.scope_label %>)<% } %>
|
|
14
|
+
</div>
|
|
15
|
+
<div class='caption' style='font-size:10px; opacity:0.7;'><%= point.url %></div>
|
|
16
|
+
</a>
|
|
17
|
+
</div>
|
|
18
|
+
<% }) %>
|
|
19
|
+
<% } else if (typeof peer_qr !== 'undefined' && peer_qr) { %>
|
|
20
|
+
<div class='qr'>
|
|
21
|
+
<a href="<%=peer_url%>" target="_blank" style="text-decoration:none; color:inherit; display:block;">
|
|
22
|
+
<img src="<%=peer_qr%>" alt="Open <%=peer_url%>" style="width:128px; height:128px; image-rendering: pixelated;"/>
|
|
23
|
+
<div class='caption'>Scan to open</div>
|
|
24
|
+
<div class='caption' style='font-size:10px; opacity:0.7;'><%=peer_url%></div>
|
|
25
|
+
</a>
|
|
26
|
+
</div>
|
|
27
|
+
<% } %>
|
package/server/views/review.ejs
CHANGED
|
@@ -948,10 +948,10 @@ body.dark .top-menu .btn2.selected {
|
|
|
948
948
|
<button class='btn2' id='inspector' data-tippy-content="X-ray mode"><i class="fa-solid fa-eye"></i></button>
|
|
949
949
|
<button class='btn2' id='hidden-placeholder'><i class="fa-solid fa-bars"></i></button>
|
|
950
950
|
<div class='mode-selector'>
|
|
951
|
-
<a class="btn2 <%=type === 'review' ? 'selected' : ''%>" href="<%=review_tab%>"><div><i class="fa-regular fa-message"></i></div><div class='caption'>Forum</div></a>
|
|
952
|
-
<a class="btn2 <%=type === 'files' ? 'selected' : ''%>" href="/p/<%=name%>/files"><div><i class="fa-solid fa-file-lines"></i></div><div class='caption'>Files</div></a>
|
|
953
|
-
<a class="btn2 <%=type === 'browse' ? 'selected' : ''%>" href="<%=dev_tab%>"><div><i class="fa-solid fa-code"></i></div><div class='caption'>Dev</div></a>
|
|
954
951
|
<a class="btn2 <%=type === 'run' ? 'selected' : ''%>" href="<%=run_tab%>"><div><i class="fa-solid fa-circle-play"></i></div><div class='caption'>Run</div></a>
|
|
952
|
+
<a class="btn2 <%=type === 'browse' ? 'selected' : ''%>" href="<%=dev_tab%>"><div><i class="fa-solid fa-code"></i></div><div class='caption'>Dev</div></a>
|
|
953
|
+
<a class="btn2 <%=type === 'files' ? 'selected' : ''%>" href="/p/<%=name%>/files"><div><i class="fa-solid fa-file-lines"></i></div><div class='caption'>Files</div></a>
|
|
954
|
+
<a class="btn2 <%=type === 'review' ? 'selected' : ''%>" href="<%=review_tab%>"><div><i class="fa-regular fa-message"></i></div><div class='caption'>Forum</div></a>
|
|
955
955
|
</div>
|
|
956
956
|
<a class='btn2' href="/columns" data-tippy-content="split into 2 columns">
|
|
957
957
|
<div><i class="fa-solid fa-table-columns"></i></div>
|
|
@@ -776,15 +776,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
776
776
|
<a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
|
|
777
777
|
<a class='tab' href="/agents"><i class="fa-solid fa-robot"></i><div class='caption'>Agents</div></a>
|
|
778
778
|
<a class='tab' href="/home?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
|
|
779
|
-
|
|
780
|
-
<div class='qr' style='padding:12px 10px; text-align:center;'>
|
|
781
|
-
<a href="<%=peer_url%>" target="_blank" style="text-decoration:none; color:inherit; display:block;">
|
|
782
|
-
<img src="<%=peer_qr%>" alt="Open <%=peer_url%>" style="width:128px; height:128px; image-rendering: pixelated;"/>
|
|
783
|
-
<div class='caption'>Scan to open</div>
|
|
784
|
-
<div class='caption' style='font-size:10px; opacity:0.7;'><%=peer_url%></div>
|
|
785
|
-
</a>
|
|
786
|
-
</div>
|
|
787
|
-
<% } %>
|
|
779
|
+
<%- include('partials/peer_access_points', { peer_access_points, peer_url, peer_qr }) %>
|
|
788
780
|
</aside>
|
|
789
781
|
</main>
|
|
790
782
|
<script>
|
|
@@ -571,15 +571,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
571
571
|
<a class='tab' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
|
|
572
572
|
<a class='tab' href="/agents"><i class="fa-solid fa-robot"></i><div class='caption'>Agents</div></a>
|
|
573
573
|
<a class='tab selected' href="/home?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
|
|
574
|
-
|
|
575
|
-
<div class='qr' style='padding:12px 10px; text-align:center;'>
|
|
576
|
-
<a href="<%=peer_url%>" target="_blank" style="text-decoration:none; color:inherit; display:block;">
|
|
577
|
-
<img src="<%=peer_qr%>" alt="Open <%=peer_url%>" style="width:128px; height:128px; image-rendering: pixelated;"/>
|
|
578
|
-
<div class='caption'>Scan to open</div>
|
|
579
|
-
<div class='caption' style='font-size:10px; opacity:0.7;'><%=peer_url%></div>
|
|
580
|
-
</a>
|
|
581
|
-
</div>
|
|
582
|
-
<% } %>
|
|
574
|
+
<%- include('partials/peer_access_points', { peer_access_points, peer_url, peer_qr }) %>
|
|
583
575
|
</aside>
|
|
584
576
|
</main>
|
|
585
577
|
<script>
|
package/server/views/shell.ejs
CHANGED
|
@@ -1493,6 +1493,9 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
1493
1493
|
this.term.focus()
|
|
1494
1494
|
}, true)
|
|
1495
1495
|
term.attachCustomKeyEventHandler(event => {
|
|
1496
|
+
if (event.type && event.type.toLowerCase() !== 'keydown') {
|
|
1497
|
+
return true
|
|
1498
|
+
}
|
|
1496
1499
|
if ((event.ctrlKey || event.metaKey) && event.key === 'c') {
|
|
1497
1500
|
const selection = term.getSelection();
|
|
1498
1501
|
if (selection) {
|
|
@@ -1532,6 +1532,9 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
1532
1532
|
this.term.focus()
|
|
1533
1533
|
}, true)
|
|
1534
1534
|
term.attachCustomKeyEventHandler(event => {
|
|
1535
|
+
if (event.type && event.type.toLowerCase() !== 'keydown') {
|
|
1536
|
+
return true
|
|
1537
|
+
}
|
|
1535
1538
|
if ((event.ctrlKey || event.metaKey) && event.key === 'c') {
|
|
1536
1539
|
const selection = term.getSelection();
|
|
1537
1540
|
if (selection) {
|
package/server/views/tools.ejs
CHANGED
|
@@ -1275,15 +1275,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
1275
1275
|
<a class='tab selected' href="/tools"><i class="fa-solid fa-toolbox"></i><div class='caption'>Installed Tools</div></a>
|
|
1276
1276
|
<a class='tab' href="/agents"><i class="fa-solid fa-robot"></i><div class='caption'>Agents</div></a>
|
|
1277
1277
|
<a class='tab' href="/home?mode=settings"><i class="fa-solid fa-gear"></i><div class='caption'>Settings</div></a>
|
|
1278
|
-
|
|
1279
|
-
<div class='qr' style='padding:12px 10px; text-align:center;'>
|
|
1280
|
-
<a href="<%=peer_url%>" target="_blank" style="text-decoration:none; color:inherit; display:block;">
|
|
1281
|
-
<img src="<%=peer_qr%>" alt="Open <%=peer_url%>" style="width:128px; height:128px; image-rendering: pixelated;"/>
|
|
1282
|
-
<div class='caption'>Scan to open</div>
|
|
1283
|
-
<div class='caption' style='font-size:10px; opacity:0.7;'><%=peer_url%></div>
|
|
1284
|
-
</a>
|
|
1285
|
-
</div>
|
|
1286
|
-
<% } %>
|
|
1278
|
+
<%- include('partials/peer_access_points', { peer_access_points, peer_url, peer_qr }) %>
|
|
1287
1279
|
</aside>
|
|
1288
1280
|
</main>
|
|
1289
1281
|
<script>
|