pinokiod 3.48.0 → 3.49.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.
@@ -534,6 +534,12 @@ const init = async (options, kernel) => {
534
534
  // 1. if _ENVIRONMENT exists, create ENVIRONMENT by appending _ENVIRONMENT to ENVIRONMENT
535
535
  // 2. if _ENVIRONMENT doesn't exist, just write ENVIRONMENT
536
536
  // if _ENVIRONMENT exists,
537
+
538
+ let root_exists = await kernel.exists(root)
539
+ if (!root_exists) {
540
+ await fs.promises.mkdir(root, { recursive: true }).catch((e) => { })
541
+ }
542
+
537
543
  let _environment = path.resolve(root, "_ENVIRONMENT")
538
544
  let _exists = await kernel.exists(_environment)
539
545
  if (options && options.no_inherit) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "3.48.0",
3
+ "version": "3.49.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/server/index.js CHANGED
@@ -5458,21 +5458,37 @@ class Server {
5458
5458
  } else {
5459
5459
  // if there is no menu, display all files
5460
5460
  let p = this.kernel.path("api", name)
5461
- let files = await fs.promises.readdir(p, { withFileTypes: true })
5462
- files = files.filter((file) => {
5463
- return file.name.endsWith(".json") || file.name.endsWith(".js")
5464
- }).filter((file) => {
5465
- return file.name !== "pinokio.js" && file.name !== "pinokio.json" && file.name !== "pinokio_meta.json"
5466
- })
5467
- config = {
5468
- title: name,
5469
- menu: files.map((file) => {
5470
- return {
5471
- text: file.name,
5472
- href: file.name
5473
- }
5461
+
5462
+ let html_path = path.resolve(p, "index.html")
5463
+ let html_exists = await this.kernel.exists(html_path)
5464
+ if (html_exists) {
5465
+ config = {
5466
+ title: name,
5467
+ menu: [{
5468
+ default: true,
5469
+ icon: "fa-solid fa-link",
5470
+ text: "index.html",
5471
+ href: "index.html?raw=true",
5472
+ }]
5473
+ }
5474
+ } else {
5475
+ let files = await fs.promises.readdir(p, { withFileTypes: true })
5476
+ files = files.filter((file) => {
5477
+ return file.name.endsWith(".json") || file.name.endsWith(".js")
5478
+ }).filter((file) => {
5479
+ return file.name !== "pinokio.js" && file.name !== "pinokio.json" && file.name !== "pinokio_meta.json"
5474
5480
  })
5481
+ config = {
5482
+ title: name,
5483
+ menu: files.map((file) => {
5484
+ return {
5485
+ text: file.name,
5486
+ href: file.name
5487
+ }
5488
+ })
5489
+ }
5475
5490
  }
5491
+
5476
5492
  let uri = this.kernel.path("api")
5477
5493
  await this.renderMenu(req, uri, name, config, [])
5478
5494
  }
@@ -5522,6 +5538,14 @@ class Server {
5522
5538
  // res.json({ success: true })
5523
5539
  // }))
5524
5540
 
5541
+ this.app.get("/info/procs", ex(async (req, res) => {
5542
+ console.time("Refresh")
5543
+ await this.kernel.processes.refresh()
5544
+ console.timeEnd("Refresh")
5545
+ res.json({
5546
+ info: this.kernel.processes.info
5547
+ })
5548
+ }))
5525
5549
 
5526
5550
  this.app.get("/info/system", ex(async (req,res) => {
5527
5551
  let current_peer_info = await this.kernel.peer.current_host()
@@ -308,14 +308,82 @@ const refreshParent = (e) => {
308
308
  window.parent.postMessage(e, "*")
309
309
  }
310
310
  }
311
- document.addEventListener("DOMContentLoaded", () => {
311
+ let tippyInstances = [];
312
+
313
+ function initTippy() {
312
314
  try {
313
- tippy("[data-tippy-content]", {
314
- theme: "pointer"
315
- })
315
+ tippyInstances = tippy("[data-tippy-content]", {
316
+ theme: "pointer",
317
+ onCreate(instance) {
318
+ updateTippyPlacement(instance);
319
+ }
320
+ });
316
321
  } catch(e) {
317
- console.log(e)
322
+ console.log(e);
318
323
  }
324
+ }
325
+
326
+ function updateTippyPlacement(instance) {
327
+ //const isMobileOrMinimized = window.innerWidth <= 800 || document.body.classList.contains('minimized');
328
+ const isMinimized = document.body.classList.contains('minimized');
329
+ const isHeaderElement = instance.reference.closest('header.navheader');
330
+ const isSidebarTab = instance.reference.closest('aside') && instance.reference.classList.contains('tab');
331
+
332
+ //if (isHeaderElement && isMobileOrMinimized) {
333
+ if (isMinimized) {
334
+ console.log(">1")
335
+ instance.setProps({ placement: 'right' });
336
+ } else if (isSidebarTab) {
337
+ console.log(">2")
338
+ instance.setProps({ placement: 'left' });
339
+ } else {
340
+ console.log(">3")
341
+ instance.setProps({ placement: 'top' });
342
+ }
343
+ }
344
+
345
+ function updateAllTooltips() {
346
+ tippyInstances.forEach(updateTippyPlacement);
347
+ }
348
+
349
+ function setTabTooltips() {
350
+ // Set data-tippy-content for sidebar tabs based on their .caption text
351
+ const tabs = document.querySelectorAll('aside .tab');
352
+ tabs.forEach(tab => {
353
+ const caption = tab.querySelector('.caption');
354
+ if (caption && caption.textContent.trim()) {
355
+ tab.setAttribute('data-tippy-content', caption.textContent.trim());
356
+ }
357
+ });
358
+ }
359
+
360
+ document.addEventListener("DOMContentLoaded", () => {
361
+ setTabTooltips();
362
+ initTippy();
363
+
364
+ if (window.windowStorage) {
365
+ let frame_key = window.frameElement?.name || "";
366
+ let window_mode = windowStorage.getItem(frame_key + ":window_mode")
367
+ if (window_mode) {
368
+ if (window_mode === "minimized") {
369
+ document.body.classList.add("minimized")
370
+ updateAllTooltips()
371
+ }
372
+ }
373
+ }
374
+
375
+ // Listen for window resize
376
+ window.addEventListener('resize', updateAllTooltips);
377
+
378
+ // Listen for body class changes (for minimize/maximize)
379
+ const observer = new MutationObserver((mutations) => {
380
+ mutations.forEach((mutation) => {
381
+ if (mutation.attributeName === 'class' && mutation.target === document.body) {
382
+ updateAllTooltips();
383
+ }
384
+ });
385
+ });
386
+ observer.observe(document.body, { attributes: true });
319
387
 
320
388
  if (document.querySelector("#screenshot")) {
321
389
  document.querySelector("#screenshot").addEventListener("click", (e) => {
@@ -415,9 +483,9 @@ document.addEventListener("DOMContentLoaded", () => {
415
483
 
416
484
  if (document.querySelector(".urlbar")) {
417
485
  document.querySelector(".urlbar").addEventListener("submit", (e) => {
486
+ debugger
418
487
  e.preventDefault()
419
488
  e.stopPropagation()
420
- debugger
421
489
  location.href = "/container?url=" + e.target.querySelector("input[type=url]").value
422
490
  })
423
491
  }
@@ -430,7 +498,6 @@ document.addEventListener("DOMContentLoaded", () => {
430
498
  fetch("/pinokio/log", {
431
499
  method: "post",
432
500
  }).then((res) => {
433
- console.log("RES", res)
434
501
  let btn = document.querySelector("#genlog")
435
502
  let btn2 = document.querySelector("#downloadlogs")
436
503
  btn2.classList.remove("hidden")
@@ -440,9 +507,19 @@ document.addEventListener("DOMContentLoaded", () => {
440
507
  })
441
508
  })
442
509
  }
510
+ if (document.querySelector("#collapse") && window.windowStorage) {
511
+ document.querySelector("#collapse").addEventListener("click", (e) => {
512
+ document.body.classList.toggle("minimized")
513
+ let frame_key = window.frameElement?.name || "";
514
+ if (document.body.classList.contains("minimized")) {
515
+ windowStorage.setItem(frame_key + ":window_mode", "minimized")
516
+ } else {
517
+ windowStorage.setItem(frame_key + ":window_mode", "full")
518
+ }
519
+ })
520
+ }
443
521
  if (document.querySelector("#close-window")) {
444
522
  const isInIframe = window.self !== window.top;
445
- console.log("isInIframe", isInIframe)
446
523
  if (isInIframe) {
447
524
  document.querySelector("#close-window").classList.remove("hidden")
448
525
  document.querySelector("#close-window").addEventListener("click", (e) => {
@@ -1166,6 +1166,8 @@ body.dark .memory {
1166
1166
  .memory-item {
1167
1167
  }
1168
1168
  main {
1169
+ min-width: 0;
1170
+ flex-grow: 1;
1169
1171
  }
1170
1172
  main h1 {
1171
1173
  margin: 0;
@@ -1191,6 +1193,7 @@ body.dark .offline .indicator {
1191
1193
  .container {
1192
1194
  flex-grow: 1;
1193
1195
  box-sizing: border-box;
1196
+ min-width: 0;
1194
1197
  /*
1195
1198
  padding: 0 20px;
1196
1199
  */
@@ -2136,6 +2139,8 @@ footer.status {
2136
2139
  padding: 5px 5px 10px;
2137
2140
  }
2138
2141
  */
2142
+ #close-window {
2143
+ }
2139
2144
  #error-screen .btn {
2140
2145
  font-size: 14px;
2141
2146
  padding: 15px 30px;
@@ -2337,21 +2342,6 @@ body.dark .mode-selector .btn2.selected {
2337
2342
  border-radius: 5px;
2338
2343
  }
2339
2344
 
2340
- .urlbar {
2341
- flex-grow: 1;
2342
- margin: 0 20px;
2343
- }
2344
- body.dark .urlbar input[type=url] {
2345
- background: rgba(255,255,255,0.1);
2346
- color: white;
2347
- }
2348
- .urlbar input[type=url] {
2349
- background: rgba(0,0,0,0.05);
2350
- border-radius: 6px;
2351
- border: none;
2352
- padding: 10px;
2353
- width: 100%;
2354
- }
2355
2345
 
2356
2346
 
2357
2347
 
@@ -2378,9 +2368,6 @@ body.minimized header {
2378
2368
  overflow: auto;
2379
2369
  flex-shrink: 0;
2380
2370
  }
2381
- body.minimized header h1 .urlbar {
2382
- display: none;
2383
- }
2384
2371
  body.minimized header h1 .btn2 {
2385
2372
  padding: 10px;
2386
2373
  width: 100%;
@@ -2413,16 +2400,22 @@ body.minimized .appcanvas, body.minimized main {
2413
2400
  body.minimized .appcanvas {
2414
2401
  padding-top: 20px;
2415
2402
  }
2403
+ body.minimized main {
2404
+ padding-top: 10px;
2405
+ }
2416
2406
  body.minimized main .container {
2417
2407
  margin-left: 0;
2418
2408
  }
2419
2409
  body.minimized .app-icon {
2420
2410
  display: block;
2421
2411
  }
2412
+ /*
2422
2413
  body.minimized aside {
2423
2414
  display: none;
2424
2415
  }
2416
+ */
2425
2417
 
2418
+ /*
2426
2419
  @media only screen and (max-width: 800px) {
2427
2420
  header .dropdown-content {
2428
2421
  position: relative;
@@ -2451,9 +2444,6 @@ body.minimized aside {
2451
2444
  overflow: auto;
2452
2445
  display: block;
2453
2446
  }
2454
- header h1 .urlbar {
2455
- display: none;
2456
- }
2457
2447
  .mode-selector {
2458
2448
  flex-direction: column;
2459
2449
  padding: 0;
@@ -2470,9 +2460,9 @@ body.minimized aside {
2470
2460
  .mode-selector .caption {
2471
2461
  display: none;
2472
2462
  }
2473
- /*
2474
- .appcanvas, main {
2475
- */
2463
+ main {
2464
+ padding-top: 10px;
2465
+ }
2476
2466
  .appcanvas {
2477
2467
  padding-top: 20px;
2478
2468
  }
@@ -2482,7 +2472,5 @@ body.minimized aside {
2482
2472
  .app-icon {
2483
2473
  display: block;
2484
2474
  }
2485
- aside {
2486
- display: none;
2487
- }
2488
2475
  }
2476
+ */
@@ -0,0 +1,174 @@
1
+ .url-input-container {
2
+ position: relative;
3
+ width: 100%;
4
+ }
5
+ .url-dropdown {
6
+ position: absolute;
7
+ top: 100%;
8
+ left: 0;
9
+ right: 0;
10
+ background: white;
11
+ border: 1px solid rgba(255,255,255,0.1);
12
+ border-top: none;
13
+ border-radius: 0 0 5px 5px;
14
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
15
+ max-height: 300px;
16
+ overflow-y: auto;
17
+ z-index: 1000;
18
+ display: none;
19
+ }
20
+ body.dark .url-dropdown {
21
+ background: rgb(27, 28, 29);
22
+ /*
23
+ border-color: #4a5568;
24
+ */
25
+ box-shadow: 0 2px 8px rgba(255,255,255,0.1);
26
+ }
27
+ .url-dropdown-item {
28
+ padding: 12px 16px;
29
+ cursor: pointer;
30
+ border-bottom: 1px solid #eee;
31
+ display: flex;
32
+ flex-direction: column;
33
+ gap: 4px;
34
+ }
35
+ body.dark .url-dropdown-item {
36
+ border-bottom-color: rgba(255,255,255,0.1);
37
+ }
38
+ .url-dropdown-item:hover {
39
+ background: #f7fafc;
40
+ }
41
+ body.dark .url-dropdown-item:hover {
42
+ background: rgba(255,255,255,0.04);
43
+ }
44
+ .url-dropdown-item:last-child {
45
+ border-bottom: none;
46
+ }
47
+ .url-dropdown-name {
48
+ font-weight: bold;
49
+ color: #2d3748;
50
+ font-size: 14px;
51
+ }
52
+ body.dark .url-dropdown-name {
53
+ color: #e2e8f0;
54
+ }
55
+ .url-dropdown-url {
56
+ color: #718096;
57
+ font-size: 12px;
58
+ }
59
+ body.dark .url-dropdown-url {
60
+ color: #a0aec0;
61
+ }
62
+ .url-dropdown-loading {
63
+ padding: 12px 16px;
64
+ font-size: 14px;
65
+ }
66
+ body.dark .url-dropdown-loading {
67
+ color: #a0aec0;
68
+ }
69
+ .url-dropdown-empty {
70
+ padding: 12px 16px;
71
+ text-align: center;
72
+ color: #718096;
73
+ font-style: italic;
74
+ }
75
+ body.dark .url-dropdown-empty {
76
+ color: #a0aec0;
77
+ }
78
+ .urlbar {
79
+ flex-grow: 1;
80
+ margin: 0 20px;
81
+ }
82
+ body.dark .mobile-link-button {
83
+ background: rgba(255,255,255,0.1);
84
+ padding: 5px;
85
+ }
86
+ body.dark .urlbar input[type=url] {
87
+ background: rgba(255,255,255,0.1);
88
+ color: white;
89
+ }
90
+ body.minimized .mobile-link-button {
91
+ border-radius: 0;
92
+ }
93
+ .mobile-link-button {
94
+ background: rgba(0,0,0,0.05);
95
+ padding: 5px;
96
+ flex-grow: 1;
97
+ }
98
+ .urlbar input[type=url] {
99
+ background: rgba(0,0,0,0.05);
100
+ border-radius: 6px;
101
+ border: none;
102
+ padding: 10px;
103
+ width: 100%;
104
+ }
105
+ body.minimized header h1 .urlbar {
106
+ display: none;
107
+ }
108
+ body.minimized header h1 .mobile-link-button {
109
+ display: block;
110
+ }
111
+ @media only screen and (max-width: 800px) {
112
+ header h1 .urlbar {
113
+ display: none;
114
+ }
115
+ header h1 .mobile-link-button {
116
+ display: block;
117
+ }
118
+ }
119
+ .mobile-link-button {
120
+ display: none;
121
+ }
122
+ .url-modal-overlay {
123
+ position: fixed;
124
+ top: 0;
125
+ left: 0;
126
+ width: 100%;
127
+ height: 100%;
128
+ background: rgba(0, 0, 0, 0.5);
129
+ z-index: 10000;
130
+ display: none;
131
+ justify-content: center;
132
+ align-items: center;
133
+ }
134
+ .url-modal-content {
135
+ background: white;
136
+ padding: 20px;
137
+ border-radius: 10px;
138
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
139
+ width: 90%;
140
+ max-width: 500px;
141
+ position: relative;
142
+ }
143
+ body.dark .url-modal-content {
144
+ background: rgb(27, 28, 29);
145
+ }
146
+ .url-modal-close {
147
+ position: absolute;
148
+ top: 10px;
149
+ right: 15px;
150
+ font-size: 24px;
151
+ color: #aaa;
152
+ cursor: pointer;
153
+ user-select: none;
154
+ }
155
+ .url-modal-close:hover {
156
+ color: #000;
157
+ }
158
+ body.dark .url-modal-close:hover {
159
+ color: #fff;
160
+ }
161
+ .url-modal-input {
162
+ width: 100%;
163
+ padding: 15px;
164
+ font-size: 16px;
165
+ border: 1px solid #ddd;
166
+ border-radius: 5px;
167
+ box-sizing: border-box;
168
+ background: white;
169
+ }
170
+ body.dark .url-modal-input {
171
+ background: rgba(255, 255, 255, 0.1);
172
+ border-color: rgba(255, 255, 255, 0.2);
173
+ color: white;
174
+ }