pinokiod 1.0.30 → 1.0.32

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/shell.js CHANGED
@@ -31,6 +31,11 @@ class Shell {
31
31
  this.platform = os.platform()
32
32
  this.logs = {}
33
33
  this.shell = this.platform === 'win32' ? 'cmd.exe' : 'bash';
34
+
35
+ // Windows: /D => ignore AutoRun Registry Key
36
+ // Others: --noprofile => ignore .bash_profile, --norc => ignore .bashrc
37
+ this.args = this.platform === 'win32' ? ["/D"] : ["--noprofile", "--norc"]
38
+
34
39
  //this.vt = new Terminal({ allowProposedApi: true, scrollback: 5, })
35
40
  // this.vt = new Terminal({
36
41
  // allowProposedApi: true,
@@ -113,6 +118,9 @@ class Shell {
113
118
  this.env.GRADIO_TEMP_DIR = path.resolve(this.kernel.homedir, "cache", "GRADIO_TEMP_DIR")
114
119
  this.env.PIP_CONFIG_FILE = path.resolve(this.kernel.homedir, "pipconfig")
115
120
 
121
+ this.env.PS1 = "<<PINOKIO SHELL>> "
122
+ // this.env.PROMPT_COMMAND = "export PS1=\"<<PINOKIO SHELL>> \""
123
+
116
124
  let PATH_KEY;
117
125
  if (this.env.Path) {
118
126
  PATH_KEY = "Path"
@@ -182,6 +190,8 @@ class Shell {
182
190
  // automatically add self to the shells registry
183
191
  this.kernel.shell.add(this)
184
192
 
193
+ console.log("** this.env", this.env)
194
+
185
195
  if (params.sudo) {
186
196
  let options = {
187
197
  name: "Pinokio",
@@ -352,7 +362,7 @@ class Shell {
352
362
  //let re = /([\r\n]+[^\r\n]+)(\1)/gs
353
363
  let re = /(.+)(\1)/gs
354
364
  console.log("get prompt - pty.spawn", config)
355
- let term = pty.spawn(this.shell, [], config)
365
+ let term = pty.spawn(this.shell, this.args, config)
356
366
  console.log("terminal spawned", term)
357
367
  let ready
358
368
  console.log("create terminal for prompt")
@@ -544,7 +554,7 @@ class Shell {
544
554
  if (!this.ptyProcess) {
545
555
  // ptyProcess doesn't exist => create
546
556
  this.done = false
547
- this.ptyProcess = pty.spawn(this.shell, [], config)
557
+ this.ptyProcess = pty.spawn(this.shell, this.args, config)
548
558
  this.ptyProcess.onData((data) => {
549
559
  if (!this.done) {
550
560
  this.queue.push(data)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "1.0.30",
3
+ "version": "1.0.32",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/server/index.js CHANGED
@@ -343,6 +343,7 @@ class Server {
343
343
  } else if (pathComponents.length === 0 && req.query.mode === "settings") {
344
344
  let configArray = [{
345
345
  key: "home",
346
+ description: "* Do NOT use exFAT drives",
346
347
  val: this.kernel.homedir,
347
348
  placeholder: "Enter the absolute path to use as your Pinokio home folder (D:\\pinokio, /Users/alice/pinokiofs, etc.)"
348
349
  }, {
@@ -351,6 +352,7 @@ class Server {
351
352
  options: ["light", "dark"]
352
353
  }]
353
354
  console.log("agent", this.agent)
355
+ console.log({ configArray })
354
356
  res.render("settings", {
355
357
  version: this.version,
356
358
  logo: this.logo,
@@ -1168,10 +1170,16 @@ class Server {
1168
1170
  }
1169
1171
  }
1170
1172
  }
1173
+ config.menu[i].target = "@" + (config.menu[i].id || config.menu[i].src)
1171
1174
  }
1175
+
1176
+
1172
1177
  config.menu = config.menu.filter((item) => {
1173
1178
  return item.btn
1174
1179
  })
1180
+
1181
+
1182
+
1175
1183
  console.log("config", JSON.stringify(config,null,2))
1176
1184
  return config
1177
1185
  } else {
@@ -1602,6 +1610,7 @@ class Server {
1602
1610
  if (req.query.mode === 'settings') {
1603
1611
  let configArray = [{
1604
1612
  key: "home",
1613
+ description: "* Do NOT use exFAT drives",
1605
1614
  val: this.kernel.homedir ? this.kernel.homedir : path.resolve(os.homedir(), "pinokio"),
1606
1615
  placeholder: "Enter the absolute path to use as your Pinokio home folder (D:\\pinokio, /Users/alice/pinokiofs, etc.)"
1607
1616
  }, {
@@ -1849,9 +1858,25 @@ class Server {
1849
1858
  theme: this.theme,
1850
1859
  agent: this.agent,
1851
1860
  src: "/_api/" + name,
1852
- rawpath
1861
+ rawpath,
1853
1862
  })
1854
1863
  })
1864
+ this.app.post("/pinokio/delete", async (req, res) => {
1865
+ if (req.body.name) {
1866
+ let folderPath = this.kernel.path("api", req.body.name)
1867
+ console.log("delete", folderPath)
1868
+ await rimraf(folderPath)
1869
+ await new Promise((resolve, reject) => {
1870
+ setTimeout(() => {
1871
+ resolve()
1872
+ }, 5000)
1873
+ })
1874
+ console.log("deleted")
1875
+ res.json({ success: true })
1876
+ } else {
1877
+ res.json({ error: e.stack })
1878
+ }
1879
+ })
1855
1880
  // this.app.get("/pinokio/shell_state", (req, res) => {
1856
1881
  // let states = this.kernel.shell.shells.map((s) => {
1857
1882
  // return {
@@ -135,7 +135,8 @@ const createTerm = () => {
135
135
  //theme: xtermTheme.Piatto_Light,
136
136
  //theme: xtermTheme.Github,
137
137
  //theme: xtermTheme.Cobalt_Neon, // top legibility
138
- theme: xtermTheme.Duotone_Dark,
138
+ //theme: xtermTheme.Duotone_Dark,
139
+ theme: xtermTheme.FrontEndDelight,
139
140
  //theme: xtermTheme.Seafoam_Pastel,
140
141
  //theme: xtermTheme.IC_Green_PPL,
141
142
  //theme: xtermTheme.FunForrest,
@@ -7,19 +7,21 @@
7
7
  */
8
8
  /*
9
9
  --dark-nav-bg: #161616;
10
- */
11
10
  --dark-nav-bg: rgb(31, 29, 39);
11
+ */
12
+ --dark-nav-bg: rgb(27, 28, 29);
12
13
 
14
+ --dark-bg: rgb(27, 28, 29);
13
15
  /*
14
16
  --dark-bg: #202020;
15
- */
16
17
  --dark-bg: rgb(31, 29, 39);
18
+ */
17
19
  --light-bg: rgba(0,0,150,0.05);
18
20
 
19
21
  --light-thin: rgba(0,0,0,0.1);
20
22
  --dark-thin: rgba(255,255,255,0.03);
21
23
 
22
- --dark-color: rgba(255,255,255,0.9);
24
+ --dark-color: rgba(255,255,255,0.8);
23
25
  --light-color: rgba(0,0,0,0.9);
24
26
 
25
27
  --dark-fade: rgba(255,255,255,0.6);
@@ -43,7 +45,10 @@
43
45
  --light-btn-color: white;
44
46
 
45
47
  --dark-btn-bg: rgba(0,0,0,0.8);
48
+ /*
46
49
  --dark-btn-color: #b7a1ff;
50
+ */
51
+ --dark-btn-color: whitesmoke;
47
52
  }
48
53
  body.columns footer {
49
54
  }
@@ -77,14 +82,19 @@ footer pre {
77
82
  background: none !important;
78
83
  }
79
84
  footer {
85
+ font-family: verdana;
80
86
  overflow: hidden;
87
+ font-size: 11px;
88
+ font-weight: normal;
81
89
  /*
82
90
  overflow: auto;
83
91
  */
84
92
  box-sizing: border-box;
85
93
  color: var(--dark-color);
86
94
  background: var(--dark-bg);
95
+ /*
87
96
  border-top: 1px solid rgba(255,255,255,0.05);
97
+ */
88
98
  display: flex;
89
99
  align-items: center;
90
100
  padding: 10px;
@@ -99,6 +109,8 @@ footer b {
99
109
  flex-shrink: 0;
100
110
  color: var(--dark-btn-color);
101
111
  margin-right: 10px;
112
+ font-weight: normal;
113
+ font-size: 11px;
102
114
  /*
103
115
  background: var(--dark-btn-color);
104
116
  color: var(--dark-bg);
@@ -837,9 +849,12 @@ body.dark .line:hover {
837
849
  vertical-align: middle;
838
850
  font-weight: normal;
839
851
  }
852
+ body.dark .line .avatar i {
853
+ color: var(--dark-btn-color);
854
+ }
840
855
  .line .avatar i {
841
856
  font-size: 60px;
842
- color: var(--dark-btn-color);
857
+ color: var(--dark-bg);
843
858
  }
844
859
  .line .description {
845
860
  font-size: 13px;
@@ -132,7 +132,8 @@ document.addEventListener("DOMContentLoaded", () => {
132
132
  //theme: xtermTheme.Seafoam_Pastel,
133
133
  //theme: xtermTheme.IC_Green_PPL,
134
134
  //theme: xtermTheme.FunForrest,
135
- theme: xtermTheme.Jackie_Brown,
135
+ //theme: xtermTheme.Jackie_Brown,
136
+ theme: xtermTheme.FrontEndDelight,
136
137
  //theme: xtermTheme.Ocean,
137
138
 
138
139
  //theme: xtermTheme.Blazer,
@@ -30,6 +30,12 @@ body {
30
30
  .menu {
31
31
  overflow: auto;
32
32
  }
33
+ body.dark .m {
34
+ border-top: 1px solid rgba(255,255,255,0.04);
35
+ }
36
+ .m {
37
+ border-top: 1px solid rgba(0,0,0,0.04);
38
+ }
33
39
  .container {
34
40
  display: flex;
35
41
  flex-direction: column;
@@ -196,6 +202,9 @@ body.dark .header-item.cursor {
196
202
  border-left: 5px solid gold;
197
203
  */
198
204
  }
205
+ .frame-link {
206
+ cursor: pointer;
207
+ }
199
208
  body .frame-link.selected {
200
209
  /*
201
210
  border-right: 10px solid gold;
@@ -210,7 +219,10 @@ body .frame-link.selected {
210
219
  color: white;
211
220
  }
212
221
  body.dark .frame-link.selected {
213
- background: rgba(0,0,0,0.2) !important;
222
+ background: rgba(0,0,0,0.7) !important;
223
+ }
224
+ .frame-link .loader {
225
+ padding: 5px;
214
226
  }
215
227
  .frame-link .tab {
216
228
  flex-grow: 1;
@@ -218,7 +230,9 @@ body.dark .frame-link.selected {
218
230
  width: 100%;
219
231
  */
220
232
  word-break: break-word;
233
+ /*
221
234
  margin-right: 10px;
235
+ */
222
236
  }
223
237
  .frame-link .tab .flexible {
224
238
  min-width: 5px;
@@ -265,22 +279,31 @@ body.dark .grid-btns .btn2 {
265
279
  margin-right: 10px;
266
280
  }
267
281
  .temp-menu {
282
+ /*
268
283
  border-top: 1px solid rgba(0,0,0,0.1);
284
+ */
269
285
  }
270
286
  .temp-menu .del i {
271
287
  margin: 0;
272
288
  }
289
+ #delete {
290
+ color: brown;
291
+ }
273
292
  body .footer {
274
293
  }
275
294
  body.dark nav {
295
+ /*
276
296
  border-bottom: 1px solid rgba(255,255,255,0.04);
297
+ */
277
298
  }
278
299
  nav {
279
300
  background: white;
280
301
  padding: 5px;
281
302
  cursor: grab !important;
282
303
  -webkit-app-region: drag !important;
304
+ /*
283
305
  border-bottom: 1px solid rgba(0,0,0,0.04);
306
+ */
284
307
  box-sizing: border-box;
285
308
  }
286
309
  nav .btn2 {
@@ -293,7 +316,8 @@ nav .logo {
293
316
  }
294
317
  #location {
295
318
  padding: 5px;
296
- font-size: 14px;
319
+ font-size: 12px;
320
+ font-family: verdana;
297
321
  }
298
322
  .bar {
299
323
  -webkit-app-region: no-drag !important;
@@ -333,6 +357,21 @@ body.dark #new-tab {
333
357
  padding-left: 15px;
334
358
  box-sizing: border-box;
335
359
  }
360
+ body.dark .loader-popup {
361
+ background: rgba(0,0,0,0.2);
362
+ color: whitesmoke;
363
+ }
364
+ .loader-popup {
365
+ text-transform: uppercase;
366
+ font-size: 12px;
367
+ letter-spacing: 1px;
368
+ padding: 20px;
369
+ background: rgba(0,0,0,0.2);
370
+ color: white;
371
+ }
372
+ body.dark .loader-container {
373
+ background: rgba(255,255,255,0.3);
374
+ }
336
375
  </style>
337
376
  </head>
338
377
  <body class='<%=theme%>'>
@@ -343,9 +382,12 @@ body.dark #new-tab {
343
382
  <div><%=config.title%></div>
344
383
  </div>
345
384
  </div>
346
- <div class='m system'>
385
+ <div class='m n system' data-type="n">
347
386
  <!--<a data-index="0" target="<%=src%>" href="<%=src%>" class='btn header-item frame-link'>-->
348
- <a target="<%=src%>" href="<%=src%>" class='btn header-item frame-link'>
387
+ <div id='delete' data-name="<%=name%>" class='btn header-item frame-link'>
388
+ <div class='tab'><i class="fa-solid fa-trash-can"></i> Delete</div>
389
+ </div>
390
+ <a target="<%=src%>" href="<%=src%>" class='btn header-item frame-link' data-index="0">
349
391
  <div class='tab'><i class="fa-regular fa-folder-open"></i> Files</div>
350
392
  </a>
351
393
  </div>
@@ -399,12 +441,14 @@ body.dark #new-tab {
399
441
  -->
400
442
  </nav>
401
443
  <main class='browserview'>
402
- <% if (false && config.menu) { %>
403
- <% config.menu.forEach((item) => { %>
404
- <% if (item.btn && item.src) { %>
405
- <iframe name='<%=item.src%>' class='hidden'></iframe>
406
- <% } %>
407
- <% }) %>
444
+ <% if (false) { %>
445
+ <% if (config.menu) { %>
446
+ <% config.menu.forEach((item) => { %>
447
+ <% if (item.btn && item.src) { %>
448
+ <iframe name='<%=item.src%>' class='hidden'></iframe>
449
+ <% } %>
450
+ <% }) %>
451
+ <% } %>
408
452
  <% } %>
409
453
  </main>
410
454
  </div>
@@ -425,6 +469,35 @@ const getTarget = (href) => {
425
469
  return u.pathname
426
470
  }
427
471
  }
472
+ const subUrlOf = (s, f) => {
473
+ debugger
474
+
475
+ let subsetUrl = (s.startsWith("http") ? s : "http://localhost" + s)
476
+ let fullUrl = (f.startsWith("http") ? f: "http://localhost" + f)
477
+
478
+ const subsetParsed = new URL(subsetUrl)
479
+ const fullParsed = new URL(fullUrl)
480
+
481
+ if (subsetParsed.pathname !== fullParsed.pathname) {
482
+ return false;
483
+ }
484
+
485
+ // Check if all search parameters in the subset URL are present in the full URL
486
+ for (const [key, val] of subsetParsed.searchParams) {
487
+
488
+ if (!fullParsed.searchParams.has(key)) {
489
+ return false
490
+ }
491
+ console.log("key", key)
492
+ console.log("f", fullParsed.searchParams.get(key))
493
+ console.log("s", val)
494
+ if (fullParsed.searchParams.get(key) !== val) {
495
+ return false
496
+ }
497
+ }
498
+
499
+ return true;
500
+ }
428
501
  const renderCursor = () => {
429
502
  document.querySelectorAll(".selectable").forEach((el) => {
430
503
  el.classList.remove("cursor")
@@ -462,10 +535,18 @@ const renderSelection = (e, force) => {
462
535
  document.querySelector(".bar").classList.remove("hidden")
463
536
  //let id = getTarget(location.hash.slice(1))
464
537
  let id = location.hash.slice(1)
465
- let type = id[0]
466
- let index = id.slice(1)
467
538
 
468
- console.log({ type, index })
539
+
540
+ let selector
541
+ if (id.startsWith("@")) {
542
+ selector = `aside [target='${id.slice(1)}']`
543
+ } else {
544
+ let type = id[0]
545
+ let index = id.slice(1)
546
+ console.log({ type, index })
547
+ selector = `aside .${type} [data-index='${index}']`
548
+ }
549
+
469
550
 
470
551
  // select the selected link
471
552
  // document.querySelectorAll(".frame-link").forEach((el) => {
@@ -475,107 +556,162 @@ console.log({ type, index })
475
556
 
476
557
 
477
558
  // const target = document.querySelector(`[target='${id}']`)
559
+
560
+
478
561
  let target
479
562
  if (e) {
563
+ // If the renderSelection is triggered by an event, look for the frame-link that's triggering the event
480
564
  if (e.target.classList.contains("frame-link")) {
481
565
  target = e.target
482
566
  } else {
483
567
  target = e.target.closest(".frame-link")
484
568
  }
569
+ } else {
570
+ // if not triggered by an event, look for the target from the location hash
571
+ target = document.querySelector(selector)
485
572
  }
486
573
 
487
574
 
488
- if (!target) {
489
- // find target by id
490
- //target = document.querySelector("aside [target='" + id + "']")
491
- target = document.querySelector(`aside .${type} [data-index='${index}']`)
492
- }
575
+ // if the target was found either through:
576
+ // 1. looking for the frame-link that triggered the event
577
+ // 2. or by looking at the location hash
578
+ //
579
+ // => select that tab and frame
493
580
 
494
581
  if (target) {
495
582
  console.log("# 3")
496
583
 
497
584
 
585
+ // Instantiate a frame with the selected target's href
498
586
  let url = target.href
587
+ console.log("> url", url)
499
588
  document.querySelector("#open-browser").href = url
500
589
  document.querySelector("#clone-tab").setAttribute("data-href", url)
501
590
  document.querySelector("#location").innerHTML = url
502
591
 
503
- // document.querySelector("#location").innerHTML = location.hash.slice(1)
504
- //
505
- // if (location.hash.slice(1).startsWith("/")) {
506
- // //document.querySelector("#open-browser").classList.add("hidden")
507
- // document.querySelector("#open-browser").classList.remove("hidden")
508
- // document.querySelector("#open-browser").href = location.hash.slice(1)
509
- // } else {
510
- // document.querySelector("#open-browser").classList.remove("hidden")
511
- // //document.querySelector("#open-browser").href = id
512
- // document.querySelector("#open-browser").href = location.hash.slice(1)
513
- // }
514
- // document.querySelector("#clone-tab").setAttribute("data-href", location.hash.slice(1))
515
-
516
-
517
592
 
593
+ // select the selected target element (tab)
518
594
  target.classList.add("selected")
519
595
 
520
- // select the iframe
596
+ // hide all frames
521
597
  document.querySelectorAll("iframe").forEach((el) => {
522
598
  el.classList.add("hidden")
523
599
  })
524
- let targetFrame = document.querySelector(`iframe[name='${target.target}']`)
525
- if (targetFrame) {
526
- targetFrame.classList.remove("hidden")
527
600
 
528
- // if the iframe already exists, do not
529
- if (loaded[target.target]){
530
601
 
531
- let mode = target.getAttribute("data-mode")
532
- if (mode === "refresh") {
533
- targetFrame.src = target.href
534
- return
602
+ debugger
603
+
604
+ // Look for the frame
605
+ // 1. if it's hard (".h")
606
+ // look for the url that matches
607
+ // 2. if it's soft (".s")
608
+ // find using the name attribute
609
+ let targetFrame;
610
+ if (target.closest(".h")) {
611
+ let hardFrames = document.querySelectorAll(".browserview iframe[name^='@']")
612
+ let port = new URL(target.href).port
613
+ for(let frame of hardFrames) {
614
+ console.log({ src: frame.src, href: target.href, target: target.target })
615
+ // Types of links in the tab
616
+ if (String(port) === "42000") {
617
+ // 1. running from 42000 => find a frame whose base URL matches the tab's base URL
618
+ // Pinokio links
619
+ let targetPath = new URL(target.href).pathname
620
+ let framePath = new URL(frame.src).pathname
621
+ if (targetPath === framePath) {
622
+ let beforeName = frame.name
623
+ frame.name = target.target
624
+ console.log("SET FRAME", { before: beforeName, after: frame.name, target: target.target })
625
+ targetFrame = frame
626
+ break
627
+ }
628
+ } else {
629
+ // 2. rest => find the frame whose src exactly matches the tab's url
630
+ if (target.href === frame.src) {
631
+ frame.name = target.target
632
+ targetFrame = frame
633
+ break
634
+ }
535
635
  }
636
+ // find the frame whose path matches
637
+ }
638
+ } else if (target.closest(".s")) {
639
+ targetFrame = document.querySelector(`iframe[name='${target.target}']`)
640
+ } else if (target.closest(".n")) {
641
+ targetFrame = document.querySelector(`iframe[name='${target.target}']`)
642
+ }
643
+
644
+
645
+ /*
646
+ // Load the link in the frame
647
+
648
+ 1. if the frame was found:
649
+ - if "refresh": true => refresh
650
+ - otherwise,
651
+ - if the target frame has been already loaded, don't do anything
652
+ - frame: start.json?mode=abc, link: start.json?mode=abc => don't touch
653
+ - link === frame
654
+ - frame: start.json?mode=abc, link: start.json?mode=def => should load
655
+ - link !== frame && !frame.includes(link)
656
+ - frame: start.json?mode=abc, link: start.json => don't touch
657
+ - link !== frame && frame.includes(link)
536
658
 
537
- console.log("# 4")
538
659
 
660
+
661
+ if the link is different
662
+
663
+ - if the target frame has not been loaded, refresh
664
+ 2. if the frame was NOT found => create one
665
+
666
+ */
667
+
668
+ if (targetFrame) {
669
+ targetFrame.classList.remove("hidden")
670
+ let mode = target.getAttribute("data-mode")
671
+ if (mode === "refresh") {
672
+ targetFrame.src = target.href
673
+ } else {
539
674
  if (e) {
540
- console.log("# 5", { src: targetFrame.src, href: target.href, target: target.target })
541
- // triggered with a click
542
- // do not reload iframe if the href and the src is the same
543
675
  if (target.closest(".h")) {
544
- // if (targetFrame.src.includes(target.target)) {
545
- if (targetFrame.src.includes(target.href)) {
546
- // if (targetFrame.src === target.href) {
547
- e.preventDefault()
548
- e.stopPropagation()
676
+ debugger
677
+ e.preventDefault()
678
+ e.stopPropagation()
679
+ let sub = subUrlOf(target.href, targetFrame.src)
680
+ console.log("issub", sub)
681
+ if (!sub) {
682
+ targetFrame.src = target.href
549
683
  }
684
+ //if (target.href === targetFrame.src) {
685
+ // // same url. don't do anything
686
+ // e.preventDefault()
687
+ // e.stopPropagation()
688
+ //} else {
689
+ // if (targetFrame.src.includes(target.href)) {
690
+ // // different url, but the frame's url contains the tab url => don't touch
691
+ // e.preventDefault()
692
+ // e.stopPropagation()
693
+ // } else {
694
+ // // different url, and the frame's url does not contain the tab url => change the src of the frame and load
695
+ // targetFrame.src = target.href
696
+ // e.preventDefault()
697
+ // e.stopPropagation()
698
+ // }
699
+ //}
550
700
  } else if (target.closest(".s")) {
701
+ // load unconditionally => .s doesn't change
702
+ e.preventDefault()
703
+ e.stopPropagation()
704
+ } else if (target.closest(".n")) {
705
+ // load unconditionally => .n doesn't change
551
706
  e.preventDefault()
552
707
  e.stopPropagation()
553
708
  }
554
709
  } else {
555
- console.log("# 6")
556
710
  if (force) {
557
711
  console.log("# 7")
558
- // if (targetFrame.src !== target.href) {
559
- targetFrame.src = target.href
560
- // }
712
+ targetFrame.src = target.href
561
713
  }
562
714
  }
563
- } else {
564
- console.log("# 8")
565
- //targetFrame.contentWindow.addEventListener("load", () => {
566
- if (e) {
567
- console.log("# 9")
568
- // coming from a click => don't need to set the src
569
- } else {
570
- console.log("# 10")
571
- // load without click
572
- if (targetFrame.src !== target.href) {
573
- console.log("# 11")
574
- targetFrame.src = target.href
575
- }
576
- }
577
- loaded[target.target] = true
578
- //});
579
715
  }
580
716
  } else {
581
717
  console.log("# 12")
@@ -589,6 +725,84 @@ console.log({ type, index })
589
725
  document.querySelector("main").appendChild(frame)
590
726
  loaded[target.target] = true
591
727
  }
728
+
729
+ // if (targetFrame) {
730
+ // targetFrame.classList.remove("hidden")
731
+ //
732
+ // // if the iframe already exists, do not
733
+ // if (loaded[target.target]){
734
+ //
735
+ // // Force refresh option
736
+ // //
737
+ // // menu := [{
738
+ // // text,
739
+ // // icon,
740
+ // // mode: "refresh" => refresh regardless of any condition
741
+ // // }]
742
+ // let mode = target.getAttribute("data-mode")
743
+ // if (mode === "refresh") {
744
+ // targetFrame.src = target.href
745
+ // } else {
746
+ // console.log("# 4")
747
+ // if (e) {
748
+ // // if triggered by a click event,
749
+ // // 1. if it's a hard link (".h")
750
+ // // - ignore if the pathname is the same
751
+ // // - reload if
752
+ // console.log("# 5", { src: targetFrame.src, href: target.href, target: target.target })
753
+ // // triggered with a click
754
+ // // do not reload iframe if the href and the src is the same
755
+ // if (target.closest(".h")) {
756
+ // // if (targetFrame.src.includes(target.target)) {
757
+ // if (targetFrame.src.includes(target.href)) {
758
+ // // if (targetFrame.src === target.href) {
759
+ // e.preventDefault()
760
+ // e.stopPropagation()
761
+ // }
762
+ // } else if (target.closest(".s")) {
763
+ // e.preventDefault()
764
+ // e.stopPropagation()
765
+ // }
766
+ // } else {
767
+ // // if not triggered by event
768
+ // // refresh ONLY if programmatically forced refresh
769
+ // console.log("# 6")
770
+ // if (force) {
771
+ // console.log("# 7")
772
+ // targetFrame.src = target.href
773
+ // }
774
+ // }
775
+ // }
776
+ //
777
+ // } else {
778
+ // console.log("# 8")
779
+ // //targetFrame.contentWindow.addEventListener("load", () => {
780
+ // if (e) {
781
+ // console.log("# 9")
782
+ // // coming from a click => don't need to set the src
783
+ // } else {
784
+ // console.log("# 10")
785
+ // // load without click
786
+ // if (targetFrame.src !== target.href) {
787
+ // console.log("# 11")
788
+ // targetFrame.src = target.href
789
+ // }
790
+ // }
791
+ // loaded[target.target] = true
792
+ // //});
793
+ // }
794
+ // } else {
795
+ // console.log("# 12")
796
+ // let frame = document.createElement("iframe")
797
+ // frame.name = target.target
798
+ // frame.src = target.href
799
+ // frame.setAttribute(
800
+ // "allow",
801
+ // "clipboard-read *; clipboard-write *; accelerometer *; ambient-light-sensor *; autoplay *; battery *; camera *; display-capture *; gamepad *; geolocation *; gyroscope *; hid *; identity-credentials-get *; microphone *; midi *; otp-credentials *; serial *;"
802
+ // )
803
+ // document.querySelector("main").appendChild(frame)
804
+ // loaded[target.target] = true
805
+ // }
592
806
  } else {
593
807
  console.log("# 13")
594
808
  // couldn't find item,
@@ -598,7 +812,7 @@ console.log({ type, index })
598
812
  }
599
813
  } else {
600
814
  console.log("# 14")
601
- document.querySelector(".bar").classList.add("hidden")
815
+ // document.querySelector(".bar").classList.add("hidden")
602
816
  }
603
817
  }
604
818
  console.log("loaded before", loaded)
@@ -673,7 +887,6 @@ const syncTabs = async () => {
673
887
  })
674
888
  }
675
889
  const addTab = async (url) => {
676
- debugger
677
890
  let item = document.createElement("a")
678
891
  //let id = "ts" + Date.now()
679
892
  let index = document.querySelectorAll("aside .s .frame-link").length
@@ -717,6 +930,47 @@ document.querySelector(".app-info").addEventListener("click", async (e) => {
717
930
  renderSelection()
718
931
 
719
932
  })
933
+ document.querySelector("#delete").addEventListener("click", async (e) => {
934
+ e.preventDefault()
935
+ e.stopPropagation()
936
+ const confirmed = confirm("Are you sure you wish to delete the app?")
937
+ if (confirmed) {
938
+
939
+
940
+
941
+ let name = document.querySelector("#delete").getAttribute("data-name")
942
+ console.log("delete", name)
943
+ Swal.fire({
944
+ html: '<i class="fa-solid fa-circle-notch fa-spin"></i> Deleting',
945
+ customClass: {
946
+ container: "loader-container",
947
+ popup: "loader-popup",
948
+ htmlContainer: "loader-dialog",
949
+ footer: "hidden",
950
+ actions: "hidden"
951
+ }
952
+ });
953
+ let res = await fetch("/pinokio/delete", {
954
+ method: "post",
955
+ headers: {
956
+ "Content-Type": "application/json"
957
+ },
958
+ body: JSON.stringify({ name })
959
+ }).then((res) => {
960
+ return res.json()
961
+ })
962
+ console.log("res", res)
963
+ Swal.close()
964
+ if (res) {
965
+ if (res.success) {
966
+ location.href = "/"
967
+ } else if (res.error) {
968
+ alert(res.error)
969
+ }
970
+ }
971
+ } else {
972
+ }
973
+ })
720
974
  document.querySelector("aside").addEventListener("click", async (e) => {
721
975
  let target
722
976
 
@@ -771,9 +1025,19 @@ document.querySelector("aside").addEventListener("click", async (e) => {
771
1025
  // location.hash = id
772
1026
 
773
1027
  //location.hash = target.getAttribute("href")
774
- let index = target.getAttribute("data-index")
775
- let type = target.closest(".m").getAttribute("data-type")
776
- location.hash = type + index
1028
+
1029
+ if (target.closest(".h")) {
1030
+ location.hash = target.target
1031
+ } else {
1032
+ let index = target.getAttribute("data-index")
1033
+ let type = target.closest(".m").getAttribute("data-type")
1034
+
1035
+ console.log({ type, index })
1036
+
1037
+ debugger
1038
+
1039
+ location.hash = type + index
1040
+ }
777
1041
 
778
1042
  document.querySelectorAll(".frame-link").forEach((el) => {
779
1043
  el.classList.remove("selected")
@@ -812,6 +1076,29 @@ const refresh = async () => {
812
1076
  console.log("refresh", html)
813
1077
  */
814
1078
  document.querySelector(".menu").innerHTML = html
1079
+
1080
+
1081
+ // update the frames so the name matches the tab links
1082
+
1083
+ // 1. iterate through all the "h" menu items
1084
+ // 2. for each tab that starts with "h" (hard), iterate through all iframes
1085
+ // 3. to find a frame whose src.includes(item.href)
1086
+ // 4. update the frame's name to the target attribute
1087
+
1088
+ // let hardFrames = document.querySelectorAll(".browserview iframe[name^=h]")
1089
+ // for(let frame of hardFrames) {
1090
+ // frame.removeAttribute("name")
1091
+ // location.hash = ""
1092
+ // }
1093
+
1094
+
1095
+ location.hash = ""
1096
+
1097
+
1098
+
1099
+
1100
+ //
1101
+
815
1102
  renderSelection()
816
1103
  // cursorIndex = 0
817
1104
  //renderCursor()
@@ -819,13 +1106,21 @@ const refresh = async () => {
819
1106
  }
820
1107
  window.addEventListener('message', (event) => {
821
1108
  console.log("Message received from the child: ", event.data); // Message received from child
822
- if (event.data && event.data.action) {
823
- if (event.data.action.type === "newtab") {
824
- console.log("create tab", event.data.action.url)
825
- addTab(event.data.action.url)
1109
+ if (event.data) {
1110
+ if (event.data.action) {
1111
+ if (event.data.action.type === "newtab") {
1112
+ console.log("create tab", event.data.action.url)
1113
+ addTab(event.data.action.url)
1114
+ }
1115
+ } else if (event.data.type) {
1116
+ if (event.data.type === 'disconnect') {
1117
+ // location.hash = ""
1118
+ refresh()
1119
+ } else {
1120
+ refresh()
1121
+ }
826
1122
  }
827
1123
  } else {
828
- console.log("data", event.data)
829
1124
  refresh()
830
1125
  }
831
1126
  });
@@ -517,7 +517,8 @@ document.addEventListener("DOMContentLoaded", async () => {
517
517
  //theme: xtermTheme.Github,
518
518
 
519
519
  //theme: xtermTheme.Cobalt_Neon, // top legibility
520
- theme: xtermTheme.Duotone_Dark,
520
+ //theme: xtermTheme.Duotone_Dark,
521
+ theme: xtermTheme.FrontEndDelight,
521
522
  //theme: xtermTheme.Seafoam_Pastel,
522
523
  //theme: xtermTheme.IC_Green_PPL,
523
524
  //theme: xtermTheme.FunForrest,
@@ -508,7 +508,10 @@ document.addEventListener("DOMContentLoaded", async () => {
508
508
  //theme: xtermTheme.Github,
509
509
 
510
510
  //theme: xtermTheme.Cobalt_Neon, // top legibility
511
- theme: xtermTheme.Duotone_Dark,
511
+ //theme: xtermTheme.Duotone_Dark,
512
+ //theme: xtermTheme.Batman,
513
+ //theme: xtermTheme.Brogrammer,
514
+ theme: xtermTheme.FrontEndDelight,
512
515
  //theme: xtermTheme.Seafoam_Pastel,
513
516
  //theme: xtermTheme.IC_Green_PPL,
514
517
  //theme: xtermTheme.FunForrest,
@@ -128,7 +128,8 @@ const createTerm = () => {
128
128
  //theme: xtermTheme.Github,
129
129
 
130
130
  //theme: xtermTheme.Cobalt_Neon, // top legibility
131
- theme: xtermTheme.Duotone_Dark,
131
+ //theme: xtermTheme.Duotone_Dark,
132
+ theme: xtermTheme.FrontEndDelight,
132
133
  //theme: xtermTheme.Seafoam_Pastel,
133
134
  //theme: xtermTheme.IC_Green_PPL,
134
135
  //theme: xtermTheme.FunForrest,
@@ -10,7 +10,10 @@
10
10
  </div>
11
11
  <% } else { %>
12
12
  <% if (item.btn) { %>
13
+ <!--
13
14
  <a data-index="<%=index%>" target="h<%=index%>" data-mode="<%=item.mode%>" href="<%=item.href%>" class='btn header-item frame-link'>
15
+ -->
16
+ <a data-index="<%=index%>" target="<%=item.target%>" data-mode="<%=item.mode%>" href="<%=item.href%>" class='btn header-item frame-link'>
14
17
  <div class='tab'><%-item.btn%></div>
15
18
  <% if (item.running) { %>
16
19
  <div class='loader'>
@@ -63,18 +63,28 @@
63
63
  border-top: 1px solid rgba(255,255,255,0.1);
64
64
  border-bottom: 1px solid rgba(255,255,255,0.1);
65
65
  */
66
- padding: 15px 0;
66
+ padding: 20px 0;
67
+ }
68
+ .titleview h1 {
69
+ font-size: 40px;
70
+ text-transform: uppercase;
71
+ letter-spacing: 0;
67
72
  }
68
73
  .item button {
69
74
  padding: 10px 20px;
70
75
  }
71
76
  .item label {
72
77
  display: block;
73
- font-weight: bold;
74
- text-transform: capitalize;
75
- font-size: 14px;
78
+ text-transform: uppercase;
79
+ font-size: 30px;
76
80
  padding-bottom: 5px;
77
81
  }
82
+ .item .explanation {
83
+ padding-top: 5px;
84
+ color: brown;
85
+ font-size: 14px;
86
+ font-weight: bold;
87
+ }
78
88
  body.dark .item input[type=text] {
79
89
  background: rgba(255,255,255,0.1);
80
90
  color: white;
@@ -87,9 +97,7 @@ body.dark .item select {
87
97
  padding: 10px;
88
98
  flex-grow: 1;
89
99
  border: none;
90
- /*
91
100
  background: rgba(0,0,0,0.05);
92
- */
93
101
  width: 100%;
94
102
  }
95
103
  .item select {
@@ -230,6 +238,9 @@ header .home {
230
238
  <input class='homepath' name="<%=c.key%>" type='text' placeholder="<%=c.placeholder ? c.placeholder : ''%>">
231
239
  <% } %>
232
240
  <% } %>
241
+ <% if (c.description) { %>
242
+ <div class='explanation'><%=c.description%></div>
243
+ <% } %>
233
244
  </div>
234
245
  <% }) %>
235
246
  <br>