pinokiod 7.2.7 → 7.2.9

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.
@@ -5288,6 +5288,7 @@ header.navheader .mode-selector .community-mode-toggle {
5288
5288
  </a>
5289
5289
  <%})%>
5290
5290
  </div>
5291
+ <div class='active-nested-path hidden' id='active-nested-path'></div>
5291
5292
  </div>
5292
5293
  <div class='menu-actions'>
5293
5294
  <% if (type === 'run') { %>
@@ -7184,6 +7185,7 @@ const rerenderMenuSection = (container, html) => {
7184
7185
  }
7185
7186
 
7186
7187
  if (!target) {
7188
+ activeNestedFocusMenu = null
7187
7189
  syncActiveNestedPath()
7188
7190
  browserPopoutSurface.hide()
7189
7191
  document.querySelector(".container").classList.remove("active")
@@ -7217,6 +7219,7 @@ const rerenderMenuSection = (container, html) => {
7217
7219
  el.classList.remove("selected")
7218
7220
  })
7219
7221
  target.classList.add("selected")
7222
+ activeNestedFocusMenu = null
7220
7223
  syncActiveNestedPath({ selectedLink: target })
7221
7224
  if (skipPersistedSelection && target.hasAttribute('data-default')) {
7222
7225
  ignorePersistedSelection = false
@@ -8052,7 +8055,162 @@ const rerenderMenuSection = (container, html) => {
8052
8055
 
8053
8056
  const getSubmenu = (menu) => getDirectChild(menu, ".submenu")
8054
8057
  const getToggle = (menu) => getDirectChild(menu, ".reveal")
8055
- const syncActiveNestedPath = () => {}
8058
+ const activeNestedPathRoot = document.getElementById("active-nested-path")
8059
+ const activeNestedProxyMap = new WeakMap()
8060
+ let activeNestedFocusMenu = null
8061
+
8062
+ const getNestedMenuChain = (node) => {
8063
+ if (!node) {
8064
+ return []
8065
+ }
8066
+ let current = node
8067
+ if (!current.classList || !current.classList.contains("nested-menu")) {
8068
+ current = current.closest(".nested-menu")
8069
+ }
8070
+ const chain = []
8071
+ while (current) {
8072
+ chain.unshift(current)
8073
+ current = current.parentElement ? current.parentElement.closest(".nested-menu") : null
8074
+ }
8075
+ return chain
8076
+ }
8077
+
8078
+ const sanitizeActiveNestedProxy = (proxy) => {
8079
+ if (!proxy) {
8080
+ return null
8081
+ }
8082
+ proxy.removeAttribute("id")
8083
+ proxy.classList.remove("frame-link", "selected", "tab-link-popover-host")
8084
+ proxy.classList.add("active-nested-proxy")
8085
+ proxy.setAttribute("data-active-nested-proxy", "true")
8086
+ proxy.querySelectorAll(".tab-link-popover-trigger").forEach((node) => {
8087
+ node.remove()
8088
+ })
8089
+ return proxy
8090
+ }
8091
+
8092
+ const buildActiveNestedProxy = (child, isCurrent) => {
8093
+ if (!child) {
8094
+ return null
8095
+ }
8096
+ let proxy
8097
+ if (child.classList && child.classList.contains("nested-menu")) {
8098
+ const toggle = getToggle(child)
8099
+ if (!toggle) {
8100
+ return null
8101
+ }
8102
+ proxy = toggle.cloneNode(true)
8103
+ } else {
8104
+ proxy = child.cloneNode(true)
8105
+ }
8106
+ sanitizeActiveNestedProxy(proxy)
8107
+ if (child.classList && child.classList.contains("nested-menu")) {
8108
+ const loader = proxy.querySelector(".loader")
8109
+ if (loader) {
8110
+ loader.innerHTML = `<i class="fa-solid ${isCurrent ? "fa-angle-down" : "fa-angle-right"}"></i>`
8111
+ }
8112
+ }
8113
+ proxy.classList.toggle("is-current", Boolean(isCurrent))
8114
+ activeNestedProxyMap.set(proxy, child)
8115
+ return proxy
8116
+ }
8117
+
8118
+ const syncActiveNestedPath = ({ selectedLink = null } = {}) => {
8119
+ if (!activeNestedPathRoot) {
8120
+ return
8121
+ }
8122
+ if (activeNestedFocusMenu && !activeNestedFocusMenu.isConnected) {
8123
+ activeNestedFocusMenu = null
8124
+ }
8125
+ const currentSelectedLink = (selectedLink && selectedLink.isConnected)
8126
+ ? selectedLink
8127
+ : document.querySelector("aside .frame-link.selected")
8128
+ const chain = activeNestedFocusMenu
8129
+ ? getNestedMenuChain(activeNestedFocusMenu)
8130
+ : getNestedMenuChain(currentSelectedLink)
8131
+
8132
+ activeNestedPathRoot.replaceChildren()
8133
+
8134
+ if (!chain.length) {
8135
+ activeNestedPathRoot.classList.add("hidden")
8136
+ if (window.PinokioMenuScrollHints && typeof window.PinokioMenuScrollHints.update === "function") {
8137
+ window.PinokioMenuScrollHints.update()
8138
+ }
8139
+ return
8140
+ }
8141
+
8142
+ chain.forEach((menu, index) => {
8143
+ const submenu = getSubmenu(menu)
8144
+ if (!submenu) {
8145
+ return
8146
+ }
8147
+ const row = document.createElement("div")
8148
+ row.className = "m active-nested-row"
8149
+ row.dataset.activeNestedLevel = String(index)
8150
+ const nextMenu = chain[index + 1] || null
8151
+
8152
+ Array.from(submenu.children).forEach((child) => {
8153
+ let isCurrent = false
8154
+ if (child.classList && child.classList.contains("nested-menu")) {
8155
+ isCurrent = child === nextMenu || (!nextMenu && currentSelectedLink ? child.contains(currentSelectedLink) : false)
8156
+ } else {
8157
+ isCurrent = child === currentSelectedLink
8158
+ }
8159
+ const proxy = buildActiveNestedProxy(child, isCurrent)
8160
+ if (proxy) {
8161
+ row.appendChild(proxy)
8162
+ }
8163
+ })
8164
+
8165
+ if (row.childElementCount > 0) {
8166
+ activeNestedPathRoot.appendChild(row)
8167
+ }
8168
+ })
8169
+
8170
+ if (!activeNestedPathRoot.childElementCount) {
8171
+ activeNestedPathRoot.classList.add("hidden")
8172
+ if (window.PinokioMenuScrollHints && typeof window.PinokioMenuScrollHints.update === "function") {
8173
+ window.PinokioMenuScrollHints.update()
8174
+ }
8175
+ return
8176
+ }
8177
+
8178
+ activeNestedPathRoot.classList.remove("hidden")
8179
+ const currentProxy = activeNestedPathRoot.querySelector(".active-nested-proxy.is-current")
8180
+ if (currentProxy && typeof currentProxy.scrollIntoView === "function") {
8181
+ currentProxy.scrollIntoView({
8182
+ block: "nearest",
8183
+ inline: "nearest"
8184
+ })
8185
+ }
8186
+ if (window.PinokioMenuScrollHints && typeof window.PinokioMenuScrollHints.update === "function") {
8187
+ window.PinokioMenuScrollHints.update()
8188
+ }
8189
+ }
8190
+
8191
+ if (activeNestedPathRoot) {
8192
+ activeNestedPathRoot.addEventListener("click", (event) => {
8193
+ const proxy = event.target.closest("[data-active-nested-proxy='true']")
8194
+ if (!proxy || !activeNestedPathRoot.contains(proxy)) {
8195
+ return
8196
+ }
8197
+ const source = activeNestedProxyMap.get(proxy)
8198
+ if (!source || !source.isConnected) {
8199
+ return
8200
+ }
8201
+ event.preventDefault()
8202
+ event.stopPropagation()
8203
+ if (source.classList && source.classList.contains("nested-menu")) {
8204
+ activeNestedFocusMenu = source
8205
+ syncActiveNestedPath()
8206
+ return
8207
+ }
8208
+ activeNestedFocusMenu = null
8209
+ if (typeof source.click === "function") {
8210
+ source.click()
8211
+ }
8212
+ })
8213
+ }
8056
8214
 
8057
8215
  renderSelection()
8058
8216
 
@@ -27,6 +27,7 @@
27
27
  </button>
28
28
  </div>
29
29
  <a href="/home" class="tab <%= sidebarSelected === 'home' ? 'selected' : '' %>" data-tippy-content="This machine"><i class='fas fa-laptop-code'></i><div class='caption'>This machine</div></a>
30
+ <a href="/workspaces" class="tab <%= sidebarSelected === 'workspaces' ? 'selected' : '' %>" data-tippy-content="Workspaces"><i class="fa-solid fa-folder-tree"></i><div class='caption'>Workspaces</div></a>
30
31
  <a href="/network" class="tab <%= sidebarSelected === 'network' ? 'selected' : '' %>" data-tippy-content="Local network"><i class="fa-solid fa-wifi"></i><div class='caption'>Local network</div></a>
31
32
  <% if (sidebarList.length > 0) { %>
32
33
  <% sidebarList.forEach(({ host, name, platform }) => { %>
@@ -0,0 +1,61 @@
1
+ <%
2
+ const shellCount = workspace.counts && Number.isFinite(workspace.counts.shells) ? workspace.counts.shells : 0;
3
+ const scriptCount = workspace.counts && Number.isFinite(workspace.counts.scripts) ? workspace.counts.scripts : 0;
4
+ const draftCount = workspace.counts && Number.isFinite(workspace.counts.drafts) ? workspace.counts.drafts : 0;
5
+ const shellTitles = Array.isArray(workspace.shells) ? workspace.shells.map((shell) => shell.title || shell.id || "").join(" ") : "";
6
+ const scriptTitles = Array.isArray(workspace.scripts) ? workspace.scripts.map((script) => script.title || script.id || "").join(" ") : "";
7
+ const draft = workspace.draft || null;
8
+ const draftId = draft && draft.id ? draft.id : `draft-${index}`;
9
+ const searchText = [workspace.name, workspace.cwd, shellTitles, scriptTitles, draft && draft.title].filter(Boolean).join(" ");
10
+ const modifiedLabel = dateLabel(workspace.modifiedAt);
11
+ const details = [];
12
+ if (shellCount > 0) details.push(plural(shellCount, "terminal"));
13
+ if (scriptCount > 0) details.push(plural(scriptCount, "script"));
14
+ if (draftCount > 0) details.push(draftCount === 1 ? "Draft ready" : plural(draftCount, "draft"));
15
+ if (modifiedLabel) details.push(modifiedLabel);
16
+ %>
17
+ <div
18
+ class="workspace-card workspace-line line align-top"
19
+ data-cwd="<%= workspace.cwd %>"
20
+ data-name="<%= workspace.name %>"
21
+ data-index="<%= index %>"
22
+ data-launch-count-total="<%= workspace.usageCount || 0 %>"
23
+ data-last-launch-at="<%= workspace.lastOpenedAt || workspace.modifiedAt || "" %>"
24
+ data-search="<%= searchText %>"
25
+ >
26
+ <h3>
27
+ <div class="workspace-icon item-icon">
28
+ <i class="fa-solid <%= workspace.running ? "fa-folder-open" : "fa-folder" %>" aria-hidden="true"></i>
29
+ </div>
30
+ <div class="col">
31
+ <div class="title">
32
+ <i class="fa-solid fa-circle" aria-hidden="true"></i>
33
+ <span><%= workspace.name || "Workspace" %></span>
34
+ </div>
35
+ <div class="uri"><%= workspace.cwd %></div>
36
+ <% if (details.length) { %>
37
+ <div class="description"><%= details.join(" / ") %></div>
38
+ <% } %>
39
+ <div class="menu-btns">
40
+ <% if (workspace.primaryUrl && shellCount === 1) { %>
41
+ <a class="btn" href="<%= workspace.primaryUrl %>" title="Open terminal"><i class="fa-solid fa-terminal" aria-hidden="true"></i> Terminal</a>
42
+ <% } else if (shellCount > 1) { %>
43
+ <button class="btn" type="button" data-open-workspace="<%= workspace.cwd %>" data-workspace-modal-mode="terminals" title="Open terminals"><i class="fa-solid fa-terminal" aria-hidden="true"></i> Terminals</button>
44
+ <% } %>
45
+ <% if (workspace.launchUrl) { %>
46
+ <button class="btn" type="button" data-open-workspace="<%= workspace.cwd %>" data-workspace-modal-mode="session" title="Start session"><i class="fa-solid fa-play" aria-hidden="true"></i> Start</button>
47
+ <% } %>
48
+ <button class="btn" type="button" data-open-path="<%= workspace.cwd %>" title="Open folder"><i class="fa-solid fa-folder-open" aria-hidden="true"></i> Folder</button>
49
+ <% if (draft && draft.postPath) { %>
50
+ <button class="btn" type="button" data-open-path="<%= draft.postPath %>" title="Open draft"><i class="fa-solid fa-file-lines" aria-hidden="true"></i> Draft</button>
51
+ <% if (draft.excerpt) { %>
52
+ <button class="btn" type="button" data-preview-toggle="<%= draftId %>"><i class="fa-solid fa-eye" aria-hidden="true"></i> Preview</button>
53
+ <% } %>
54
+ <% } %>
55
+ </div>
56
+ <% if (draft && draft.excerpt) { %>
57
+ <div class="workspace-draft-preview" data-preview-panel="<%= draftId %>" hidden><%= draft.excerpt %></div>
58
+ <% } %>
59
+ </div>
60
+ </h3>
61
+ </div>
@@ -3086,5 +3086,13 @@ const reloadMemory = async () => {
3086
3086
  </a>
3087
3087
  </div>
3088
3088
  </div>
3089
+ <% if (typeof draft_watch_enabled !== 'undefined' && draft_watch_enabled) { %>
3090
+ <script>
3091
+ window.PinokioDraftContext = {
3092
+ cwd: <%- JSON.stringify((typeof draft_watch_cwd !== 'undefined' && draft_watch_cwd) ? draft_watch_cwd : '').replace(/</g, '\\u003c') %>
3093
+ };
3094
+ </script>
3095
+ <script src="/drafts.js"></script>
3096
+ <% } %>
3089
3097
  </body>
3090
3098
  </html>
@@ -10030,5 +10030,6 @@ body.dark .swal2-popup.pinokio-diff-modal .pinokio-modal-footer--commit .pinokio
10030
10030
  requestAnimationFrame(setViewport)
10031
10031
  })()
10032
10032
  </script>
10033
+ <script src="/drafts.js"></script>
10033
10034
  </body>
10034
10035
  </html>