pinokiod 5.3.19 → 5.3.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "5.3.19",
3
+ "version": "5.3.20",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -2692,17 +2692,43 @@ if (typeof window !== 'undefined' && !window.__pinokioNavigateListenerInstalled)
2692
2692
  try {
2693
2693
  console.info('[pinokio:navigate] received', { origin: event.origin, url: event.data?.url });
2694
2694
  } catch (_) {}
2695
- const frame = document.activeElement;
2696
- if (!frame || frame.tagName !== 'IFRAME') {
2695
+ const rawUrl = typeof event.data.url === 'string' ? event.data.url : '';
2696
+ if (!rawUrl) {
2697
2697
  try {
2698
- console.warn('[pinokio:navigate] no active iframe');
2698
+ console.warn('[pinokio:navigate] empty url');
2699
2699
  } catch (_) {}
2700
2700
  return;
2701
2701
  }
2702
- const rawUrl = typeof event.data.url === 'string' ? event.data.url : '';
2703
- if (!rawUrl) {
2702
+ const communityFrame = document.querySelector('iframe.community-frame');
2703
+ if (communityFrame) {
2704
+ let fromCommunity = false;
2704
2705
  try {
2705
- console.warn('[pinokio:navigate] empty url');
2706
+ fromCommunity = event.source === communityFrame.contentWindow;
2707
+ } catch (_) {
2708
+ fromCommunity = false;
2709
+ }
2710
+ if (fromCommunity) {
2711
+ let communityTarget;
2712
+ try {
2713
+ const base = communityFrame.getAttribute('src') || window.location.origin;
2714
+ communityTarget = new URL(rawUrl, base);
2715
+ } catch (_) {
2716
+ try {
2717
+ console.warn('[pinokio:navigate] invalid url', rawUrl);
2718
+ } catch (_) {}
2719
+ return;
2720
+ }
2721
+ communityFrame.src = communityTarget.toString();
2722
+ try {
2723
+ console.info('[pinokio:navigate] navigated community', communityFrame.src);
2724
+ } catch (_) {}
2725
+ return;
2726
+ }
2727
+ }
2728
+ const frame = document.activeElement;
2729
+ if (!frame || frame.tagName !== 'IFRAME') {
2730
+ try {
2731
+ console.warn('[pinokio:navigate] no active iframe');
2706
2732
  } catch (_) {}
2707
2733
  return;
2708
2734
  }
@@ -197,7 +197,6 @@ function initUrlDropdown(config = {}) {
197
197
  { key: 'run', label: 'Run', icon: 'fa-solid fa-circle-play', suffix: '' },
198
198
  { key: 'dev', label: 'Dev', icon: 'fa-solid fa-code', suffix: '/dev' },
199
199
  { key: 'files', label: 'Files', icon: 'fa-solid fa-file-lines', suffix: '/files' },
200
- { key: 'review', label: 'Forum', icon: 'fa-regular fa-message', suffix: '/review' },
201
200
  ];
202
201
 
203
202
  const buildTarget = (suffix) => {
@@ -724,7 +724,7 @@ body.dark .plugin-option:hover {
724
724
  <aside>
725
725
  <div class='btn-tab'>
726
726
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
727
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
727
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Community</div></a>
728
728
  </div>
729
729
  <a href="/home" class='tab'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
730
730
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -161,6 +161,7 @@ body.dark .m {
161
161
  flex: 1 1 auto;
162
162
  min-width: 0;
163
163
  min-height: 0;
164
+ position: relative;
164
165
  }
165
166
  main.browserview {
166
167
  flex: 1 1 auto;
@@ -207,6 +208,22 @@ body.dark .community-resizer::before {
207
208
  .appcanvas.community-open .community-drawer {
208
209
  display: flex;
209
210
  }
211
+ .appcanvas.community-expanded .community-resizer {
212
+ display: none;
213
+ }
214
+ .appcanvas.community-expanded .community-drawer {
215
+ position: absolute;
216
+ inset: 0;
217
+ width: 100%;
218
+ min-width: 0;
219
+ max-width: none;
220
+ border-left: 0;
221
+ z-index: 10;
222
+ box-shadow: 0 24px 60px rgba(0,0,0,0.35);
223
+ }
224
+ body.dark .appcanvas.community-expanded .community-drawer {
225
+ box-shadow: 0 24px 60px rgba(0,0,0,0.6);
226
+ }
210
227
  .community-drawer-inner {
211
228
  display: flex;
212
229
  flex-direction: column;
@@ -234,6 +251,26 @@ body.dark .community-drawer-bar {
234
251
  font-size: 12px;
235
252
  font-weight: 700;
236
253
  }
254
+ .community-drawer-home {
255
+ display: inline-flex;
256
+ align-items: center;
257
+ gap: 8px;
258
+ padding: 0;
259
+ border: 0;
260
+ background: none;
261
+ font: inherit;
262
+ color: inherit;
263
+ cursor: pointer;
264
+ }
265
+ .community-drawer-home:disabled {
266
+ cursor: not-allowed;
267
+ opacity: 0.6;
268
+ }
269
+ .community-drawer-home:focus-visible {
270
+ outline: 2px solid rgba(59, 130, 246, 0.5);
271
+ outline-offset: 2px;
272
+ border-radius: 6px;
273
+ }
237
274
  .community-drawer-status {
238
275
  width: 8px;
239
276
  height: 8px;
@@ -276,6 +313,96 @@ body.dark .community-drawer-status {
276
313
  opacity: 0.5;
277
314
  cursor: not-allowed;
278
315
  }
316
+ .community-drawer-location {
317
+ position: relative;
318
+ padding: 6px 10px;
319
+ border-bottom: 1px solid rgba(0,0,0,0.08);
320
+ background: rgba(255,255,255,0.7);
321
+ cursor: text;
322
+ }
323
+ body.dark .community-drawer-location {
324
+ border-bottom-color: rgba(255,255,255,0.08);
325
+ background: rgba(15, 17, 21, 0.75);
326
+ }
327
+ .community-drawer-location-input {
328
+ width: 100%;
329
+ border: 1px solid rgba(0,0,0,0.12);
330
+ border-radius: 6px;
331
+ padding: 4px 6px;
332
+ font-size: 11px;
333
+ font-family: inherit;
334
+ color: transparent;
335
+ caret-color: transparent;
336
+ background: rgba(255,255,255,0.9);
337
+ white-space: nowrap;
338
+ overflow: hidden;
339
+ text-overflow: ellipsis;
340
+ }
341
+ .community-drawer-location-input::placeholder {
342
+ color: rgba(15, 23, 42, 0.55);
343
+ }
344
+ .community-drawer-location-input[readonly] {
345
+ cursor: text;
346
+ }
347
+ body.dark .community-drawer-location-input {
348
+ border-color: rgba(255,255,255,0.12);
349
+ background: rgba(15, 17, 21, 0.7);
350
+ }
351
+ body.dark .community-drawer-location-input::placeholder {
352
+ color: rgba(248, 250, 252, 0.55);
353
+ }
354
+ .community-drawer-location-overlay {
355
+ position: absolute;
356
+ inset: 6px 10px;
357
+ padding: 4px 6px;
358
+ pointer-events: none;
359
+ font-size: 11px;
360
+ line-height: 1.4;
361
+ font-family: inherit;
362
+ color: rgba(15, 23, 42, 0.75);
363
+ display: flex;
364
+ align-items: center;
365
+ white-space: nowrap;
366
+ overflow: hidden;
367
+ text-overflow: ellipsis;
368
+ }
369
+ body.dark .community-drawer-location-overlay {
370
+ color: rgba(248, 250, 252, 0.75);
371
+ }
372
+ .community-drawer-location-textarea {
373
+ position: absolute;
374
+ inset: 6px 10px;
375
+ width: calc(100% - 20px);
376
+ border: 1px solid rgba(0,0,0,0.12);
377
+ border-radius: 6px;
378
+ padding: 4px 6px;
379
+ font-size: 11px;
380
+ line-height: 1.4;
381
+ font-family: inherit;
382
+ color: rgba(15, 23, 42, 0.85);
383
+ background: rgba(255,255,255,0.98);
384
+ resize: none;
385
+ opacity: 0;
386
+ pointer-events: none;
387
+ z-index: 2;
388
+ overflow-wrap: anywhere;
389
+ word-break: break-all;
390
+ }
391
+ body.dark .community-drawer-location-textarea {
392
+ border-color: rgba(255,255,255,0.12);
393
+ background: rgba(15, 17, 21, 0.95);
394
+ color: rgba(248, 250, 252, 0.85);
395
+ }
396
+ .community-drawer-location.is-expanded {
397
+ z-index: 5;
398
+ }
399
+ .community-drawer-location.is-expanded .community-drawer-location-overlay {
400
+ opacity: 0;
401
+ }
402
+ .community-drawer-location.is-expanded .community-drawer-location-textarea {
403
+ opacity: 1;
404
+ pointer-events: auto;
405
+ }
279
406
  .community-drawer-body {
280
407
  flex: 1 1 auto;
281
408
  min-height: 0;
@@ -4015,7 +4142,7 @@ header.navheader .mode-selector .community-mode-toggle {
4015
4142
  <a class="btn2 <%=type === 'files' ? 'selected' : ''%>" href="<%=files_tab%>"><div><i class="fa-solid fa-file-lines"></i></div><div class='caption'>Files</div></a>
4016
4143
  <% if (registryEnabled) { %>
4017
4144
  <button type='button' id='community-mode-toggle' class="btn2 community-mode-toggle" data-tippy-content="Community" aria-pressed="false">
4018
- <div><i class="fa-regular fa-message"></i></div><div class='caption'>Community</div>
4145
+ <div><i class="fa-solid fa-globe"></i></div><div class='caption'>Community</div>
4019
4146
  </button>
4020
4147
  <% } %>
4021
4148
  </div>
@@ -4116,7 +4243,7 @@ header.navheader .mode-selector .community-mode-toggle {
4116
4243
  <% if (registryEnabled) { %>
4117
4244
  <button type='button' id='community-toggle' class="btn header-item" data-tippy-content="community">
4118
4245
  <div class='tab'>
4119
- <i class="fa-regular fa-message"></i>
4246
+ <i class="fa-solid fa-globe"></i>
4120
4247
  <div class='display'>Community</div>
4121
4248
  <div class='flexible'></div>
4122
4249
  </div>
@@ -4258,32 +4385,48 @@ header.navheader .mode-selector .community-mode-toggle {
4258
4385
  <div class='community-drawer-inner'>
4259
4386
  <div class='community-drawer-bar'>
4260
4387
  <div class='community-drawer-title'>
4261
- <i class="fa-regular fa-message"></i>
4262
- <span>Community</span>
4388
+ <button type="button" class="community-drawer-home" data-tippy-content="Community home" aria-label="Community home">
4389
+ <i class="fa-solid fa-globe"></i>
4390
+ <span>Community</span>
4391
+ </button>
4263
4392
  <span class='community-drawer-status' data-state="offline" data-tippy-content="Offline" aria-label="Offline" role="img"></span>
4264
4393
  </div>
4265
4394
  <div class='community-drawer-actions'>
4395
+ <button type='button' class='btn2 community-drawer-back' disabled data-tippy-content="Back" aria-label="Back">
4396
+ <i class="fa-solid fa-chevron-left"></i>
4397
+ </button>
4398
+ <button type='button' class='btn2 community-drawer-forward' disabled data-tippy-content="Forward" aria-label="Forward">
4399
+ <i class="fa-solid fa-chevron-right"></i>
4400
+ </button>
4266
4401
  <button type='button' class='btn2 community-drawer-refresh' disabled data-tippy-content="Refresh" aria-label="Refresh community">
4267
4402
  <i class="fa-solid fa-rotate-right"></i>
4268
4403
  </button>
4269
4404
  <button type='button' class='btn2 community-drawer-toggle' data-tippy-content="Connect to Pinokio Network" aria-label="Connect to Pinokio Network">
4270
4405
  <i class="fa-solid fa-link"></i>
4271
4406
  </button>
4407
+ <button type='button' class='btn2 community-drawer-expand' data-tippy-content="Expand panel" aria-label="Expand panel" aria-pressed="false">
4408
+ <i class="fa-solid fa-expand"></i>
4409
+ </button>
4272
4410
  <button type='button' class='btn2 community-drawer-close' data-tippy-content="Close panel" aria-label="Close community panel">
4273
4411
  <i class="fa-solid fa-xmark"></i>
4274
4412
  </button>
4275
4413
  </div>
4276
4414
  </div>
4415
+ <div class='community-drawer-location'>
4416
+ <input class='community-drawer-location-input' type='text' value="" readonly aria-label="Community URL">
4417
+ <div class='community-drawer-location-overlay' aria-hidden="true"></div>
4418
+ <textarea class='community-drawer-location-textarea' rows="1" readonly aria-label="Community URL"></textarea>
4419
+ </div>
4277
4420
  <div class='community-drawer-body'>
4278
4421
  <div class='community-drawer-empty'>
4279
4422
  <div class='community-drawer-empty-head'>
4280
4423
  <div class='community-drawer-empty-icon'>
4281
4424
  <i class="fa-solid fa-plug-circle-xmark" aria-hidden="true"></i>
4282
4425
  </div>
4283
- <div class='community-drawer-empty-title'>Connect to Pinokio Network</div>
4426
+ <div class='community-drawer-empty-title'>Load Community</div>
4284
4427
  </div>
4285
- <div class='community-drawer-empty-note muted'>Grant network access to connect to Pinokio Network.</div>
4286
- <button type='button' class='btn community-drawer-connect'>Allow access</button>
4428
+ <div class='community-drawer-empty-note muted'>Load https://pinokio.co in the panel (requires network)</div>
4429
+ <button type='button' class='btn community-drawer-connect'>Load</button>
4287
4430
  </div>
4288
4431
  <iframe class='community-frame hidden' title="Community updates"></iframe>
4289
4432
  </div>
@@ -10594,15 +10737,29 @@ document.addEventListener("DOMContentLoaded", () => {
10594
10737
  const communityModeToggle = document.getElementById("community-mode-toggle")
10595
10738
  const frame = drawer.querySelector(".community-frame")
10596
10739
  const connectBtn = drawer.querySelector(".community-drawer-connect")
10740
+ const backBtn = drawer.querySelector(".community-drawer-back")
10741
+ const forwardBtn = drawer.querySelector(".community-drawer-forward")
10597
10742
  const refreshBtn = drawer.querySelector(".community-drawer-refresh")
10598
10743
  const toggleBtn = drawer.querySelector(".community-drawer-toggle")
10744
+ const expandBtn = drawer.querySelector(".community-drawer-expand")
10599
10745
  const closeBtn = drawer.querySelector(".community-drawer-close")
10746
+ const homeBtn = drawer.querySelector(".community-drawer-home")
10747
+ const locationContainer = drawer.querySelector(".community-drawer-location")
10748
+ const locationInput = drawer.querySelector(".community-drawer-location-input")
10749
+ const locationOverlay = drawer.querySelector(".community-drawer-location-overlay")
10750
+ const locationTextarea = drawer.querySelector(".community-drawer-location-textarea")
10600
10751
  const statusDot = drawer.querySelector(".community-drawer-status")
10601
10752
  const empty = drawer.querySelector(".community-drawer-empty")
10602
10753
  const emptyTitle = drawer.querySelector(".community-drawer-empty-title")
10603
10754
  const emptyNote = drawer.querySelector(".community-drawer-empty-note")
10604
10755
  const resizer = document.getElementById("community-resizer")
10605
10756
  const url = drawer.dataset.communityUrl || ""
10757
+ let communityOrigin = ""
10758
+ try {
10759
+ communityOrigin = url ? new URL(url).origin : ""
10760
+ } catch (_) {
10761
+ communityOrigin = ""
10762
+ }
10606
10763
  const enabledKey = "pinokio.community.enabled"
10607
10764
  const openKey = "pinokio.community.open"
10608
10765
  const widthKey = "pinokio.community.width"
@@ -10629,6 +10786,9 @@ document.addEventListener("DOMContentLoaded", () => {
10629
10786
  }
10630
10787
  communityMode = nextMode
10631
10788
  appcanvas.classList.toggle("community-mode", communityMode)
10789
+ if (communityMode) {
10790
+ setExpanded(false)
10791
+ }
10632
10792
  if (communityModeToggle) {
10633
10793
  communityModeToggle.classList.toggle("selected", communityMode)
10634
10794
  communityModeToggle.setAttribute("aria-pressed", communityMode ? "true" : "false")
@@ -10674,6 +10834,8 @@ document.addEventListener("DOMContentLoaded", () => {
10674
10834
  } else {
10675
10835
  open = true
10676
10836
  }
10837
+ let expanded = false
10838
+ let locationExpanded = false
10677
10839
 
10678
10840
  const COMMUNITY_MIN_WIDTH = 240
10679
10841
  const COMMUNITY_MAX_WIDTH = 640
@@ -10736,6 +10898,10 @@ document.addEventListener("DOMContentLoaded", () => {
10736
10898
  const setOpen = (next, opts) => {
10737
10899
  const persist = !(opts && opts.persist === false)
10738
10900
  open = !!next
10901
+ if (!open) {
10902
+ setExpanded(false)
10903
+ setLocationExpanded(false)
10904
+ }
10739
10905
  if (appcanvas) {
10740
10906
  appcanvas.classList.toggle("community-open", open)
10741
10907
  }
@@ -10764,6 +10930,118 @@ document.addEventListener("DOMContentLoaded", () => {
10764
10930
  }
10765
10931
  }
10766
10932
 
10933
+ const setExpanded = (next) => {
10934
+ const nextExpanded = !!next
10935
+ if (expanded === nextExpanded) {
10936
+ return
10937
+ }
10938
+ expanded = nextExpanded
10939
+ if (appcanvas) {
10940
+ appcanvas.classList.toggle("community-expanded", expanded)
10941
+ }
10942
+ if (expandBtn) {
10943
+ expandBtn.setAttribute("aria-pressed", expanded ? "true" : "false")
10944
+ const icon = expandBtn.querySelector("i")
10945
+ if (icon) {
10946
+ icon.className = expanded ? "fa-solid fa-compress" : "fa-solid fa-expand"
10947
+ }
10948
+ const label = expanded ? "Exit full screen" : "Expand panel"
10949
+ expandBtn.setAttribute("aria-label", label)
10950
+ setTooltip(expandBtn, label)
10951
+ }
10952
+ }
10953
+
10954
+ const setNavDisabled = (disabled) => {
10955
+ if (backBtn) backBtn.disabled = disabled
10956
+ if (forwardBtn) forwardBtn.disabled = disabled
10957
+ }
10958
+
10959
+ const syncLocationTextareaHeight = () => {
10960
+ if (!locationTextarea || !locationContainer || !drawer) return
10961
+ locationTextarea.style.height = "auto"
10962
+ const desired = locationTextarea.scrollHeight
10963
+ const drawerRect = drawer.getBoundingClientRect()
10964
+ const containerRect = locationContainer.getBoundingClientRect()
10965
+ const maxHeight = Math.max(36, Math.floor(drawerRect.bottom - containerRect.top - 8))
10966
+ if (desired > maxHeight) {
10967
+ locationTextarea.style.height = `${maxHeight}px`
10968
+ locationTextarea.style.overflowY = "auto"
10969
+ } else {
10970
+ locationTextarea.style.height = `${desired}px`
10971
+ locationTextarea.style.overflowY = "hidden"
10972
+ }
10973
+ }
10974
+
10975
+ const setLocationExpanded = (next) => {
10976
+ if (!locationContainer || !locationTextarea) return
10977
+ const nextExpanded = !!next
10978
+ if (locationExpanded === nextExpanded) return
10979
+ locationExpanded = nextExpanded
10980
+ locationContainer.classList.toggle("is-expanded", locationExpanded)
10981
+ if (locationExpanded) {
10982
+ syncLocationTextareaHeight()
10983
+ requestAnimationFrame(() => {
10984
+ try {
10985
+ locationTextarea.focus()
10986
+ locationTextarea.select()
10987
+ } catch (_) {}
10988
+ })
10989
+ } else {
10990
+ locationTextarea.style.height = ""
10991
+ locationTextarea.style.overflowY = ""
10992
+ }
10993
+ }
10994
+
10995
+ const setLocationFull = (value) => {
10996
+ const nextValue = typeof value === "string" ? value.trim() : ""
10997
+ if (locationInput) {
10998
+ locationInput.value = nextValue
10999
+ locationInput.title = nextValue
11000
+ }
11001
+ if (locationOverlay) {
11002
+ locationOverlay.textContent = nextValue
11003
+ }
11004
+ if (locationTextarea) {
11005
+ locationTextarea.value = nextValue
11006
+ locationTextarea.title = nextValue
11007
+ if (locationExpanded) {
11008
+ syncLocationTextareaHeight()
11009
+ }
11010
+ }
11011
+ }
11012
+
11013
+ const getCurrentCommunityUrl = () => {
11014
+ const inputValue = locationInput ? String(locationInput.value || "").trim() : ""
11015
+ const textareaValue = locationTextarea ? String(locationTextarea.value || "").trim() : ""
11016
+ const overlayValue = locationOverlay ? String(locationOverlay.textContent || "").trim() : ""
11017
+ return inputValue || textareaValue || overlayValue || url || ""
11018
+ }
11019
+
11020
+ const syncLocation = () => {
11021
+ if (!locationInput) return
11022
+ if (!url) {
11023
+ locationInput.placeholder = "Unavailable"
11024
+ setLocationFull("")
11025
+ return
11026
+ }
11027
+ if (!enabled) {
11028
+ locationInput.placeholder = "Not connected"
11029
+ setLocationFull("")
11030
+ return
11031
+ }
11032
+ let nextValue = url
11033
+ try {
11034
+ if (frame && frame.contentWindow && frame.contentWindow.location) {
11035
+ const href = frame.contentWindow.location.href
11036
+ if (typeof href === "string" && href) {
11037
+ nextValue = href
11038
+ }
11039
+ }
11040
+ } catch (_) {}
11041
+ locationInput.placeholder = ""
11042
+ setLocationFull(nextValue)
11043
+ }
11044
+
10767
11045
  const setStatusDot = (state, label) => {
10768
11046
  if (!statusDot) return
10769
11047
  statusDot.setAttribute("data-state", state)
@@ -10787,18 +11065,31 @@ document.addEventListener("DOMContentLoaded", () => {
10787
11065
  }
10788
11066
  }
10789
11067
 
11068
+ const goHome = () => {
11069
+ if (!enabled || !url || !frame) return
11070
+ frame.dataset.loaded = "1"
11071
+ frame.src = url
11072
+ setLocationFull(url)
11073
+ }
11074
+
10790
11075
  const updateState = () => {
10791
11076
  if (!url) {
10792
11077
  setStatusDot("unavailable", "Unavailable")
10793
11078
  if (refreshBtn) {
10794
11079
  refreshBtn.disabled = true
10795
11080
  }
11081
+ if (homeBtn) {
11082
+ homeBtn.disabled = true
11083
+ setTooltip(homeBtn, "Unavailable")
11084
+ }
10796
11085
  if (toggleBtn) {
10797
11086
  toggleBtn.disabled = true
10798
11087
  setTooltip(toggleBtn, "Unavailable")
10799
11088
  }
11089
+ setNavDisabled(true)
10800
11090
  if (empty) empty.classList.remove("hidden")
10801
11091
  if (frame) frame.classList.add("hidden")
11092
+ syncLocation()
10802
11093
  return
10803
11094
  }
10804
11095
  if (enabled) {
@@ -10806,6 +11097,11 @@ document.addEventListener("DOMContentLoaded", () => {
10806
11097
  if (refreshBtn) {
10807
11098
  refreshBtn.disabled = false
10808
11099
  }
11100
+ if (homeBtn) {
11101
+ homeBtn.disabled = false
11102
+ setTooltip(homeBtn, "Community home")
11103
+ }
11104
+ setNavDisabled(false)
10809
11105
  setToggleState(true)
10810
11106
  if (empty) empty.classList.add("hidden")
10811
11107
  if (frame) {
@@ -10820,10 +11116,16 @@ document.addEventListener("DOMContentLoaded", () => {
10820
11116
  if (refreshBtn) {
10821
11117
  refreshBtn.disabled = true
10822
11118
  }
11119
+ if (homeBtn) {
11120
+ homeBtn.disabled = true
11121
+ setTooltip(homeBtn, "Connect to Pinokio Network")
11122
+ }
11123
+ setNavDisabled(true)
10823
11124
  setToggleState(false)
10824
11125
  if (empty) empty.classList.remove("hidden")
10825
11126
  if (frame) frame.classList.add("hidden")
10826
11127
  }
11128
+ syncLocation()
10827
11129
  }
10828
11130
 
10829
11131
  const setEnabled = (next) => {
@@ -10836,6 +11138,20 @@ document.addEventListener("DOMContentLoaded", () => {
10836
11138
  updateState()
10837
11139
  }
10838
11140
 
11141
+ const navigateFrame = (direction) => {
11142
+ if (!enabled || !url || !frame) return
11143
+ if (direction !== "back" && direction !== "forward") return
11144
+ try {
11145
+ const targetOrigin = communityOrigin || "*"
11146
+ if (frame.contentWindow) {
11147
+ frame.contentWindow.postMessage(
11148
+ { type: "pinokio:community:navigate", direction },
11149
+ targetOrigin
11150
+ )
11151
+ }
11152
+ } catch (_) {}
11153
+ }
11154
+
10839
11155
  if (toggle) {
10840
11156
  toggle.addEventListener("click", () => setOpen(!open))
10841
11157
  }
@@ -10864,12 +11180,42 @@ document.addEventListener("DOMContentLoaded", () => {
10864
11180
  setEnabled(true)
10865
11181
  })
10866
11182
  }
11183
+ if (backBtn) {
11184
+ backBtn.addEventListener("click", () => {
11185
+ navigateFrame("back")
11186
+ })
11187
+ }
11188
+ if (forwardBtn) {
11189
+ forwardBtn.addEventListener("click", () => {
11190
+ navigateFrame("forward")
11191
+ })
11192
+ }
11193
+ if (refreshBtn) {
11194
+ refreshBtn.addEventListener("click", () => {
11195
+ if (!enabled || !url || !frame) return
11196
+ const targetUrl = getCurrentCommunityUrl()
11197
+ if (!targetUrl) return
11198
+ frame.dataset.loaded = "1"
11199
+ frame.src = targetUrl
11200
+ setLocationFull(targetUrl)
11201
+ })
11202
+ }
10867
11203
  if (toggleBtn) {
10868
11204
  toggleBtn.addEventListener("click", () => {
10869
11205
  if (!url) return
10870
11206
  setEnabled(!enabled)
10871
11207
  })
10872
11208
  }
11209
+ if (expandBtn) {
11210
+ expandBtn.addEventListener("click", () => {
11211
+ setExpanded(!expanded)
11212
+ })
11213
+ }
11214
+ if (homeBtn) {
11215
+ homeBtn.addEventListener("click", () => {
11216
+ goHome()
11217
+ })
11218
+ }
10873
11219
  if (closeBtn) {
10874
11220
  closeBtn.addEventListener("click", () => {
10875
11221
  if (communityMode) {
@@ -10879,14 +11225,43 @@ document.addEventListener("DOMContentLoaded", () => {
10879
11225
  setOpen(false)
10880
11226
  })
10881
11227
  }
10882
- if (refreshBtn) {
10883
- refreshBtn.addEventListener("click", () => {
10884
- if (!enabled || !url || !frame) return
10885
- frame.dataset.loaded = "1"
10886
- frame.src = url
11228
+
11229
+ if (locationInput) {
11230
+ locationInput.addEventListener("focus", () => {
11231
+ setLocationExpanded(true)
11232
+ })
11233
+ }
11234
+ if (locationTextarea) {
11235
+ locationTextarea.addEventListener("blur", () => {
11236
+ setLocationExpanded(false)
11237
+ })
11238
+ locationTextarea.addEventListener("keydown", (event) => {
11239
+ if (event.key !== "Escape") return
11240
+ event.preventDefault()
11241
+ try {
11242
+ locationTextarea.blur()
11243
+ } catch (_) {}
11244
+ })
11245
+ }
11246
+
11247
+ if (frame) {
11248
+ frame.addEventListener("load", () => {
11249
+ syncLocation()
10887
11250
  })
10888
11251
  }
10889
11252
 
11253
+ window.addEventListener("message", (event) => {
11254
+ if (!event || !event.data || !frame) return
11255
+ if (event.data.type !== "pinokio:community:location") return
11256
+ if (typeof event.data.url !== "string") return
11257
+ if (communityOrigin && event.origin !== communityOrigin) return
11258
+ if (!enabled) return
11259
+ if (locationInput) {
11260
+ locationInput.placeholder = ""
11261
+ }
11262
+ setLocationFull(event.data.url)
11263
+ })
11264
+
10890
11265
  if (!url) {
10891
11266
  if (connectBtn) {
10892
11267
  connectBtn.disabled = true
@@ -10977,7 +11352,7 @@ document.addEventListener("DOMContentLoaded", () => {
10977
11352
  }
10978
11353
  })()
10979
11354
 
10980
- (function() {
11355
+ ;(function() {
10981
11356
  const scroller = document.querySelector(".appcanvas > aside .menu-scroller")
10982
11357
  if (!scroller) return
10983
11358
  const updateScrollHints = () => {
@@ -967,7 +967,7 @@ document.addEventListener("DOMContentLoaded", () => {
967
967
  <aside>
968
968
  <div class='btn-tab'>
969
969
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
970
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
970
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Community</div></a>
971
971
  </div>
972
972
  <a href="/home" class='tab'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
973
973
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -913,7 +913,7 @@ document.addEventListener('DOMContentLoaded', function() {
913
913
  <aside>
914
914
  <div class='btn-tab'>
915
915
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
916
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
916
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Community</div></a>
917
917
  </div>
918
918
  <a href="/home" class='tab'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
919
919
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -494,10 +494,10 @@ body.dark aside .current.selected {
494
494
  <div class='app-btns'>
495
495
  <!--
496
496
  <a class='btn create-new' href="/init"><i class="fa-solid fa-plus"></i> Build</a>
497
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i> Discover</a>
497
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i> Community</a>
498
498
  -->
499
499
  <!--
500
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-magnifying-glass"></i> Discover</a>
500
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-magnifying-glass"></i> Community</a>
501
501
  -->
502
502
  </div>
503
503
  <% if (display.includes("form")) { %>
@@ -541,9 +541,6 @@ body.dark aside .current.selected {
541
541
  <button class='btn browse' data-src="<%=item.dev_url%>">
542
542
  <i class="fa-solid fa-code"></i> Dev
543
543
  </button>
544
- <button class='btn browse' data-src="<%=item.review_url%>">
545
- <i class="fa-regular fa-message"></i> Forum
546
- </button>
547
544
  <button class='btn browse' data-src="<%=item.view_url%>">
548
545
  <i class="fa-regular fa-eye"></i> View
549
546
  </button>
@@ -635,9 +632,6 @@ body.dark aside .current.selected {
635
632
  <button class='btn browse' data-src="<%=item.dev_url%>">
636
633
  <i class="fa-solid fa-code"></i> Dev
637
634
  </button>
638
- <button class='btn browse' data-src="<%=item.review_url%>">
639
- <i class="fa-regular fa-message"></i> Forum
640
- </button>
641
635
  <button class='btn browse' data-src="<%=item.view_url%>">
642
636
  <i class="fa-regular fa-eye"></i> View
643
637
  </button>
@@ -690,7 +684,7 @@ body.dark aside .current.selected {
690
684
  <h1>Welcome.</h1>
691
685
  <br>
692
686
  <div>Get started by installing or creating some pinokio scripts.</div>
693
- <a href="/home?mode=explore" class='btn'><i class="fa-solid fa-globe"></i> Discover</a>
687
+ <a href="/home?mode=explore" class='btn'><i class="fa-solid fa-globe"></i> Community</a>
694
688
  <span>&nbsp;or&nbsp;</span>
695
689
  <button type='button' class='btn' onclick="(function(btn){ if(btn){ btn.click(); } })(document.getElementById('create-launcher-button'))"><i class="fa-solid fa-wand-magic-sparkles"></i> Create</button>
696
690
  </div>
@@ -731,7 +725,7 @@ body.dark aside .current.selected {
731
725
  <aside>
732
726
  <div class='btn-tab'>
733
727
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
734
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
728
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Community</div></a>
735
729
  </div>
736
730
  <a href="/home" class='tab selected'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
737
731
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -311,7 +311,7 @@ body.dark .open-menu, body.dark .browse {
311
311
  <!--
312
312
  <a class='btn create-new' href="/create"><i class="fa-solid fa-folder-plus"></i> Create</a>
313
313
  -->
314
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-magnifying-glass"></i> Discover</a>
314
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-magnifying-glass"></i> Community</a>
315
315
  </div>
316
316
  <% if (display.includes("form")) { %>
317
317
  <input type='search' class="flexible" placeholder='Filter downloaded apps'>
@@ -479,7 +479,7 @@ body.dark .open-menu, body.dark .browse {
479
479
  <h1>Welcome.</h1>
480
480
  <br>
481
481
  <div>Get started by installing some Pinokio scripts.</div>
482
- <a href="/home?mode=explore" class='btn'><i class="fa-solid fa-globe"></i> Visit Discover Page</a>
482
+ <a href="/home?mode=explore" class='btn'><i class="fa-solid fa-globe"></i> Visit Community Page</a>
483
483
  </div>
484
484
  <% } %>
485
485
  <% } else { %>
@@ -1938,7 +1938,7 @@ body.dark .ace-editor {
1938
1938
  <aside>
1939
1939
  <div class='btn-tab'>
1940
1940
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
1941
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
1941
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Community</div></a>
1942
1942
  </div>
1943
1943
  <a href="/home" class='tab'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
1944
1944
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -691,7 +691,7 @@ document.addEventListener('DOMContentLoaded', function() {
691
691
  <!--
692
692
  <div class='app-btns'>
693
693
  <a class='btn create-new' href="/init"><i class="fa-solid fa-plus"></i> Build</a>
694
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-magnifying-glass"></i> Discover</a>
694
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-magnifying-glass"></i> Community</a>
695
695
  </div>
696
696
  -->
697
697
  <input type='search' class="flexible" placeholder='Search apps'>
@@ -988,7 +988,7 @@ document.addEventListener('DOMContentLoaded', function() {
988
988
  <aside>
989
989
  <div class='btn-tab'>
990
990
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
991
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
991
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Community</div></a>
992
992
  </div>
993
993
  <a href="/home" class='tab'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
994
994
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -1192,7 +1192,7 @@ document.addEventListener('DOMContentLoaded', function() {
1192
1192
  <aside>
1193
1193
  <div class='btn-tab'>
1194
1194
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
1195
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
1195
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Community</div></a>
1196
1196
  </div>
1197
1197
  <a href="/home" class='tab'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
1198
1198
  <a href="/network" class='tab selected'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -412,7 +412,7 @@ input:checked + .slider:before {
412
412
  <a href="/connect" class='btn2'><div><i class="fa-solid fa-circle-user"></i></div><div>Connect</div></a>
413
413
  <div class='flexible'></div>
414
414
  <div class='nav-btns'>
415
- <a class='btn2' id='explore' href="/home?mode=explore"><div><i class="fa-solid fa-magnifying-glass"></i></div><div>Discover</div></a>
415
+ <a class='btn2' id='explore' href="/home?mode=explore"><div><i class="fa-solid fa-magnifying-glass"></i></div><div>Community</div></a>
416
416
  <a class='btn2' href="<%=portal%>" target="_blank"><div><i class="fa-solid fa-question"></i></div><div>Help</div></a>
417
417
  <a class='btn2' id='genlog' href="/logs"><div><i class="fa-solid fa-laptop-code"></i></div><div>Logs</div></a>
418
418
  <a class='btn2' href="/home?mode=settings"><div><i class="fa-solid fa-gear"></i></div><div>Settings</div></a>
@@ -791,7 +791,7 @@ document.addEventListener('DOMContentLoaded', function() {
791
791
  <aside>
792
792
  <div class='btn-tab'>
793
793
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
794
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
794
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Community</div></a>
795
795
  </div>
796
796
  <a href="/home" class='tab'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
797
797
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -626,7 +626,7 @@ document.addEventListener('DOMContentLoaded', function() {
626
626
  <aside>
627
627
  <div class='btn-tab'>
628
628
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
629
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
629
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Community</div></a>
630
630
  </div>
631
631
  <a href="/home" class='tab'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
632
632
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
@@ -1267,7 +1267,7 @@ document.addEventListener('DOMContentLoaded', function() {
1267
1267
  <aside>
1268
1268
  <div class='btn-tab'>
1269
1269
  <button type='button' class='btn' id='create-launcher-button'><i class="fa-solid fa-plus"></i><div class='caption'>Create</div></button>
1270
- <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Discover</div></a>
1270
+ <a class='btn' id='explore' href="/home?mode=explore"><i class="fa-solid fa-globe"></i><div class='caption'>Community</div></a>
1271
1271
  </div>
1272
1272
  <a href="/home" class='tab'><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
1273
1273
  <a href="/network" class='tab'><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>