pinokiod 3.24.0 → 3.26.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/api/exec/index.js +67 -0
- package/kernel/api/index.js +1 -0
- package/kernel/bin/caddy.js +1 -1
- package/kernel/index.js +1 -6
- package/kernel/peer.js +23 -5
- package/kernel/plugin.js +24 -41
- package/kernel/prototype.js +25 -0
- package/kernel/router/index.js +13 -0
- package/kernel/router/localhost_home_router.js +11 -0
- package/kernel/shell.js +13 -10
- package/kernel/shells.js +52 -47
- package/kernel/util.js +0 -1
- package/package.json +2 -1
- package/server/index.js +307 -220
- package/server/public/modalinput.js +3 -1
- package/server/public/style.css +1 -1
- package/server/socket.js +0 -19
- package/server/views/500.ejs +7 -6
- package/server/views/app.ejs +76 -11
- package/server/views/d.ejs +123 -12
- package/server/views/index.ejs +69 -1
- package/server/views/init/index.ejs +299 -92
- package/server/views/install.ejs +7 -1
- package/server/views/net.ejs +94 -166
- package/server/views/network.ejs +3 -2
- package/server/views/partials/dynamic.ejs +1 -1
- package/server/views/start.ejs +268 -0
|
@@ -3,6 +3,7 @@ const ModalInput = async (params, uri) => {
|
|
|
3
3
|
{
|
|
4
4
|
title,
|
|
5
5
|
type: "modal" (default) |"notify"
|
|
6
|
+
confirm: "OK",
|
|
6
7
|
form: [{
|
|
7
8
|
type,
|
|
8
9
|
items,
|
|
@@ -20,6 +21,7 @@ const ModalInput = async (params, uri) => {
|
|
|
20
21
|
let description = (params.description ? `<div class='desc'>${params.description}</div>` : "")
|
|
21
22
|
let result = await Swal.fire({
|
|
22
23
|
title: (params.title || ""),
|
|
24
|
+
customClass: params.customClass,
|
|
23
25
|
html: description + form.map((field) => {
|
|
24
26
|
let type = (field.type ? field.type : "text")
|
|
25
27
|
let autofocus = (field.autofocus ? "autofocus" : "")
|
|
@@ -68,7 +70,7 @@ const ModalInput = async (params, uri) => {
|
|
|
68
70
|
}
|
|
69
71
|
}).join("\n"),
|
|
70
72
|
//focusConfirm: false,
|
|
71
|
-
confirmButtonText: 'Done',
|
|
73
|
+
confirmButtonText: params.confirm || 'Done',
|
|
72
74
|
didRender: () => {
|
|
73
75
|
Swal.getPopup().querySelectorAll('[data-type=file]').forEach((el, index) => {
|
|
74
76
|
const dz = new Dropzone(el, {
|
package/server/public/style.css
CHANGED
|
@@ -1408,7 +1408,7 @@ body.dark .not-running-apps .line.align-top h3 .col .title i {
|
|
|
1408
1408
|
color: rgba(255,255,255,0.4);
|
|
1409
1409
|
}
|
|
1410
1410
|
.not-running-apps .line.align-top h3 .col .title i {
|
|
1411
|
-
color: rgba(0,0,0,0.
|
|
1411
|
+
color: rgba(0,0,0,0.4);
|
|
1412
1412
|
}
|
|
1413
1413
|
.running-apps .line.align-top h3 .col .title i {
|
|
1414
1414
|
color: yellowgreen;
|
package/server/socket.js
CHANGED
|
@@ -61,9 +61,6 @@ class Socket {
|
|
|
61
61
|
// link git every time before processing
|
|
62
62
|
await this.parent.kernel.api.init()
|
|
63
63
|
// look for repos that match
|
|
64
|
-
|
|
65
|
-
console.log("REQ", req)
|
|
66
|
-
|
|
67
64
|
if (req.uri) {
|
|
68
65
|
if (req.mode === "open") {
|
|
69
66
|
// get the default script and respond
|
|
@@ -359,15 +356,9 @@ class Socket {
|
|
|
359
356
|
|
|
360
357
|
if (key.startsWith("shell/")) {
|
|
361
358
|
let unix_id = key.slice(6)
|
|
362
|
-
console.log({ key, unix_id })
|
|
363
|
-
|
|
364
359
|
let unix_path = unix_id.split("_")[0]
|
|
365
360
|
let native_path = Util.u2p(unix_path)
|
|
366
|
-
|
|
367
361
|
let native_path_exists = await new Promise(r=>fs.access(native_path, fs.constants.F_OK, e => r(!e)))
|
|
368
|
-
|
|
369
|
-
console.log({ unix_path, native_path, native_path_exists })
|
|
370
|
-
|
|
371
362
|
if (native_path_exists) {
|
|
372
363
|
let cwd = native_path
|
|
373
364
|
let session = this.sessions[key]
|
|
@@ -375,16 +366,6 @@ class Socket {
|
|
|
375
366
|
await Util.log(logpath, buf, session)
|
|
376
367
|
}
|
|
377
368
|
}
|
|
378
|
-
|
|
379
|
-
//let api_name = key.split("_")[0]
|
|
380
|
-
//let api_path = this.parent.kernel.path("api", api_name)
|
|
381
|
-
//let api_path_exists = await new Promise(r=>fs.access(api_path, fs.constants.F_OK, e => r(!e)))
|
|
382
|
-
//if (api_path_exists) {
|
|
383
|
-
// let cwd = api_path
|
|
384
|
-
// let session = this.sessions[key]
|
|
385
|
-
// let logpath = path.resolve(cwd, "logs/shell")
|
|
386
|
-
// await Util.log(logpath, buf, session)
|
|
387
|
-
//}
|
|
388
369
|
}
|
|
389
370
|
}
|
|
390
371
|
}
|
package/server/views/500.ejs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<meta charset="UTF-8">
|
|
4
4
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
5
5
|
<style>
|
|
6
|
-
body
|
|
6
|
+
body.error-body {
|
|
7
7
|
width: 100%;
|
|
8
8
|
margin: 0;
|
|
9
9
|
background: royalblue;
|
|
@@ -20,26 +20,27 @@ h1 {
|
|
|
20
20
|
pre {
|
|
21
21
|
width: 100%;
|
|
22
22
|
}
|
|
23
|
-
footer {
|
|
23
|
+
body.error-body footer.error-footer {
|
|
24
|
+
display: block;
|
|
24
25
|
border-left: 4px solid white;
|
|
25
26
|
padding: 10px 20px;
|
|
26
27
|
margin-top: 50px;
|
|
27
28
|
}
|
|
28
|
-
footer ol {
|
|
29
|
+
body.error-body footer.error-footer ol {
|
|
29
30
|
padding-inline-start: 20px;
|
|
30
31
|
margin: 0;
|
|
31
32
|
padding-top: 10px;
|
|
32
33
|
}
|
|
33
|
-
footer a {
|
|
34
|
+
body.error-body footer.error-footer a {
|
|
34
35
|
color: white;
|
|
35
36
|
font-weight: bold;
|
|
36
37
|
}
|
|
37
38
|
</style>
|
|
38
39
|
</head>
|
|
39
|
-
<body>
|
|
40
|
+
<body class='error-body'>
|
|
40
41
|
<h1>Error</h1>
|
|
41
42
|
<pre><%=stack%></pre>
|
|
42
|
-
<footer>
|
|
43
|
+
<footer class='error-footer'>
|
|
43
44
|
<div>You may want to try:</div>
|
|
44
45
|
<ol>
|
|
45
46
|
<li>Update Pinokio: Simply install the latest version, it should only update the app binary while keeping all the data in tact. <a href="<%=install%>" target="_blank">Go to Download Page</a></li>
|
package/server/views/app.ejs
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
<link href="/filepond-plugin-image-preview.min.css" rel="stylesheet" />
|
|
14
14
|
<link href="/filepond-plugin-image-edit.min.css" rel="stylesheet" />
|
|
15
15
|
<link href="/style.css" rel="stylesheet"/>
|
|
16
|
+
<script src="/modalinput.js"></script>
|
|
16
17
|
<% if (agent === "electron") { %>
|
|
17
18
|
<link href="/electron.css" rel="stylesheet"/>
|
|
18
19
|
<% } %>
|
|
@@ -178,7 +179,10 @@ body.dark .header-item.btn {
|
|
|
178
179
|
color: var(--dark-color);
|
|
179
180
|
}
|
|
180
181
|
.header-item.btn {
|
|
182
|
+
/*
|
|
181
183
|
padding: 5px 8px;
|
|
184
|
+
*/
|
|
185
|
+
padding: 7px;
|
|
182
186
|
background: none !important;
|
|
183
187
|
color: var(--light-color);
|
|
184
188
|
}
|
|
@@ -615,7 +619,19 @@ nav .logo {
|
|
|
615
619
|
font-size: 20px;
|
|
616
620
|
padding: 10px 30px;
|
|
617
621
|
}
|
|
622
|
+
.error-message > div {
|
|
623
|
+
width: 500px;
|
|
624
|
+
}
|
|
618
625
|
.error-message {
|
|
626
|
+
width: 100%;
|
|
627
|
+
/*
|
|
628
|
+
background: royalblue !important;
|
|
629
|
+
*/
|
|
630
|
+
color: white;
|
|
631
|
+
display: flex;
|
|
632
|
+
justify-content: center;
|
|
633
|
+
align-items: center;
|
|
634
|
+
/*
|
|
619
635
|
display: flex;
|
|
620
636
|
flex-direction: column;
|
|
621
637
|
justify-content: center;
|
|
@@ -628,6 +644,7 @@ nav .logo {
|
|
|
628
644
|
line-height: 40px;
|
|
629
645
|
color: black;
|
|
630
646
|
letter-spacing: -2px;
|
|
647
|
+
*/
|
|
631
648
|
}
|
|
632
649
|
body.dark #location {
|
|
633
650
|
color: white;
|
|
@@ -752,11 +769,15 @@ body.dark .submenu {
|
|
|
752
769
|
overflow: auto;
|
|
753
770
|
display: flex;
|
|
754
771
|
flex-grow: 1;
|
|
772
|
+
/*
|
|
755
773
|
border-top: 1px solid rgba(0, 0,0 ,0.04);
|
|
774
|
+
*/
|
|
756
775
|
}
|
|
776
|
+
/*
|
|
757
777
|
body.dark .appcanvas {
|
|
758
778
|
border-top: 1px solid rgba(255,255,255,0.04);
|
|
759
779
|
}
|
|
780
|
+
*/
|
|
760
781
|
.filler {
|
|
761
782
|
display: none;
|
|
762
783
|
}
|
|
@@ -792,19 +813,34 @@ body.dark .top-menu .btn2.selected {
|
|
|
792
813
|
color: white;
|
|
793
814
|
}
|
|
794
815
|
body.minimized #collapse {
|
|
816
|
+
/*
|
|
795
817
|
background: none !important;
|
|
818
|
+
*/
|
|
819
|
+
border: none !important;
|
|
796
820
|
}
|
|
797
821
|
body.dark #collapse {
|
|
822
|
+
border-bottom: 4px solid white;
|
|
823
|
+
/*
|
|
798
824
|
background: rgba(255,255,255,0.07);
|
|
825
|
+
*/
|
|
799
826
|
}
|
|
800
827
|
#collapse {
|
|
828
|
+
border-bottom: 4px solid black;
|
|
829
|
+
/*
|
|
801
830
|
background: rgba(0,0,0,0.04);
|
|
831
|
+
*/
|
|
802
832
|
}
|
|
803
833
|
body.dark .mode-selector .btn2.selected {
|
|
834
|
+
/*
|
|
804
835
|
background: rgba(255,255,255,0.07);
|
|
836
|
+
*/
|
|
837
|
+
border-bottom: 4px solid white;
|
|
805
838
|
}
|
|
806
839
|
.mode-selector .btn2.selected {
|
|
840
|
+
border-bottom: 4px solid black;
|
|
841
|
+
/*
|
|
807
842
|
background: rgba(0,0,0,0.04);
|
|
843
|
+
*/
|
|
808
844
|
}
|
|
809
845
|
.mode-selector {
|
|
810
846
|
display: flex;
|
|
@@ -1024,9 +1060,12 @@ body.dark .mode-selector .btn2.selected {
|
|
|
1024
1060
|
<% } %>
|
|
1025
1061
|
</div>
|
|
1026
1062
|
<% } %>
|
|
1027
|
-
|
|
1028
|
-
<
|
|
1029
|
-
|
|
1063
|
+
<%if (type!=='run') { %>
|
|
1064
|
+
<a id='devtab' data-mode="refresh" target="<%=dev_link%>" href="<%=dev_link%>" class="btn header-item frame-link selected">
|
|
1065
|
+
<div class="tab"><i class="fa-solid fa-keyboard"></i> Build</div>
|
|
1066
|
+
<div class='loader'><i class='fa-solid fa-angle-right'></i></div>
|
|
1067
|
+
</a>
|
|
1068
|
+
<% } %>
|
|
1030
1069
|
<div class="dynamic <%=type==='run' ? '' : 'selected'%>">
|
|
1031
1070
|
<div class='submenu'>
|
|
1032
1071
|
<% if (plugin_menu) { %>
|
|
@@ -1051,7 +1090,7 @@ body.dark .mode-selector .btn2.selected {
|
|
|
1051
1090
|
<% if (type === "browse") { %>
|
|
1052
1091
|
<div class='nested-menu selected git blue'>
|
|
1053
1092
|
<div class='btn header-item frame-link reveal'>
|
|
1054
|
-
<div class='tab'><i class="fa-solid fa-clock-rotate-left"></i> Version
|
|
1093
|
+
<div class='tab'><i class="fa-solid fa-clock-rotate-left"></i> Version History</div>
|
|
1055
1094
|
<div class='loader'><i class="fa-solid fa-angle-down"></i><i class="fa-solid fa-angle-up hidden"></i></div>
|
|
1056
1095
|
</div>
|
|
1057
1096
|
<div class='submenu' id='git-repos'>
|
|
@@ -1124,9 +1163,10 @@ body.dark .mode-selector .btn2.selected {
|
|
|
1124
1163
|
</aside>
|
|
1125
1164
|
<% if (error) { %>
|
|
1126
1165
|
<div class='error-message'>
|
|
1127
|
-
<
|
|
1128
|
-
|
|
1129
|
-
|
|
1166
|
+
<div>
|
|
1167
|
+
<h1><i class="fa-solid fa-triangle-exclamation"></i> Error</h1>
|
|
1168
|
+
<div><%=error%></div>
|
|
1169
|
+
</div>
|
|
1130
1170
|
</div>
|
|
1131
1171
|
<% } else { %>
|
|
1132
1172
|
<div class='container'>
|
|
@@ -1855,7 +1895,6 @@ body.dark .mode-selector .btn2.selected {
|
|
|
1855
1895
|
}
|
|
1856
1896
|
})
|
|
1857
1897
|
document.querySelector("aside").addEventListener("click", async (e) => {
|
|
1858
|
-
console.log("ASIDE CLICK")
|
|
1859
1898
|
let target
|
|
1860
1899
|
|
|
1861
1900
|
// 0. handle dropdowns
|
|
@@ -2014,7 +2053,6 @@ body.dark .mode-selector .btn2.selected {
|
|
|
2014
2053
|
} else {
|
|
2015
2054
|
target = e.target.closest(".frame-link")
|
|
2016
2055
|
}
|
|
2017
|
-
console.log( { target })
|
|
2018
2056
|
|
|
2019
2057
|
|
|
2020
2058
|
|
|
@@ -2109,7 +2147,6 @@ body.dark .mode-selector .btn2.selected {
|
|
|
2109
2147
|
document.querySelectorAll(".frame-link").forEach((el) => {
|
|
2110
2148
|
el.classList.remove("selected")
|
|
2111
2149
|
})
|
|
2112
|
-
console.log("SELECTED")
|
|
2113
2150
|
target.classList.add("selected")
|
|
2114
2151
|
|
|
2115
2152
|
renderSelection(e)
|
|
@@ -2156,9 +2193,23 @@ body.dark .mode-selector .btn2.selected {
|
|
|
2156
2193
|
const try_dynamic = async () => {
|
|
2157
2194
|
console.log("Try_dynamic")
|
|
2158
2195
|
let rendered
|
|
2196
|
+
let status
|
|
2159
2197
|
const dynamic = await fetch("<%=dynamic%>").then((res) => {
|
|
2198
|
+
status = res.status
|
|
2160
2199
|
return res.text()
|
|
2161
2200
|
})
|
|
2201
|
+
console.log("STatus", status)
|
|
2202
|
+
if (status == 500) {
|
|
2203
|
+
ModalInput({
|
|
2204
|
+
description: dynamic,
|
|
2205
|
+
confirm: "OK",
|
|
2206
|
+
customClass: {
|
|
2207
|
+
popup: "full-popup",
|
|
2208
|
+
title: "full-title"
|
|
2209
|
+
}
|
|
2210
|
+
})
|
|
2211
|
+
return
|
|
2212
|
+
}
|
|
2162
2213
|
if (dynamic && dynamic.length > 0) {
|
|
2163
2214
|
console.log({ dynamic })
|
|
2164
2215
|
if (document.querySelector(".dynamic .submenu")) {
|
|
@@ -2199,9 +2250,23 @@ body.dark .mode-selector .btn2.selected {
|
|
|
2199
2250
|
}, 1000)
|
|
2200
2251
|
})
|
|
2201
2252
|
}
|
|
2253
|
+
let status
|
|
2202
2254
|
const html = await fetch("<%=sidebar%>").then((res) => {
|
|
2255
|
+
status = res.status
|
|
2203
2256
|
return res.text()
|
|
2204
2257
|
})
|
|
2258
|
+
console.log({ status })
|
|
2259
|
+
if (status == 500) {
|
|
2260
|
+
ModalInput({
|
|
2261
|
+
description: html,
|
|
2262
|
+
confirm: "OK",
|
|
2263
|
+
customClass: {
|
|
2264
|
+
popup: "full-popup",
|
|
2265
|
+
title: "full-title"
|
|
2266
|
+
}
|
|
2267
|
+
})
|
|
2268
|
+
return
|
|
2269
|
+
}
|
|
2205
2270
|
document.querySelector(".menu").innerHTML = html
|
|
2206
2271
|
|
|
2207
2272
|
<% if (type !== 'run') { %>
|
|
@@ -2342,7 +2407,7 @@ body.dark .mode-selector .btn2.selected {
|
|
|
2342
2407
|
}).then((res) => {
|
|
2343
2408
|
console.log("STATE", res)
|
|
2344
2409
|
let selection
|
|
2345
|
-
if (res.selected) {
|
|
2410
|
+
if (res && res.selected) {
|
|
2346
2411
|
selection = document.querySelector(`[href='${res.selected}']`)
|
|
2347
2412
|
} else {
|
|
2348
2413
|
selection = document.querySelector("#devtab")
|
package/server/views/d.ejs
CHANGED
|
@@ -20,7 +20,9 @@ main {
|
|
|
20
20
|
width: 100%;
|
|
21
21
|
box-sizing: border-box;
|
|
22
22
|
display: flex;
|
|
23
|
+
/*
|
|
23
24
|
flex-wrap: wrap;
|
|
25
|
+
*/
|
|
24
26
|
padding: 20px;
|
|
25
27
|
/*
|
|
26
28
|
justify-content: center;
|
|
@@ -29,8 +31,8 @@ main {
|
|
|
29
31
|
.tab-content {
|
|
30
32
|
display: flex;
|
|
31
33
|
flex-wrap: wrap;
|
|
32
|
-
gap:
|
|
33
|
-
padding: 10px
|
|
34
|
+
gap: 15px;
|
|
35
|
+
padding: 10px 0px 0;
|
|
34
36
|
}
|
|
35
37
|
.submenu.tab {
|
|
36
38
|
margin: 10px 0;
|
|
@@ -41,7 +43,10 @@ main {
|
|
|
41
43
|
}
|
|
42
44
|
*/
|
|
43
45
|
.tab {
|
|
46
|
+
/*
|
|
44
47
|
min-width: 250px;
|
|
48
|
+
*/
|
|
49
|
+
width: 100%;
|
|
45
50
|
text-decoration: none;
|
|
46
51
|
display: flex;
|
|
47
52
|
/*
|
|
@@ -51,10 +56,9 @@ main {
|
|
|
51
56
|
font-weight: bold;
|
|
52
57
|
color: black;
|
|
53
58
|
overflow: hidden;
|
|
54
|
-
margin: 10px;
|
|
55
59
|
box-sizing: border-box;
|
|
56
|
-
border-radius:
|
|
57
|
-
align-items:
|
|
60
|
+
border-radius: 10px;
|
|
61
|
+
align-items: flex-start;
|
|
58
62
|
padding: 10px 15px;
|
|
59
63
|
/*
|
|
60
64
|
width: 120px;
|
|
@@ -70,7 +74,9 @@ body.dark .tab {
|
|
|
70
74
|
background: rgba(255,255,255,0.03);
|
|
71
75
|
}
|
|
72
76
|
.tab h2 {
|
|
77
|
+
/*
|
|
73
78
|
padding: 5px 2px 10px;
|
|
79
|
+
*/
|
|
74
80
|
/*
|
|
75
81
|
text-align: center;
|
|
76
82
|
*/
|
|
@@ -88,7 +94,7 @@ body.dark .tab {
|
|
|
88
94
|
color: black;
|
|
89
95
|
display: flex;
|
|
90
96
|
justify-content: center;
|
|
91
|
-
font-size:
|
|
97
|
+
font-size: 30px;
|
|
92
98
|
align-items: center;
|
|
93
99
|
border-radius: 3px;
|
|
94
100
|
}
|
|
@@ -117,39 +123,74 @@ body.dark .tab i {
|
|
|
117
123
|
}
|
|
118
124
|
*/
|
|
119
125
|
.menu-container {
|
|
120
|
-
|
|
126
|
+
/*
|
|
127
|
+
border: 15px solid rgba(0,0,0,0.04);
|
|
121
128
|
background: white;
|
|
129
|
+
border-radius: 20px;
|
|
130
|
+
*/
|
|
122
131
|
}
|
|
132
|
+
/*
|
|
123
133
|
body.dark .menu-container {
|
|
124
134
|
background: rgba(255,255,255,0.03);
|
|
125
135
|
}
|
|
136
|
+
*/
|
|
126
137
|
.menu-container {
|
|
127
138
|
width: 100%;
|
|
128
139
|
box-sizing: border-box;
|
|
129
140
|
margin: 20px;
|
|
130
141
|
}
|
|
131
142
|
body.dark .tab-header {
|
|
143
|
+
/*
|
|
132
144
|
background: rgba(0,0,0,0.3);
|
|
145
|
+
*/
|
|
146
|
+
/*
|
|
147
|
+
border-left: 10px solid white;
|
|
148
|
+
*/
|
|
133
149
|
}
|
|
134
150
|
.tab-header {
|
|
151
|
+
padding: 0 5px;
|
|
152
|
+
/*
|
|
135
153
|
background: rgba(0,0,0,0.04);
|
|
136
|
-
|
|
154
|
+
*/
|
|
155
|
+
/*
|
|
156
|
+
padding: 8px 10px;
|
|
157
|
+
*/
|
|
137
158
|
font-weight: bold;
|
|
159
|
+
/*
|
|
160
|
+
border-left: 10px solid black;
|
|
161
|
+
*/
|
|
138
162
|
}
|
|
139
163
|
.container {
|
|
140
164
|
margin: 0;
|
|
141
165
|
padding: 0 !important;
|
|
142
166
|
}
|
|
167
|
+
.subtitle {
|
|
168
|
+
font-size: 12px;
|
|
169
|
+
opacity: 0.6;
|
|
170
|
+
padding: 2px;
|
|
171
|
+
}
|
|
143
172
|
.btns {
|
|
144
173
|
display: flex;
|
|
174
|
+
padding-top: 10px;
|
|
175
|
+
gap: 5px;
|
|
145
176
|
}
|
|
146
177
|
body.dark .btn {
|
|
147
178
|
background: rgba(255,255,255,0.08);
|
|
179
|
+
color: white;
|
|
180
|
+
border: none;
|
|
148
181
|
}
|
|
149
182
|
.btn {
|
|
150
183
|
padding: 7px 10px;
|
|
184
|
+
background: none;
|
|
185
|
+
background: rgba(0,0,0,0.08);
|
|
186
|
+
color: rgba(0,0,0,0.7);
|
|
187
|
+
/*
|
|
188
|
+
border: 1px solid rgba(0,0,0,0.4);
|
|
189
|
+
*/
|
|
190
|
+
border-radius: 30px;
|
|
191
|
+
/*
|
|
151
192
|
background: rgba(0,0,0,0.8);
|
|
152
|
-
|
|
193
|
+
*/
|
|
153
194
|
}
|
|
154
195
|
.btn.run-btn {
|
|
155
196
|
flex-grow: 1;
|
|
@@ -159,6 +200,37 @@ body.dark .btn {
|
|
|
159
200
|
background: royalblue !important;
|
|
160
201
|
*/
|
|
161
202
|
}
|
|
203
|
+
.tab-header h3 {
|
|
204
|
+
margin: 0;
|
|
205
|
+
font-size: 16px;
|
|
206
|
+
}
|
|
207
|
+
.tab-header h3 i {
|
|
208
|
+
font-size: 18px;
|
|
209
|
+
}
|
|
210
|
+
header {
|
|
211
|
+
padding: 50px 40px 0;
|
|
212
|
+
display: flex;
|
|
213
|
+
gap: 10px;
|
|
214
|
+
}
|
|
215
|
+
header h1 {
|
|
216
|
+
font-size: 40px;
|
|
217
|
+
}
|
|
218
|
+
.pulling {
|
|
219
|
+
display: flex;
|
|
220
|
+
justify-content: center;
|
|
221
|
+
flex-direction: column;
|
|
222
|
+
}
|
|
223
|
+
.pulling i {
|
|
224
|
+
/*
|
|
225
|
+
font-size: 20px;
|
|
226
|
+
*/
|
|
227
|
+
}
|
|
228
|
+
.pulling .loading {
|
|
229
|
+
display: flex;
|
|
230
|
+
flex-direction: row;
|
|
231
|
+
align-items: center;
|
|
232
|
+
gap: 5px;
|
|
233
|
+
}
|
|
162
234
|
</style>
|
|
163
235
|
<script src="/hotkeys.min.js"></script>
|
|
164
236
|
<script src="/sweetalert2.js"></script>
|
|
@@ -167,11 +239,26 @@ body.dark .btn {
|
|
|
167
239
|
<script src="/nav.js"></script>
|
|
168
240
|
</head>
|
|
169
241
|
<body class='<%=theme%>' data-agent="<%=agent%>">
|
|
242
|
+
<header>
|
|
243
|
+
<h1>Build</h1>
|
|
244
|
+
<a class='btn' href="https://github.com/pinokiocomputer/code/issues" target="_blank"><i class="fa-solid fa-up-right-from-square"></i> Request a tool</a>
|
|
245
|
+
<a class='btn' id='git-pull'><i class="fa-solid fa-rotate"></i> Check for new tools</a>
|
|
246
|
+
<div class='pulling hidden'>
|
|
247
|
+
<div class='loading'>
|
|
248
|
+
<i class="fa-solid fa-circle-notch fa-spin"></i> refreshing...
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
</header>
|
|
170
252
|
<main>
|
|
171
253
|
<% dynamic.forEach((item, index) => { %>
|
|
172
254
|
<% if (item.menu) { %>
|
|
173
255
|
<div class='menu-container'>
|
|
174
|
-
<div class='tab-header'
|
|
256
|
+
<div class='tab-header'>
|
|
257
|
+
<h3><i class='<%=item.icon%>'></i> <%=item.title%></h3>
|
|
258
|
+
<% if (item.subtitle) { %>
|
|
259
|
+
<div class='subtitle'><%=item.subtitle%></div>
|
|
260
|
+
<% } %>
|
|
261
|
+
</div>
|
|
175
262
|
<div class='tab-content'>
|
|
176
263
|
<% item.menu.forEach((i) => { %>
|
|
177
264
|
<div class='tab'>
|
|
@@ -182,8 +269,11 @@ body.dark .btn {
|
|
|
182
269
|
<% } %>
|
|
183
270
|
<div class='col'>
|
|
184
271
|
<h2><%=i.title%></h1>
|
|
272
|
+
<% if (i.subtitle) { %>
|
|
273
|
+
<div class='subtitle'><%=i.subtitle%></div>
|
|
274
|
+
<% } %>
|
|
185
275
|
<div class='btns'>
|
|
186
|
-
<a class='run-btn btn' href="<%=i.href%>"><i class="fa-solid fa-play"></i>
|
|
276
|
+
<a class='run-btn btn' href="<%=i.href%>"><i class="fa-solid <%=i.type === "Start" ? 'fa-play' : 'fa-rocket'%>"></i> <%=i.type%></a>
|
|
187
277
|
<a class='btn' target="_blank" href="<%=i.link%>"><i class="fa-solid fa-question"></i></a>
|
|
188
278
|
</div>
|
|
189
279
|
</div>
|
|
@@ -196,8 +286,11 @@ body.dark .btn {
|
|
|
196
286
|
<img src="<%=item.image%>">
|
|
197
287
|
<div class='col'>
|
|
198
288
|
<h2><%=item.title%></h1>
|
|
289
|
+
<% if (item.subtitle) { %>
|
|
290
|
+
<div class='subtitle'><%=item.subtitle%></div>
|
|
291
|
+
<% } %>
|
|
199
292
|
<div class='btns'>
|
|
200
|
-
<a class='run-btn btn' href="<%=item.href%>"><i class="fa-solid fa-play"></i>
|
|
293
|
+
<a class='run-btn btn' href="<%=item.href%>"><i class="fa-solid <%=item.type === "Start" ? 'fa-play' : 'fa-rocket'%>"></i> <%=item.type%></a>
|
|
201
294
|
<a class='btn' target="_blank" href="<%=item.link%>"><i class="fa-solid fa-question"></i></a>
|
|
202
295
|
</div>
|
|
203
296
|
</div>
|
|
@@ -220,6 +313,24 @@ setTimeout(() => {
|
|
|
220
313
|
location.href = location.href
|
|
221
314
|
}, 2000)
|
|
222
315
|
<% } %>
|
|
316
|
+
document.querySelector("#git-pull").addEventListener("click", (e) => {
|
|
317
|
+
e.preventDefault()
|
|
318
|
+
e.stopPropagation()
|
|
319
|
+
document.querySelector(".pulling").classList.remove("hidden")
|
|
320
|
+
document.querySelector("#git-pull").classList.add("hidden")
|
|
321
|
+
fetch("/plugin/update", {
|
|
322
|
+
method: "POST"
|
|
323
|
+
}).then((res) => {
|
|
324
|
+
return res.json()
|
|
325
|
+
}).then((res) => {
|
|
326
|
+
if (res.success) {
|
|
327
|
+
location.href = location.href
|
|
328
|
+
} else if(res.error) {
|
|
329
|
+
document.querySelector("#git-pull").classList.remove("hidden")
|
|
330
|
+
alert(res.error)
|
|
331
|
+
}
|
|
332
|
+
})
|
|
333
|
+
})
|
|
223
334
|
</script>
|
|
224
335
|
</body>
|
|
225
336
|
</html>
|
package/server/views/index.ejs
CHANGED
|
@@ -18,6 +18,35 @@
|
|
|
18
18
|
<link href="/electron.css" rel="stylesheet"/>
|
|
19
19
|
<% } %>
|
|
20
20
|
<style>
|
|
21
|
+
.bubble {
|
|
22
|
+
position: relative;
|
|
23
|
+
background: rgba(0,0,0,0.1);
|
|
24
|
+
color: #333;
|
|
25
|
+
border-radius: 10px;
|
|
26
|
+
padding: 10px 15px;
|
|
27
|
+
font-size: 14px;
|
|
28
|
+
flex-grow: 1;
|
|
29
|
+
line-height: 1.4;
|
|
30
|
+
margin: 0 10px;
|
|
31
|
+
font-weight: bold;
|
|
32
|
+
}
|
|
33
|
+
/* Left-side tail */
|
|
34
|
+
.bubble::before {
|
|
35
|
+
content: "";
|
|
36
|
+
position: absolute;
|
|
37
|
+
top: 10px; /* Vertical alignment of the tail */
|
|
38
|
+
left: -20px; /* Positioning outside the bubble */
|
|
39
|
+
border-width: 10px;
|
|
40
|
+
border-style: solid;
|
|
41
|
+
border-color: transparent rgba(0,0,0,0.1) transparent transparent;
|
|
42
|
+
}
|
|
43
|
+
body.dark .bubble {
|
|
44
|
+
background: rgba(0,0,0,0.4);
|
|
45
|
+
color: white;
|
|
46
|
+
}
|
|
47
|
+
body.dark .bubble:before {
|
|
48
|
+
border-color: transparent rgba(0,0,0,0.4) transparent transparent;
|
|
49
|
+
}
|
|
21
50
|
.line2 {
|
|
22
51
|
display: flex;
|
|
23
52
|
align-items: center;
|
|
@@ -253,11 +282,33 @@ aside .tab.selected {
|
|
|
253
282
|
font-weight: bold;
|
|
254
283
|
opacity: 1;
|
|
255
284
|
}
|
|
285
|
+
#suggestion {
|
|
286
|
+
padding: 20px;
|
|
287
|
+
display: flex;
|
|
288
|
+
align-items: center;
|
|
289
|
+
}
|
|
290
|
+
#suggestion img {
|
|
291
|
+
width: 50px;
|
|
292
|
+
height: 50px;
|
|
293
|
+
}
|
|
294
|
+
#suggestion h4 {
|
|
295
|
+
margin: 0;
|
|
296
|
+
}
|
|
297
|
+
/*
|
|
298
|
+
#suggestion .prompt {
|
|
299
|
+
padding: 10px 15px;
|
|
300
|
+
margin: 10px 0;
|
|
301
|
+
border-left: 10px solid rgba(0,0,0,0.1);
|
|
302
|
+
}
|
|
303
|
+
*/
|
|
256
304
|
body.dark aside .current.selected {
|
|
257
305
|
/*
|
|
258
306
|
border-left: 10px solid white;
|
|
259
307
|
*/
|
|
260
308
|
}
|
|
309
|
+
.container {
|
|
310
|
+
margin-right: 20px;
|
|
311
|
+
}
|
|
261
312
|
@media only screen and (max-width: 480px) {
|
|
262
313
|
.btn2 {
|
|
263
314
|
padding: 5px;
|
|
@@ -380,7 +431,6 @@ body.dark aside .current.selected {
|
|
|
380
431
|
<a href="/net/<%=name%>" class='submenu tab'><i class="fa-brands fa-<%=brands[platform]%>"></i> <%=name%> (<%=current_host === host ? 'this machine' : host%>)</a>
|
|
381
432
|
<% }) %>
|
|
382
433
|
<% } %>
|
|
383
|
-
<div class='tab'><i class="fa-solid fa-code"></i> Dev</div>
|
|
384
434
|
</aside>
|
|
385
435
|
<div class='container'>
|
|
386
436
|
<% if (ishome) { %>
|
|
@@ -401,6 +451,13 @@ body.dark aside .current.selected {
|
|
|
401
451
|
</form>
|
|
402
452
|
<% } %>
|
|
403
453
|
<% if (ishome) { %>
|
|
454
|
+
<!--
|
|
455
|
+
<div id='suggestion' class='hidden'>
|
|
456
|
+
<img src="/pinokio-black.png"/>
|
|
457
|
+
<div class='bubble prompt'></div>
|
|
458
|
+
<button id='create-ai' class='btn'>Create</button>
|
|
459
|
+
</div>
|
|
460
|
+
-->
|
|
404
461
|
<% if (running.length > 0) { %>
|
|
405
462
|
<div class='running-apps'>
|
|
406
463
|
<% running.forEach((item) => { %>
|
|
@@ -758,7 +815,18 @@ const renderSearch = () => {
|
|
|
758
815
|
}
|
|
759
816
|
}
|
|
760
817
|
|
|
818
|
+
// suggest(target.value)
|
|
819
|
+
|
|
761
820
|
}
|
|
821
|
+
//const suggest = (str) => {
|
|
822
|
+
// // suggestion
|
|
823
|
+
// if (str.length > 0) {
|
|
824
|
+
// document.querySelector("#suggestion").classList.remove("hidden")
|
|
825
|
+
// } else {
|
|
826
|
+
// document.querySelector("#suggestion").classList.add("hidden")
|
|
827
|
+
// }
|
|
828
|
+
// document.querySelector("#suggestion .prompt").innerHTML = str
|
|
829
|
+
//}
|
|
762
830
|
|
|
763
831
|
renderSearch()
|
|
764
832
|
|