pinokiod 7.5.9 → 7.5.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/kernel/api/shell/index.js +1 -4
- package/kernel/index.js +1 -1
- package/kernel/shell.js +3 -2
- package/kernel/shell_conda_runtime_guard.js +263 -105
- package/kernel/shells.js +1 -1
- package/package.json +1 -1
- package/release_notes/8.0.0/assets/app-ask-ai-drawer.png +0 -0
- package/release_notes/8.0.0/assets/app-detail-header-actions.png +0 -0
- package/release_notes/8.0.0/assets/autolaunch-dependencies.png +0 -0
- package/release_notes/8.0.0/assets/connect-huggingface-login.png +0 -0
- package/release_notes/8.0.0/assets/home-app-actions.png +0 -0
- package/release_notes/8.0.0/assets/home-sidebar-apps.png +0 -0
- package/release_notes/8.0.0/assets/logs-terminal-reporting.png +0 -0
- package/release_notes/8.0.0/assets/mobile-home-footer-nav.png +0 -0
- package/release_notes/8.0.0/assets/network-phone-access.png +0 -0
- package/release_notes/8.0.0/assets/plugins-agent-tools.png +0 -0
- package/release_notes/8.0.0/assets/skills-management.png +0 -0
- package/release_notes/8.0.0/assets/tools-runtime-management.png +0 -0
- package/release_notes/8.0.0/ui.md +91 -0
- package/server/public/logs.js +65 -5
- package/server/public/style.css +2 -2
- package/server/views/app.ejs +10 -1
- package/server/views/index.ejs +218 -14
- package/test/logs-ask-ai.test.js +245 -0
- package/test/shell-api.test.js +7 -6
- package/test/shell-conda-runtime-guard.test.js +477 -77
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Pinokio 8.0.0 UI Updates
|
|
2
|
+
|
|
3
|
+
This release brings Pinokio's main surfaces into a quieter, more consistent workspace: app discovery, app launch controls, logs, tools, plugins, skills, autolaunch, setup, and mobile navigation now share the same visual language and action patterns.
|
|
4
|
+
|
|
5
|
+
The notes below are grouped by what users will notice, not by commit history. Screenshots were captured from the live local UI after comparing `de83785` to the current `HEAD`.
|
|
6
|
+
|
|
7
|
+
## Cleaner App Discovery
|
|
8
|
+
|
|
9
|
+
Pinokio's home screen now behaves more like a compact app manager. The sidebar is unified with the rest of the product, the app list is easier to scan, search and sort stay prominent, and each app row exposes quick actions without forcing users into the full app page first.
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
The new action panel gives installed apps a focused command surface for common launch, install, update, reset, file, and dev actions. Related commands are grouped in one drawer, which reduces row clutter while keeping the next action close to the app.
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
## App Workspace And Assistance
|
|
18
|
+
|
|
19
|
+
App pages have been rebuilt around a more durable workspace shell. The page chrome, left command rail, right utility panels, app title area, status indicators, resource labels, and launch actions have been tightened so app-specific work feels connected to the rest of Pinokio.
|
|
20
|
+
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
Ask AI now opens as an in-app assistance drawer with searchable terminal and desktop agents. Instead of a generic help entry point, users can choose from bundled agents such as Codex, Claude Code, Qwen Code, Antigravity, Cursor, VS Code, and desktop integrations directly inside the app context.
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
## Plugins, Agents, And Skills
|
|
28
|
+
|
|
29
|
+
The Plugins page now separates terminal plugins from desktop plugins and shows install/manage affordances in a single list. This makes the new bundled native tools easier to understand: terminal agents launch inside Pinokio, while desktop tools launch externally.
|
|
30
|
+
|
|
31
|
+

|
|
32
|
+
|
|
33
|
+
Pinokio also has a new Skills management surface. Users can see where managed skills are stored, where they sync, whether each skill is valid, and whether it is currently enabled. The page also supports downloading skills from a Git URL.
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
## Startup And Launch Requirements
|
|
38
|
+
|
|
39
|
+
Autolaunch is now a first-class configuration page. Users can search installed apps, choose which launch script should run at startup, see how many apps are enabled, and toggle startup behavior without digging through app internals.
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
Setup and requirements screens now present blocked routes as a clear checklist. When a destination such as Local network needs a package update, Pinokio shows what is installed, what needs attention, and the action required before continuing.
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
## Logs, Diagnostics, And Issue Reporting
|
|
48
|
+
|
|
49
|
+
Logs have been redesigned around a file tree and live reader. Users can inspect logs from the machine, stream a selected file, clear the view, keep auto-scroll on, and generate a diagnostic zip from the same screen.
|
|
50
|
+
|
|
51
|
+

|
|
52
|
+
|
|
53
|
+
Behind that surface, the issue-reporting flow is more capable: recent logs can be summarized, redacted, copied, handed to Ask AI, or prepared as a registry draft. Those states require an app failure or report context, so they are not shown in this static screenshot set.
|
|
54
|
+
|
|
55
|
+
## Tools And Runtime Readiness
|
|
56
|
+
|
|
57
|
+
The Tools page now groups package bundles with readiness counts, per-bundle install state, and package-level status. Users can see which runtime bundles are ready, which need installation, and which package manager modules are present without reading terminal output first.
|
|
58
|
+
|
|
59
|
+

|
|
60
|
+
|
|
61
|
+
## Login And Connected Services
|
|
62
|
+
|
|
63
|
+
The Hugging Face login flow has been redesigned as a clear device-authorization page. It states the connection state, the credential provider, the reason to log in, and the next action without mixing auth details into unrelated setup UI.
|
|
64
|
+
|
|
65
|
+

|
|
66
|
+
|
|
67
|
+
GitHub and git-related modals also received layout cleanup: modal tabs, footers, repository status controls, checkpoint rows, and history/diff areas were tightened so longer repository workflows fit better in the available space.
|
|
68
|
+
|
|
69
|
+
## Mobile And Remote Access
|
|
70
|
+
|
|
71
|
+
Mobile layouts now prioritize the app list and move primary navigation to a bottom bar. Search, sort, app cards, favorites, and action buttons remain reachable on a phone-width viewport without the desktop sidebar competing for space.
|
|
72
|
+
|
|
73
|
+

|
|
74
|
+
|
|
75
|
+
Phone and LAN access also received targeted polish. QR and network access entry points are gated behind setup readiness, install terminals attach correctly over LAN, and the old mobile "Tap to connect" curtain has been replaced with a quieter first-interaction audio primer.
|
|
76
|
+
|
|
77
|
+
## Smaller Visual Polish
|
|
78
|
+
|
|
79
|
+
Several changes are intentionally broad but subtle:
|
|
80
|
+
|
|
81
|
+
- Shared sidebar styling now covers home, app, tools, plugins, skills, logs, settings, setup, network, and auth pages.
|
|
82
|
+
- App navigation is more responsive, especially where action labels previously wrapped or crowded the header.
|
|
83
|
+
- Screenshot/capture modals, footer status indicators, popovers, tabs, and terminal controls use flatter, tighter styling.
|
|
84
|
+
- Checkpoints rows, git history dialogs, network troubleshoot panels, and auth pages were normalized to match the newer page shell.
|
|
85
|
+
- Hidden or unused toolbar buttons were removed from the visible chrome so users see fewer inactive controls.
|
|
86
|
+
|
|
87
|
+
## Screenshot Coverage Notes
|
|
88
|
+
|
|
89
|
+
Captured screenshots cover the major visible themes: home discovery, app actions, app workspace chrome, Ask AI, plugins, skills, autolaunch, setup requirements, logs, tools, connected-service login, and mobile navigation.
|
|
90
|
+
|
|
91
|
+
Some UI states were not practical to screenshot without changing runtime state or forcing failures: failed-terminal fallback, report-draft creation, live dependency orchestration while an app is launching, completed peer-network routing, and git/checkpoint modal edge cases. Those changes are still included above because they are user-visible when the relevant workflow is active.
|
package/server/public/logs.js
CHANGED
|
@@ -505,7 +505,39 @@
|
|
|
505
505
|
window.location.href = href
|
|
506
506
|
return true
|
|
507
507
|
}
|
|
508
|
-
|
|
508
|
+
createAskAiLaunchId() {
|
|
509
|
+
try {
|
|
510
|
+
if (window.crypto && typeof window.crypto.randomUUID === 'function') {
|
|
511
|
+
return window.crypto.randomUUID()
|
|
512
|
+
}
|
|
513
|
+
} catch (_) {}
|
|
514
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`
|
|
515
|
+
}
|
|
516
|
+
waitForAskAiLaunchAck(launchId, timeoutMs = 1500) {
|
|
517
|
+
return new Promise((resolve) => {
|
|
518
|
+
let settled = false
|
|
519
|
+
let timer = null
|
|
520
|
+
const finish = (value) => {
|
|
521
|
+
if (settled) return
|
|
522
|
+
settled = true
|
|
523
|
+
if (timer) {
|
|
524
|
+
window.clearTimeout(timer)
|
|
525
|
+
}
|
|
526
|
+
window.removeEventListener('message', onMessage)
|
|
527
|
+
resolve(value)
|
|
528
|
+
}
|
|
529
|
+
const onMessage = (event) => {
|
|
530
|
+
const data = event && event.data && typeof event.data === 'object' ? event.data : null
|
|
531
|
+
if (!data || data.e !== 'pinokio:ask-ai-launch-result' || data.launchId !== launchId) {
|
|
532
|
+
return
|
|
533
|
+
}
|
|
534
|
+
finish(data.opened !== false)
|
|
535
|
+
}
|
|
536
|
+
window.addEventListener('message', onMessage)
|
|
537
|
+
timer = window.setTimeout(() => finish(false), timeoutMs)
|
|
538
|
+
})
|
|
539
|
+
}
|
|
540
|
+
async dispatchAskAiLaunch(tool, prompt) {
|
|
509
541
|
const launchHref = this.buildAskAiLaunchHref(tool, prompt)
|
|
510
542
|
if (!launchHref) {
|
|
511
543
|
this.setStatus('Could not launch this plugin.', true)
|
|
@@ -531,11 +563,38 @@
|
|
|
531
563
|
}
|
|
532
564
|
} catch (_) {}
|
|
533
565
|
}
|
|
566
|
+
try {
|
|
567
|
+
const parentDrawer = window.parent && window.parent !== window ? window.parent.PinokioAskAiDrawer : null
|
|
568
|
+
if (parentDrawer && typeof parentDrawer.openWithAgent === 'function') {
|
|
569
|
+
const opened = parentDrawer.openWithAgent(payload)
|
|
570
|
+
if (opened !== false) {
|
|
571
|
+
this.setStatus('Launching Ask AI…')
|
|
572
|
+
return true
|
|
573
|
+
}
|
|
574
|
+
} else if (parentDrawer && typeof parentDrawer.openWithUrl === 'function') {
|
|
575
|
+
const opened = parentDrawer.openWithUrl(launchHref, {
|
|
576
|
+
workspaceCwd: this.workspaceCwd,
|
|
577
|
+
prompt: payload.prompt
|
|
578
|
+
})
|
|
579
|
+
if (opened !== false) {
|
|
580
|
+
this.setStatus('Launching Ask AI…')
|
|
581
|
+
return true
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
} catch (_) {}
|
|
534
585
|
try {
|
|
535
586
|
if (window.parent && window.parent !== window && typeof window.parent.postMessage === 'function') {
|
|
587
|
+
const launchId = this.createAskAiLaunchId()
|
|
588
|
+
payload.launchId = launchId
|
|
589
|
+
const ack = this.waitForAskAiLaunchAck(launchId)
|
|
536
590
|
window.parent.postMessage(payload, '*')
|
|
537
|
-
|
|
538
|
-
|
|
591
|
+
const opened = await ack
|
|
592
|
+
if (opened) {
|
|
593
|
+
this.setStatus('Launching Ask AI…')
|
|
594
|
+
return true
|
|
595
|
+
}
|
|
596
|
+
this.setStatus('Could not confirm Ask AI launch.', true)
|
|
597
|
+
return false
|
|
539
598
|
}
|
|
540
599
|
} catch (_) {}
|
|
541
600
|
window.location.href = launchHref
|
|
@@ -730,7 +789,7 @@
|
|
|
730
789
|
}
|
|
731
790
|
syncRunState()
|
|
732
791
|
}
|
|
733
|
-
const run = () => {
|
|
792
|
+
const run = async () => {
|
|
734
793
|
const prompt = String(promptTextarea.value || '').trim()
|
|
735
794
|
const tool = this.selectedAskAiTool()
|
|
736
795
|
if (!prompt) {
|
|
@@ -748,7 +807,7 @@
|
|
|
748
807
|
close()
|
|
749
808
|
return
|
|
750
809
|
}
|
|
751
|
-
if (this.dispatchAskAiLaunch(tool, prompt)) {
|
|
810
|
+
if (await this.dispatchAskAiLaunch(tool, prompt)) {
|
|
752
811
|
close()
|
|
753
812
|
}
|
|
754
813
|
}
|
|
@@ -867,6 +926,7 @@
|
|
|
867
926
|
this.populateAskAiLauncherTools(tools)
|
|
868
927
|
launcher.error.textContent = ''
|
|
869
928
|
launcher.promptTextarea.value = ASK_AI_DEFAULT_PROMPT
|
|
929
|
+
launcher.syncRunState()
|
|
870
930
|
launcher.setOpen(true)
|
|
871
931
|
}
|
|
872
932
|
formatGenerated(value) {
|
package/server/public/style.css
CHANGED
|
@@ -3698,9 +3698,9 @@ body.dark .swal2-styled.swal2-confirm{
|
|
|
3698
3698
|
*/
|
|
3699
3699
|
.noty_bar {
|
|
3700
3700
|
max-width: 300px !important;
|
|
3701
|
-
background:
|
|
3701
|
+
background: #1b1c1d !important;
|
|
3702
3702
|
color: white !important;
|
|
3703
|
-
border
|
|
3703
|
+
border: 1px solid rgba(255, 255, 255, 0.08) !important;
|
|
3704
3704
|
z-index: 1000000000000;
|
|
3705
3705
|
}
|
|
3706
3706
|
.noty_body a {
|
package/server/views/app.ejs
CHANGED
|
@@ -17093,7 +17093,16 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
|
17093
17093
|
return
|
|
17094
17094
|
}
|
|
17095
17095
|
if (messageType === "pinokio:ask-ai-launch") {
|
|
17096
|
-
openWithAgent(event.data)
|
|
17096
|
+
const opened = openWithAgent(event.data)
|
|
17097
|
+
if (event.source && event.data.launchId) {
|
|
17098
|
+
try {
|
|
17099
|
+
event.source.postMessage({
|
|
17100
|
+
e: "pinokio:ask-ai-launch-result",
|
|
17101
|
+
launchId: event.data.launchId,
|
|
17102
|
+
opened: opened !== false
|
|
17103
|
+
}, event.origin && event.origin !== "null" ? event.origin : "*")
|
|
17104
|
+
} catch (_) {}
|
|
17105
|
+
}
|
|
17097
17106
|
} else if (messageType === "pinokio:ask-ai-open-url") {
|
|
17098
17107
|
openWithUrl(event.data.url, {
|
|
17099
17108
|
workspaceCwd: typeof event.data.workspaceCwd === "string" ? event.data.workspaceCwd : ""
|
package/server/views/index.ejs
CHANGED
|
@@ -197,6 +197,15 @@ body.dark .context-menu-wrapper {
|
|
|
197
197
|
text-transform: none;
|
|
198
198
|
transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
|
|
199
199
|
}
|
|
200
|
+
.home-app-line .menu-btns > .open-actions-modal {
|
|
201
|
+
width: 28px;
|
|
202
|
+
min-width: 28px;
|
|
203
|
+
padding: 0 !important;
|
|
204
|
+
}
|
|
205
|
+
.home-app-line .menu-btns > .open-actions-modal i {
|
|
206
|
+
width: 14px;
|
|
207
|
+
font-size: 13px;
|
|
208
|
+
}
|
|
200
209
|
body.dark .home-app-line .menu-btns > .btn {
|
|
201
210
|
border-color: rgba(255, 255, 255, 0.075) !important;
|
|
202
211
|
background: rgba(255, 255, 255, 0.045) !important;
|
|
@@ -749,6 +758,8 @@ body.dark .home-search-form .home-apps-sort .ts-dropdown [data-selectable].optio
|
|
|
749
758
|
gap: 8px;
|
|
750
759
|
}
|
|
751
760
|
body.is-home {
|
|
761
|
+
--home-actions-drawer-width: min(420px, calc(100vw - 240px));
|
|
762
|
+
--home-actions-drawer-top: 0px;
|
|
752
763
|
--home-page-nav-bg: #ffffff;
|
|
753
764
|
--home-page-nav-border: rgba(15, 23, 42, 0.12);
|
|
754
765
|
--home-page-accent: #6b7280;
|
|
@@ -1164,6 +1175,69 @@ body.dark .home-actions-empty {
|
|
|
1164
1175
|
border-color: rgba(255, 255, 255, 0.12);
|
|
1165
1176
|
color: rgba(226, 232, 240, 0.58);
|
|
1166
1177
|
}
|
|
1178
|
+
@media only screen and (min-width: 961px) {
|
|
1179
|
+
body.is-home.home-actions-drawer-open main > .container {
|
|
1180
|
+
padding-right: calc(var(--home-actions-drawer-width) + 16px);
|
|
1181
|
+
}
|
|
1182
|
+
@keyframes homeActionsDrawerIn {
|
|
1183
|
+
from {
|
|
1184
|
+
opacity: 0.72;
|
|
1185
|
+
transform: translateX(18px);
|
|
1186
|
+
}
|
|
1187
|
+
to {
|
|
1188
|
+
opacity: 1;
|
|
1189
|
+
transform: translateX(0);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
@keyframes homeActionsDrawerOut {
|
|
1193
|
+
from {
|
|
1194
|
+
opacity: 1;
|
|
1195
|
+
transform: translateX(0);
|
|
1196
|
+
}
|
|
1197
|
+
to {
|
|
1198
|
+
opacity: 0.72;
|
|
1199
|
+
transform: translateX(18px);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
.home-actions-dialog.is-docked[open] {
|
|
1203
|
+
top: var(--home-actions-drawer-top);
|
|
1204
|
+
right: 0;
|
|
1205
|
+
bottom: 0;
|
|
1206
|
+
left: auto;
|
|
1207
|
+
width: var(--home-actions-drawer-width);
|
|
1208
|
+
max-height: none;
|
|
1209
|
+
height: calc(100vh - var(--home-actions-drawer-top));
|
|
1210
|
+
border-top: none;
|
|
1211
|
+
border-right: none;
|
|
1212
|
+
border-bottom: none;
|
|
1213
|
+
border-radius: 0;
|
|
1214
|
+
box-shadow: none;
|
|
1215
|
+
transform: none;
|
|
1216
|
+
animation: homeActionsDrawerIn 180ms cubic-bezier(0.22, 1, 0.36, 1);
|
|
1217
|
+
will-change: transform, opacity;
|
|
1218
|
+
}
|
|
1219
|
+
body.dark .home-actions-dialog.is-docked[open] {
|
|
1220
|
+
box-shadow: none;
|
|
1221
|
+
}
|
|
1222
|
+
.home-actions-dialog.is-docked.is-closing[open] {
|
|
1223
|
+
pointer-events: none;
|
|
1224
|
+
animation: homeActionsDrawerOut 130ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
|
|
1225
|
+
}
|
|
1226
|
+
.home-actions-dialog.is-docked::backdrop {
|
|
1227
|
+
background: transparent;
|
|
1228
|
+
}
|
|
1229
|
+
.home-actions-dialog.is-docked .home-actions-shell {
|
|
1230
|
+
height: 100%;
|
|
1231
|
+
min-height: 0;
|
|
1232
|
+
}
|
|
1233
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1234
|
+
.home-actions-dialog.is-docked[open],
|
|
1235
|
+
.home-actions-dialog.is-docked.is-closing[open] {
|
|
1236
|
+
animation: none;
|
|
1237
|
+
will-change: auto;
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1167
1241
|
#suggestion {
|
|
1168
1242
|
padding: 20px;
|
|
1169
1243
|
display: flex;
|
|
@@ -1452,8 +1526,8 @@ body.dark aside .current.selected {
|
|
|
1452
1526
|
>
|
|
1453
1527
|
<i class="fa-<%=item.starred ? "solid" : "regular"%> fa-star" aria-hidden="true"></i>
|
|
1454
1528
|
</button>
|
|
1455
|
-
<button class='btn open-menu open-actions-modal' type='button' data-dialog-id="home-actions-running-<%=index%>" aria-haspopup="dialog" title="
|
|
1456
|
-
<i class="fa-solid fa-
|
|
1529
|
+
<button class='btn open-menu open-actions-modal' type='button' data-dialog-id="home-actions-running-<%=index%>" aria-haspopup="dialog" aria-expanded="false" title="Open actions panel" aria-label="Open actions panel">
|
|
1530
|
+
<i class="fa-solid fa-list-ul" aria-hidden="true"></i>
|
|
1457
1531
|
</button>
|
|
1458
1532
|
<% const autolaunchRunningScript = !!(item.autolaunch_starting && item.autolaunch_script && item.running_scripts && item.running_scripts.some((s) => { const scriptName = s && (s.name || s.script_path || s.path || ""); return scriptName === item.autolaunch_script || String(scriptName).endsWith(`/${item.autolaunch_script}`) })) %>
|
|
1459
1533
|
<% if (item.autolaunch_starting && !autolaunchRunningScript) { %>
|
|
@@ -1551,8 +1625,8 @@ body.dark aside .current.selected {
|
|
|
1551
1625
|
>
|
|
1552
1626
|
<i class="fa-<%=item.starred ? "solid" : "regular"%> fa-star" aria-hidden="true"></i>
|
|
1553
1627
|
</button>
|
|
1554
|
-
<button class='btn open-menu open-actions-modal' type='button' data-dialog-id="home-actions-not-running-<%=index%>" aria-haspopup="dialog" title="
|
|
1555
|
-
<i class="fa-solid fa-
|
|
1628
|
+
<button class='btn open-menu open-actions-modal' type='button' data-dialog-id="home-actions-not-running-<%=index%>" aria-haspopup="dialog" aria-expanded="false" title="Open actions panel" aria-label="Open actions panel">
|
|
1629
|
+
<i class="fa-solid fa-list-ul" aria-hidden="true"></i>
|
|
1556
1630
|
</button>
|
|
1557
1631
|
<% if (notRunningTerminalOnlineCount > 0) { %>
|
|
1558
1632
|
<% const notRunningTerminalLabel = notRunningTerminalOnlineCount > 0 ? `${notRunningTerminalOnlineCount} terminal${notRunningTerminalOnlineCount === 1 ? "" : "s"} online` : "Terminals" %>
|
|
@@ -2488,6 +2562,10 @@ const startHomeAutolaunchPolling = () => {
|
|
|
2488
2562
|
startHomeAutolaunchPolling()
|
|
2489
2563
|
document.addEventListener("keydown", (e) => {
|
|
2490
2564
|
e = e || window.event;
|
|
2565
|
+
if (e.key === "Escape" && !hasHomeActionsBlockingOverlay() && closeActiveHomeActionsDrawer()) {
|
|
2566
|
+
e.preventDefault()
|
|
2567
|
+
return
|
|
2568
|
+
}
|
|
2491
2569
|
if (e.key === "ArrowUp") {
|
|
2492
2570
|
console.log("up arrow pressed");
|
|
2493
2571
|
selectedIndex = Math.max(selectedIndex-1, 0)
|
|
@@ -2583,12 +2661,6 @@ const closeContextMenuForNode = (node) => {
|
|
|
2583
2661
|
contextMenu.dataset.open = 'false'
|
|
2584
2662
|
}
|
|
2585
2663
|
}
|
|
2586
|
-
const dialog = node && typeof node.closest === 'function'
|
|
2587
|
-
? node.closest('.home-actions-dialog')
|
|
2588
|
-
: null
|
|
2589
|
-
if (dialog && dialog.open && typeof dialog.close === 'function') {
|
|
2590
|
-
dialog.close()
|
|
2591
|
-
}
|
|
2592
2664
|
}
|
|
2593
2665
|
window.PinokioHomeCloseContextMenu = closeContextMenuForNode
|
|
2594
2666
|
const setHomeActionsTab = (dialog, tabName) => {
|
|
@@ -2606,6 +2678,90 @@ const setHomeActionsTab = (dialog, tabName) => {
|
|
|
2606
2678
|
panel.hidden = !isActive
|
|
2607
2679
|
})
|
|
2608
2680
|
}
|
|
2681
|
+
const homeActionsDrawerMedia = window.matchMedia('(min-width: 961px)')
|
|
2682
|
+
const homeActionsReducedMotionMedia = window.matchMedia('(prefers-reduced-motion: reduce)')
|
|
2683
|
+
const isHomeActionsDrawerViewport = () => homeActionsDrawerMedia.matches
|
|
2684
|
+
const syncHomeActionsDrawerState = () => {
|
|
2685
|
+
const hasDockedDialog = Boolean(document.querySelector('.home-actions-dialog.is-docked[open]'))
|
|
2686
|
+
document.body.classList.toggle('home-actions-drawer-open', hasDockedDialog)
|
|
2687
|
+
}
|
|
2688
|
+
const setHomeActionsDrawerOffset = () => {
|
|
2689
|
+
const header = document.querySelector('body.is-home > header.navheader')
|
|
2690
|
+
const top = header ? Math.max(0, Math.round(header.getBoundingClientRect().bottom)) : 0
|
|
2691
|
+
document.body.style.setProperty('--home-actions-drawer-top', `${top}px`)
|
|
2692
|
+
}
|
|
2693
|
+
const setHomeActionsTriggerExpanded = (dialog, expanded) => {
|
|
2694
|
+
if (!dialog || !dialog.id) {
|
|
2695
|
+
return
|
|
2696
|
+
}
|
|
2697
|
+
document.querySelectorAll('.open-actions-modal').forEach((button) => {
|
|
2698
|
+
if (button.getAttribute('data-dialog-id') === dialog.id) {
|
|
2699
|
+
button.setAttribute('aria-expanded', expanded ? 'true' : 'false')
|
|
2700
|
+
}
|
|
2701
|
+
})
|
|
2702
|
+
}
|
|
2703
|
+
const closeHomeActionsDialog = (dialog) => {
|
|
2704
|
+
if (!dialog || !dialog.open) {
|
|
2705
|
+
return
|
|
2706
|
+
}
|
|
2707
|
+
const shouldAnimate = dialog.classList.contains('is-docked')
|
|
2708
|
+
&& isHomeActionsDrawerViewport()
|
|
2709
|
+
&& !homeActionsReducedMotionMedia.matches
|
|
2710
|
+
if (!shouldAnimate) {
|
|
2711
|
+
if (typeof dialog.close === 'function') {
|
|
2712
|
+
dialog.close()
|
|
2713
|
+
} else {
|
|
2714
|
+
dialog.removeAttribute('open')
|
|
2715
|
+
dialog.classList.remove('is-docked', 'is-closing')
|
|
2716
|
+
setHomeActionsTriggerExpanded(dialog, false)
|
|
2717
|
+
syncHomeActionsDrawerState()
|
|
2718
|
+
}
|
|
2719
|
+
return
|
|
2720
|
+
}
|
|
2721
|
+
if (dialog.classList.contains('is-closing')) {
|
|
2722
|
+
return
|
|
2723
|
+
}
|
|
2724
|
+
dialog.classList.add('is-closing')
|
|
2725
|
+
let finished = false
|
|
2726
|
+
const finishClose = () => {
|
|
2727
|
+
if (finished) {
|
|
2728
|
+
return
|
|
2729
|
+
}
|
|
2730
|
+
finished = true
|
|
2731
|
+
dialog.removeEventListener('animationend', finishClose)
|
|
2732
|
+
if (dialog.open) {
|
|
2733
|
+
dialog.close()
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
dialog.addEventListener('animationend', finishClose)
|
|
2737
|
+
window.setTimeout(finishClose, 180)
|
|
2738
|
+
}
|
|
2739
|
+
const closeHomeActionsDialogs = (exceptDialog = null) => {
|
|
2740
|
+
document.querySelectorAll('.home-actions-dialog[open]').forEach((dialog) => {
|
|
2741
|
+
if (dialog === exceptDialog) {
|
|
2742
|
+
return
|
|
2743
|
+
}
|
|
2744
|
+
if (typeof dialog.close === 'function') {
|
|
2745
|
+
dialog.close()
|
|
2746
|
+
} else {
|
|
2747
|
+
dialog.removeAttribute('open')
|
|
2748
|
+
dialog.classList.remove('is-docked', 'is-closing')
|
|
2749
|
+
setHomeActionsTriggerExpanded(dialog, false)
|
|
2750
|
+
}
|
|
2751
|
+
})
|
|
2752
|
+
syncHomeActionsDrawerState()
|
|
2753
|
+
}
|
|
2754
|
+
document.querySelectorAll('.home-actions-dialog').forEach((dialog) => {
|
|
2755
|
+
if (dialog.dataset.homeActionsBound === 'true') {
|
|
2756
|
+
return
|
|
2757
|
+
}
|
|
2758
|
+
dialog.dataset.homeActionsBound = 'true'
|
|
2759
|
+
dialog.addEventListener('close', () => {
|
|
2760
|
+
dialog.classList.remove('is-docked', 'is-closing')
|
|
2761
|
+
setHomeActionsTriggerExpanded(dialog, false)
|
|
2762
|
+
syncHomeActionsDrawerState()
|
|
2763
|
+
})
|
|
2764
|
+
})
|
|
2609
2765
|
const openHomeActionsDialog = (button) => {
|
|
2610
2766
|
if (!button) {
|
|
2611
2767
|
return
|
|
@@ -2615,13 +2771,61 @@ const openHomeActionsDialog = (button) => {
|
|
|
2615
2771
|
if (!dialog) {
|
|
2616
2772
|
return
|
|
2617
2773
|
}
|
|
2774
|
+
if (dialog.open) {
|
|
2775
|
+
closeHomeActionsDialog(dialog)
|
|
2776
|
+
return
|
|
2777
|
+
}
|
|
2778
|
+
closeHomeActionsDialogs(dialog)
|
|
2618
2779
|
setHomeActionsTab(dialog, button.getAttribute('data-default-tab') || 'run')
|
|
2619
|
-
if (
|
|
2780
|
+
if (isHomeActionsDrawerViewport()) {
|
|
2781
|
+
setHomeActionsDrawerOffset()
|
|
2782
|
+
dialog.classList.remove('is-closing')
|
|
2783
|
+
dialog.classList.add('is-docked')
|
|
2784
|
+
if (!dialog.open) {
|
|
2785
|
+
if (typeof dialog.show === 'function') {
|
|
2786
|
+
dialog.show()
|
|
2787
|
+
} else {
|
|
2788
|
+
dialog.setAttribute('open', '')
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
button.setAttribute('aria-expanded', 'true')
|
|
2792
|
+
syncHomeActionsDrawerState()
|
|
2793
|
+
} else if (typeof dialog.showModal === 'function') {
|
|
2794
|
+
dialog.classList.remove('is-docked')
|
|
2620
2795
|
dialog.showModal()
|
|
2796
|
+
button.setAttribute('aria-expanded', 'true')
|
|
2621
2797
|
} else {
|
|
2798
|
+
dialog.classList.remove('is-docked')
|
|
2622
2799
|
dialog.setAttribute('open', '')
|
|
2800
|
+
button.setAttribute('aria-expanded', 'true')
|
|
2623
2801
|
}
|
|
2624
2802
|
}
|
|
2803
|
+
const closeActiveHomeActionsDrawer = () => {
|
|
2804
|
+
const dialog = document.querySelector('.home-actions-dialog.is-docked[open]')
|
|
2805
|
+
if (!dialog) {
|
|
2806
|
+
return false
|
|
2807
|
+
}
|
|
2808
|
+
if (typeof dialog.close === 'function') {
|
|
2809
|
+
closeHomeActionsDialog(dialog)
|
|
2810
|
+
} else {
|
|
2811
|
+
dialog.removeAttribute('open')
|
|
2812
|
+
dialog.classList.remove('is-docked', 'is-closing')
|
|
2813
|
+
setHomeActionsTriggerExpanded(dialog, false)
|
|
2814
|
+
syncHomeActionsDrawerState()
|
|
2815
|
+
}
|
|
2816
|
+
return true
|
|
2817
|
+
}
|
|
2818
|
+
const hasHomeActionsBlockingOverlay = () => {
|
|
2819
|
+
return Boolean(document.querySelector('.swal2-container.swal2-shown, .swal2-container.swal2-backdrop-show'))
|
|
2820
|
+
}
|
|
2821
|
+
const handleHomeActionsDrawerMediaChange = () => {
|
|
2822
|
+
closeHomeActionsDialogs()
|
|
2823
|
+
}
|
|
2824
|
+
if (typeof homeActionsDrawerMedia.addEventListener === 'function') {
|
|
2825
|
+
homeActionsDrawerMedia.addEventListener('change', handleHomeActionsDrawerMediaChange)
|
|
2826
|
+
} else if (typeof homeActionsDrawerMedia.addListener === 'function') {
|
|
2827
|
+
homeActionsDrawerMedia.addListener(handleHomeActionsDrawerMediaChange)
|
|
2828
|
+
}
|
|
2625
2829
|
const navigateHomeAppLine = (line) => {
|
|
2626
2830
|
if (!line) {
|
|
2627
2831
|
return
|
|
@@ -2866,13 +3070,13 @@ document.addEventListener("click", async (e) => {
|
|
|
2866
3070
|
e.preventDefault()
|
|
2867
3071
|
e.stopPropagation()
|
|
2868
3072
|
const dialog = target.closest(".home-actions-dialog")
|
|
2869
|
-
if (dialog
|
|
2870
|
-
dialog
|
|
3073
|
+
if (dialog) {
|
|
3074
|
+
closeHomeActionsDialog(dialog)
|
|
2871
3075
|
}
|
|
2872
3076
|
return
|
|
2873
3077
|
}
|
|
2874
3078
|
if (e.target.classList.contains("home-actions-dialog")) {
|
|
2875
|
-
e.target
|
|
3079
|
+
closeHomeActionsDialog(e.target)
|
|
2876
3080
|
return
|
|
2877
3081
|
}
|
|
2878
3082
|
if (e.target.classList.contains("home-actions-tab")) {
|